🤖 fix: unify 1M context header injection for gateway + direct Anthropic#2366
Merged
🤖 fix: unify 1M context header injection for gateway + direct Anthropic#2366
Conversation
The mux-gateway handler in createModel() ignored muxProviderOptions entirely, so the anthropic-beta: context-1m-2025-08-07 header was never sent for gateway-routed Anthropic requests. This caused compaction retry with 1M context to fail for gateway users: the retry correctly set use1MContext in options, but createModel re-entered the mux-gateway handler which never translated that flag into the HTTP header. The full chain: mux client -> parley gateway (forwards anthropic-beta via whitelisted headers) -> Vercel AI Gateway -> Anthropic API. Without the header at the first hop, it never reaches Anthropic. Fix: mirror the same is1MEnabled check from the direct anthropic handler in the mux-gateway path, and pass anthropic-beta to createGateway(). Add integration test that seeds ~260k tokens of history (exceeding the 200k default limit for Opus 4.6), sends a /compact request without 1M pre-enabled, and verifies the 1M retry succeeds.
95850ac to
11c1f3f
Compare
Move the anthropic-beta: context-1m-2025-08-07 header from provider-creation
time (createAnthropic/createGateway) to per-request time (streamText headers).
Before: the is1MEnabled check and buildAnthropicHeaders() call was duplicated
in both the direct anthropic handler and the mux-gateway handler inside
createModel(). Every future Anthropic beta header would need the same
duplication.
After: a single buildRequestHeaders() function in common/utils/ai/ computes
per-request headers, normalizing gateway model strings the same way
buildProviderOptions() does. The headers flow through aiService →
streamManager → streamText({ headers }). Both the Anthropic SDK and the
Gateway SDK merge per-request headers with provider-level headers via
combineHeaders(), and parley whitelists anthropic-beta for forwarding.
The integration test (compaction1MRetry) passes unchanged, confirming the
per-request path works end-to-end.
Move buildRequestHeaders() from standalone requestHeaders.ts into providerOptions.ts alongside buildProviderOptions(). Both functions share the same gateway-normalization and provider-branching pattern, so colocating them reduces file fragmentation and fixes a layering smell (common/ importing from node/). - Move ANTHROPIC_1M_CONTEXT_HEADER constant to providerOptions.ts - Re-export from providerModelFactory.ts for backward compat - Merge aiService.ts imports into single providerOptions import - Delete src/common/utils/ai/requestHeaders.ts - Add 7 focused tests for buildRequestHeaders in providerOptions.test.ts
github-actions bot
pushed a commit
that referenced
this pull request
Feb 12, 2026
The 1M context beta header injection was moved from provider-creation-time to per-request via buildRequestHeaders() in providerOptions.ts (#2366). This left buildAnthropicHeaders() in providerModelFactory.ts as dead code (only referenced by its own tests). Remove the function, its backward-compat re-export of ANTHROPIC_1M_CONTEXT_HEADER, and the associated test block.
github-actions bot
pushed a commit
that referenced
this pull request
Feb 12, 2026
The 1M context beta header injection was moved from provider-creation-time to per-request via buildRequestHeaders() in providerOptions.ts (#2366). This left buildAnthropicHeaders() in providerModelFactory.ts as dead code (only referenced by its own tests). Remove the function, its backward-compat re-export of ANTHROPIC_1M_CONTEXT_HEADER, and the associated test block.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fix compaction 1M context retry always failing for gateway-routed Anthropic models by moving the
anthropic-betaheader from provider-creation time to per-request time, eliminating the two-path duplication that caused the gateway handler to silently drop the header. Colocate the newbuildRequestHeaders()alongsidebuildProviderOptions()since they share the same gateway-normalization and provider-branching pattern.Background
The
mux-gatewayhandler inproviderModelFactory.createModel()never readmuxProviderOptions, so theanthropic-beta: context-1m-2025-08-07header was never sent for gateway-routed Anthropic models. This caused compaction to always fail with "prompt is too long" for gateway users on Opus 4.6 — the retry correctly setuse1MContextin options, butcreateModel()re-entered the gateway handler which never translated that flag into the HTTP header.Implementation
buildRequestHeaders()insrc/common/utils/ai/providerOptions.ts— colocated withbuildProviderOptions()since both normalize gateway model strings and branch on provider. Single injection site for per-request HTTP headers, regardless of direct or gateway routing.Threading:
aiService.streamMessage()→streamManager.startStream()→streamText({ headers }). Both the Anthropic SDK and Gateway SDK merge per-request headers with provider-level headers viacombineHeaders(). Parley'sforwardAIGatewayHeaders()whitelistsanthropic-betafor forwarding.Removed: Duplicated
is1MEnabled+buildAnthropicHeaders()calls from both theanthropicandmux-gatewayhandlers increateModel(). Removed standalonerequestHeaders.ts— logic consolidated intoproviderOptions.ts.Validation
compaction1MRetry.integration.test.ts): seeds ~260k tokens of history (exceeding Opus 4.6's 200k default), sends/compactwithout 1M pre-enabled, verifies the 1M retry succeedsbuildRequestHeaders(direct, gateway, non-Anthropic, unsupported model,use1MContextModelslist)make typecheckandmake static-checkpassRisks
Low.
streamText({ headers })is a stable AI SDK parameter. Both the Anthropic and Gateway SDKs merge these with provider-level headers. Theanthropic-betaheader is not user-configurable, so removing the merge withnormalizedConfig.headershas no effect.Generated with
mux• Model:anthropic:claude-opus-4-6• Thinking:high• Cost:$31.17