From 2f5780ebf9c996d571c0f3ad4422cec6e50d34d5 Mon Sep 17 00:00:00 2001 From: jenkins Date: Mon, 10 Aug 2026 22:11:42 -0300 Subject: [PATCH] hermes(agent): accept bounded raw Jetson votes --- .../hermes/plugins/auto-router/__init__.py | 18 +++++++++++++++--- testing/tests/test_hermes_auto_router.py | 9 +++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/services/hermes/plugins/auto-router/__init__.py b/services/hermes/plugins/auto-router/__init__.py index 4bdbc4608..1cc1c0815 100644 --- a/services/hermes/plugins/auto-router/__init__.py +++ b/services/hermes/plugins/auto-router/__init__.py @@ -276,6 +276,17 @@ def _classifier_input(text: str) -> str: return text[:400] + "\n...\n" + text[-595:] +def _parse_scalar_vote(content: Any, codes: tuple[str, ...]) -> str | None: + """Accept Ollama's raw or JSON-string rendering of one bounded vote.""" + raw = str(content or "").strip() + try: + value = json.loads(raw) + except (TypeError, ValueError, json.JSONDecodeError): + value = raw + value = str(value or "").strip().upper() + return value if value in codes else None + + def _jetson_scalar( text: str, prompt: str, codes: tuple[str, ...], timeout: float ) -> tuple[str | None, int]: @@ -300,12 +311,13 @@ def _jetson_scalar( try: with urllib.request.urlopen(request, timeout=timeout) as response: envelope = json.load(response) - value = json.loads(envelope.get("message", {}).get("content", "")) + value = _parse_scalar_vote( + envelope.get("message", {}).get("content", ""), codes + ) except (OSError, TimeoutError, ValueError, TypeError, json.JSONDecodeError): return None, round((time.monotonic() - started) * 1000) - value = str(value or "").strip().upper() latency_ms = round((time.monotonic() - started) * 1000) - return (value if value in codes else None), latency_ms + return value, latency_ms def _validated_local_route( diff --git a/testing/tests/test_hermes_auto_router.py b/testing/tests/test_hermes_auto_router.py index ade3daef0..7eb0490f8 100644 --- a/testing/tests/test_hermes_auto_router.py +++ b/testing/tests/test_hermes_auto_router.py @@ -135,6 +135,15 @@ def test_local_classifier_accepts_only_bounded_route_decisions(): assert (partial.provider, partial.effort) == ("codex", "medium") +def test_scalar_vote_accepts_raw_and_json_strings_but_remains_bounded(): + codes = ("C", "A") + + assert router._parse_scalar_vote("C", codes) == "C" + assert router._parse_scalar_vote('"A"', codes) == "A" + assert router._parse_scalar_vote(" codex ", codes) is None + assert router._parse_scalar_vote("C\nA", codes) is None + + def test_jetson_requests_separate_bounded_provider_and_effort_votes(monkeypatch): calls = []