You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
ACP PromptResponse.usage reports only the turn's final assistant message #41660
ACP documents PromptResponse.usage as "Token usage for this turn", but OpenCode fills it
from the turn's final assistant message only. Each tool-call step gets its own assistant
message (session/prompt.ts:1188), so a turn with N tool calls reports 1 of N+1 model
requests.
Measured on a 3-tool-call turn (4 requests) — reported vs summed from opencode export:
The reported row is byte-identical to the final request's. The skew is uneven — the first
request pays the large cache write — so any hit rate derived from it reads high, 98.8% vs
74.6% here. Single-request turns are exact.
buildUsage (packages/opencode/src/acp/usage.ts:90) takes a single message; totalSessionCost just below it already reduces over the list, and the cost path accumulates
where the token path assigns (session/processor.ts:444-445).
Happy to PR this. Should the sum be bounded to the initiating user message, and do subtask
and compaction messages (same session, same parentID) count toward the turn?
Plugins
none
OpenCode version
1.18.16
Steps to reproduce
Drive opencode over ACP and send a prompt that makes at least one tool call.
Read PromptResponse.usage from the session/prompt response.
Run opencode export <sessionID> and sum tokens across the turn's assistant messages.
The value from step 2 equals the final message's row, not the sum.
The aggregation half also reproduces without a model:
UsageService.buildUsage(UsageService.latestAssistantMessage(messages)) returns the last
message's tokens by construction.
Screenshot and/or share link
No response
Operating System
macOS 26.5 (Darwin 25.5.0)
Terminal
n/a — driven over ACP, not the TUI
Reacted by racheldistyl, Jonathan Tavares and Elliot Hesp
Still reproduces on 1.18.32 (latest), and promptResponse on dev (b471c2b) still builds usage from the final assistant message only (UsageService.buildUsage(info) in packages/opencode/src/acp/service.ts).
Another data point, with a different provider (google/gemini-3.8-flash, driven over ACP). Prompt: write two files with two shell commands, cat both, then summarise. That's 4 model requests.
The reported numbers equal the last request's row, as described above.
#42489 fixes exactly this: it sums the turn's assistant messages and has tests. It was closed by the automated stale-PR cleanup, not in review. Could a maintainer reopen it and take a look? Happy to test it against this repro.
Activity
Ehesp commentedon Sep 27, 2026
Still reproduces on 1.18.32 (latest), and
promptResponseondev(b471c2b) still buildsusagefrom the final assistant message only (UsageService.buildUsage(info)inpackages/opencode/src/acp/service.ts).Another data point, with a different provider (
google/gemini-3.8-flash, driven over ACP). Prompt: write two files with two shell commands,catboth, then summarise. That's 4 model requests.The reported numbers equal the last request's row, as described above.
#42489 fixes exactly this: it sums the turn's assistant messages and has tests. It was closed by the automated stale-PR cleanup, not in review. Could a maintainer reopen it and take a look? Happy to test it against this repro.