mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-11-06 05:17:15 +00:00
fix(agent): a task with its own URL re-probes when that URL's pin changes
The route identity read a provider entry's context pin only for a task that names the entry. A task with `provider: custom` and its own `base_url` returned early, but the probe still reads the pin of the entry at that URL, so lowering only that pin (900K to 80K) left a warm agent's trigger on the old window. The identity now carries the pin for the route's own URL too. Reported-by: greptile-apps[bot]
This commit is contained in:
1 parent
129e86cd1d
commit
8e7cf55eb6
2 files changed
+37
-8
No files matched your search
@@ -24,7 +24,8 @@ def _mark_checked(agent: Any, route: tuple) -> None:
|
||||
|
||||
def compression_route_identity() -> tuple:
|
||||
"""The configured compression route a probe measures: the task's provider, model, URL and context
|
||||
length, plus the URL of a ``providers:`` / ``custom_providers:`` entry the task names. A config this
|
||||
length, the URL of a ``providers:`` / ``custom_providers:`` entry the task names, and the context pin
|
||||
a provider entry sets for the compression model at the route's URL. A config this
|
||||
cannot read yields ``("unreadable",)``: the main request carries on and the probe reports the problem."""
|
||||
try:
|
||||
return _route_identity()
|
||||
@@ -38,15 +39,19 @@ def _route_identity() -> tuple:
|
||||
cfg = _get_auxiliary_task_config("compression")
|
||||
route = tuple(str(cfg.get(k) or "") for k in ("provider", "model", "base_url", "context_length"))
|
||||
provider = route[0].strip()
|
||||
if not provider or provider in ("auto", "main", "custom") or route[2]:
|
||||
return route
|
||||
from hermes_cli.config import get_custom_provider_context_length
|
||||
from hermes_cli.runtime_provider_custom import _get_named_custom_provider
|
||||
entry = _get_named_custom_provider(provider, resolve_credentials=False) or {}
|
||||
url, model = str(entry.get("base_url") or ""), route[1] or str(entry.get("model") or "")
|
||||
# The context pin the probe will read for this model at this URL (per-model, else entry-level).
|
||||
if route[2]:
|
||||
url, model, named = route[2], route[1], ()
|
||||
elif not provider or provider in ("auto", "main", "custom"):
|
||||
return route
|
||||
else:
|
||||
from hermes_cli.runtime_provider_custom import _get_named_custom_provider
|
||||
entry = _get_named_custom_provider(provider, resolve_credentials=False) or {}
|
||||
url, model = str(entry.get("base_url") or ""), route[1] or str(entry.get("model") or "")
|
||||
named = (url, str(entry.get("model") or ""))
|
||||
# The context pin the probe reads for this model at this URL (a matching entry's per-model, else entry-level).
|
||||
pin = get_custom_provider_context_length(model=model, base_url=url) if url and model else None
|
||||
return route + (url, str(entry.get("model") or ""), str(pin or ""))
|
||||
return route + named + (str(pin or ""),)
|
||||
|
||||
|
||||
def _drop_stale_ceiling(agent: Any) -> None:
|
||||
|
||||
@@ -710,6 +710,30 @@ def test_a_changed_provider_context_pin_reprobes_a_warm_agent(monkeypatch, tmp_p
|
||||
assert agent.context_compressor.threshold_tokens == 80_000
|
||||
|
||||
|
||||
|
||||
def test_a_changed_provider_pin_reprobes_a_task_that_sets_its_own_url(monkeypatch, tmp_path):
|
||||
"""``provider: custom`` with the task's own ``base_url``: the probe still reads the pin of the
|
||||
provider entry at that URL, so lowering only that pin (900K to 80K) re-probes a warm agent."""
|
||||
import json
|
||||
from agent.conversation_compression_feasibility import ensure_compression_feasibility_checked
|
||||
home = tmp_path / "home"
|
||||
home.mkdir()
|
||||
monkeypatch.setenv("HERMES_HOME", str(home))
|
||||
url = "http://gateway.invalid/v1"
|
||||
task = {"provider": "custom", "model": "small", "base_url": url}
|
||||
entry = {"name": "work-gateway", "base_url": url, "models": {"small": {"context_length": 900_000}}}
|
||||
(home / "config.yaml").write_text(json.dumps({"auxiliary": {"compression": task}, "custom_providers": [entry]}))
|
||||
agent = _warm_agent_on(home, [entry])
|
||||
(home / "config.yaml").write_text(json.dumps({"auxiliary": {"compression": task}, "custom_providers": [entry]}))
|
||||
client = MagicMock(base_url=url, api_key="test-key")
|
||||
with patch("agent.auxiliary_client.get_text_auxiliary_client", return_value=(client, "small")):
|
||||
ensure_compression_feasibility_checked(agent, 200_000)
|
||||
assert agent.context_compressor.threshold_tokens == 750_000
|
||||
entry["models"]["small"]["context_length"] = 80_000
|
||||
(home / "config.yaml").write_text(json.dumps({"auxiliary": {"compression": task}, "custom_providers": [entry]}))
|
||||
ensure_compression_feasibility_checked(agent, 200_000)
|
||||
assert agent.context_compressor.threshold_tokens == 80_000
|
||||
|
||||
def test_a_route_edited_during_the_probe_is_probed_again(monkeypatch, tmp_path):
|
||||
"""The latch records the route the probe measured: an edit that lands while the probe runs is
|
||||
probed on the next request instead of being labelled with the earlier measurement."""
|
||||
|
||||
Reference in new issue
Block a user