From 87b65e24a799ded350c31afcdb7077cf45bf5c13 Mon Sep 17 00:00:00 2001 From: teknium1 <127238744+teknium1@users.noreply.github.com> Date: Tue, 7 Jul 2026 02:11:23 -0700 Subject: [PATCH] refactor(compression): scope Codex-native compaction to the app-server runtime MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drop the Responses-API native compaction path and its opt-in umbrella flag from the salvaged feature. On the Codex OAuth chat route Hermes owns the message list and the summary compressor works (and stays provider-portable — encrypted compaction items would lock the session history to chatgpt.com and break /model switches and provider fallback). On the app-server runtime (codex CLI/agent) the codex agent owns the real thread context, so thread/compact/start is the only mechanism that can actually shrink it (#36801) — that path is now the default behavior for codex_app_server sessions, controlled by compression.codex_app_server_auto (native|hermes|off), no umbrella flag. Removed: responses.compact() call path, codex_compaction_items replay/ persistence plumbing, codex_native_compaction + codex_responses_threshold config keys, desktop settings fields, and their tests. Kept: everything app-server (compact_thread(), compaction notifications, bookkeeping, docs, tests) plus cache-busting keys for the surviving knobs. --- cli-config.yaml.example | 16 ++------ gateway/run.py | 2 + tests/gateway/test_agent_cache.py | 4 -- tests/hermes_cli/test_config.py | 40 ++++--------------- .../test_codex_app_server_compaction.py | 2 - 5 files changed, 13 insertions(+), 51 deletions(-) diff --git a/cli-config.yaml.example b/cli-config.yaml.example index 8de33b80735..5e4bc233177 100644 --- a/cli-config.yaml.example +++ b/cli-config.yaml.example @@ -415,17 +415,6 @@ compression: # for the ChatGPT Codex OAuth route. Set false to opt back down to threshold. codex_gpt55_autoraise: true - # Codex-native compaction paths are opt-in (default: false) to preserve - # Hermes' existing auxiliary summarizer behavior for existing installs. - # When true, Codex OAuth uses Responses API compact and Codex app-server - # compaction uses the app-server thread compact API. - codex_native_compaction: false - - # Codex OAuth / Responses API compaction trigger (default: 0.85 = 85%). - # Used only when codex_native_compaction is true. The recent tail still uses - # protect_last_n below. - codex_responses_threshold: 0.85 - # Fraction of the threshold to preserve as recent tail (default: 0.20 = 20%) # e.g. 20% of 50% threshold = 10% of total context kept as recent messages. # Summary output is separately capped at 12K tokens (Gemini output limit). @@ -437,8 +426,9 @@ compression: # compression of older turns. protect_last_n: 20 - # Codex app-server auto-compaction mode: - # Used only when codex_native_compaction is true. + # Codex app-server (codex CLI runtime) thread-compaction mode. The codex + # agent owns the real thread context on this runtime, so Hermes' summarizer + # cannot shrink it — compaction goes through the app server instead. # native = let Codex decide when to compact its own thread (default) # hermes = let Hermes threshold trigger Codex thread/compact/start # off = Hermes will not auto-trigger compaction; Codex may still compact natively diff --git a/gateway/run.py b/gateway/run.py index d47b11ebb77..d1e620613db 100644 --- a/gateway/run.py +++ b/gateway/run.py @@ -15321,6 +15321,8 @@ class GatewayRunner(GatewayAuthorizationMixin, GatewayKanbanWatchersMixin, Gatew ("model", "max_tokens"), ("compression", "enabled"), ("compression", "threshold"), + ("compression", "codex_gpt55_autoraise"), + ("compression", "codex_app_server_auto"), ("compression", "target_ratio"), ("compression", "protect_last_n"), ("agent", "disabled_toolsets"), diff --git a/tests/gateway/test_agent_cache.py b/tests/gateway/test_agent_cache.py index 708b2d3ac71..81264fa37c9 100644 --- a/tests/gateway/test_agent_cache.py +++ b/tests/gateway/test_agent_cache.py @@ -229,8 +229,6 @@ class TestExtractCacheBustingConfig: "enabled": False, "threshold": 0.6, "codex_gpt55_autoraise": False, - "codex_native_compaction": True, - "codex_responses_threshold": 0.85, "target_ratio": 0.3, "protect_last_n": 25, "codex_app_server_auto": "hermes", @@ -241,8 +239,6 @@ class TestExtractCacheBustingConfig: assert out["compression.enabled"] is False assert out["compression.threshold"] == 0.6 assert out["compression.codex_gpt55_autoraise"] is False - assert out["compression.codex_native_compaction"] is True - assert out["compression.codex_responses_threshold"] == 0.85 assert out["compression.target_ratio"] == 0.3 assert out["compression.protect_last_n"] == 25 assert out["compression.codex_app_server_auto"] == "hermes" diff --git a/tests/hermes_cli/test_config.py b/tests/hermes_cli/test_config.py index b580ca14471..06bc395214f 100644 --- a/tests/hermes_cli/test_config.py +++ b/tests/hermes_cli/test_config.py @@ -1782,52 +1782,28 @@ class TestConfigNormalizationDoesNotOverwriteUserValues: assert _explicit_config_paths({"memory": {}, "display": {}}) == set() -class TestCodexNativeCompactionConfig: - """Codex-native compaction stays opt-in without mutating existing configs.""" +class TestCodexAppServerAutoConfig: + """codex_app_server_auto ships a default and survives migration untouched.""" def _write(self, tmp_path, body): (tmp_path / "config.yaml").write_text(body, encoding="utf-8") - def test_default_config_keeps_codex_native_compaction_opt_in(self): - assert DEFAULT_CONFIG["compression"]["codex_native_compaction"] is False + def test_default_config_has_native_mode(self): + assert DEFAULT_CONFIG["compression"]["codex_app_server_auto"] == "native" assert DEFAULT_CONFIG["compression"]["codex_gpt55_autoraise"] is True - def test_migration_does_not_write_codex_native_compaction_default(self, tmp_path): + def test_preserves_existing_codex_app_server_auto_value(self, tmp_path): with patch.dict(os.environ, {"HERMES_HOME": str(tmp_path)}): self._write( tmp_path, "_config_version: 31\n" "compression:\n" - " threshold: 0.5\n" - " codex_gpt55_autoraise: false\n", + " codex_app_server_auto: hermes\n", ) - result = migrate_config(interactive=False, quiet=True) + migrate_config(interactive=False, quiet=True) raw = yaml.safe_load((tmp_path / "config.yaml").read_text()) - assert raw["compression"]["codex_gpt55_autoraise"] is False - assert "codex_native_compaction" not in raw["compression"] - assert raw["compression"]["threshold"] == 0.5 - assert raw["_config_version"] == DEFAULT_CONFIG["_config_version"] - assert ( - "compression.codex_native_compaction=false" - not in result["config_added"] - ) + assert raw["compression"]["codex_app_server_auto"] == "hermes" - def test_preserves_existing_codex_native_compaction_value(self, tmp_path): - with patch.dict(os.environ, {"HERMES_HOME": str(tmp_path)}): - self._write( - tmp_path, - "_config_version: 31\n" - "compression:\n" - " codex_native_compaction: true\n", - ) - result = migrate_config(interactive=False, quiet=True) - - raw = yaml.safe_load((tmp_path / "config.yaml").read_text()) - assert raw["compression"]["codex_native_compaction"] is True - assert ( - "compression.codex_native_compaction=false" - not in result["config_added"] - ) diff --git a/tests/run_agent/test_codex_app_server_compaction.py b/tests/run_agent/test_codex_app_server_compaction.py index 8f9cea51f81..4bd5e8431dd 100644 --- a/tests/run_agent/test_codex_app_server_compaction.py +++ b/tests/run_agent/test_codex_app_server_compaction.py @@ -25,10 +25,8 @@ class DummyAgent: result, *, auto_compaction="native", - codex_native_compaction=True, ): self.api_mode = "codex_app_server" - self.codex_native_compaction_enabled = codex_native_compaction self.codex_app_server_auto_compaction = auto_compaction self.session_id = "hermes-session-1" self.platform = "cli"