Conversation
… string
The Responses API and the Agents SDK both carry function_call.arguments as an opaque
JSON string. Every other handler puts a parsed object on a tool_call part, because
Anthropic and LangChain hand over an object.
Passing the string through left the content carriers encoding it a second time, so a
reader saw "arguments": "{\"q\":1}" on an OpenAI span and "arguments": {"q": 1} on an
Anthropic span describing the same kind of call.
Both handlers already parse this string to call the tool. Only the span disagreed with
the code two lines below it.
A string that is not JSON comes back verbatim rather than raising. A truncated stream
is worth reporting as it arrived, and raising inside the telemetry path would take down
a run the provider has already billed. The helper runs before the tool call rather than
reusing the parsed arguments, so a malformed string still reaches the span that records
the failure.
Applied at the seven sites that build a tool_call part or write tool-call content,
across both OpenAI packages. The shared content layer is untouched: how a provider
spells its arguments is the call site's business, the same rule the cache folding
follows.
Re-landing the content of #23, which was merged into the branch of #22 rather than into
main and so never shipped. Rebased onto main and the conflict with #18's
inputContentParts resolved by keeping both helpers.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Warning
This content was written by AI.
Summary
The Responses API and the Agents SDK carry
function_call.argumentsas an opaque JSON string. Anthropic and LangChain hand over an object, and every other handler puts an object on atool_callpart. Passing the string through meant the content carriers encoded it a second time, so an OpenAI span and an Anthropic span described the same kind of tool call differently.Both handlers already parse that string to call the tool. Only the span disagreed with the code two lines below it.
A string that is not JSON comes back verbatim rather than raising. A truncated stream is worth reporting as it arrived, and raising inside the telemetry path would take down a run the provider has already billed. The helper runs before the tool call rather than reusing the parsed arguments, so a malformed string still reaches the span that records the failure.
The shared content layer is untouched. How a provider spells its arguments is the call site's business, the same rule the cache folding follows.
This re-lands #23, which was merged into the branch of #22 instead of into main and so never shipped. Rebased onto main, with the overlap against #18's
inputContentPartsresolved by keeping both helpers.Note
Overview
OpenAI’s Responses API and Agents SDK expose
function_call.argumentsas a JSON string, while other providers recordtool_callparts with parsed objects. Passing the raw string into span content caused double JSON encoding, so OpenAI traces disagreed with Anthropic-style spans for the same kind of call.Both
openai-messagesandopenai-agentsnow use a sharedtoolArguments()helper: parse valid JSON strings before writing chat output, input replay, andexecute_toolattributes; invalid or truncated strings stay verbatim so telemetry never throws and failed calls still show what the model sent.New span tests lock in parsed objects on
gen_ai.output.messagesand malformed-argument behavior on tool spans.Reviewed by Cursor Bugbot for commit 45e335d. Bugbot is set up for automated code reviews on this repo. Configure here.