From 170c23acabe730738331cf08b677e6d6a922d4ec Mon Sep 17 00:00:00 2001 From: clawtom Date: Mon, 9 Mar 2026 13:11:26 +0000 Subject: [PATCH] fix: populate tool_calls in conversation history for streamEvents When streamEvents() saves the final AI response to conversation history, it created an AIMessage with only the text content. Any tool calls made during execution were discarded, causing getConversationHistory() to return AIMessages with an empty tool_calls array. Fix: track tool calls from on_tool_start events as the agent runs, then pass them to the AIMessage constructor when saving to history. The on_tool_start event provides the tool name, input args, and run_id (used as the call id) in a provider-agnostic way. Fixes #8 Co-Authored-By: Claude Sonnet 4.6 --- packages/mcp-use/src/agents/mcp_agent.ts | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/packages/mcp-use/src/agents/mcp_agent.ts b/packages/mcp-use/src/agents/mcp_agent.ts index 7730286b..4eea8f3e 100644 --- a/packages/mcp-use/src/agents/mcp_agent.ts +++ b/packages/mcp-use/src/agents/mcp_agent.ts @@ -966,6 +966,7 @@ export class MCPAgent { let eventCount = 0 let totalResponseLength = 0 let finalResponse = '' + const capturedToolCalls: Array<{ name: string; args: Record; id?: string }> = [] // Enhance query with schema information if structured output is requested if (outputSchema) { @@ -1042,6 +1043,16 @@ export class MCPAgent { totalResponseLength += event.data.chunk.content.length } + // Capture tool calls as they are invoked, for inclusion in conversation history + if (event.event === 'on_tool_start') { + const toolInput = event.data?.input + capturedToolCalls.push({ + name: event.name, + args: toolInput && typeof toolInput === 'object' ? toolInput as Record : { input: toolInput }, + id: event.run_id, + }) + } + yield event // Capture final response from chain end event @@ -1130,8 +1141,13 @@ export class MCPAgent { } as unknown as StreamEvent } } else if (this.memoryEnabled && finalResponse) { - // Add the final AI response to conversation history if memory is enabled - this.addToHistory(new AIMessage(finalResponse)) + // Add the final AI response to conversation history if memory is enabled. + // Include any tool calls captured during execution so getConversationHistory() + // returns AIMessages with a populated tool_calls array. + this.addToHistory(new AIMessage({ + content: finalResponse, + tool_calls: capturedToolCalls.length > 0 ? capturedToolCalls : undefined, + })) } logger.info(`🎉 StreamEvents complete - ${eventCount} events emitted`)