Skip to content

Wire cost accounting through to persistence and CLI #1

@rogue-socket

Description

@rogue-socket

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 SQLite steps table, line 234 of storage/sqlite.py
  • model_name (per step) — in SQLite steps table

What's Lost

  • LLMClient._run_usage[run_id]["cost_usd"] — calculated per-request with _estimate_cost_usd() using pricing_usd_per_1k_tokens config
  • 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

  1. Add cost_usd: Optional[float] = None field to StepExecution dataclass (core.py:211)
  2. Add cost_usd column to SQLite steps table (storage/sqlite.py:234)
  3. Update storage.append_step() to persist cost
  4. Pass cost from LLMClient response through AgentResult to Executor._dispatch_agent()
  5. Add run-level cost aggregation field to Run model
  6. Update CLI inspect to 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions