Skip to content

fix(provider): harden Claude tool-call adjacency normalization#5719

Closed
chrisolszewski wants to merge 5 commits into
anomalyco:devfrom
chrisolszewski:fix/anthropic-tool-adjacency
Closed

fix(provider): harden Claude tool-call adjacency normalization#5719
chrisolszewski wants to merge 5 commits into
anomalyco:devfrom
chrisolszewski:fix/anthropic-tool-adjacency

Conversation

@chrisolszewski

Copy link
Copy Markdown
Contributor

Summary

Fixes Anthropic API 400 errors caused by incorrect message adjacency when using tool calls. Anthropic requires that tool calls in an assistant message be the last content blocks (terminal tool calls). This PR implements a "Terminal Suffix" strategy to strictly enforce this.

Key Changes

  • Terminal Suffix Normalization: Ensures assistant messages always end with a contiguous block of tool calls. Any text following a tool call is moved to a new subsequent assistant message.
  • Safe ID Sanitization: Hardens sanitizeToolParts to avoid ID collisions using a Map + base64url fallback, ensuring uniqueness even when sanitization modifies IDs.
  • Synthetic Attachment Handling: Moves synthetic "attachment" user messages (generated by tools) to follow tool results, maintaining correct conversation flow.
  • Type Safety: Strengthened type guards (isToolCallPart) to reject malformed arrays and require valid tool names.
  • Cleanup: Removed unsafe casts and duplicate metadata emission.

Verification

  • Unit Tests:
    • packages/opencode/test/provider/transform.test.ts: Added coverage for split/duplicate/partial results, ID collision avoidance, and idempotence.
    • packages/opencode/test/provider/anthropic-regression.test.ts: Added regression test matching the specific failure shape (tool call followed by text).
  • Manual Verification: Verified against local E2E harness with Anthropic models (Claude 3.5 Sonnet) ensuring no 400 errors on complex tool usage patterns.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant