From a1fd2c4ddc7a0cf7a3d7caf062b3f3267ed6b385 Mon Sep 17 00:00:00 2001 From: rcourtman Date: Thu, 29 Jan 2026 08:19:55 +0000 Subject: [PATCH] fix(ai): skip orphaned tool calls when pruning messages When pruning older messages to fit context limits, we may cut off a user message that preceded an assistant message with tool calls. This leaves an orphaned tool call sequence at the start. Extend pruneMessagesForModel to: - Skip leading assistant messages with tool calls - Also skip their following tool results - Ensures clean message sequence for all providers --- internal/ai/chat/agentic.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/internal/ai/chat/agentic.go b/internal/ai/chat/agentic.go index 2ff0263b6..c50546a79 100644 --- a/internal/ai/chat/agentic.go +++ b/internal/ai/chat/agentic.go @@ -1251,10 +1251,23 @@ func pruneMessagesForModel(messages []Message) []Message { start := len(messages) - MaxContextMessagesLimit pruned := messages[start:] + + // Skip leading tool results (orphaned from pruned tool calls) for len(pruned) > 0 && pruned[0].ToolResult != nil { pruned = pruned[1:] } + // If we start with an assistant message that has tool calls, + // skip it and its following tool results — we've pruned the + // user message that preceded it, so the sequence is broken. + for len(pruned) > 0 && pruned[0].Role == "assistant" && len(pruned[0].ToolCalls) > 0 { + pruned = pruned[1:] + // Also skip the tool results that followed + for len(pruned) > 0 && pruned[0].ToolResult != nil { + pruned = pruned[1:] + } + } + return pruned }