Skip to content

fix(anthropic): support Claude 4.x models and mixed-content tool calls#1500

Open
ming-hsien wants to merge 1 commit into
tmc:mainfrom
ming-hsien:main
Open

fix(anthropic): support Claude 4.x models and mixed-content tool calls#1500
ming-hsien wants to merge 1 commit into
tmc:mainfrom
ming-hsien:main

Conversation

@ming-hsien
Copy link
Copy Markdown

Problem

Two bugs that prevent langchaingo from working correctly with Claude 4.x models (e.g. claude-opus-4-7, claude-sonnet-4-6):

1. temperature field causes HTTP 400 on Claude 4.x

messagePayload and MessageRequest both declare Temperature float64 \json:"temperature"`withoutomitempty. This means every API request serializes "temperature": 0even when the caller never set a temperature. Claude 4.x models have deprecated thetemperature` parameter and return:

400: temperature is deprecated for this model.

2. Mixed text + tool_use responses break conversation history

When Claude returns a response that contains both a text block and one or more tool_use blocks, processAnthropicResponse correctly produces one ContentChoice per content block. However, handleAIMessage only inspected Parts[0] of the reassembled MessageContent. If the first part was TextContent, all subsequent ToolCall parts were silently dropped when writing the assistant message back to history.

On the next turn, the tool_result block referenced a tool_use ID that no longer existed in the assistant message, causing Anthropic to reject the request with:

400: Each tool_result block must have a corresponding tool_use block in the previous message.

Fix

  • Add omitempty to Temperature in messagePayload and MessageRequest so the field is omitted when not explicitly set.
  • Rewrite handleAIMessage to iterate over all Parts instead of only Parts[0], correctly emitting both text and tool_use content blocks in a single assistant message.

Tested with

  • claude-opus-4-7
  • claude-sonnet-4-6

- Add omitempty to temperature field in messagePayload and MessageRequest
  so that unset temperature (0.0) is not serialized into the request body.
  Claude 4.x models (e.g. claude-opus-4-7) have deprecated the temperature
  parameter and return HTTP 400 when it is present.

- Rewrite handleAIMessage to iterate over all Parts instead of only Parts[0].
  When Claude returns a response containing both a text block and tool_use
  blocks, processAnthropicResponse produces one ContentChoice per block.
  The caller reassembles them into a single MessageContent with mixed Parts
  (TextContent followed by ToolCall). The original implementation only
  inspected Parts[0], so ToolCall entries were silently dropped from the
  assistant message written to history. On the next turn Anthropic rejected
  the request with "tool_result block has no corresponding tool_use block".
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