fix(coding-agent): make JSON streaming output linear (#7394)

Fixes #7290

Co-authored-by: Mario Zechner <badlogicgames@gmail.com>
This commit is contained in:
Christian Klotz 2026-08-03 19:33:22 +03:00 • committed by GitHub
parent 32850ef7c5
commit a4475344fb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 142 additions and 36 deletions

View file

@ -914,17 +914,15 @@ Emitted when a message begins and completes. The `message` field contains an `Ag
### message_update (Streaming)
Emitted during streaming of assistant messages. Contains both the partial message and a streaming delta event.
Emitted during streaming of assistant messages. Contains a delta event without a cumulative message snapshot.
```json
{
"type": "message_update",
"message": {...},
"assistantMessageEvent": {
"type": "text_delta",
"contentIndex": 0,
"delta": "Hello ",
"partial": {...}
"delta": "Hello "
}
}
```
@ -933,7 +931,6 @@ The `assistantMessageEvent` field contains one of these delta types:
| Type | Description |
|------|-------------|
| `start` | Message generation started |
| `text_start` | Text content block started |
| `text_delta` | Text content chunk |
| `text_end` | Text content block ended |
@ -943,17 +940,21 @@ The `assistantMessageEvent` field contains one of these delta types:
| `toolcall_start` | Tool call started |
| `toolcall_delta` | Tool call arguments chunk |
| `toolcall_end` | Tool call ended (includes full `toolCall` object) |
| `done` | Message complete (reason: `"stop"`, `"length"`, `"toolUse"`) |
| `error` | Error occurred (reason: `"aborted"`, `"error"`) |
Example streaming a text response:
```json
{"type":"message_update","message":{...},"assistantMessageEvent":{"type":"text_start","contentIndex":0,"partial":{...}}}
{"type":"message_update","message":{...},"assistantMessageEvent":{"type":"text_delta","contentIndex":0,"delta":"Hello","partial":{...}}}
{"type":"message_update","message":{...},"assistantMessageEvent":{"type":"text_delta","contentIndex":0,"delta":" world","partial":{...}}}
{"type":"message_update","message":{...},"assistantMessageEvent":{"type":"text_end","contentIndex":0,"content":"Hello world","partial":{...}}}
{"type":"message_update","assistantMessageEvent":{"type":"text_start","contentIndex":0}}
{"type":"message_update","assistantMessageEvent":{"type":"text_delta","contentIndex":0,"delta":"Hello"}}
{"type":"message_update","assistantMessageEvent":{"type":"text_delta","contentIndex":0,"delta":" world"}}
{"type":"message_update","assistantMessageEvent":{"type":"text_end","contentIndex":0,"content":"Hello world"}}
```
`message_update` intentionally omits the former cumulative `message` field and
`assistantMessageEvent.partial`. Clients that need a live partial message must assemble it
from `message_start` and subsequent events using `contentIndex`. Treat `message_end.message`
as authoritative. For tool calls, buffer `toolcall_delta.delta`; `toolcall_end.toolCall`
contains the completed call.
### bash_execution_update
Emitted once for each output chunk from a direct `bash` command. `id` matches the command's `id`, allowing clients to associate output with the correct command.
@ -1362,6 +1363,7 @@ Source files:
- [`packages/ai/src/types.ts`](../../ai/src/types.ts) - `Model`, `UserMessage`, `AssistantMessage`, `ToolResultMessage`
- [`packages/agent/src/types.ts`](../../agent/src/types.ts) - `AgentMessage`, `AgentEvent`
- [`src/core/messages.ts`](../src/core/messages.ts) - `BashExecutionMessage`
- [`src/modes/json-event.ts`](../src/modes/json-event.ts) - `JsonAgentSessionEvent`
- [`src/modes/rpc/rpc-types.ts`](../src/modes/rpc/rpc-types.ts) - RPC command/response types, extension UI request/response types
### Model