atlas-iac/testing/tests/test_hermes_switchyard_provider_pool.py

72 lines
2.3 KiB
Python
Raw Permalink Normal View History

"""Provider-neutral fallback contracts for Hermes automatic routing."""
from __future__ import annotations
import tomllib
from testing.tests.test_hermes_chat_support import HERMES, _documents
def _config() -> dict:
manifest = _documents(HERMES / "switchyard-configmap.yaml")[0]
return tomllib.loads(manifest["data"]["routes.toml"])
def _provider(target_id: str) -> str | None:
parts = target_id.split("/")
if len(parts) >= 3 and parts[0] in {"route", "worker"}:
return parts[1]
return None
def test_every_classifier_selects_from_both_hosted_providers():
"""No automatic classifier may narrow its candidate set to one provider."""
config = _config()
targets = config["targets"]
classifiers = {
name: route
for name, route in config["routes"].items()
if route["type"] == "llm_classifier"
}
assert classifiers
for route in classifiers.values():
providers = {
_provider(targets[name]["id"])
for name in route["targets"]
}
assert {"codex", "claude"} <= providers
def test_classifier_failure_uses_an_even_cross_provider_pool():
"""The required Switchyard default must name a neutral pool, not a provider."""
config = _config()
targets = config["targets"]
routes = config["routes"]
routes_by_id = {route["id"]: route for route in routes.values()}
for route in routes.values():
if route["type"] != "llm_classifier":
continue
fallback_target_name = route["default_target"]
assert fallback_target_name in route["targets"]
assert fallback_target_name.startswith("neutral_")
fallback_target = targets[fallback_target_name]
assert fallback_target["llm_client"] == "neutral_pool"
pool = routes_by_id[fallback_target["id"]]
assert pool["type"] == "random"
assert pool["weights"] == [1.0, 1.0]
pool_providers = [
_provider(targets[name]["id"])
for name in pool["targets"]
]
assert sorted(pool_providers) == ["claude", "codex"]
neutral_client = config["llm_clients"]["neutral_pool"]
assert neutral_client == {
"format": "openai_chat",
"base_url": "http://127.0.0.1:9005/v1",
"max_retries": 0,
}