Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

agent-finops

A lightweight, correct-by-construction cost-capture layer for local AI-agent session transcripts. Pure Python stdlib only (sqlite3, argparse, json, os) — no third-party dependencies, nothing to download, ~15 s full sync.

A sync / report / sql CLI over a typed SQLite ledger (package: agentfinops):

python -m agentfinops sync                    # incremental ingest (mtime watermark)
python -m agentfinops report --by project     # cost by project (also: model | session_id)
python -m agentfinops sql "SELECT model, sum(output_tokens) FROM messages GROUP BY model"

Why

Off-the-shelf capture tools (e.g. pond) get the raw ingest right but leave two correctness footguns and ship no cost semantics. agent-finops is our own recreation of that approach, refined to fix each weakness at the structural level rather than papering over it at query time.

# Weakness elsewhere Fix here Locus
R1 one row per JSONL line → Claude Code repeats cumulative usage across a multi-tool turn's lines → a naive SUM double-counts ~2.6× dedup at ingest on (session_id, message_id), keeping the max-output row; a plain SUM is already correct — the footgun is structurally impossible store.py UPSERT
R2 token counters buried in a JSON blob → fragile json_get paths first-class typed columns store.py schema
R3 no cost/pricing semantics built-in pricing table + cost formula, 1h/5m cache-write split priced separately, unpriced model = named gap not silent $0 pricing.py, report.py
R4 heavy binary + embedding-model download for search we don't need pure stdlib, ~15 s full sync, nothing to download whole package
R5 no sub-agent / workflow-boundary concept key sessions on real sessionId + capture is_sidechain / parent_uuid / source_agent adapter.py
R6 (the one strength worth keeping) lossless raw_json fallback column store.py

The typed ledger

Every billable assistant message becomes one row in messages, with token counters, model, timestamp, and the 1h/5m cache-write split as typed columns — queryable directly, no blob-path fragility. De-duplication is enforced at ingest by PRIMARY KEY (session_id, message_id) and an UPSERT that keeps the row with the greatest output_tokens (the authoritative/completed emission of a turn that Claude Code spreads across several JSONL lines). Because of that, a plain aggregate over messages is already correct — there is no consumer-side dedup query to forget.

Cost model

Costs are applied per row from a small, declarative pricing table (pricing.py), at list-price defaults. The formula prices the 1-hour and 5-minute cache writes separately (2.00× and 1.25× the input rate) and cache reads at 0.10×. A model absent from the table is priced at $0 and surfaced as a named gap in the report — never a silent zero folded into a total.

Commands

  • sync — incremental ingest of ~/.claude/projects/**/*.jsonl (only re-reads files whose mtime moved past the stored watermark; --force to re-read all).
  • report --by model|project|session_id — cost + token report over the ledger.
  • sql "<SELECT ...>" — read-only SQL surface over the typed columns (SELECT/WITH only).

Validation

Dogfooded over a real local corpus: sync over 2,553 files → 84,561 deduped messages / 1,729 logical sessions in ~15 s, ≈ $9,836 indicative list-price cost. The double-count footgun is provably absent — SELECT count(*), count(DISTINCT session_id||message_id) FROM messages returns equal counts — and GROUP BY is_sidechain cleanly separates main-agent from sub-agent spend.

Scope

This is the capture + cost-semantics layer. Boundary-semantics attribution (sub-agent-spawn cost roll-up, cache amortization, "who must justify this spend"), a budget-guard, and billing are deliberately out of scope for this package.

About

Correct-by-construction cost-capture layer for local AI-agent session transcripts (pure stdlib).

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages