Skip to content

feat(usage): read Devin usage from the Devin CLI's session history - #12

Merged
adampeterhiggins merged 1 commit into
mainfrom
t3code/devin-usage-history
Sep 28, 2026
Merged

adampeterhiggins merged 1 commit into
mainfrom
t3code/devin-usage-history

Conversation

@adampeterhiggins

Copy link
Copy Markdown
Owner

Problem

Devin usage only came from T3's own provider event logs. That missed every Devin session run outside T3, and even for T3-run sessions it captured roughly one usage event per turn instead of one per model request. On one real session, the event logs recorded about 2–5% of the tokens Devin itself recorded (for example 4,153 vs 1.80M uncached input tokens).

Fix

Upstream's new Cursor, OpenCode and Antigravity readers (pingdotgg#10409 upstream) read each provider's own local history store. Devin keeps an equivalent SQLite store at ~/.local/share/devin/cli/sessions.db, and every assistant message records its request's input_tokens (uncached), output_tokens, cache_read_tokens, cache_creation_tokens and generation_model.

  • New devinUsageReader.ts, modeled on opencodeUsageReader.ts: opens the database read-only with a short busy_timeout, and extracts only the usage fields in SQL so large tool outputs never load into memory.
  • Deduplicates on message_id, because forked sessions copy nodes (67,698 assistant rows vs 20,283 distinct messages locally). Records use each message's own timestamp, so a fork's later copy can't pull an old message into a recent date range.
  • The database already includes the sessions T3 drives over ACP, so T3's event logs are now only a fallback when the database is missing. Reading both would double count.
  • The shared data root (Devin and OpenCode) now uses the host environment's HOME, as the Cursor path already did, so tests read their fixtures instead of the real machine's history.
  • Updated the web usage-page note and docs/user/usage.md, and fixed an existing Devin test whose expected record was missing the fast field added in the upstream sync.

Against a snapshot of real data, a 30-day read took about 0.6 s: 8,024 requests across 80 sessions. compactor (Devin's context compaction) and some glm-* requests are counted but unpriced unless a custom price is set.

Verified with vp test run src/usage/ (125 passing), plus lint and a typecheck of the server package.

Co-Authored-By: Claude Opus 5.5 (1M context) noreply@anthropic.com

🤖 Generated with Claude Code

Devin usage came only from T3's own event logs, which missed sessions run
outside T3 and captured roughly one usage event per turn instead of one per
model request. Read per-request metrics from the Devin CLI's sessions.db
instead, following the OpenCode reader, and fall back to the event logs only
when that database is missing.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@adampeterhiggins
adampeterhiggins merged commit 3b287e9 into main Sep 28, 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