Repository navigation
feat(llc): parse CLI token usage and report to LLC budget (#10220) - #10242
Merged
Merged
Conversation
CLI/subprocess adapters (claude_code + the subscription variants that inherit it) never parsed token usage from their output, so those agents accrued ZERO tracked budget — unlike autobot_agent_adapter which calls ingest_cost_event. - AdapterRunStatus gains tokens_in/tokens_out - subprocess_support.extract_usage() parses the stream-json result event's usage block (input + cache-read + cache-creation = tokens_in; output_tokens) - ClaudeCodeAdapter._status attaches usage on a clean-success run - _await_adapter_completion returns the full AdapterRunStatus; on COMPLETED, _dispatch_registry_adapter forwards usage to BudgetService.ingest_cost_event (best-effort; BudgetExhausted re-raised → GH#8215 hard-stop marks run FAILED) Tests: extract_usage (cache-sum/basic/none/zero/non-int) + _ingest_adapter_usage (bills with model, no-ops when usage unknown, BudgetExhausted propagates, other errors best-effort) + updated dispatch tests for the new return type. 120 pass. Closes #10220 (part of #9923).
Contributor
✅ SSOT Configuration Compliance: Passing🎉 No hardcoded values detected that have SSOT config equivalents! |
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.
Thinking Path
From the #9008/#9033 adapter audit (decomposed into #10217–10220). The subprocess CLI adapters —
claude_codeand the subscription variants that inherit it — never parsed token usage from their output, so those agents accrued zero tracked budget, unlikeautobot_agent_adapterwhich callsBudgetService.ingest_cost_event. This closes that gap (#9008 AC5, #9033 AC4).What Changed
AdapterRunStatusgainstokens_in/tokens_out.subprocess_support.extract_usage()— pure helper parsing the stream-jsonresultevent'susageblock:tokens_in = input + cache_read + cache_creation,tokens_out = output_tokens; returns(None, None)when no usage (so we never record bogus zeros).ClaudeCodeAdapter._statusattaches parsed usage on a clean-success run (subscription adapters inherit it)._await_adapter_completionnow returns the fullAdapterRunStatus; onCOMPLETED,_dispatch_registry_adapterforwards usage toBudgetService.ingest_cost_event(session, agent_id, tokens_in, tokens_out, model)— best-effort, exceptBudgetExhaustedwhich is re-raised (GH#8215 hard-stop → run marked FAILED). Token-vs-dollar mode is handled by the budget service per the agent's config (feat(llc/budget): token-based budget mode — track agent budgets in token counts alongside dollar amounts #8997), so subscription agents bill in tokens automatically.Verification
pytest llc/tests/test_heartbeat_scheduler.py llc/adapters/tests/test_subprocess_support.py llc/adapters/tests/test_claude_code_adapter.py llc/adapters/tests/test_subscription_adapters.py llc/tests/test_registry_adapter_rate_limit.py→ 120 passed; rate-limit + liveness suites → 18 passedextract_usage(cache-sum / basic / none / all-zero / non-int) and_ingest_adapter_usage(bills with model, no-ops on unknown usage,BudgetExhaustedpropagates, other errors best-effort); existing dispatch tests updated for the new return typeModel Used
Claude Opus 4.8
Closes #10220 (part of #9923)