fix(tui): include sub-agent costs in session cost - #58
Merged
Conversation
Session spend (header, /stats, cockpit cap row) counted main-loop tokens only: each finished sub-agent's engine-reported cost_usd decorated its card but never reached the session figure. Bank the final cost per task id from finished subagent_state frames - upsert, so replayed frames never double-count - add the sum to all three surfaces, and reset it with the other session telemetry on session swap and clear. Absent cost stays absent: unavailable is never $0.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Sub-agent LLM spend was missing from every session-cost surface: the header, the /stats cost row, and the cockpit cost-cap row all computed
costUSD(sessCtxTok, sessOutTok, prices)— main-loop tokens only. Each finished sub-agent's engine-reportedcost_usd(wire v2 P6) decorated its card in the transcript but never reached the session figure.Fix
task_id(Model.subCosts), upserted fromfinishedsubagent_stateframes — replayed frames overwrite instead of double-counting.subCostTotal()to all three surfaces (header, /stats, cockpit cap row — the cap judges total spend).The framed result envelope stays display-only (it carries no
task_id, so it cannot upsert safely); state frames are the single source of truth.Tests (RED-first)
6 new tests in
internal/tui/subagent_cost_test.go; the 4 behavioral tests were confirmed failing before the fix:TestSubagentCostAddsToHeader— header = main + sub ($0.016 + $0.0175 = $0.0335)TestSubagentCostReplayIsIdempotent— replayed finish frames never double-countTestStatsCardIncludesSubagentCost— /stats cost row carries sub-agent spendTestCockpitCapRowIncludesSubagentCost— cap row compares total spend against the capTestSubagentNoCostReportsNothing— guard: absent cost never distorts the figureTestClearResetsSubagentCost— guard: /clear wipes banked costsVerification
make fmt·make vetclean ·make lint0 issues ·make test(go test -race ./...) all green.