Repository navigation
fix(core): lower unparseable streaming tool input to an object - #57438
chiragjangiir wants to merge 1 commit into
Conversation
A tool call still in `streaming` state keeps its raw argument text. When that text is not valid JSON, `toolInput` returned it unchanged, so the Anthropic lowerer sent `tool_use.input` as a string and the API answered 400 "Input should be an object". A streaming tool call now only lowers its decoded arguments when they are a JSON object; anything else (unparseable text, or a non-object JSON value) lowers to an empty object until the call settles, matching the object contract the non-streaming states already enforce. Fixes anomalyco#56127
|
The following comment was made by an LLM, it may be inaccurate: |
There was a problem hiding this comment.
The fix works. I ran the #56127 reproduction (toLLMMessages followed by the Anthropic Messages request compiler) on the base and on this branch. On the base, a streaming tool call with invalid or truncated JSON arguments produces a string tool_use.input, and JSON that parses but isn't an object ([1], 42, null) is sent as is. With this change, all of those lower to {}, while a valid JSON object is still passed through unchanged. session-runner-message.test.ts and the packages/core typecheck pass.
Public API: unchanged. The change is internal to how session history is turned into provider messages.
No blocking concerns.
Related: #51452
|
Thanks for updating your PR! It now meets our contributing guidelines. 👍 |
Issue for this PR
Closes #56127
Type of change
What does this PR do?
A tool call that is still in the
streamingstate retains its raw argument text. If that text is not valid JSON,toolInputinto-llm-message.tspreviously returned it unchanged. The Anthropic lowerer then senttool_use.inputas a string, causing the API to reject the request with400 tool_use.input: Input should be an object.This change only lowers decoded arguments when they are a JSON object. Unparseable text and non-object JSON values now lower to
{}while the tool call is still streaming. This preserves the object contract already used by therunning,completed, anderrorstates.How did you verify your code works?
packages/core/test/session-runner-message.test.tsthat passes a streamingshelltool call withinput: "not-json"throughtoLLMMessagesand asserts that the resulting tool-call input is{}.packages/coretest suite. The 31 failures were identical to the pre-change baseline in this environment; no additional failures were introduced.typecheck,oxlint, andprettierchecks pass.Screenshots / recordings
Not applicable — protocol-layer fix with no UI changes.
Checklist