fix(llm): tolerate unparseable stored tool-call arguments in Anthropic/Google/AWS formatters#6321
Open
PranavMishra28 wants to merge 1 commit into
Conversation
… formats The Anthropic, Google, and AWS chat-context formatters call json.loads(msg.arguments) directly. FunctionCall.arguments is only canonicalized to valid JSON when the model output parses; unparseable output (unrecoverable open-weight calls, or history restored via ChatContext.from_dict) persists verbatim, so formatting that history on a later turn raised json.JSONDecodeError and aborted the whole request. Add a shared parse_tool_call_arguments() helper that falls back to an empty object (with a warning) when the arguments aren't a JSON object, and use it in the three formatters. OpenAI/Mistral already pass arguments through as an opaque string and are unaffected. Fixes livekit#6308 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
eaa86ee to
3e886e8
Compare
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.
This PR contains:
What is the current behavior? (You can also link to an open issue here)
Fixes #6308.
FunctionCall.argumentsholds the model's raw tool-call output and is only canonicalized to valid JSON when it parses successfully. When it can't be parsed — an open-weight model's output thatjson_repaircan't recover (the call fails as aToolErrorand the raw string persists), or history built outside the execution path (ChatContext.from_dict, a customllm_node, restored session state) — the raw string stays in chat history verbatim.The Anthropic, Google, and AWS chat-context formatters call
json.loads(msg.arguments)directly into_chat_ctx. A later, healthy turn that formats that history then raisesjson.JSONDecodeErrorand the whole request aborts. OpenAI and Mistral passargumentsthrough as an opaque string, so they don't hit this.What is the new behavior?
Adds a shared
parse_tool_call_arguments()helper in_provider_format/utils.pythat returns the parsed dict when the stored arguments are a JSON object, and otherwise logs a warning and falls back to an empty object{}. The three JSON-object formatters call it instead ofjson.loads(...).{}is preferred over a best-effort repair: the historical tool call already produced its output, so fabricating arguments the model never sent risks feeding wrong data back to the provider. A tool call's arguments are always a named-parameter object, so JSON that parses to a non-object (array, scalar,null) degrades the same way.Tests added in
tests/test_chat_ctx.pycover all three providers against unparseable arguments, a valid-args passthrough regression, and empty/non-object arguments. The unparseable/non-object cases fail onmain(raiseJSONDecodeError) and pass with this change.Does this PR introduce a breaking change? (What changes might users need to make in their application due to this PR?)
No. Valid arguments format exactly as before; only previously-crashing inputs change behavior — from a raised
JSONDecodeErrorto an empty-args object plus a warning log.Other information:
Developed with Claude Code; reviewed and tested by Pranav before marking ready for review.