Skip to content

feat(cost): token usage tracking and budget enforcement#78

Closed
Enreign wants to merge 4 commits intomainfrom
feat/cost-tracking
Closed

feat(cost): token usage tracking and budget enforcement#78
Enreign wants to merge 4 commits intomainfrom
feat/cost-tracking

Conversation

@Enreign
Copy link
Copy Markdown
Collaborator

@Enreign Enreign commented Mar 16, 2026

Description

Adds per-session and per-day token cost tracking with configurable budget enforcement.

Changes

  • src/cost.rsCostTracker (SQLite-backed), calculate_cost with built-in model pricing (Claude + OpenAI), CostSummary with by-model and by-ghost breakdowns
  • src/config.rsCostConfig with daily_budget_usd, session_budget_usd, on_budget_exceeded (warn/block), model_prices override map
  • src/main.rssparks cost [today|session:<key>] subcommand
  • config.example.toml[cost] section with all fields documented

Built-in model pricing

Model Input ($/1M) Output ($/1M)
claude-opus-4-6 $15.00 $75.00
claude-sonnet-4-6 $3.00 $15.00
gpt-4o $5.00 $15.00
gpt-4o-mini $0.15 $0.60

Prices can be overridden per-model in config.toml.

Type of Change

  • New feature

Pre-PR Checklist

  • cargo check -q passes
  • cargo test -q passes (415 tests, 0 failures)

🤖 Generated with Claude Code

Enreign and others added 4 commits March 16, 2026 23:37
- Fix SQL injection risk: replace format!()-interpolated date_expr in
  summary_since() with a fully parameterized query; add all_summary()
  method with its own safe prepared statement
- Fix bounds panic: replace prices[0]/prices[1] index access on
  config.model_prices entries with .get(n).copied().unwrap_or(0.0)
- Implement check_session_budget(): session_budget_usd was declared in
  CostConfig but had no corresponding enforcement method; add it with
  the same warn/block semantics as check_daily_budget()
- Remove misplaced delivery_channel_severity test from cost.rs (alerts
  domain logic has no place in the cost module's test suite)
- Fix CLI 'all' scope: previously fell through silently to today_summary();
  now routes to all_summary() and prints an actionable error for unknown scopes
- Add missing tests: calculate_cost_zero_tokens, cost_tracker_disabled_skips_record,
  check_daily_budget_warn_does_not_err, check_daily_budget_block_returns_err,
  check_session_budget_block_returns_err (12 tests total, up from 8)
- Restore sonarqube.rs dependency that main.rs declares as a mod

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
src/alerts.rs only exists on the proactive-alerting branch, not here.
The stray `mod alerts;` caused a compile error that failed all CI jobs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The proactive alerting engine only exists on the proactive-alerting
branch. Remove the AlertEngine instantiation that was erroneously added
to the telegram startup path, which caused a compile error when building
with --features telegram.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@Enreign
Copy link
Copy Markdown
Collaborator Author

Enreign commented Mar 18, 2026

Not that important for now

@Enreign Enreign closed this Mar 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant