Skip to content

refactor(usage): transcript readers come from their drivers - #17576

Merged
juliusmarminge merged 1 commit into
mainfrom
t3/usage-transcript-readers
Oct 9, 2026
Merged

juliusmarminge merged 1 commit into
mainfrom
t3/usage-transcript-readers

Conversation

@juliusmarminge

@juliusmarminge juliusmarminge commented Oct 9, 2026 •

Copy link
Copy Markdown
Member

UsageService hard-coded every provider: it decoded Claude and Codex settings itself, resolved each transcript home, and the JSONL engine branched on provider === "codex" | "grok". Adding a provider meant editing the aggregator.

  • ProviderDriver gains an optional usage reader, a discriminated union (transcripts | scan) defined in provider-core/server/usage, with its own environment (UsageR) so UsageService doesn't require every driver's creation environment.
  • The JSONL engine takes a TranscriptUsageFormat (field selection, line prefilter, parsers, optional resumable state with a schema).
  • Grok's format and GROK_HOME resolution move into provider-grok. Claude's and Codex's sit next to their drivers until those become packages.
  • Codex shared-session dedupe is a format flag (sharedSessionsAcrossFiles).
  • The scan cache's cs field stores the format's schema-encoded state. It is byte-identical to the previous Codex state, so existing caches still resume.
  • Driver order for usage lives in BUILT_IN_USAGE_DRIVERS to keep today's result order (Claude, Codex, Grok, …).

No behavior change: UsageService.test.ts changed only in wiring and imports.

🤖 Generated with Claude Code (Claude Opus 5.5, Claude Code harness)

@juliusmarminge
juliusmarminge added this pull request to stack #17580 October 9, 2026 19:20
@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XXL 1,000+ changed lines (additions + deletions). labels Oct 9, 2026
@juliusmarminge juliusmarminge added the macroscope-review Opt PRs made by unvouched contributors in for Macroscope review. Vouched contributors auto-reviews label Oct 9, 2026
@juliusmarminge juliusmarminge changed the title t3/usage transcript readers refactor(usage): transcript readers come from their drivers Oct 9, 2026
Comment thread apps/server/src/provider/Drivers/codexUsage.ts
@github-actions

github-actions Bot commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

Provider Metric Main baseline This PR Impact PR ceiling
Codex Total thread wire 5.0 KiB 5.0 KiB 0 B (0.0%) 6.8 KiB ✅
Codex Thread snapshot wire 3.8 KiB 3.8 KiB 0 B (0.0%) 4.9 KiB ✅
Codex Live turn WebSocket wire 1.2 KiB 1.2 KiB 0 B (0.0%) 2.0 KiB ✅
Codex Live turn WebSocket decoded 20.9 KiB 20.9 KiB 0 B (0.0%) 29.3 KiB ✅
Codex Live turn messages 2 2 0 (0.0%) 8 ✅
Claude Total thread wire 5.0 KiB 5.0 KiB −24 B (−0.5%) 6.8 KiB ✅
Claude Thread snapshot wire 3.8 KiB 3.8 KiB 0 B (0.0%) 4.9 KiB ✅
Claude Live turn WebSocket wire 1.2 KiB 1.2 KiB −24 B (−2.0%) 2.0 KiB ✅
Claude Live turn WebSocket decoded 21.2 KiB 21.2 KiB −41 B (−0.2%) 29.3 KiB ✅
Claude Live turn messages 2 1 −1 (−50.0%) 8 ✅

Baseline: 454b94a · PR result: 6c36724 · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 108.5 KiB
  • Claude decoded thread snapshot: 108.8 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

@macroscopeapp

macroscopeapp Bot commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This is a broad production usage-pipeline refactor that introduces a new provider-core reader contract, moves three transcript implementations, generalizes resumable parsing and cache state, and rewires UsageService dispatch. The tests support the intended behavior, but the shared infrastructure and persisted-cache boundary make the change too substantial for automatic approval.

You can add or adjust custom eligibility rules. Learn more.

@coderabbitai

coderabbitai Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Path: .coderabbit.config.ts
  • Review profile: CHILL
  • Plan: Team
  • Run ID: f3654a44-46bd-4d09-9cd1-4a6133683d44

📥 Commits

Reviewing files that changed from the base of the PR and between 9291a7b and 6c36724.


📒 Files selected for processing (5)
  • apps/server/src/provider/Drivers/claudeUsage.ts
  • apps/server/src/provider/Drivers/codexUsage.ts
  • apps/server/src/usage/UsageService.test.ts
  • apps/server/src/usage/UsageService.ts
  • packages/provider-core/src/server/usage.ts

🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/server/src/usage/UsageService.test.ts

Limit details: You’ve used all 10 included reviews currently available.



📝 Walkthrough

Walkthrough

Provider-core adds shared provider usage-reader contracts. Claude, Codex, and Grok add transcript readers. The server discovers readers through built-in drivers and uses their formats for transcript parsing, resumable state, cache decoding, and shared-session deduplication.

Changes

Provider usage reader integration

Layer / File(s) Summary
Usage contracts and shared types
packages/provider-core/src/server/usage.ts, packages/provider-core/src/server/driver.ts, packages/provider-core/package.json, apps/server/src/usage/*
Provider-core adds usage records, transcript formats, scan contracts, and reader environment types. Existing usage consumers import shared usage types from provider-core.
Provider transcript readers
apps/server/src/provider/Drivers/*Usage*, apps/server/src/provider/Drivers/{ClaudeDriver,CodexDriver}.ts, packages/provider-grok/src/server/*, packages/provider-grok/package.json
Claude, Codex, and Grok add transcript parsers and directory readers. Their drivers expose those readers, and tests cover provider-specific parsing and token or cost handling.
Generic transcript parsing and cache
apps/server/src/usage/usageTranscriptReader*, apps/server/src/usage/usageScanCache*, apps/server/src/usage/usageTestFormats.ts, apps/server/src/usage/usageTranscripts*
The transcript reader and cache accept provider-supplied formats and generic persisted state. Tests use format objects; the previous shared transcript parser and its tests are removed.
Usage service integration and deduplication
apps/server/src/provider/builtInDrivers.ts, apps/server/src/usage/UsageService*
UsageService resolves registered readers and passes their formats to scanning and cache decoding. Cross-file deduplication uses reader-declared shared sessions.

Priority: ⬇️ Low

Estimated code review effort: 4 (Complex) | ~60 minutes

Change: Refactor

Sequence Diagram(s)

sequenceDiagram
  participant UsageService
  participant BUILT_IN_USAGE_DRIVERS
  participant ProviderUsageReader
  participant readTranscriptRecords
  UsageService->>BUILT_IN_USAGE_DRIVERS: enumerate usage readers
  UsageService->>ProviderUsageReader: resolve transcript directories
  UsageService->>readTranscriptRecords: parse files using reader formats
Loading

Merge Risk: ⚪ Minimal · up to 6c367

No identified issue blocks merging this change after normal checks.

Pre-merge checks | Passed 3 | Failed 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check Warning The description explains the problem and the main implementation changes, but it does not provide the required Scope and approval information or focused verification results. It also omits the templat… Add the required Problem, Change, Scope and approval, and Verification sections. Link the triaged issue or maintainer approval, explain any approval exemption if applicable, and list focused tests or manual checks with observed results and …
✅ Passed checks (3 passed)
Check name Status Explanation
Title check Passed The title clearly summarizes the primary change: transcript readers now come from provider drivers.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.

Full details: Description check

Explanation

The description explains the problem and the main implementation changes, but it does not provide the required Scope and approval information or focused verification results. It also omits the template section headings.

Resolution

Add the required Problem, Change, Scope and approval, and Verification sections. Link the triaged issue or maintainer approval, explain any approval exemption if applicable, and list focused tests or manual checks with observed results and any checks not run.



  • Fix all pre-merge checks with AI
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR

🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR


  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Usage-based review receipt

Note

This review was completed with usage-based billing: files reviewed beyond your plan's included limits are billed at $0.25/file. View usage-based billing.


Comment @coderabbitai help to get the list of available commands.

ProviderDriver gains an optional usage reader (provider-core/server/usage).
The JSONL engine takes a TranscriptUsageFormat instead of branching on the
provider. Claude and Codex formats sit next to their drivers; Grok's format
and GROK_HOME resolution move into provider-grok. UsageService builds each
driver's instances generically and no longer hard-codes transcript homes.
The scan cache stores the format's encoded state in cs, byte-compatible
with the previous Codex state.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@juliusmarminge
juliusmarminge force-pushed the t3/usage-transcript-readers branch from 9291a7b to 6c36724 Compare October 9, 2026 20:28
@juliusmarminge

Copy link
Copy Markdown
Member Author

Adversarial review (3 reviewers, one per layer group) found no blockers. Two behavior changes against main are fixed in this push:

  • refactor(usage): transcript readers come from their drivers #17576: the generic instance builder dropped instances whose config doesn't decode. On main only Claude and Codex did that. Grok and Antigravity read history by home or profile alone, so a malformed config hid their usage. Instances now reach every reader with config: undefined. Claude and Codex skip them as before, while Grok and Antigravity read them. A regression case in UsageService.test.ts fails without the fix (46 vs 59 tokens).
  • refactor(usage): Cursor account usage comes from provider-cursor #17578: the Cursor scan re-read settings instead of using the snapshot the rest of the read (and the in-flight dedupe key) used, and a failed re-read looked like "usage is off". Scan readers now get the read's settings snapshot.

Also verified: the parsers, prefilters and field selection match main. The Codex cs cache is byte-identical. Cursor TTL, refresh dedupe, persistence and messages are unchanged, and CursorKeychain is built once (proven by test). OpenCode and Antigravity roots, ordering and aliased-dir dedupe are unchanged.

@juliusmarminge
juliusmarminge merged commit e5dca23 into main Oct 9, 2026
29 checks passed
@juliusmarminge
juliusmarminge deleted the t3/usage-transcript-readers branch October 9, 2026 22:26
github-actions Bot added a commit to omarcresp/t3code-flake that referenced this pull request Oct 10, 2026
## What's Changed
* chore(deps): upgrade Effect to 4.0.2 by @juliusmarminge in pingdotgg/t3code#17571
* fix(devices): recover stalled video without losing simulator input by @juliusmarminge in pingdotgg/t3code#17566
* fix(web): keep checkout stable while pr actions load by @maria-rcks in pingdotgg/t3code#16625
* fix(mobile): show waiting thread status by @maria-rcks in pingdotgg/t3code#16693
* feat(web): add parent thread breadcrumb navigation by @maria-rcks in pingdotgg/t3code#16666
* fix(server): restart inactivity after snoozed threads wake by @maria-rcks in pingdotgg/t3code#16674
* feat(desktop): passkeys in the in-app browser on macOS by @juliusmarminge in pingdotgg/t3code#16952
* fix(client): load earlier turns works for MCP threads over T3 Connect by @juliusmarminge in pingdotgg/t3code#17599
* refactor(client): sign relay request URLs built from the HttpApi contract by @juliusmarminge in pingdotgg/t3code#17602
* refactor(source-control): add @t3tools/source-control-core by @juliusmarminge in pingdotgg/t3code#17573
* refactor(source-control): Forgejo lives in @t3tools/source-control-forgejo by @juliusmarminge in pingdotgg/t3code#17581
* refactor(source-control): Azure DevOps lives in @t3tools/source-control-azure-devops by @juliusmarminge in pingdotgg/t3code#17592
* refactor(source-control): GitLab lives in @t3tools/source-control-gitlab by @juliusmarminge in pingdotgg/t3code#17594
* refactor(source-control): Bitbucket lives in @t3tools/source-control-bitbucket by @juliusmarminge in pingdotgg/t3code#17597
* refactor(source-control): GitHub lives in @t3tools/source-control-github by @juliusmarminge in pingdotgg/t3code#17607
* refactor(usage): transcript readers come from their drivers by @juliusmarminge in pingdotgg/t3code#17576
* refactor(usage): OpenCode usage comes from provider-opencode by @juliusmarminge in pingdotgg/t3code#17577
* refactor(usage): Cursor account usage comes from provider-cursor by @juliusmarminge in pingdotgg/t3code#17578
* refactor(usage): Antigravity usage is a reader on its driver by @juliusmarminge in pingdotgg/t3code#17579
* refactor(usage): usage readers use Effect FileSystem and SqlClient by @juliusmarminge in pingdotgg/t3code#17615
* fix(web): composer context strip pads both edges evenly by @limineol in pingdotgg/t3code#17562
* test(usage): v4 cache upgrade test waits for the migrated cache write by @Mnigos in pingdotgg/t3code#17553
* feat(mobile): support Duo in the shared iOS app by @juliusmarminge in pingdotgg/t3code#12648
* refactor(source-control): GitManager reads provider resolvers, not host kinds by @juliusmarminge in pingdotgg/t3code#17617
* refactor(source-control): PullRequestService reads GitHub resolvers, not its kind by @juliusmarminge in pingdotgg/t3code#17619
* refactor(source-control): Forgejo identity and Azure DevOps addressing move into their packages by @juliusmarminge in pingdotgg/t3code#17624
* refactor: home directory comes from a HostProcessHomeDirectory reference by @juliusmarminge in pingdotgg/t3code#17628
* refactor(shared): host process references live in a HostProcess module by @juliusmarminge in pingdotgg/t3code#17641
* feat(web): filter PR comments by bots and resolved threads by @juliusmarminge in pingdotgg/t3code#17645
* fix(clients): remove redundant prefix from PR watch status by @extoci in pingdotgg/t3code#17635
* fix(web): pending requests wait until you stop typing by @maria-rcks in pingdotgg/t3code#17637
* fix(models): remove new badges from Claude Opus and Sonnet 5.5 by @extoci in pingdotgg/t3code#17646
* fix(ui): keep focus and selection borders visible across the app by @maria-rcks in pingdotgg/t3code#16675
* fix(mobile): prevent row presses during native back swipes by @juliusmarminge in pingdotgg/t3code#17648
* fix(server): Codex shadow homes replace stray sqlite maintenance locks by @juliusmarminge in pingdotgg/t3code#17663
* feat(desktop): T3 Code can be your default web browser on macOS by @juliusmarminge in pingdotgg/t3code#17587
* test(server): the ACP process-tree test no longer collides with the runner's own pid by @yordis in pingdotgg/t3code#17647
* fix(web): keep branch restore action inline in narrow composers by @Saikrishna1876 in pingdotgg/t3code#14811
* fix(web): composer banner actions stay inline whenever they fit by @maria-rcks in pingdotgg/t3code#17640


**Full Changelog**: pingdotgg/t3code@v0.0.46-nightly.20261009.2886...v0.0.46-nightly.20261010.2908

Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.46-nightly.20261010.2908
github-actions Bot added a commit to davidvanderklay/t3code-flake that referenced this pull request Oct 10, 2026
## What's Changed
* chore(deps): upgrade Effect to 4.0.2 by @juliusmarminge in pingdotgg/t3code#17571
* fix(devices): recover stalled video without losing simulator input by @juliusmarminge in pingdotgg/t3code#17566
* fix(web): keep checkout stable while pr actions load by @maria-rcks in pingdotgg/t3code#16625
* fix(mobile): show waiting thread status by @maria-rcks in pingdotgg/t3code#16693
* feat(web): add parent thread breadcrumb navigation by @maria-rcks in pingdotgg/t3code#16666
* fix(server): restart inactivity after snoozed threads wake by @maria-rcks in pingdotgg/t3code#16674
* feat(desktop): passkeys in the in-app browser on macOS by @juliusmarminge in pingdotgg/t3code#16952
* fix(client): load earlier turns works for MCP threads over T3 Connect by @juliusmarminge in pingdotgg/t3code#17599
* refactor(client): sign relay request URLs built from the HttpApi contract by @juliusmarminge in pingdotgg/t3code#17602
* refactor(source-control): add @t3tools/source-control-core by @juliusmarminge in pingdotgg/t3code#17573
* refactor(source-control): Forgejo lives in @t3tools/source-control-forgejo by @juliusmarminge in pingdotgg/t3code#17581
* refactor(source-control): Azure DevOps lives in @t3tools/source-control-azure-devops by @juliusmarminge in pingdotgg/t3code#17592
* refactor(source-control): GitLab lives in @t3tools/source-control-gitlab by @juliusmarminge in pingdotgg/t3code#17594
* refactor(source-control): Bitbucket lives in @t3tools/source-control-bitbucket by @juliusmarminge in pingdotgg/t3code#17597
* refactor(source-control): GitHub lives in @t3tools/source-control-github by @juliusmarminge in pingdotgg/t3code#17607
* refactor(usage): transcript readers come from their drivers by @juliusmarminge in pingdotgg/t3code#17576
* refactor(usage): OpenCode usage comes from provider-opencode by @juliusmarminge in pingdotgg/t3code#17577
* refactor(usage): Cursor account usage comes from provider-cursor by @juliusmarminge in pingdotgg/t3code#17578
* refactor(usage): Antigravity usage is a reader on its driver by @juliusmarminge in pingdotgg/t3code#17579
* refactor(usage): usage readers use Effect FileSystem and SqlClient by @juliusmarminge in pingdotgg/t3code#17615
* fix(web): composer context strip pads both edges evenly by @limineol in pingdotgg/t3code#17562
* test(usage): v4 cache upgrade test waits for the migrated cache write by @Mnigos in pingdotgg/t3code#17553
* feat(mobile): support Duo in the shared iOS app by @juliusmarminge in pingdotgg/t3code#12648
* refactor(source-control): GitManager reads provider resolvers, not host kinds by @juliusmarminge in pingdotgg/t3code#17617
* refactor(source-control): PullRequestService reads GitHub resolvers, not its kind by @juliusmarminge in pingdotgg/t3code#17619
* refactor(source-control): Forgejo identity and Azure DevOps addressing move into their packages by @juliusmarminge in pingdotgg/t3code#17624
* refactor: home directory comes from a HostProcessHomeDirectory reference by @juliusmarminge in pingdotgg/t3code#17628
* refactor(shared): host process references live in a HostProcess module by @juliusmarminge in pingdotgg/t3code#17641
* feat(web): filter PR comments by bots and resolved threads by @juliusmarminge in pingdotgg/t3code#17645
* fix(clients): remove redundant prefix from PR watch status by @extoci in pingdotgg/t3code#17635
* fix(web): pending requests wait until you stop typing by @maria-rcks in pingdotgg/t3code#17637
* fix(models): remove new badges from Claude Opus and Sonnet 5.5 by @extoci in pingdotgg/t3code#17646
* fix(ui): keep focus and selection borders visible across the app by @maria-rcks in pingdotgg/t3code#16675
* fix(mobile): prevent row presses during native back swipes by @juliusmarminge in pingdotgg/t3code#17648
* fix(server): Codex shadow homes replace stray sqlite maintenance locks by @juliusmarminge in pingdotgg/t3code#17663
* feat(desktop): T3 Code can be your default web browser on macOS by @juliusmarminge in pingdotgg/t3code#17587
* test(server): the ACP process-tree test no longer collides with the runner's own pid by @yordis in pingdotgg/t3code#17647
* fix(web): keep branch restore action inline in narrow composers by @Saikrishna1876 in pingdotgg/t3code#14811
* fix(web): composer banner actions stay inline whenever they fit by @maria-rcks in pingdotgg/t3code#17640


**Full Changelog**: pingdotgg/t3code@v0.0.46-nightly.20261009.2886...v0.0.46-nightly.20261010.2908

Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.46-nightly.20261010.2908
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

macroscope-review Opt PRs made by unvouched contributors in for Macroscope review. Vouched contributors auto-reviews size:XXL 1,000+ changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant