fix(coding-agent): preserve usage in streaming events (#7982)

Fixes #7911
This commit is contained in:
Christian Klotz 2026-08-13 00:32:26 +03:00 • committed by GitHub
parent 9795d60230
commit c93ea6ccf0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 62 additions and 11 deletions

View file

@ -919,6 +919,14 @@ Emitted during streaming of assistant messages. Contains a delta event without a
```json
{
"type": "message_update",
"usage": {
"input": 100,
"output": 1,
"cacheRead": 0,
"cacheWrite": 0,
"totalTokens": 101,
"cost": {"input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0, "total": 0}
},
"assistantMessageEvent": {
"type": "text_delta",
"contentIndex": 0,
@ -943,12 +951,15 @@ The `assistantMessageEvent` field contains one of these delta types:
Example streaming a text response:
```json
{"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"}}
{"type":"message_update","usage":{...},"assistantMessageEvent":{"type":"text_start","contentIndex":0}}
{"type":"message_update","usage":{...},"assistantMessageEvent":{"type":"text_delta","contentIndex":0,"delta":"Hello"}}
{"type":"message_update","usage":{...},"assistantMessageEvent":{"type":"text_delta","contentIndex":0,"delta":" world"}}
{"type":"message_update","usage":{...},"assistantMessageEvent":{"type":"text_end","contentIndex":0,"content":"Hello world"}}
```
The top-level `usage` field contains the latest cumulative provider-reported usage. It may remain
zero until completion when a provider does not report usage during streaming.
`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`