TanStack AI version
0.54
Framework/Library version
React 19
Describe the bug and the steps to reproduce it
What happens
When useChat is connected to a third-party AG-UI server (Pydantic AI's AGUIAdapter in my case), the model calls a registered .client() tool, the tool call is rendered, and then the run just ends. The .client() handler is never invoked and no continuation run is started.
The server emits the canonical AG-UI sequence for a frontend tool:
TOOL_CALL_START { toolCallId: "tooluse_…", toolCallName: "ping" }
TOOL_CALL_ARGS { delta: "" }
TOOL_CALL_END
RUN_FINISHED { outcome: { type: "success" } }
Why
Client-tool execution is only triggered from StreamProcessor.handleInterrupts (activities/chat/stream/processor.ts), i.e. when RUN_FINISHED carries outcome.type: "interrupt" with a metadata.kind: "client_tool" interrupt. That's the shape TanStack's own chat() emits, but it isn't what AG-UI specifies.
Per ag-ui-protocol/ag-ui#2731, a frontend tool call ends the run with a plain success outcome. It may include pendingToolCallIds; otherwise the client derives the unanswered calls from the stream. The client then executes the tools and continues with role: "tool" messages in the next run's history. There is no success-outcome path that calls onToolCall, so nothing fires.
Expected
On a success RUN_FINISHED, the client should dispatch onToolCall for tool calls that were started but not answered by TOOL_CALL_RESULT, using outcome.pendingToolCallIds when present. The rest of the pipeline already exists (pendingToolExecutions, addToolResultForClientTool, continuation). The interrupt path would stay unchanged.
Repro
- Pydantic AI agent exposed via
AGUIAdapter, no server-side ping tool.
useChat({ connection: fetchServerSentEvents(url), tools: [pingDef.client(() => 'pong')] })
- Ask the agent to call
ping and report the result → handler never runs, conversation stops.
Your Minimal, Reproducible Example - (Sandbox Highly Recommended)
_
Screenshots or Videos (Optional)
No response
Do you intend to try to help solve this bug with your own PR?
None
Terms & Code of Conduct
TanStack AI version
0.54
Framework/Library version
React 19
Describe the bug and the steps to reproduce it
What happens
When
useChatis connected to a third-party AG-UI server (Pydantic AI'sAGUIAdapterin my case), the model calls a registered.client()tool, the tool call is rendered, and then the run just ends. The.client()handler is never invoked and no continuation run is started.The server emits the canonical AG-UI sequence for a frontend tool:
Why
Client-tool execution is only triggered from
StreamProcessor.handleInterrupts(activities/chat/stream/processor.ts), i.e. whenRUN_FINISHEDcarriesoutcome.type: "interrupt"with ametadata.kind: "client_tool"interrupt. That's the shape TanStack's ownchat()emits, but it isn't what AG-UI specifies.Per ag-ui-protocol/ag-ui#2731, a frontend tool call ends the run with a plain
successoutcome. It may includependingToolCallIds; otherwise the client derives the unanswered calls from the stream. The client then executes the tools and continues withrole: "tool"messages in the next run's history. There is nosuccess-outcome path that callsonToolCall, so nothing fires.Expected
On a
successRUN_FINISHED, the client should dispatchonToolCallfor tool calls that were started but not answered byTOOL_CALL_RESULT, usingoutcome.pendingToolCallIdswhen present. The rest of the pipeline already exists (pendingToolExecutions,addToolResultForClientTool, continuation). The interrupt path would stay unchanged.Repro
AGUIAdapter, no server-sidepingtool.useChat({ connection: fetchServerSentEvents(url), tools: [pingDef.client(() => 'pong')] })pingand report the result → handler never runs, conversation stops.Your Minimal, Reproducible Example - (Sandbox Highly Recommended)
_
Screenshots or Videos (Optional)
No response
Do you intend to try to help solve this bug with your own PR?
None
Terms & Code of Conduct