fix(agent): don't apply Codex gpt-5.5 autoraise notice when an external context engine is active

When context.engine selects a plugin engine (e.g. LCM), the host
compression threshold — including the Codex gpt-5.5 50% -> 85%
autoraise — only configures the built-in ContextCompressor and never
reaches the plugin. The autoraise notice still fired, telling the user
auto-compaction was raised when nothing actually changed, and the
startup context-limit line printed the host percent next to the
engine's own threshold_tokens, contradicting itself.

- Clear _compression_threshold_autoraised when a plugin engine is
  selected, suppressing both the CLI startup notice and the gateway
  turn-1 replay via _compression_warning.
- Print the active engine's own threshold_percent in the startup
  context-limit line so percent and token count agree.
- Built-in behavior is preserved, including the fallback path where a
  configured engine fails to load and the built-in compressor takes
  over.

Fixes #44439
This commit is contained in:
AIalliAI 2026-06-11 19:50:06 +00:00 committed by Teknium
parent fff2408961
commit 60391d0eef
2 changed files with 111 additions and 1 deletions

View file

@ -1773,6 +1773,12 @@ def init_agent(
if _selected_engine is not None:
agent.context_compressor = _selected_engine
# External engines own compaction policy: the host compression
# threshold (including the Codex gpt-5.5 autoraise above) only
# configures the built-in ContextCompressor and never reaches the
# plugin, so the autoraise notice would announce a change that does
# not apply. Drop it. (#44439)
agent._compression_threshold_autoraised = None
# Resolve context_length for plugin engines — mirrors switch_model() path
from agent.model_metadata import get_model_context_length
_plugin_ctx_len = get_model_context_length(
@ -2012,7 +2018,13 @@ def init_agent(
if not agent.quiet_mode:
if compression_enabled:
print(f"📊 Context limit: {agent.context_compressor.context_length:,} tokens (compress at {int(compression_threshold*100)}% = {agent.context_compressor.threshold_tokens:,})")
# Report the active engine's own threshold — for a plugin engine
# the host compression_threshold is not in effect, and mixing the
# two printed a percent that contradicted the token count. (#44439)
_active_threshold_pct = getattr(
agent.context_compressor, "threshold_percent", compression_threshold
)
print(f"📊 Context limit: {agent.context_compressor.context_length:,} tokens (compress at {int(_active_threshold_pct*100)}% = {agent.context_compressor.threshold_tokens:,})")
else:
print(f"📊 Context limit: {agent.context_compressor.context_length:,} tokens (auto-compression disabled)")
# Notice with the exact opt-back-out command. Printed inline at startup

View file

@ -139,3 +139,101 @@ def test_plugin_engine_update_model_args():
assert "model" in kw
assert "provider" in kw
assert "api_mode" in kw
def _codex_agent_kwargs():
return dict(
model="gpt-5.5",
provider="openai-codex",
api_key="test-key-1234567890",
base_url="https://chatgpt.com/backend-api/codex",
quiet_mode=True,
skip_context_files=True,
skip_memory=True,
)
def test_codex_gpt55_autoraise_suppressed_for_plugin_engine():
"""Codex gpt-5.5 autoraise must not fire when an external engine is active.
Regression test for #44439 — the host compression threshold (including
the 0.85 autoraise) never reaches a plugin context engine, so the notice
announced a change that did not apply.
"""
engine = _StubEngine()
cfg = {
"context": {"engine": "stub"},
"compression": {"enabled": True, "threshold": 0.75},
"agent": {},
}
with (
patch("hermes_cli.config.load_config", return_value=cfg),
patch("plugins.context_engine.load_context_engine", return_value=engine),
patch("agent.model_metadata.get_model_context_length", return_value=272_000),
patch("run_agent.get_tool_definitions", return_value=[]),
patch("run_agent.check_toolset_requirements", return_value={}),
patch("run_agent.OpenAI"),
):
from run_agent import AIAgent
agent = AIAgent(**_codex_agent_kwargs())
assert agent.context_compressor is engine
assert agent._compression_threshold_autoraised is None
assert agent._compression_warning is None
# The engine's own policy is untouched by the host threshold.
assert engine.threshold_percent == 0.75
def test_codex_gpt55_autoraise_still_applies_to_builtin_compressor():
"""Stock built-in compressor keeps the 50% → 85% Codex gpt-5.5 autoraise."""
cfg = {
"compression": {"enabled": True, "threshold": 0.50},
"agent": {},
}
with (
patch("hermes_cli.config.load_config", return_value=cfg),
patch("agent.context_compressor.get_model_context_length", return_value=272_000),
patch("run_agent.get_tool_definitions", return_value=[]),
patch("run_agent.check_toolset_requirements", return_value={}),
patch("run_agent.OpenAI"),
):
from run_agent import AIAgent
agent = AIAgent(**_codex_agent_kwargs())
assert agent._compression_threshold_autoraised == {"from": 0.50, "to": 0.85}
assert agent.context_compressor.threshold_percent == 0.85
# Gateway parity: the notice is stashed for replay on turn 1.
assert agent._compression_warning and "85%" in agent._compression_warning
def test_codex_gpt55_autoraise_applies_when_plugin_engine_missing():
"""If the configured engine fails to load, the built-in compressor is
active and the autoraise (plus its notice) must still apply."""
cfg = {
"context": {"engine": "no-such-engine"},
"compression": {"enabled": True, "threshold": 0.50},
"agent": {},
}
with (
patch("hermes_cli.config.load_config", return_value=cfg),
patch(
"plugins.context_engine.load_context_engine",
side_effect=ValueError("not found"),
),
patch("hermes_cli.plugins.get_plugin_context_engine", return_value=None),
patch("agent.context_compressor.get_model_context_length", return_value=272_000),
patch("run_agent.get_tool_definitions", return_value=[]),
patch("run_agent.check_toolset_requirements", return_value={}),
patch("run_agent.OpenAI"),
):
from run_agent import AIAgent
agent = AIAgent(**_codex_agent_kwargs())
assert agent._compression_threshold_autoraised == {"from": 0.50, "to": 0.85}
assert agent.context_compressor.threshold_percent == 0.85