From 9ad039f77bca4e5e37937e5adcb41b43a0f71863 Mon Sep 17 00:00:00 2001 From: Juergen Kunz Date: Tue, 20 Jan 2026 02:03:20 +0000 Subject: [PATCH] feat(provider.ollama): add chain-of-thought reasoning support to chat messages and Ollama provider --- changelog.md | 7 +++++++ ts/00_commitinfo_data.ts | 2 +- ts/abstract.classes.multimodal.ts | 4 ++++ ts/provider.ollama.ts | 21 ++++++++++++++++----- 4 files changed, 28 insertions(+), 6 deletions(-) diff --git a/changelog.md b/changelog.md index 93e0f89..a4f73d7 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,12 @@ # Changelog +## 2026-01-20 - 0.13.0 - feat(provider.ollama) +add chain-of-thought reasoning support to chat messages and Ollama provider + +- Added optional reasoning?: string to chat message and chat response interfaces to surface chain-of-thought data. +- Propagates reasoning from message history into formatted requests sent to Ollama. +- Maps Ollama response fields (thinking or reasoning) into ChatResponse.reasoning so downstream code can access model reasoning output. + ## 2026-01-20 - 0.12.1 - fix(docs) update documentation: clarify provider capabilities, add provider capabilities summary, polish examples and formatting, and remove Serena project config diff --git a/ts/00_commitinfo_data.ts b/ts/00_commitinfo_data.ts index bb7706b..4b867a2 100644 --- a/ts/00_commitinfo_data.ts +++ b/ts/00_commitinfo_data.ts @@ -3,6 +3,6 @@ */ export const commitinfo = { name: '@push.rocks/smartai', - version: '0.12.1', + version: '0.13.0', description: 'SmartAi is a versatile TypeScript library designed to facilitate integration and interaction with various AI models, offering functionalities for chat, audio generation, document processing, and vision tasks.' } diff --git a/ts/abstract.classes.multimodal.ts b/ts/abstract.classes.multimodal.ts index 5189b12..7c3fac7 100644 --- a/ts/abstract.classes.multimodal.ts +++ b/ts/abstract.classes.multimodal.ts @@ -8,6 +8,8 @@ export interface ChatMessage { content: string; /** Base64-encoded images for vision-capable models */ images?: string[]; + /** Chain-of-thought reasoning for GPT-OSS models (e.g., Ollama) */ + reasoning?: string; } /** @@ -35,6 +37,8 @@ export interface StreamingChatOptions extends ChatOptions { export interface ChatResponse { role: 'assistant'; message: string; + /** Chain-of-thought reasoning from reasoning models */ + reasoning?: string; } /** diff --git a/ts/provider.ollama.ts b/ts/provider.ollama.ts index f78c67a..0a4a35a 100644 --- a/ts/provider.ollama.ts +++ b/ts/provider.ollama.ts @@ -205,13 +205,16 @@ export class OllamaProvider extends MultiModalModel { public async chat(optionsArg: ChatOptions): Promise { // Format messages for Ollama const historyMessages = optionsArg.messageHistory.map((msg) => { - const formatted: { role: string; content: string; images?: string[] } = { + const formatted: { role: string; content: string; images?: string[]; reasoning?: string } = { role: msg.role, content: msg.content, }; if (msg.images && msg.images.length > 0) { formatted.images = msg.images; } + if (msg.reasoning) { + formatted.reasoning = msg.reasoning; + } return formatted; }); @@ -254,6 +257,7 @@ export class OllamaProvider extends MultiModalModel { return { role: 'assistant' as const, message: result.message.content, + reasoning: result.message.thinking || result.message.reasoning, }; } @@ -283,6 +287,7 @@ export class OllamaProvider extends MultiModalModel { return { role: 'assistant' as const, message: response.message, + reasoning: response.thinking, }; } @@ -296,15 +301,18 @@ export class OllamaProvider extends MultiModalModel { const timeout = optionsArg.timeout || this.defaultTimeout; const modelOptions = { ...this.defaultOptions, ...optionsArg.options }; - // Format history messages with optional images + // Format history messages with optional images and reasoning const historyMessages = optionsArg.messageHistory.map((msg) => { - const formatted: { role: string; content: string; images?: string[] } = { + const formatted: { role: string; content: string; images?: string[]; reasoning?: string } = { role: msg.role, content: msg.content, }; if (msg.images && msg.images.length > 0) { formatted.images = msg.images; } + if (msg.reasoning) { + formatted.reasoning = msg.reasoning; + } return formatted; }); @@ -410,15 +418,18 @@ export class OllamaProvider extends MultiModalModel { const timeout = optionsArg.timeout || this.defaultTimeout; const modelOptions = { ...this.defaultOptions, ...optionsArg.options }; - // Format history messages with optional images + // Format history messages with optional images and reasoning const historyMessages = optionsArg.messageHistory.map((msg) => { - const formatted: { role: string; content: string; images?: string[] } = { + const formatted: { role: string; content: string; images?: string[]; reasoning?: string } = { role: msg.role, content: msg.content, }; if (msg.images && msg.images.length > 0) { formatted.images = msg.images; } + if (msg.reasoning) { + formatted.reasoning = msg.reasoning; + } return formatted; });