Repository navigation
Wire cost accounting through to persistence and CLI #1
Copy link
Copy link
Open
Labels
enhancementNew feature or requestNew feature or request
Description
Summary
Token usage is captured during agent strategy execution and persisted to SQLite, but USD cost is calculated in-memory by LLMClient and lost when the process exits. CLI inspect recalculates cost at display time from stored tokens + pricing config — meaning cost is never a first-class persisted artifact.
Current Data Flow (with 6 break points)
Provider API → Adapter extracts usage dict → LLMResponse.usage
→ LLMClient._record_usage_and_enforce_post_call_limits()
→ Calculates cost_usd via _estimate_cost_usd() (lines 308-330)
→ Stores in self._run_usage[run_id]["cost_usd"] ← IN-MEMORY ONLY (BREAK 1)
→ Strategy._aggregate_usage(turns) ← aggregates TOKENS only, ignores cost (BREAK 5)
→ AgentResult.token_usage = aggregated tokens
→ Executor: execution.token_usage = agent_result.token_usage ← NO cost_usd field (BREAK 2-3)
→ Storage: steps.token_usage_json column ← EXISTS, persisted correctly
→ Storage: steps.cost_usd column ← DOES NOT EXIST (BREAK 4)
→ CLI inspect: recalculates cost from tokens + pricing config at display time
What's Persisted Today
token_usage_json(per step) — in SQLitestepstable, line 234 ofstorage/sqlite.pymodel_name(per step) — in SQLitestepstable
What's Lost
LLMClient._run_usage[run_id]["cost_usd"]— calculated per-request with_estimate_cost_usd()usingpricing_usd_per_1k_tokensconfig- Per-step cost breakdown
- Run-level total cost
Key Code Locations
| Component | File | Lines | Status |
|---|---|---|---|
| Cost calculation | llm/client.py |
308-330 | _estimate_cost_usd() — working, in-memory only |
| Usage recording | llm/client.py |
246-281 | _record_usage_and_enforce_post_call_limits() — stores to _run_usage dict |
| Token aggregation | agent/strategies.py |
248-256 | _aggregate_usage() — sums tokens, ignores cost |
| StepExecution model | core.py |
191-214 | Has token_usage field, NO cost_usd field |
| SQLite steps schema | storage/sqlite.py |
214-239 | Has token_usage_json column, NO cost_usd column |
| CLI inspect display | cli.py |
3480-3526 | Recalculates cost from tokens + pricing at display time |
| CLI cost estimator | cli.py |
271-297 | _estimate_step_cost_usd() — display-time recalculation |
Implementation Path
- Add
cost_usd: Optional[float] = Nonefield toStepExecutiondataclass (core.py:211) - Add
cost_usdcolumn to SQLitestepstable (storage/sqlite.py:234) - Update
storage.append_step()to persist cost - Pass cost from
LLMClientresponse throughAgentResulttoExecutor._dispatch_agent() - Add run-level cost aggregation field to
Runmodel - Update CLI
inspectto display persisted cost instead of recalculating
Priority
Tier 1 — High Impact, Low Effort. The data is already captured; it needs ~6 touch points to wire through to persistence.
🤖 Generated with Claude Code
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or request
Activity
feat: persist cost, async-safe wrappers, memory injection, CLI polish