Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 57 additions & 9 deletions amplifier_module_provider_anthropic/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,17 @@ def __init__(
self._enable_1m_context = self._config_bool(
self.config.get("enable_1m_context", True)
)
# Operator assertion that this Anthropic account is entitled to the
# beta-gated 1M context window (a usage-tier requirement on top of the
# context-1m-2025-08-07 beta header). Sending the beta header is
# necessary but NOT sufficient: a non-entitled account is still capped
# at 200K. We therefore only *advertise* a beta-gated 1M window when
# the operator confirms entitlement here, so downstream clients do not
# budget against a window the API will reject. GA 1M windows (e.g.
# Opus 4.8+) are unaffected and always advertised. Default False.
self._context_1m_entitled = self._config_bool(
self.config.get("context_1m_entitled", False)
)
self._fallback_sonnet_model = str(
self.config.get("fallback_sonnet_model", "claude-sonnet-4-6")
)
Expand Down Expand Up @@ -670,9 +681,9 @@ def get_info(self) -> ProviderInfo:
"max_tokens": 4096,
"temperature": 0.7,
"timeout": 600.0,
"context_window": 1000000
if self._enable_1m_context and self._default_caps.supports_1m
else self._default_caps.base_context_window,
"context_window": self._advertised_context_window(
self.default_model, self._default_caps
),
"max_output_tokens": self._default_caps.max_output_tokens,
},
config_fields=[
Expand Down Expand Up @@ -704,6 +715,22 @@ def get_info(self) -> ProviderInfo:
"default_model": "not_contains:haiku"
}, # Hide for Haiku (doesn't support 1M)
),
ConfigField(
id="context_1m_entitled",
display_name="1M Context Entitlement",
field_type="boolean",
prompt=(
"Is this account entitled to the beta 1M context window? "
"Only enable if Anthropic has granted 1M access; otherwise "
"the advertised window stays at 200K to avoid overflow."
),
required=False,
default="false",
requires_model=True,
show_when={
"default_model": "not_contains:haiku"
},
),
ConfigField(
id="enable_prompt_caching",
display_name="Prompt Caching",
Expand Down Expand Up @@ -859,12 +886,7 @@ async def list_models(self) -> list[ModelInfo]:
self._extract_runtime_model_info(raw_model),
)

has_1m = self._enable_1m_context and caps.supports_1m
context_window = (
max(caps.base_context_window, 1000000)
if has_1m
else caps.base_context_window
)
context_window = self._advertised_context_window(model_id, caps)

result.append(
ModelInfo(
Expand Down Expand Up @@ -1160,6 +1182,32 @@ def _dedupe_headers(headers: list[str]) -> list[str]:
deduped.append(header)
return deduped

def _advertised_context_window(
self, model_id: str, caps: ModelCapabilities
) -> int:
"""Return the context window to *advertise* for ``model_id``.

The 1M window exists in two forms:

* **GA** (e.g. Opus 4.8+) -- always honored; safe to advertise.
* **Beta-gated** (Sonnet 4.6/4.7, Opus 4.6/4.7) -- requires the
``context-1m-2025-08-07`` beta header AND a usage-tier
entitlement. A non-entitled account is still capped at 200K, so
advertising 1M to it makes downstream clients skip context
compaction and overflow the real cap with a hard
``prompt is too long: N > 200000 maximum`` 400.

We advertise beta-gated 1M only when the operator asserts
entitlement via ``context_1m_entitled``; GA 1M is always advertised.
Falls back to ``base_context_window`` (200K) otherwise.
"""
if not (self._enable_1m_context and caps.supports_1m):
return caps.base_context_window
beta_gated = self._should_add_context_1m_beta(model_id, caps)
if beta_gated and not self._context_1m_entitled:
return caps.base_context_window
return max(caps.base_context_window, 1000000)

def _should_add_context_1m_beta(
self, model_id: str, request_caps: ModelCapabilities
) -> bool:
Expand Down
95 changes: 95 additions & 0 deletions tests/test_advertised_context_window.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
"""Tests for advertised context-window gating (_advertised_context_window).

A beta-gated 1M context window (Sonnet 4.6/4.7, Opus 4.6/4.7) must only be
advertised when the operator asserts entitlement via ``context_1m_entitled``;
otherwise the advertised window stays at the 200K base so downstream clients
don't skip compaction and overflow the real cap. GA 1M windows (Opus 4.8+)
are always advertised.
"""

from typing import cast

from amplifier_core import ModuleCoordinator

from amplifier_module_provider_anthropic import AnthropicProvider

from tests._helpers import FakeCoordinator

_BASE = 200000
_ONE_M = 1000000


def _make_provider(default_model: str, **config_overrides) -> AnthropicProvider:
provider = AnthropicProvider(
api_key="test-key",
config={
"use_streaming": False,
"default_model": default_model,
**config_overrides,
},
)
provider.coordinator = cast(ModuleCoordinator, FakeCoordinator())
return provider


def _advertised(model_id: str, **config_overrides) -> int:
provider = _make_provider(model_id, **config_overrides)
caps = AnthropicProvider._get_capabilities(model_id)
return provider._advertised_context_window(model_id, caps)


class TestBetaGatedNotEntitled:
"""Default (no entitlement): beta-gated 1M is NOT advertised."""

def test_sonnet_46_advertises_base(self):
assert _advertised("claude-sonnet-4-6") == _BASE

def test_opus_47_advertises_base(self):
assert _advertised("claude-opus-4-7-20260416") == _BASE


class TestBetaGatedEntitled:
"""With context_1m_entitled=True: beta-gated 1M IS advertised."""

def test_sonnet_46_advertises_1m(self):
assert _advertised("claude-sonnet-4-6", context_1m_entitled=True) == _ONE_M

def test_opus_47_advertises_1m(self):
assert (
_advertised("claude-opus-4-7-20260416", context_1m_entitled=True) == _ONE_M
)


class TestGaOneMillionAlwaysAdvertised:
"""GA 1M (Opus 4.8+) is advertised regardless of the entitlement flag."""

def test_opus_48_advertises_1m_without_flag(self):
assert _advertised("claude-opus-4-8") == _ONE_M

def test_opus_48_advertises_1m_with_flag(self):
assert _advertised("claude-opus-4-8", context_1m_entitled=True) == _ONE_M


class TestNoOneMillionSupport:
"""Models without 1M support always advertise the base window."""

def test_haiku_advertises_base(self):
assert _advertised("claude-haiku-4-5", context_1m_entitled=True) == _BASE

def test_sonnet_45_advertises_base(self):
# Sonnet 4.5 has supports_1m=False
assert _advertised("claude-sonnet-4-5", context_1m_entitled=True) == _BASE


class TestEnable1mContextDisabled:
"""enable_1m_context=False forces the base window even when entitled."""

def test_sonnet_46_disabled(self):
assert (
_advertised(
"claude-sonnet-4-6",
enable_1m_context=False,
context_1m_entitled=True,
)
== _BASE
)