mirror of
https://github.com/sipeed/picoclaw.git
synced 2026-06-12 18:08:54 +00:00
fix(provider): deduplicate tool results and merge consecutive tool_result blocks for Anthropic API (#1793)
Anthropic API returns 400 when multiple tool_result blocks share the same tool_use_id, or when consecutive tool results are sent as separate user messages. This fix: 1. Adds ToolCallID deduplication in sanitizeHistoryForProvider (context.go) to drop duplicate tool results before sending to any provider. 2. Merges consecutive tool result messages into a single user message with multiple tool_result content blocks in Anthropic's buildRequestBody, for both "user" (with ToolCallID) and "tool" role messages. 3. Adds tests for both behaviors. Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -678,8 +678,21 @@ func sanitizeHistoryForProvider(history []providers.Message) []providers.Message
|
||||
// like DeepSeek that enforce: "An assistant message with 'tool_calls' must
|
||||
// be followed by tool messages responding to each 'tool_call_id'."
|
||||
final := make([]providers.Message, 0, len(sanitized))
|
||||
seenToolCallID := make(map[string]bool)
|
||||
for i := 0; i < len(sanitized); i++ {
|
||||
msg := sanitized[i]
|
||||
|
||||
// Deduplicate tool results by ToolCallID
|
||||
if msg.Role == "tool" && msg.ToolCallID != "" {
|
||||
if seenToolCallID[msg.ToolCallID] {
|
||||
logger.DebugCF("agent", "Dropping duplicate tool result", map[string]any{
|
||||
"tool_call_id": msg.ToolCallID,
|
||||
})
|
||||
continue
|
||||
}
|
||||
seenToolCallID[msg.ToolCallID] = true
|
||||
}
|
||||
|
||||
if msg.Role == "assistant" && len(msg.ToolCalls) > 0 {
|
||||
// Collect expected tool_call IDs
|
||||
expected := make(map[string]bool, len(msg.ToolCalls))
|
||||
|
||||
Reference in New Issue
Block a user