#10006: feat: add append-only spend ledger for token usage tracking
gateway
commands
stale
Cluster:
Session Management Enhancements
## Summary
- Adds an append-only JSONL spend ledger (`~/.openclaw/state/spend.jsonl`) that records one line per LLM call, replacing the need to re-scan all session transcripts for usage queries
- Maintains an in-memory `SpendAggregator` with daily, per-provider, and per-model breakdowns that rebuilds from the ledger on gateway startup and stays current as new entries append
- Adds a new `usage.spend` gateway endpoint with `days`, `provider`, `model`, `agentId`, and `groupBy` query params for instant aggregated results
- Hooks both code paths that make LLM calls: channel-routed messages (`agent-runner.ts`) and CLI agent commands (`commands/agent.ts`) via a shared `recordSpendFromResult` helper
## Changed files
**New:**
- `src/infra/spend-ledger.ts` — Core ledger module (SpendEntry, append/load, SpendAggregator, recordSpendFromResult)
- `src/infra/spend-ledger.test.ts` — 13 unit tests
- `src/auto-reply/reply/agent-runner.spend-ledger.test.ts` — 2 integration tests (channel path)
- `src/commands/agent.spend-ledger.test.ts` — 3 integration tests (CLI path)
**Modified:**
- `src/auto-reply/reply/agent-runner.ts` — Record spend on channel-routed messages
- `src/commands/agent.ts` — Record spend on CLI agent commands
- `src/gateway/server-methods/usage.ts` — Add `usage.spend` endpoint
- `src/gateway/server.impl.ts` — Init spend aggregator on gateway startup
## Test plan
- [x] `pnpm build` passes
- [x] `pnpm check` (tsgo + oxlint + oxfmt) passes with 0 errors
- [x] 18 new tests pass across 3 test files
- [x] Full test suite passes (pre-existing `src/memory/` failures on Node 20 only)
- [x] Manual e2e: started gateway, sent 3 messages via Anthropic API, verified `spend.jsonl` entries and `usage.spend` endpoint returns correct aggregations
🤖 Generated with [Claude Code](https://claude.com/claude-code)
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
This PR introduces an append-only JSONL spend ledger and an in-memory `SpendAggregator` that rebuilds from the ledger on gateway startup, plus a new `usage.spend` gateway method for querying aggregated spend by time/provider/model/agent.
Spend recording is hooked into both main LLM execution paths (`src/auto-reply/reply/agent-runner.ts` and `src/commands/agent.ts`) via a shared `recordSpendFromResult()` helper, and tests cover both module behavior and the two integration call sites.
<h3>Confidence Score: 3/5</h3>
- This PR is close, but has a few correctness issues that should be fixed before merge.
- Core approach (append-only ledger + in-memory aggregator + endpoint + call-site hooks) is straightforward and well-tested, but there are clear functional issues: directory creation is cached globally across paths, `groupBy=day` is accepted but not implemented, and the resolved ledger path appears inconsistent with the documented location depending on what `resolveStateDir()` returns.
- src/infra/spend-ledger.ts
<!-- greptile_other_comments_section -->
<sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#20561: feat: add Sisyphus-style orchestration features
by dfggggx198601 · 2026-02-19
74.4%
#13889: feat: Slack channel cache, session cost alerts & checkpoint/recover...
by trevorgordon981 · 2026-02-11
74.1%
#21699: feat(agents): add opt-in OpenAI payload logging for embedded runs
by jcp · 2026-02-20
73.1%
#13215: fix: pass agentId to loadCostUsageSummary in /usage cost command
by veast · 2026-02-10
72.7%
#8713: feat: gateway memory monitor, install linger, docs and failover
by quratus · 2026-02-04
72.5%
#11788: feat: inter-agent communication via CLI scripts
by jingkang0822 · 2026-02-08
72.4%
#21589: Post-Performance Roadmap: Milestones A–D (contracts, observability,...
by Doji-Hammer · 2026-02-20
72.1%
#13686: Add opt-in rate limiting and token-based budgets for external API c...
by ShresthSamyak · 2026-02-10
72.0%
#11227: cli: add reflect add/list/show (local JSONL reflections)
by itskai-dev · 2026-02-07
71.7%
#9163: Fix: Save Anthropic setup token to config file
by vishaltandale00 · 2026-02-04
71.6%