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:
@@ -188,6 +188,31 @@ func TestSanitizeHistoryForProvider_PlainConversation(t *testing.T) {
|
||||
assertRoles(t, result, "user", "assistant", "user", "assistant")
|
||||
}
|
||||
|
||||
func TestSanitizeHistoryForProvider_DuplicateToolResults(t *testing.T) {
|
||||
history := []providers.Message{
|
||||
msg("user", "do something"),
|
||||
assistantWithTools("A", "B"),
|
||||
toolResult("A"),
|
||||
toolResult("B"),
|
||||
toolResult("A"), // duplicate
|
||||
toolResult("B"), // duplicate
|
||||
msg("assistant", "done"),
|
||||
}
|
||||
|
||||
result := sanitizeHistoryForProvider(history)
|
||||
if len(result) != 5 {
|
||||
t.Fatalf("expected 5 messages, got %d: %+v", len(result), roles(result))
|
||||
}
|
||||
assertRoles(t, result, "user", "assistant", "tool", "tool", "assistant")
|
||||
// Verify the kept tool results have the correct IDs
|
||||
if result[2].ToolCallID != "A" {
|
||||
t.Errorf("expected tool result A, got %q", result[2].ToolCallID)
|
||||
}
|
||||
if result[3].ToolCallID != "B" {
|
||||
t.Errorf("expected tool result B, got %q", result[3].ToolCallID)
|
||||
}
|
||||
}
|
||||
|
||||
func roles(msgs []providers.Message) []string {
|
||||
r := make([]string, len(msgs))
|
||||
for i, m := range msgs {
|
||||
|
||||
Reference in New Issue
Block a user