Skip to content

fix(core): properly handle empty or missing arguments for ToolCallChunk #32017

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 10 commits into
base: master
Choose a base branch
from

Conversation

amznero
Copy link

@amznero amznero commented Jul 14, 2025

Description: Streaming tool call chunks: if chunk["args"] == None, the tool call is incorrectly marked as an InvalidToolCall.

Fixes #32016

@amznero amznero requested a review from eyurtsev as a code owner July 14, 2025 11:16
Copy link

vercel bot commented Jul 14, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
langchain 🛑 Canceled (Inspect) Jul 14, 2025 4:40pm

Copy link

codspeed-hq bot commented Jul 14, 2025

CodSpeed WallTime Performance Report

Merging #32017 will not alter performance

Comparing amznero:bugfix_tool_call_args (62099a1) with master (d96b75f)

⚠️ Unknown Walltime execution environment detected

Using the Walltime instrument on standard Hosted Runners will lead to inconsistent data.

For the most accurate results, we recommend using CodSpeed Macro Runners: bare-metal machines fine-tuned for performance measurement consistency.

Summary

✅ 13 untouched benchmarks

Copy link

codspeed-hq bot commented Jul 14, 2025

CodSpeed Instrumentation Performance Report

Merging #32017 will not alter performance

Comparing amznero:bugfix_tool_call_args (62099a1) with master (d96b75f)

Summary

✅ 14 untouched benchmarks

@mdrxy mdrxy changed the title fix(core): properly handle empty or missing arguments in AIMessageChunk class fix(core): properly handle empty or missing arguments for ToolCallChunk Jul 14, 2025
@mdrxy
Copy link
Collaborator

mdrxy commented Jul 14, 2025

Passing this off to @eyurtsev for final review/approval

Co-authored-by: Christophe Bornet <[email protected]>
mdrxy and others added 2 commits July 14, 2025 12:27
Co-authored-by: Christophe Bornet <[email protected]>
Co-authored-by: Christophe Bornet <[email protected]>
@@ -195,7 +195,7 @@ class ToolCall(TypedDict):

name: str
"""The name of the tool to be called."""
args: dict[str, Any]
args: Optional[dict[str, Any]]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this change necessary?

An empty dict represents no args currently. I'd rather not add a second way to represent the same information

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, an empty dict should represent a completed tool call that has no arguments.

None is used exclusively to represent the in-progress state where arguments have not yet been received during streaming.

Using an empty dictionary for both the "no arguments" state and the "arguments are coming" state makes them indistinguishable. We wouldn't know how to interpret the message, e.g. two scenarios to illustrate this:

  1. Final State (No Arguments): The model finishes a tool call and intends for it to have zero args. It correctly sends args={}. We'd see this and execute the tool immediately.
  2. In-Transit State (Streaming): The model starts a tool call and is about to stream the arguments. If it used {} as a temporary placeholder, we'd see args={}

If we went back to args_ = parse_partial_json(chunk["args"]) if chunk["args"] != "" else {}, it doesn't handle the case where chunk["args"] is literally None. When a streaming chunk arrives with args=None, chunk["args"] != "" evaluates to True (since None != ""). The code then tries to execute parse_partial_json(None), which results in a TypeError

Even if it mapped None to {} we still lose the ability to distinguish between the two different scenarios.

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.

Failed to used non-argument tool call or MCP in stream mode
4 participants