ag-ui-protocol / ag-ui-protocol/ag-ui

[Bug]: [langgraph/typescript] Back-to-back tool calls: second TOOL_CALL_START is never emitted and arg deltas are routed to the wrong tool

Open
#2,007 0 comments 0 reactions 0 assignees View on GitHub
bug Integration
Dominant language
Python
Stars
15.9k
Forks
1.4k
Avg merge
1d 17h
Merged PRs (30d)
163

Description

## Description

TypeScript-side equivalent of #871 and #1016 (which describe the same bug in the Python integration).

The condition that opens a new tool call in the TypeScript `OnChatModelStream` handler is:

```ts
// integrations/langgraph/typescript/src/agent.ts
const isToolCallStartEvent = !hasCurrentStream && toolCallData?.name;
```

When a first tool call is already streaming (`hasCurrentStream = true`, `currentStream.toolCallId = "tc-1"`) and a new chunk arrives with a different tool name (`toolCallData = { id: "tc-2", name: "lookup" }`), `isToolCallStartEvent` evaluates to `false`. Consequences:

- `TOOL_CALL_START` for `tc-2` is **never emitted**
- Subsequent arg chunks for `tc-2` arrive without a `name`, so `isToolCallArgsEvent` fires and routes those deltas into `tc-1`'s `toolCallId`
- `tc-1` is never explicitly closed with `TOOL_CALL_END`

This matches the event log shown in #1016 — one `TOOL_CALL_START`, one `TOOL_CALL_ARGS` with the wrong `tool_call_id`, one `TOOL_CALL_END` — but produced by the TypeScript handler independently.

## Reproducer

```ts
handleSingleEvent({ tool_call_chunks: [{ id: "tc-1", name: "search" }] });
// → TOOL_CALL_START tc-1 ✓

handleSingleEvent({ tool_call_chunks: [{ id: "tc-2", name: "lookup" }] });
// Actual: nothing (tc-2 start dropped)
// Expected: TOOL_CALL_END tc-1, TOOL_CALL_START tc-2

handleSingleEvent({ tool_call_chunks: [{ args: '{"q":"foo"}' }] });
// Actual: TOOL_CALL_ARGS delta routed to tc-1 (wrong tool)
// Expected: TOOL_CALL_ARGS delta routed to tc-2
```

## Affected component

`integrations/langgraph/typescript`

See also: #871, #1016 (Python)

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.