Repository navigation
Description
Summary
When OpenCode acts as an ACP agent it emits exactly one usage_update notification per turn, sent within ~1ms of the session/prompt response. ACP clients that want to render a live context indicator therefore cannot do so — there is nothing to relay during streaming, and a freshly-opened session has no usage data at all until the first turn finishes.
This is the wire-level protocol gap behind requests like #17449 / #18968 (real-time token display in the TUI). Those landed for the TUI; the ACP side is still single-shot.
Repro
OpenCode 1.15.11 over ACP/stdio. Client logs usage_update arrivals and the session/prompt response timing:
```
[15:23:38.714] usage_update raw={used:14388, size:65536}
[15:23:38.715] session/prompt response stopReason=end_turn usage={inputTokens:52, …}
```
The usage_update and the response land in the same millisecond. No other usage_update arrives during the streaming of agent_thought_chunk / agent_message_chunk events that precede them. On a brand-new session, no usage_update arrives between session/new and the first session/prompt.
Impact on ACP clients
- No live counter during streaming. A client cannot render "ctx 14388 / N (X%)" until the very last millisecond of the turn. For long reasoning turns this means the bar stays blank for the entire wait.
- Bar stays blank on fresh sessions. A user opens a session and types nothing — the client has no context-window number to show, and cannot even render an empty "ctx 0 / N" indicator, because both
usedandsizeonly arrive at end-of-turn-1. - Slash-handled and errored turns don't refresh anything. A turn that never reaches the model still costs no tokens — clients can show the previous value, but only if they have one.
Expected
Two protocol-level changes would unblock every ACP client:
- Emit
usage_updateperiodically during streaming. Even a once-per-N-tokens cadence (or coalesced batch flushes) lets clients draw a smooth live counter. Cumulativeusedis fine; clients can diff if they want a rate. - Emit one
usage_updateimmediately aftersession/new/session/load. Withused: 0(or whatever the seeded count is) and the realsize, so a freshly-opened session can already render the context indicator before the user sends anything.
(2) on its own would already fix the "blank on fresh session" half of the problem with minimal effort. (1) is the bigger lift but is what enables the live counter parity with the in-process TUI.
Related
- [FEATURE]: Real-time token display in TUI footer/header #17449 — Real-time token display in TUI footer/header (closed; TUI only)
- feat(tui): persistent token usage display in session footer #18968 — feat(tui): persistent token usage display in session footer (closed; TUI only)
- session/update notifications sent after session/prompt response (end_turn) #17505 — session/update notifications sent after session/prompt response (open; different ACP-ordering bug)
Environment
- OpenCode version: 1.15.11
- Model in repro:
deepseek/deepseek-v4-pro - Client: HAPI (https://github.com/tiann/hapi), via stdio ACP transport
Activity
github-actions commentedon Jul 31, 2026
To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.