Skip to content
Closed
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
9 changes: 9 additions & 0 deletions cli-config.yaml.example
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,15 @@ compression:
# web_extract:
# provider: "auto"
# model: ""
#
# # Context compression summarization model
# compression:
# provider: "auto"
# model: ""
# base_url: "" # optional custom OpenAI-compatible endpoint
# api_key: "" # optional API key for base_url
# context_length: null # optional explicit context window override (tokens)
# # useful when custom endpoints don't expose /models metadata

# =============================================================================
# Persistent Memory
Expand Down
1 change: 1 addition & 0 deletions hermes_cli/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,7 @@ def _ensure_hermes_home_managed(home: Path):
"model": "",
"base_url": "",
"api_key": "",
"context_length": None, # optional explicit override for the compression auxiliary runtime
"timeout": 120, # seconds — compression summarises large contexts; increase for local models
},
"session_search": {
Expand Down
12 changes: 12 additions & 0 deletions run_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -1748,10 +1748,22 @@ def _check_compression_model_feasibility(self) -> None:

aux_base_url = str(getattr(client, "base_url", ""))
aux_api_key = str(getattr(client, "api_key", ""))
aux_config_context_length = None
try:
from hermes_cli.config import load_config
_cfg = load_config()
_aux_cfg = (_cfg.get("auxiliary", {}) or {}).get("compression", {})
if isinstance(_aux_cfg, dict):
_raw_aux_ctx = _aux_cfg.get("context_length")
if _raw_aux_ctx is not None:
aux_config_context_length = int(_raw_aux_ctx)
except Exception:
aux_config_context_length = None
aux_context = get_model_context_length(
aux_model,
base_url=aux_base_url,
api_key=aux_api_key,
config_context_length=aux_config_context_length,
)

threshold = self.context_compressor.threshold_tokens
Expand Down
32 changes: 32 additions & 0 deletions tests/run_agent/test_compression_feasibility.py
Original file line number Diff line number Diff line change
Expand Up @@ -308,3 +308,35 @@ def test_run_conversation_clears_warning_after_replay(mock_get_client, mock_ctx_
agent._compression_warning = None

assert len(callback_events) == 0


@patch("agent.auxiliary_client.get_text_auxiliary_client")
def test_explicit_auxiliary_compression_context_length_override_is_forwarded(mock_get_client):
"""auxiliary.compression.context_length should override metadata probing for feasibility checks."""
agent = _make_agent(main_context=200_000, threshold_percent=0.50)
mock_client = MagicMock()
mock_client.base_url = "https://example-proxy/v1"
mock_client.api_key = "sk-aux"
mock_get_client.return_value = (mock_client, "gpt-5.4")

messages = []
agent._emit_status = lambda msg: messages.append(msg)

captured = {}

def _capture(model, **kwargs):
captured["model"] = model
captured.update(kwargs)
return 80_000

with patch("hermes_cli.config.load_config", return_value={"auxiliary": {"compression": {"context_length": 80_000}}}), \
patch("agent.model_metadata.get_model_context_length", side_effect=_capture):
agent._check_compression_model_feasibility()

assert captured["model"] == "gpt-5.4"
assert captured["base_url"] == "https://example-proxy/v1"
assert captured["api_key"] == "sk-aux"
assert captured["config_context_length"] == 80_000
assert len(messages) == 1
assert "80,000" in messages[0]
assert "100,000" in messages[0]