diff --git a/agent/native_compaction.py b/agent/native_compaction.py index f5224cb0e5..e55c5566c5 100644 --- a/agent/native_compaction.py +++ b/agent/native_compaction.py @@ -2,8 +2,8 @@ ``context_management=[{"type": "compaction", "compact_threshold": N}]`` makes the server summarize older context into an opaque ``compaction`` item once the input crosses N tokens. -Deliberately narrow: gpt-5.6 on api.openai.com or the ChatGPT Codex backend, plus exact -gpt-6-astra on official Codex OAuth. The local compressor +Deliberately narrow: gpt-5.6 on api.openai.com or the ChatGPT Codex backend, plus gpt-6-astra +(and its ``-900k`` picker alias) on official Codex OAuth. The local compressor stays armed as fallback (native threshold clamped below the local trigger); compaction items ride the ``codex_reasoning_items`` sidecar. No transport imports (shared gate, no cycles). """ @@ -17,6 +17,7 @@ from urllib.parse import urlsplit from agent.codex_headers import is_official_codex_base_url from agent.context_compressor import is_compaction_summary_message from agent.message_content import flatten_message_text +from agent.reasoning_effort import is_astra_model logger = logging.getLogger(__name__) @@ -26,22 +27,15 @@ LOCAL_TRIGGER_SAFETY_MARGIN = 8_192 DEFAULT_COMPACT_THRESHOLD = 200_000 # Substring match so dated snapshots and variants (gpt-5.6-mini) stay eligible. _ELIGIBLE_MODEL_MARKER = "gpt-5.6" -_ASTRA_NATIVE_COMPACTION_MODELS = frozenset({"gpt-6-astra", "gpt-6-astra-900k"}) def is_native_compaction_model( model: Optional[str], *, provider: Optional[str] = None, base_url: Optional[str] = None, ) -> bool: - """Preserve gpt-5.6 eligibility; Astra additionally requires official Codex OAuth. - - ``-900k`` is Hermes' local picker alias and is stripped before the request is - sent. It must retain the same native-compaction eligibility as the bare - Astra wire model; otherwise enabling the feature in a 900K session is a - silent no-op. - """ - model_name = (model or "").strip().lower().rsplit("/", 1)[-1] - return _ELIGIBLE_MODEL_MARKER in model_name or ( - model_name in _ASTRA_NATIVE_COMPACTION_MODELS + """Preserve gpt-5.6 eligibility; Astra (``-900k`` is a picker alias of the same wire slug) + additionally requires official Codex OAuth.""" + return _ELIGIBLE_MODEL_MARKER in (model or "").lower() or ( + is_astra_model(model) and (provider or "").strip().lower() == "openai-codex" and is_official_codex_base_url(base_url or "") ) diff --git a/cli-config.yaml.example b/cli-config.yaml.example index 77baaf2cfa..60a94f6eed 100644 --- a/cli-config.yaml.example +++ b/cli-config.yaml.example @@ -723,7 +723,7 @@ compression: # Native OpenAI Responses server-side compaction (default: false). When true, # gpt-5.6-family models on the DIRECT OpenAI API (api.openai.com) or a ChatGPT - # Codex subscription, plus exact gpt-6-astra on official Codex OAuth, compact + # Codex subscription, plus gpt-6-astra (and its -900k alias) on official Codex OAuth, compact # server-side: OpenAI prunes older context into an # encrypted checkpoint that Hermes replays on later turns. No other provider, # route, or model is affected. Hermes' local compression stays armed as the diff --git a/tests/agent/test_astra_oauth_native_compaction.py b/tests/agent/test_astra_oauth_native_compaction.py index 58b8341fc9..a3aa6ccc5a 100644 --- a/tests/agent/test_astra_oauth_native_compaction.py +++ b/tests/agent/test_astra_oauth_native_compaction.py @@ -1,4 +1,5 @@ -"""Exact gpt-6-astra is native-compaction eligible only on official Codex OAuth (#103720). +"""gpt-6-astra (and its ``-900k`` picker alias) is native-compaction eligible only on official +Codex OAuth (#103720). Both the destination capability (``resolve_native_compaction_capabilities``) and the per-request gate (``native_compaction_context_management``) must agree, and the request @@ -20,6 +21,9 @@ _CODEX = "https://chatgpt.com/backend-api/codex" @pytest.mark.parametrize("model,provider,base_url,eligible", [ ("gpt-6-astra", "openai-codex", _CODEX, True), ("GPT-6-ASTRA", "openai-codex", "https://chatgpt.com:443/backend-api/codex/", True), + ("gpt-6-astra-900k", "openai-codex", _CODEX, True), + ("gpt-6-astra-900k", "openai-codex", "https://relay.example/v1", False), + ("gpt-6-astra-900k", "openai", "https://api.openai.com/v1", False), ("gpt-6-astra", "openai", "https://api.openai.com/v1", False), ("gpt-6-astra", "openai", _CODEX, False), ("gpt-6-astra", "openai-codex", "https://relay.example/v1", False), diff --git a/tests/agent/test_native_compaction.py b/tests/agent/test_native_compaction.py index 5810fa6731..a6fc019711 100644 --- a/tests/agent/test_native_compaction.py +++ b/tests/agent/test_native_compaction.py @@ -46,13 +46,6 @@ class TestModelGate: assert is_native_compaction_model("gpt-5.6-mini") assert is_native_compaction_model("GPT-5.6-2026-07-15") - def test_astra_900k_picker_alias_is_eligible_on_official_codex_oauth(self): - assert is_native_compaction_model( - "gpt-6-astra-900k", - provider="openai-codex", - base_url="https://chatgpt.com/backend-api/codex", - ) - def test_other_models_ineligible(self): # gpt-5.1/5.2 fail server-side on context_management (live-verified); # gpt-5.3-codex works upstream but is outside the supported set. diff --git a/website/docs/developer-guide/context-compression-and-caching.md b/website/docs/developer-guide/context-compression-and-caching.md index d80b893596..0ea61aee12 100644 --- a/website/docs/developer-guide/context-compression-and-caching.md +++ b/website/docs/developer-guide/context-compression-and-caching.md @@ -266,7 +266,7 @@ auxiliary: | `codex_gpt55_autoraise` | `true` | bool | Raise the trigger to 85% for gpt-5.4/5.5/5.6 and gpt-6 Astra on the ChatGPT Codex OAuth route (see below). Set `false` to keep the global `threshold` | | `codex_gpt55_autoraise_notice` | `true` | bool | Show the one-time Codex gpt-5.5 autoraise notice. Set `false` to keep the 85% autoraise but suppress the banner | | `codex_app_server_auto` | `native` | `native`, `hermes`, `off` | Thread-compaction mode for Codex app-server sessions (see below) | -| `codex_responses_native` | `false` | bool | Opt in to OpenAI's server-side compaction on the Responses API. Engages for gpt-5.6-family models on the direct OpenAI API or a ChatGPT Codex subscription, and exact `gpt-6-astra` on official Codex OAuth (see below) | +| `codex_responses_native` | `false` | bool | Opt in to OpenAI's server-side compaction on the Responses API. Engages for gpt-5.6-family models on the direct OpenAI API or a ChatGPT Codex subscription, and `gpt-6-astra` (including its `-900k` picker alias) on official Codex OAuth (see below) | | `codex_responses_compact_threshold` | `null` | `null` or positive integer | Server-side compaction trigger, read **only when `codex_responses_native: true`** — it never changes when local compression fires; the local trigger is `threshold` (ratio) capped by `threshold_tokens`. `null` follows the resolved local compression trigger with an 8,192 token safety margin. A positive integer remains absolute and only clamps downward when required. Invalid values use automatic behavior. Automatic mode falls back to `200000` when no usable local trigger exists | | `in_place` | `true` | bool | Compact on the same session id instead of rotating to a new one (see below) | @@ -429,9 +429,9 @@ client-side summary pass, and ZDR-friendly (`store: false`, no Opt in with `compression.codex_responses_native: true`. The gate is deliberately narrow, re-checked on every request: -- **Models:** the gpt-5.6 family, plus exact `gpt-6-astra` on official Codex - subscription OAuth. Astra on the direct API, Astra variants and other GPT-6 - models are excluded. gpt-5.1/5.2 return HTTP 500 or stall the stream when the +- **Models:** the gpt-5.6 family, plus `gpt-6-astra` (and its `-900k` picker + alias) on official Codex subscription OAuth. Astra on the direct API, other + Astra variants and other GPT-6 models are excluded. gpt-5.1/5.2 return HTTP 500 or stall the stream when the field is present (no structured rejection to downgrade on, verified live Aug 2026). - **Routes:** `api.openai.com` (OpenAI API key) or the ChatGPT Codex backend (Codex subscription OAuth) only. xAI, GitHub/Copilot, OpenRouter, relays, and