feat: opt-in Claude 1M beta header with safe 200k fallback#514
feat: opt-in Claude 1M beta header with safe 200k fallback#514ndycode wants to merge 3 commits intoNoeFabris:devfrom
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review infoConfiguration used: Repository UI Review profile: CHILL Plan: Pro Cache: Disabled due to data retention organization setting Knowledge base: Disabled due to data retention organization setting 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (1)
📜 Recent review details⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
🧰 Additional context used🧬 Code graph analysis (1)src/plugin/logging-utils.test.ts (1)
🔇 Additional comments (1)
WalkthroughAdds two new configuration fields, Estimated code review effort🎯 4 (Complex) | ⏱️ ~55 minutes 🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. 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. Comment |
Add experimental Claude long-context beta header support for Claude 4.6 models behind config flags, with automatic one-time fallback to stable 200k behavior when provider rejects the beta header. Includes schema/docs/model metadata updates and request-level tests covering header injection, dedupe, retry-disable behavior, and rejection detection. Refs NoeFabris#506 Co-authored-by: Codex <noreply@openai.com>
b2e0b50 to
fe568b7
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (3)
src/plugin/config/schema.test.ts (1)
72-86: Add an assertion forminLengthonclaude_long_context_beta_header.The schema enforces non-empty header values; locking that in tests will prevent silent regression.
✅ Proposed test hardening
- const schema = JSON.parse(readFileSync(schemaPath, "utf8")) as { - properties?: Record<string, { type?: string; default?: unknown; description?: string }>; - }; + const schema = JSON.parse(readFileSync(schemaPath, "utf8")) as { + properties?: Record<string, { type?: string; default?: unknown; description?: string; minLength?: number }>; + }; @@ expect(claudeLongContextBetaHeader).toMatchObject({ type: "string", default: "context-1m-2025-08-07", + minLength: 1, });🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/plugin/config/schema.test.ts` around lines 72 - 86, The test for claude_long_context_beta_header misses asserting the schema's non-empty constraint; update the "documents claude_long_context_beta_header in the JSON schema" test to assert that schema.properties?.claude_long_context_beta_header has a minLength of 1 (or a numeric minLength > 0), e.g. check the existence and numeric value of minLength on the claude_long_context_beta_header object so the non-empty header requirement is locked into the test.src/plugin.ts (1)
2379-2388: Consider redactingreasonPreviewbefore debug logging.At Line 2379, the preview is taken from raw provider body text; those payloads can occasionally echo user/tool content. A lightweight scrub before logging would reduce accidental sensitive-data exposure.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/plugin.ts` around lines 2379 - 2388, The preview derived from errorBodyText (reasonPreview) may contain echoed user/tool content and should be redacted before logging; update the code around reasonPreview, pushDebug, and log.debug to run a lightweight scrub function (e.g., redactSensitive or scrubText) on the extracted string — trimming, replacing likely secrets (emails, tokens, long hex sequences, credit-card patterns) with placeholders and/or masking everything after a short safe length — and then log the redactedPreview (not the raw reasonPreview) and continue to include prepared.claudeLongContextBetaHeader and prepared.effectiveModel as before so logs no longer contain unredacted provider payloads.src/plugin/request.test.ts (1)
95-125: Add one positive 403 case for rejection detection.At Line 116, the suite verifies non-4xx behavior, but there is no positive 403 scenario. Since the detector intentionally supports both 400 and 403, adding a 403-positive test would lock that contract in.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/plugin/request.test.ts` around lines 95 - 125, Add a positive 403 test for the isUnsupportedClaudeLongContextBetaError detector: inside the existing "isUnsupportedClaudeLongContextBetaError" describe block add an it case that constructs a JSON body with error.message containing "unsupported anthropic-beta header context-1m-2025-08-07" (same pattern as the 400 positive case) calls isUnsupportedClaudeLongContextBetaError(403, body) and asserts the result is true so the test suite verifies both 400 and 403 are detected.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/plugin/config/schema.ts`:
- Line 245: The schema for claude_long_context_beta_header currently uses
z.string().min(1) which allows whitespace-only values; update the validator for
claude_long_context_beta_header to trim input before length check by using
z.string().trim().min(1).default("context-1m-2025-08-07") so whitespace-only
headers are rejected prior to being sent to the provider.
---
Nitpick comments:
In `@src/plugin.ts`:
- Around line 2379-2388: The preview derived from errorBodyText (reasonPreview)
may contain echoed user/tool content and should be redacted before logging;
update the code around reasonPreview, pushDebug, and log.debug to run a
lightweight scrub function (e.g., redactSensitive or scrubText) on the extracted
string — trimming, replacing likely secrets (emails, tokens, long hex sequences,
credit-card patterns) with placeholders and/or masking everything after a short
safe length — and then log the redactedPreview (not the raw reasonPreview) and
continue to include prepared.claudeLongContextBetaHeader and
prepared.effectiveModel as before so logs no longer contain unredacted provider
payloads.
In `@src/plugin/config/schema.test.ts`:
- Around line 72-86: The test for claude_long_context_beta_header misses
asserting the schema's non-empty constraint; update the "documents
claude_long_context_beta_header in the JSON schema" test to assert that
schema.properties?.claude_long_context_beta_header has a minLength of 1 (or a
numeric minLength > 0), e.g. check the existence and numeric value of minLength
on the claude_long_context_beta_header object so the non-empty header
requirement is locked into the test.
In `@src/plugin/request.test.ts`:
- Around line 95-125: Add a positive 403 test for the
isUnsupportedClaudeLongContextBetaError detector: inside the existing
"isUnsupportedClaudeLongContextBetaError" describe block add an it case that
constructs a JSON body with error.message containing "unsupported anthropic-beta
header context-1m-2025-08-07" (same pattern as the 400 positive case) calls
isUnsupportedClaudeLongContextBetaError(403, body) and asserts the result is
true so the test suite verifies both 400 and 403 are detected.
ℹ️ Review info
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge base: Disabled due to data retention organization setting
📒 Files selected for processing (11)
README.mdassets/antigravity.schema.jsondocs/CONFIGURATION.mddocs/MODEL-VARIANTS.mdscript/build-schema.tssrc/plugin.tssrc/plugin/config/models.tssrc/plugin/config/schema.test.tssrc/plugin/config/schema.tssrc/plugin/request.test.tssrc/plugin/request.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Greptile Review
🧰 Additional context used
🧬 Code graph analysis (3)
src/plugin/config/schema.test.ts (1)
src/plugin/config/schema.ts (1)
DEFAULT_CONFIG(469-524)
src/plugin/request.test.ts (1)
src/plugin/request.ts (2)
isUnsupportedClaudeLongContextBetaError(760-788)prepareAntigravityRequest(810-1654)
src/plugin.ts (1)
src/plugin/request.ts (1)
isUnsupportedClaudeLongContextBetaError(760-788)
🔇 Additional comments (14)
assets/antigravity.schema.json (1)
123-133: Looks good: new long-context config fields are well-scoped and backward-compatible.The defaults, types, and descriptions for both new keys are clear and align with the fallback behavior described in the PR.
README.md (1)
123-124: Docs update is clear and consistent.The 200k-base labeling and explicit opt-in/fallback note reduce ambiguity for users selecting Claude models.
Also applies to: 143-143, 194-194, 199-199
script/build-schema.ts (1)
44-47: Nice schema-generation sync.Adding these keys to
optionDescriptionskeeps generated schema docs aligned with runtime config surface.src/plugin/config/models.ts (1)
71-71: Model label clarification is good.The added “200k base” suffix improves UX without affecting behavior.
Also applies to: 76-76
src/plugin/config/schema.test.ts (1)
50-70: Good test coverage for the new config defaults and schema docs.This block cleanly validates the new boolean flag contract.
docs/MODEL-VARIANTS.md (1)
107-109: Clear and helpful clarification.The 200k-default note plus beta fallback behavior is documented in the right place for variant users.
Also applies to: 115-115
docs/CONFIGURATION.md (1)
38-39: Strong configuration docs update.The option table, behavior section, and defaults table are aligned and make the opt-in fallback path easy to understand.
Also applies to: 56-72, 191-191
src/plugin/config/schema.ts (1)
483-484: Default config wiring for new fields looks correct.
DEFAULT_CONFIGis aligned with the new opt-in behavior and default header token.src/plugin/request.test.ts (1)
692-789: Strong coverage for long-context header behavior.This block cleanly validates apply/non-apply conditions, header deduplication, and retry-disable behavior.
src/plugin.ts (2)
123-140: Toast dedupe helper is well-bounded and practical.The per-session gate plus capped set size is a solid anti-spam guard for fallback warnings.
2359-2393: The 4xx beta-rejection fallback flow is implemented cleanly.The guard on
claudeLongContextBetaApplied, one-time retry disable, toast throttling, and same-endpoint retry (i -= 1) all align with a safe fallback path.src/plugin/request.ts (3)
724-746: Header append and long-context state plumbing look solid.The shared
appendAnthropicBetaHeaderpath avoids duplicate token insertion, and the applied/header return metadata cleanly supports outer retry fallback decisions.Also applies to: 1596-1606, 1612-1612, 1649-1650
760-788: Unsupported-beta detector logic is pragmatic for fallback triggering.The status gate plus keyword checks are a reasonable balance for safely switching to the stable path when provider beta-header support is absent.
748-751: No change needed—the exact match for Sonnet is intentional and correct.The model resolver only emits tier variants (
-low,-medium,-high) for Claude Opus-thinking models, not for Sonnet. Sonnet 4.6 resolves to the exact base nameclaude-sonnet-4-6without suffix variants. The asymmetric matching—exact equality for Sonnet vs. prefix for Opus—correctly reflects this design difference.Likely an incorrect or invalid review comment.
Code Review SummaryStatus: No New Issues | Recommendation: Merge Overview
Previous Issues Status
Files Reviewed (8 files)
Code QualityThe implementation is well-structured and the previous issues have been resolved:
TypeScript compilation and all tests pass successfully. |
Greptile SummaryThis PR adds opt-in experimental Claude long-context beta header support for Claude 4.6 models with automatic fallback to stable 200k context when providers reject the beta header. Key Changes:
Implementation Quality: Confidence Score: 5/5
Important Files Changed
Sequence DiagramsequenceDiagram
participant Client
participant Plugin
participant PrepareRequest
participant Provider
participant ErrorDetector
Client->>Plugin: Request with Claude 4.6 model
Plugin->>PrepareRequest: prepareAntigravityRequest(claudeLongContextBeta=true)
alt Model is eligible (Sonnet 4.6 / Opus 4.6 Thinking)
PrepareRequest->>PrepareRequest: appendAnthropicBetaHeader(context-1m-2025-08-07)
PrepareRequest-->>Plugin: Request with beta header
else Model not eligible or beta disabled
PrepareRequest-->>Plugin: Request without beta header
end
Plugin->>Provider: Send request with beta header
Provider-->>Plugin: 400/403 Error (unsupported beta)
Plugin->>ErrorDetector: isUnsupportedClaudeLongContextBetaError()
ErrorDetector->>ErrorDetector: Check error message for beta rejection
alt Beta rejection detected
ErrorDetector-->>Plugin: true
Plugin->>Plugin: Set disableClaudeLongContextBetaForRetry=true
Plugin->>Plugin: Show toast notification (once per session)
Plugin->>Plugin: Log rejection reason (scrubbed)
Plugin->>PrepareRequest: Retry with disableClaudeLongContextBetaForRetry=true
PrepareRequest-->>Plugin: Request without beta header (200k fallback)
Plugin->>Provider: Retry without beta header
Provider-->>Plugin: 200 Success
Plugin-->>Client: Response with 200k context
else Not a beta rejection
ErrorDetector-->>Plugin: false
Plugin->>Plugin: Normal error handling
Plugin-->>Client: Error response
end
Last reviewed commit: 714c2ea |
- trim beta header config to reject whitespace-only values - assert minLength in schema JSON test - add positive 403 detection test for beta rejection - scrub provider error preview before debug logging Co-authored-by: Codex <noreply@openai.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/plugin/logging-utils.ts`:
- Around line 85-90: The current redaction chain assigned to the scrubbed
variable misses credentials when the value is prefixed with a scheme like
"Bearer"; update the authorization/api key/token/password regex used in the
.replace on scrubbed to also accept and redact an optional auth scheme and its
token (e.g., match patterns like "authorization\s*[:=]\s*Bearer\s+[^\s,;]+" or
generalize to capture an optional word scheme before the secret), so that both
"authorization: Bearer abc123" and "authorization: abc123" result in the secret
being replaced with "[redacted]" while preserving the header label; modify the
replace call that references the group for
(?:authorization|api[_-]?key|token|secret|password) to include an optional
scheme capture and redact the token portion.
ℹ️ Review info
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge base: Disabled due to data retention organization setting
📒 Files selected for processing (6)
src/plugin.tssrc/plugin/config/schema.test.tssrc/plugin/config/schema.tssrc/plugin/logging-utils.test.tssrc/plugin/logging-utils.tssrc/plugin/request.test.ts
🚧 Files skipped from review as they are similar to previous changes (2)
- src/plugin/config/schema.ts
- src/plugin/config/schema.test.ts
📜 Review details
🧰 Additional context used
🧬 Code graph analysis (3)
src/plugin/logging-utils.test.ts (1)
src/plugin/logging-utils.ts (1)
scrubTextForLog(79-93)
src/plugin/request.test.ts (1)
src/plugin/request.ts (2)
isUnsupportedClaudeLongContextBetaError(760-788)prepareAntigravityRequest(810-1654)
src/plugin.ts (2)
src/plugin/request.ts (1)
isUnsupportedClaudeLongContextBetaError(760-788)src/plugin/logging-utils.ts (1)
scrubTextForLog(79-93)
🔇 Additional comments (6)
src/plugin/logging-utils.test.ts (1)
72-88: Good targeted coverage for the new scrub utility.The tests validate both redaction markers and post-scrub truncation/normalization paths clearly.
src/plugin/request.test.ts (2)
95-135: Detection tests for unsupported long-context beta errors are well-scoped.Nice mix of true/false cases across status classes and message variants.
702-799: Claude beta-header request-path tests cover the critical branches.The added cases (apply, skip, dedupe, retry-disable) are exactly the right integration checks here.
src/plugin.ts (3)
125-142: One-time fallback toast dedupe is implemented cleanly.The set-based guard plus bounded eviction keeps behavior predictable and memory-controlled.
2049-2052: Request option wiring for long-context beta controls looks correct.These fields are passed through in the right place to support initial apply + retry downgrade behavior.
2361-2397: The beta-rejection downgrade path is robust and safely retried once.Good use of single-shot disablement, per-session toast throttling, and scrubbed reason logging before retry.
Co-authored-by: Codex <noreply@openai.com>
Summary
Deep Audit Notes
Behavior Matrix
Validation
pm run typecheck
pm test
pm run build
All passed locally in this branch.
Refs #506
Related duplicate context: #512