Skip to content

🤖 fix: unify 1M context header injection for gateway + direct Anthropic#2366

Merged
ammario merged 3 commits intomainfrom
fix/gateway-1m-context-compaction
Feb 12, 2026
Merged

🤖 fix: unify 1M context header injection for gateway + direct Anthropic#2366
ammario merged 3 commits intomainfrom
fix/gateway-1m-context-compaction

Conversation

@ammar-agent
Copy link
Collaborator

@ammar-agent ammar-agent commented Feb 11, 2026

Summary

Fix compaction 1M context retry always failing for gateway-routed Anthropic models by moving the anthropic-beta header 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 new buildRequestHeaders() alongside buildProviderOptions() since they share the same gateway-normalization and provider-branching pattern.

Background

The mux-gateway handler in providerModelFactory.createModel() never read muxProviderOptions, so the anthropic-beta: context-1m-2025-08-07 header 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 set use1MContext in options, but createModel() re-entered the gateway handler which never translated that flag into the HTTP header.

Implementation

buildRequestHeaders() in src/common/utils/ai/providerOptions.ts — colocated with buildProviderOptions() 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 via combineHeaders(). Parley's forwardAIGatewayHeaders() whitelists anthropic-beta for forwarding.

Removed: Duplicated is1MEnabled + buildAnthropicHeaders() calls from both the anthropic and mux-gateway handlers in createModel(). Removed standalone requestHeaders.ts — logic consolidated into providerOptions.ts.

Validation

  • Integration test (compaction1MRetry.integration.test.ts): seeds ~260k tokens of history (exceeding Opus 4.6's 200k default), sends /compact without 1M pre-enabled, verifies the 1M retry succeeds
  • 7 new unit tests for buildRequestHeaders (direct, gateway, non-Anthropic, unsupported model, use1MContextModels list)
  • make typecheck and make static-check pass

Risks

Low. streamText({ headers }) is a stable AI SDK parameter. Both the Anthropic and Gateway SDKs merge these with provider-level headers. The anthropic-beta header is not user-configurable, so removing the merge with normalizedConfig.headers has no effect.


Generated with mux • Model: anthropic:claude-opus-4-6 • Thinking: high • Cost: $31.17

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.
@ammar-agent ammar-agent force-pushed the fix/gateway-1m-context-compaction branch from 95850ac to 11c1f3f Compare February 11, 2026 23:24
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.
@ammar-agent ammar-agent changed the title 🤖 fix: apply 1M context header for Anthropic models via mux-gateway 🤖 fix: unify 1M context header injection for gateway + direct Anthropic Feb 11, 2026
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
@ammario ammario merged commit 84fc119 into main Feb 12, 2026
23 checks passed
@ammario ammario deleted the fix/gateway-1m-context-compaction branch February 12, 2026 00:15
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.
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.

2 participants