Skip to content

Serialize tool calls that rewrite a plain state channel - #30

Open
naftali-g wants to merge 2 commits into
masterfrom
naftali/sequential-tools
Open

Serialize tool calls that rewrite a plain state channel#30
naftali-g wants to merge 2 commits into
masterfrom
naftali/sequential-tools

Conversation

@naftali-g

Copy link
Copy Markdown
Contributor

ToolNode runs every tool call of an assistant turn in one superstep. For a tool that rewrites a plain (LastValue) channel, two such calls in one turn are two writes to that channel, and LangGraph aborts the graph with InvalidUpdateError. The model-side lever, parallel_tool_calls=False, is a property of the request, not of a tool, so it serializes everything to protect one.

serial_tools.py serializes at execution time instead:

  • a tool declares the plain keys it writes with serialize_writes(tool, "curr_spec"), stored in BaseTool.metadata;
  • make_tool_node(tools, **kwargs) returns the stock ToolNode when nothing declares, and wraps it otherwise;
  • in a wrapped batch, undeclared calls run concurrently through ToolNode with their updates passed through verbatim, so reducer-backed channels still get one write per call;
  • declared calls run one at a time, each seeing the previous one's writes through InjectedState, and their state writes collapse into a single update — one write per superstep, no reducer needed.

Sequencing matches what a model assumes when it batches two edits to one buffer: the second applies to the result of the first. A stale anchor then fails as an ordinary tool rejection it can retry, rather than aborting the graph.

@naftali-g
naftali-g requested a review from jtoman August 12, 2026 07:47
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.

1 participant