Skip to content

fix(adapters/langgraph): stamp tool_call_id onto client_tool_request interrupts#11

Open
spichen wants to merge 1 commit into
mainfrom
fix/client-tool-callid-middleware
Open

fix(adapters/langgraph): stamp tool_call_id onto client_tool_request interrupts#11
spichen wants to merge 1 commit into
mainfrom
fix/client-tool-callid-middleware

Conversation

@spichen

@spichen spichen commented Jun 19, 2026

Copy link
Copy Markdown
Owner

Problem

A ClientTool hands control back to the caller by raising interrupt({"type": "client_tool_request", ...}), but the interrupt payload omitted the originating tool_call_id. A caller resuming the run correlates the tool result it returns to the parked interrupt by tool_call_id, so without it the resume never matched — failing with No pending client_tool_request interrupt found for tool_call_id(...) — and the agent went silent after the user answered (e.g. ask_user_question).

Approach

The earlier payload-injection approach (#7) was dropped in favour of a middleware. This adds ClientToolCallIdMiddleware in the langgraph adapter: in wrap_tool_call/awrap_tool_call it catches the GraphInterrupt and stamps tool_call_id (available on request.tool_call) onto the client_tool_request interrupt value as it propagates. It is auto-wired into create_agent only for agents that declare a ClientTool, via the existing AgentSpecLoader → create_agent middleware forwarding. The tool-conversion payload is left untouched.

Tests

  • New test_client_tool_in_agent_interrupt_carries_tool_call_id (agent path: model calls a client tool → assert the parked interrupt carries tool_call_id).
  • Existing client-tool / converter tests pass; black + isort clean.

…interrupts

A ClientTool hands control back to the caller by raising
interrupt({"type": "client_tool_request", ...}), but the payload omitted the
originating tool_call_id. Callers resuming a run correlate the tool result they
return to the parked interrupt by tool_call_id, so without it the resume could
not match and the agent went silent after the user answered (e.g.
ask_user_question).

Wire a ClientToolCallIdMiddleware into create_agent for agents that declare a
ClientTool; running in the tool-call path where the id is available, it stamps
the tool_call_id onto the client_tool_request interrupt as it propagates so a
resuming caller can correlate its tool result.
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