mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-12 13:52:15 +00:00
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:
parent
fff2408961
commit
60391d0eef
2 changed files with 111 additions and 1 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue