Skip to content

fix: track Claude Opus 5 as a 1M-context model - #81

Merged
Carl723000 merged 1 commit into
ClaudeCodeUsage:mainfrom
e7d:fix/opus-5-tracking
Aug 1, 2026
Merged

Carl723000 merged 1 commit into
ClaudeCodeUsage:mainfrom
e7d:fix/opus-5-tracking

Conversation

@e7d

@e7d e7d commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Problem

claude-opus-5 is reported with a 200 000-token context window, flagged as exact. Because a real Opus 5 session routinely exceeds that, the context indicator doesn't just read high — it reads over 100%, and estimated: false means the UI has no reason to soften it.

Measured on my own logs (31 060 records, via getCurrentContextInfo):

build window context tokens reported
main 200 000 361 850 180.9%
this branch 1 000 000 362 493 36.2%

Root cause

contextWindowFor has a [1m]-suffix escape hatch and a major-version check, but the latter only matched sonnet-:

// Sonnet 5.x+ (e.g. "claude-sonnet-5") has no "-4-" segment to match
// above, so check the major version directly. (Opus 5 doesn't exist yet —
// don't guess its window size here.)
if (/sonnet-(?:[5-9]|\d\d)(?:-|\b)/.test(m)) {

That comment is now out of date, and the [1m] hatch doesn't cover the gap: Claude Code writes the bare claude-opus-5 id to its JSONL even when the session is running the 1M-context variant. Across three days of my logs:

7750 "model":"claude-opus-5"      ← no [1m] marker, ever
 723 "model":"claude-opus-4-7"
 672 "model":"claude-sonnet-5"
 637 "model":"claude-opus-4-8"

So claude-opus-5 falls through to the generic /haiku|opus|sonnet/ branch and gets 200K.

Fix

One alternation, covering Opus 5+ alongside Sonnet 5+:

if (/(?:opus|sonnet)-(?:[5-9]|\d\d)(?:-|\b)/.test(m)) {

Older models are unaffected — the (?:-|\b) anchor still prevents a date suffix from matching, so claude-3-5-sonnet-20241022, claude-sonnet-4-5-20250929 and claude-opus-4-20250514 keep their 200K window. There's a regression test pinning that.

claude-opus-5 also gets an explicit MODEL_PRICING entry. No cost figure changes — inferPricingByFamily already resolved it to the correct current-Opus tier. The entry mirrors the existing claude-sonnet-5 anchor and removes a spurious Unknown model: claude-opus-5 line from the diagnostic output, which seemed worth avoiding in an extension whose diagnostics users are asked to attach to bug reports.

Opus 5 pricing ($5 / $25 per MTok) and context window verified 2026-07-28 against https://platform.claude.com/docs/en/about-claude/models/overview — for Opus 5, as for Sonnet 5, 1M is both the default and the maximum, with no smaller context variant.

Tests

Red first, then green. The failing run was actual: 200000, expected: 1000000.

  • getCurrentContextInfo reports a 1M window for Opus 5, with or without the [1m] marker
  • getCurrentContextInfo keeps the 200K window for pre-4.6 Opus and Sonnet (regression guard)
  • getModelPricing resolves Opus 5 from the exact table, long-context variant included

npm test → 172 tests, 171 pass, 0 fail, 1 skipped (the skip is pre-existing).

Also smoke-tested as an installed VSIX in VS Code 1.129.1 on Linux.

Notes for review

  • CHANGELOG.md has an entry under 2.2.1 → Fixed. I didn't touch the READMEs: 2.2.1 has no "what's new" section in any of the seven yet, so there was nowhere consistent to put it. Happy to add one if you'd rather it landed there too.
  • Not addressed here, but possibly worth its own issue: Opus 5 fast mode bills at $10 / $50 per MTok, not $5 / $25. On Opus 5 that's a speed: "fast" request parameter rather than a distinct model id, so I couldn't tell from my logs whether it's distinguishable in the JSONL at all. If it is, current pricing under-counts those turns.

🤖 Generated with Claude Code

Claude Code writes the plain `claude-opus-5` id to its JSONL even when the
session runs the 1M-context variant, so the existing `[1m]` marker never
fired for it. `contextWindowFor` fell through to the generic opus/sonnet
branch and returned 200K flagged as exact, making the reported context
percentage five times too high with no `estimated` hint to soften it.

The major-version branch now covers Opus 5+ as well as Sonnet 5+. Pre-4.6
Opus/Sonnet and dated 3.x snapshots keep their 200K window (the alternation
still cannot match a date suffix such as `sonnet-20241022`).

`claude-opus-5` also gets an explicit pricing entry. The family fallback
already resolved it to the correct $5/$25 current-Opus tier, so no cost
figure changes; the entry mirrors the existing `claude-sonnet-5` anchor and
drops the spurious `Unknown model` line from the diagnostic output.

Opus 5 pricing and context window verified 2026-07-28 against
https://platform.claude.com/docs/en/about-claude/models/overview
@e7d
e7d requested review from Carl723000 and jack21 as code owners July 28, 2026 14:16
@github-actions github-actions Bot added the fix Patch — bug fix label Jul 28, 2026
@github-actions

Copy link
Copy Markdown

🤖 Automated first-pass review

TL;DR
A clean, well-tested fix for a concrete bug where claude-opus-5 was mistracked as 200 000 tokens instead of 1 000 000. The diff is minimal (one regex alternation + one pricing entry + tests) and passes the full test suite. Ready to merge with one minor documentation observation.

Analysis

  • Correctness: The root cause is correctly identified – missing opus in the major-version regex that only matched sonnet. The fix (/(?:opus|sonnet)-(?:[5-9]|\d\d)(?:-|\b)/) is simple, correct, and preserves the existing guard against date-suffixed models (the (?:-|\b) anchor keeps claude-opus-4-20250514 at 200K). The pricing table entry mirrors the existing claude-sonnet-5 pattern and uses the correct OPUS_CURRENT tier. Test coverage includes both the new behaviour (claude-opus-5 with and without [1m]) and a regression guard for older models.

    • Opus 5 fast-mode pricing ($10/$50 per MTok) is correctly flagged as a separate concern – out of scope for this PR.
  • Convention and i18n gaps:

    • CHANGELOG is updated under the 2.2.1 Fixed section.
    • All seven README files are not updated. AGENTS.md says “User-facing changes require a CHANGELOG.md entry and matching documentation” and “Update all seven README files together.” While this is a bug fix rather than a new feature, the context-percentage change is user-visible. The author acknowledges this and offers to add docs if preferred – a reasonable deferral. Not a blocker, but a minor gap worth noting if the maintainer expects README updates for any user-facing fix.
    • No i18n changes needed (no new user-facing strings).
  • Merge-readiness: The PR follows the project’s red-green TDD practice, npm test passes (171 of 172, with the single pre-existing skip), and a VSIX smoke test was performed. The commit is focused, the description is detailed, and the diff is minimal.

Suggested next step(s)

  1. Merge as-is, or
  2. If the maintainer prefers consistent README updates for user-facing fixes, ask the author to add a brief mention to all seven README files (or to the relevant context-window documentation section) before merging. This is optional and low-risk.

🤖 Generated by DeepSeek as an automated first pass — not a maintainer decision.

@Carl723000 Carl723000 added the patch Patch bump label Aug 1, 2026
@Carl723000
Carl723000 merged commit f5c2e10 into ClaudeCodeUsage:main Aug 1, 2026
3 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

fix Patch — bug fix patch Patch bump

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants