Skip to content

fix(unified): count OpenCode Claude Agent turns once - #2005

Closed
github-actions[bot] wants to merge 1 commit into
mainfrom
pullfrog/issue-2004-run-41253794104-attempt-1
Closed

github-actions[bot] wants to merge 1 commit into
mainfrom
pullfrog/issue-2004-run-41253794104-attempt-1

Conversation

@github-actions

@github-actions github-actions Bot commented Nov 1, 2026 •

Copy link
Copy Markdown
Contributor

Implements the accepted fix for #2004: unified reports count OpenCode claude-agent turns once, on the Claude side.

What changed:

  • rust/adapters/opencode/src/parser.rs: OpenCodeV2Message now parses content[].native.sessionID, gated on the claude-agent provider; session_message_value_to_entry returns the linked ids alongside the entry so the loader filters without a second parse.
  • rust/adapters/opencode/src/loader.rs: new load_entries_for_unified skips v2 rows whose native session has a Claude transcript on disk. Skipped sessions still count as covered, within the same database and across data directories, so the cumulative session_v2 aggregate cannot bring the usage back. Without a transcript the rows stay. Focused ccusage opencode keeps every row via the unchanged load_entries.
  • rust/adapters/claude/src/paths.rs: new public transcript_session_ids reporting modern <project>/<session>.jsonl stems, failing open (legacy agent-*.jsonl copies, nested paths, non-UTF-8 paths, and unreadable config dirs are left out so usage is kept, never dropped on a guess).
  • rust/crates/ccusage-adapter-all/src/loader.rs: unified OpenCode spec loads through load_entries_for_unified, honoring the same claude_project filter as the Claude side.
  • Docs: short notes in the OpenCode guide and adapter README.

Scope notes: the legacy message table and storage/message/*.json fallback are untouched (they predate the v2-only claude-agent provider); the reported opus alias overpricing and the unrelated session-window/Windows issues from the thread are out of scope.

Tests:

  • New: parser native-link tests (claude-agent link, other-provider ignore, missing link), loader tests (skip with transcript, keep without, aggregate suppression incl. cross-directory archive root, focused load unaffected), Claude transcript_session_ids tests, and an end-to-end unified daily test (Claude 100 in + OpenCode 50 in counted, 100-token duplicate and its cost skipped).
  • cargo fmt --check clean, cargo clippy --all-targets clean (CI gates on -D warnings), full cargo test --workspace: 63 suites, all passing.
  • Network-free pricing was unavailable (no nix here), so tests ran with CCUSAGE_PRICING_JSON_PATH pointed at the flake-lock-pinned LiteLLM snapshot downloaded once to /tmp.

Changes are left uncommitted in the working tree as instructed.

Closes #2004


Summary by cubic

Fixes unified reports double-counting OpenCode claude-agent turns. The provider runs Claude Code under the hood, so each turn was stored twice: in OpenCode's database and in Claude Code's own transcript. Unified reports now skip the OpenCode copy when the transcript is on disk, counting the turn once, on the Claude side — which also carries the resolved model id that OpenCode's opus alias lacks.

  • Skipped sessions still count as covered within the same database and across data directories, so the cumulative session_v2 aggregate cannot bring the usage back.
  • ccusage opencode keeps every row, and when a transcript is gone the OpenCode rows are counted instead, so no usage disappears.
  • Skips apply only to v2 claude-agent rows with a content[].native.sessionID; legacy message-table rows and other providers are unaffected.

Written for commit ccfaff6. Summary will update on new commits.

View guided diff Turn on auto-fix

@coderabbitai

coderabbitai Bot commented Nov 1, 2026

Copy link
Copy Markdown

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: a16f02c5-0faf-4423-a26a-ef0ef202b809

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

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

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
ccusage-guide ccfaff6 Commit Preview URL

Branch Preview URL
Nov 01 2026, 12:24 AM

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.

Unified reports count OpenCode Claude Agent sessions twice

1 participant