From 1fbcf8bb8b769f7aad148b538646e2f5324edaca Mon Sep 17 00:00:00 2001 From: Juergen Kunz Date: Tue, 20 Jan 2026 03:56:10 +0000 Subject: [PATCH] fix(driveragent): save tool_calls in message history for native tool calling When using native tool calling, the assistant's tool_calls must be saved in message history. Without this, the model doesn't know it already called a tool and loops indefinitely calling the same tool. This fix saves tool_calls in both startTaskWithNativeTools and continueWithNativeTools methods. Also updates @push.rocks/smartai to v0.13.3 for tool_calls forwarding support. --- package.json | 2 +- pnpm-lock.yaml | 10 ++++----- ts/smartagent.classes.driveragent.ts | 33 ++++++++++++++++++++++++---- 3 files changed, 35 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index 8be8b09..bd7fc93 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "@types/node": "^25.0.2" }, "dependencies": { - "@push.rocks/smartai": "^0.13.1", + "@push.rocks/smartai": "^0.13.3", "@push.rocks/smartbrowser": "^2.0.8", "@push.rocks/smartdeno": "^1.2.0", "@push.rocks/smartfs": "^1.2.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 00c4c43..ef2ec56 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,8 +9,8 @@ importers: .: dependencies: '@push.rocks/smartai': - specifier: ^0.13.1 - version: 0.13.1(typescript@5.9.3)(ws@8.18.3)(zod@3.25.76) + specifier: ^0.13.3 + version: 0.13.3(typescript@5.9.3)(ws@8.18.3)(zod@3.25.76) '@push.rocks/smartbrowser': specifier: ^2.0.8 version: 2.0.8(typescript@5.9.3) @@ -844,8 +844,8 @@ packages: '@push.rocks/qenv@6.1.3': resolution: {integrity: sha512-+z2hsAU/7CIgpYLFqvda8cn9rUBMHqLdQLjsFfRn5jPoD7dJ5rFlpkbhfM4Ws8mHMniwWaxGKo+q/YBhtzRBLg==} - '@push.rocks/smartai@0.13.1': - resolution: {integrity: sha512-V9J6a+rjBkFpdFnC6OBm8CbEtqCfJnEsUmNKfRUOiTa+VIVtD4OOceraZah6kGHWltUhZ1XV4eLWwFf4+YO3NA==} + '@push.rocks/smartai@0.13.3': + resolution: {integrity: sha512-VDZzHs101hpGMmUaectuLfcME4kHpuOS7o5ffuGk5lYl383foyAN71+5v441jpk/gLDNf2KhDACR/d2O4n90Ag==} '@push.rocks/smartarchive@4.2.4': resolution: {integrity: sha512-uiqVAXPxmr8G5rv3uZvZFMOCt8l7cZC3nzvsy4YQqKf/VkPhKIEX+b7LkAeNlxPSYUiBQUkNRoawg9+5BaMcHg==} @@ -5172,7 +5172,7 @@ snapshots: '@push.rocks/smartlog': 3.1.10 '@push.rocks/smartpath': 6.0.0 - '@push.rocks/smartai@0.13.1(typescript@5.9.3)(ws@8.18.3)(zod@3.25.76)': + '@push.rocks/smartai@0.13.3(typescript@5.9.3)(ws@8.18.3)(zod@3.25.76)': dependencies: '@anthropic-ai/sdk': 0.71.2(zod@3.25.76) '@mistralai/mistralai': 1.12.0 diff --git a/ts/smartagent.classes.driveragent.ts b/ts/smartagent.classes.driveragent.ts index f5168ea..ab2a011 100644 --- a/ts/smartagent.classes.driveragent.ts +++ b/ts/smartagent.classes.driveragent.ts @@ -517,12 +517,24 @@ Your complete output here this.isInThinkingMode = false; // Add assistant response to history - const historyMessage: plugins.smartai.ChatMessage = { + const historyMessage: any = { role: 'assistant', content: response.message || '', reasoning: response.thinking || response.reasoning, }; - this.messageHistory.push(historyMessage); + + // CRITICAL: Preserve tool_calls in history for native tool calling + // Without this, the model doesn't know it already called a tool and loops forever + if (response.toolCalls && response.toolCalls.length > 0) { + historyMessage.tool_calls = response.toolCalls.map((tc: any) => ({ + function: { + name: tc.function.name, + arguments: tc.function.arguments, + }, + })); + } + + this.messageHistory.push(historyMessage as unknown as plugins.smartai.ChatMessage); // Convert Ollama tool calls to our format let toolCalls: interfaces.INativeToolCall[] | undefined; @@ -639,11 +651,24 @@ Your complete output here this.isInThinkingMode = false; // Add assistant response to history - this.messageHistory.push({ + const historyMessage: any = { role: 'assistant', content: response.message || '', reasoning: response.thinking || response.reasoning, - }); + }; + + // CRITICAL: Preserve tool_calls in history for native tool calling + // Without this, the model doesn't know it already called a tool and loops forever + if (response.toolCalls && response.toolCalls.length > 0) { + historyMessage.tool_calls = response.toolCalls.map((tc: any) => ({ + function: { + name: tc.function.name, + arguments: tc.function.arguments, + }, + })); + } + + this.messageHistory.push(historyMessage as unknown as plugins.smartai.ChatMessage); // Convert Ollama tool calls to our format let toolCalls: interfaces.INativeToolCall[] | undefined;