Map hostedtool.CodeInterpreter to the Anthropic code_execution tool and parse its result blocks - #637
Conversation
4ff822a to
528d67f
Compare
This comment has been minimized.
This comment has been minimized.
528d67f to
5cde5d2
Compare
This comment has been minimized.
This comment has been minimized.
Wire the hosted *hostedtool.CodeInterpreter marker into the Anthropic provider so it enables the server-side code_execution tool, and parse the resulting server_tool_use / code_execution_tool_result response blocks into structured message.CodeInterpreterToolCallContent and CodeInterpreterToolResultContent. This mirrors the existing OpenAI Responses provider mapping so hosted code interpretation behaves the same across providers.
5cde5d2 to
47d149a
Compare
This comment has been minimized.
This comment has been minimized.
# Conflicts: # provider/anthropicprovider/agent.go # provider/anthropicprovider/agent_test.go
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Pull request overview
This PR adds hosted code-interpreter support to the Anthropic provider by mapping the framework’s *hostedtool.CodeInterpreter marker to Anthropic’s server-side code_execution tool, and by parsing corresponding response blocks into the framework’s structured message.CodeInterpreterToolCallContent / message.CodeInterpreterToolResultContent content types.
Changes:
- Map
*hostedtool.CodeInterpreterto Anthropiccode_execution_20250825tool parameters in request construction. - Parse Anthropic
server_tool_use(code_execution) blocks intoCodeInterpreterToolCallContentwith base64-encoded Python source (text/x-python). - Parse Anthropic
code_execution_tool_resultblocks intoCodeInterpreterToolResultContentincluding stdout/stderr and hosted file outputs, with new black-box tests covering request/response behavior.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| provider/anthropicprovider/agent.go | Adds CodeInterpreter → Anthropic code_execution tool mapping and response block parsing for server-side code execution. |
| provider/anthropicprovider/agent_test.go | Adds tests validating request tool emission and structured parsing of code execution call/result blocks. |
| if res.Stderr != "" { | ||
| result.Outputs = append(result.Outputs, &message.TextContent{ | ||
| Text: res.Stderr, | ||
| ContentHeader: message.ContentHeader{RawRepresentation: res}, | ||
| }) | ||
| } | ||
| if res.ErrorCode != "" { | ||
| result.Outputs = append(result.Outputs, &message.TextContent{ | ||
| Text: string(res.ErrorCode), | ||
| ContentHeader: message.ContentHeader{RawRepresentation: res}, | ||
| }) | ||
| } |
# Conflicts: # provider/anthropicprovider/agent_test.go
Parity review: PR #637 — Anthropic
|
There was a problem hiding this comment.
Generated by Go API Consistency Review Agent · sonnet46 · 48.8 AIC · ⌖ 5.81 AIC · ⊞ 6K
| }) | ||
| } | ||
| if res.Stderr != "" { | ||
| result.Outputs = append(result.Outputs, &message.TextContent{ |
There was a problem hiding this comment.
Parity issue: stderr mapped to TextContent instead of ErrorContent
The upstream Python implementation (agent_framework_anthropic/_chat_client.py, case "code_execution_tool_result") maps stderr to Content.from_error(message=content_block.content.stderr), which produces an ErrorContent node. Here the Go implementation maps stderr to &message.TextContent{}. Callers that switch on content type (e.g., to distinguish diagnostic output from normal output) will behave differently across SDKs.
Suggestion: use &message.ErrorContent{Message: res.Stderr, ...} for stderr to match Python semantics. Similarly, error_code (line 339) maps to TextContent in Go but to Content.from_error() in Python — both should use ErrorContent.
Upstream reference: python/packages/anthropic/agent_framework_anthropic/_chat_client.py lines 1338–1356.
| }, | ||
| } | ||
| } | ||
| contents = append(contents, call) |
There was a problem hiding this comment.
Parity note: code_execution tool-call input encoding differs from Python
The Python implementation (_chat_client.py, line 1252–1265) wraps the raw input block as Content.from_text(text=str(content_block.input)) — a plain TextContent containing the string representation of the input dict.
This Go implementation extracts the "code" key from the JSON payload and stores it base64-encoded as DataContent with media_type: text/x-python. While arguably more structured (and analogous to how OpenAI Responses surfaces it), this is a deliberate cross-SDK divergence: a consumer inspecting CodeInterpreterToolCallContent.Inputs[0] will receive a DataContent in Go but a TextContent in Python.
If this encoding difference is intentional, please document it (e.g., in a CHANGELOG entry or an inline comment noting the divergence from Python). If it should align, switch to &message.TextContent{Text: code} or align the Python side to emit DataContent.
What
Wire the hosted
*hostedtool.CodeInterpretermarker into the Anthropic provider (provider/anthropicprovider/agent.go):*hostedtool.CodeInterpreteronto Anthropic's server-sidecode_executiontool (CodeExecutionTool20250825Param), appended toparams.Tools.buildBlockcases for theserver_tool_use(code_execution) andcode_execution_tool_resultblocks, surfacing them as structuredmessage.CodeInterpreterToolCallContent(code as atext/x-pythonDataContent) andmessage.CodeInterpreterToolResultContent(stdout/stderr/error asTextContent, output files asHostedFileContent).Why
This is the code-execution sibling of the existing web-search hosted-tool support. The OpenAI Responses provider already maps
*hostedtool.CodeInterpreter(responses.go,case *hostedtool.CodeInterpreter) and emits the same structuredCodeInterpreterToolCall/CodeInterpreterToolResultcontent. The Anthropic provider had no hosted-tool branch and nocode_executionresult parsing, so hosted code interpretation silently did nothing on Anthropic. This change brings Anthropic in line with the OpenAI/.NET structured mapping so the same agent code works across providers.Tests
Added to the canonical
agent_test.go(black-box, reusing the existinghttptestharness):TestCodeInterpreterToolMapsToCodeExecutionasserts the request builder emits acode_execution/code_execution_20250825tool intools.TestCodeInterpreterResultBlocksBecomeStructuredContentfeedsserver_tool_use+code_execution_tool_resultblocks and asserts structuredCodeInterpreterToolCallContent(decoded Python source) andCodeInterpreterToolResultContent(stdout + hosted file output) are produced.go build ./...,go vet ./provider/anthropicprovider/..., andgo test ./provider/anthropicprovider/...all pass.Open design questions
CodeExecutionTool20250825Param. The SDK also exposes newer variants (20260120,20260521); should the version be configurable (e.g. viaAdditionalProperties) or track the latest?hostedtool.CodeInterpreter.Inputs(hosted file IDs) are not yet forwarded — Anthropic'scode_executioncontainer model differs from OpenAI's. Follow-up if pre-seeding files is needed.server_tool_useinput arrives viainput_json_deltaand is not yet accumulated into the call's code block. Worth a follow-up if streaming code capture is required.encrypted_stdout(EncryptedCodeExecutionResultBlock) is not surfaced; only plaintext stdout/stderr and output files are mapped today.