atlas-iac/testing/tests/test_hermes_chat_quality.py
Hermes Agent 724656d841 feat(hermes-tts): prepare fixed multilingual voice policy
Supersede draft PR #26 with a merge-safe prerequisite: bake and preload the amy, irina, and claude Piper models, route only validated server-side language to fixed voices, and leave the live voice deployment manifest unchanged.

Remove the pinned WebUI speaker selector and its persisted preference, omit client voice fields from every outbound TTS path, and keep hands-free Voice Mode and the conversation instrument intact. Hostile or legacy voice fields remain ignored by the Piper server.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-21 13:45:31 +00:00

471 lines
21 KiB
Python

"""Core configuration and workload contracts for Hermes chat."""
from __future__ import annotations
import importlib.util
import sys
from types import SimpleNamespace
import yaml
from testing.tests.test_hermes_chat_support import (
HERMES,
ROOT,
_documents,
)
def test_chat_config_enables_real_research_compute_and_delegation():
configmap = _documents(HERMES / "chat-configmap.yaml")[0]
config = yaml.safe_load(configmap["data"]["config.yaml"])
# AUTO leaves effort unset so the target chosen by Switchyard owns it.
assert "reasoning_effort" not in config["agent"]
assert config["model"]["model"] == "atlas/auto/fast"
assert config["web"] == {
"backend": "ddgs",
"search_backend": "ddgs",
"extract_backend": "public-extract",
}
assert config["delegation"]["max_concurrent_children"] == 2
assert config["delegation"]["max_iterations"] == 80
assert config["agent"]["max_turns"] == 120
assert config["tool_loop_guardrails"]["hard_stop_enabled"] is True
for platform in ("cli", "api_server"):
toolsets = config["platform_toolsets"][platform]
assert "delegation" in toolsets
assert "browser" in toolsets
assert "python_sandbox" in toolsets
assert "vision" in toolsets
assert "web" in toolsets
assert "image_gen" in toolsets
assert "terminal" not in toolsets
assert "code_execution" not in toolsets
def test_agent_config_keeps_delegated_reviewers_from_owning_task_lifecycle():
configmap = _documents(HERMES / "agent-configmap.yaml")[0]
instructions = configmap["data"]["AGENTS.md"]
soul = configmap["data"]["SOUL.md"]
config = yaml.safe_load(configmap["data"]["config.yaml"])
assert (
"Only the foreground durable worker owns its Kanban task lifecycle"
in instructions
)
assert "Never unblock and then complete" in instructions
assert "gateway dispatcher can claim the transient" in instructions
for platform in ("cli", "api_server"):
assert "kanban" in config["platform_toolsets"][platform]
assert "must never complete, block, unblock, reclaim" in instructions
assert "task's final structured result itself" in instructions
assert "Atlas organization has private visibility" in instructions
assert "may be public or private" in instructions
assert "do not infer a\nrepository's visibility" in instructions
assert "brokered Git for clone, fetch" in instructions
assert "client carries no repository credential" in instructions
assert "Never call `kanban_show` without a known, non-empty task ID" in instructions
assert "bounded ad-hoc inspection and acceptance checks may" in instructions
assert "load implementation or TDD skills" in instructions
assert "Never call `kanban_show` without\na known, non-empty task ID" in soul
assert "must load a skill only when its workflow\nmaterially applies" in soul
assert "no repository token is present in this pod" in soul
assert "`scm.bstein.dev` is Forgejo/Gitea, not GitHub" in instructions
assert "GitHub/`gh` skill for an Atlas remote" in instructions
assert "load\n`$manage-atlas-pull-requests`" in instructions
assert "Updates, merge,\napprove, close, delete, comments" in instructions
assert "Leave every PR\nunmerged for Brad's review" in instructions
assert "Use the Gitea pull-request merge endpoint" not in instructions
assert "reconcile the open PR" not in instructions
assert "use Flux reconciliation after" not in instructions
assert "PR publication ends at the verified open draft" in instructions
assert "JENKINS_BASE_URL" in instructions
assert "Do not\nuse `git reset --hard`" in instructions
rendered = (HERMES / "agent-deployment.yaml").read_text()
assert 'git config --global user.name "Hermes Agent"' in rendered
assert 'git config --global user.email "hermes@bstein.dev"' in rendered
def test_agent_image_completes_parked_kanban_tasks_atomically():
dockerfile = (ROOT / "dockerfiles" / "Dockerfile.hermes-agent").read_text()
assert (
"AND status IN ('running', 'ready', 'blocked', 'scheduled')"
in dockerfile
)
assert (
"Atomically mark running, ready, blocked, or scheduled tasks done"
in dockerfile
)
assert "kind IN ('created', 'blocked', 'unblocked')" in dockerfile
assert "payload.get(\"status\") == \"blocked\"" in dockerfile
assert "hermes-kanban-blocked-regression.py" in dockerfile
def test_sandbox_shares_only_the_tenant_workspace_without_credentials():
sandbox_docs = _documents(HERMES / "chat-sandbox.yaml")
deployments = [doc for doc in sandbox_docs if doc["kind"] == "Deployment"]
assert len(deployments) == 8
for ordinal, deployment in enumerate(deployments):
pod_spec = deployment["spec"]["template"]["spec"]
container = pod_spec["containers"][0]
assert pod_spec["automountServiceAccountToken"] is False
assert container["securityContext"]["readOnlyRootFilesystem"] is True
assert container["securityContext"]["runAsNonRoot"] is True
assert container["securityContext"]["runAsGroup"] == 10000
assert not container.get("env")
assert {mount["mountPath"] for mount in container["volumeMounts"]} == {
"/tmp",
"/workspace",
"/opt/data/workspace",
}
workspace_volume = next(
item for item in pod_spec["volumes"] if item["name"] == "workspace"
)
assert workspace_volume["persistentVolumeClaim"]["claimName"] == (
f"workspace-hermes-chat-tenant-{ordinal}"
)
statefulset = _documents(HERMES / "chat-statefulset.yaml")[0]
templates = statefulset["spec"]["volumeClaimTemplates"]
workspace = next(item for item in templates if item["metadata"]["name"] == "workspace")
assert workspace["spec"]["resources"]["requests"]["storage"] == "10Gi"
assert workspace["spec"]["accessModes"] == ["ReadWriteMany"]
pod_spec = statefulset["spec"]["template"]["spec"]
hermes = next(item for item in pod_spec["containers"] if item["name"] == "hermes")
startup = hermes["args"][0]
assert "hermes-chat-sandbox-${ordinal}.hermes-chat-sandbox" in startup
assert any(
mount["name"] == "workspace" and mount["mountPath"] == "/opt/data/workspace"
for mount in hermes["volumeMounts"]
)
policies = _documents(HERMES / "networkpolicy.yaml")
deny = next(
item
for item in policies
if item["metadata"]["name"] == "hermes-chat-sandbox-deny"
)
assert deny["spec"]["ingress"] == []
assert deny["spec"]["egress"] == []
for ordinal in range(4):
policy = next(
item
for item in policies
if item["metadata"]["name"] == f"hermes-chat-sandbox-tenant-{ordinal}"
)
assert policy["spec"]["podSelector"]["matchLabels"][
"ai.bstein.dev/tenant-ordinal"
] == str(ordinal)
source = policy["spec"]["ingress"][0]["from"][0]["podSelector"][
"matchLabels"
]
assert source["statefulset.kubernetes.io/pod-name"] == (
f"hermes-chat-tenant-{ordinal}"
)
def test_gateway_image_honors_ui_model_and_caps_reasoning():
dockerfile = (ROOT / "dockerfiles" / "Dockerfile.hermes-agent").read_text()
assert (
"FROM nousresearch/hermes-agent@sha256:"
"47d4bd4cc420b70e40ed75efdade373e45b86b7382d4013a054208982bb6ba08"
) in dockerfile
assert "_resolve_request_route" in dockerfile
assert 'allowed_providers = {"atlas-switchyard"}' in dockerfile
assert 'reasoning_effort=body.get("reasoning_effort")' in dockerfile
assert 'reasoning_config = {"enabled": True, "effort": "xhigh"}' in dockerfile
assert "ddgs==9.14.4" in dockerfile
assert "specific not in _LEGACY_WEB_BACKENDS" in dockerfile
assert '"pre_internal_route"' in dockerfile
assert "pre_internal_route hook failed" in dockerfile
assert '"pre_subagent_route"' in dockerfile
assert "pre_subagent_route hook failed" in dockerfile
assert "agent._hermes_explicit_model_pick = bool" in dockerfile
assert "agent._hermes_oneshot = True" in dockerfile
assert 'getattr(parent_agent, "_hermes_oneshot", False)' in dockerfile
assert 'var != "CLAUDE_CODE_OAUTH_TOKEN"' in dockerfile
assert '"source": "managed_claude_code_subscription"' in dockerfile
assert '"name": "Claude Code subscription (Switchyard)"' in dockerfile
assert "Anthropic API / direct OAuth (not used by Switchyard)" in dockerfile
assert "scheduleTerminalPaint" in dockerfile
assert "sessionTree.childrenByParent" in dockerfile
assert "SessionActivityPanel" in dockerfile
assert "include_children=${includeChildren}" in dockerfile
assert "_dashboard_session_is_active" in dockerfile
assert 'searchParams.get("lineage_root") || resumeParam' in dockerfile
assert "followActiveLineage" in dockerfile
assert 'next.delete("lineage_root")' in dockerfile
activity = (
ROOT / "dockerfiles" / "hermes-session-activity-panel.tsx"
).read_text()
assert "Live worker activity" in activity
assert "api.getSessionMessages" in activity
assert "aria-live=\"polite\"" in activity
assert "role=\"log\"" in activity
assert "aria-busy={running && messages.length === 0}" in activity
assert 'detail.source !== "api_server"' not in activity
assert "Poll-backed transcript; terminal rendering is not required." in activity
assert "DEFAULT_VISIBLE_MESSAGES = 250" in activity
assert "current + DEFAULT_VISIBLE_MESSAGES" in activity
assert 'Show up to{" "}' in activity
assert "Math.min(" in activity
assert "visibleMessages.map" in activity
assert "response.total_messages" in activity
assert "visibleLimit)," in activity
assert "function displayText(value: unknown)" in activity
assert "open && (" in activity
assert 'document.getElementById("hermes-resume-bootstrap")?.remove()' in activity
assert 'id="hermes-resume-bootstrap"' in dockerfile
assert 'role="status"' in dockerfile
assert 'aria-busy="true"' in dockerfile
assert "Opening Hermes worker activity…" in dockerfile
assert 'params.has("resume")' in dockerfile
assert "Open Telegram setup" in dockerfile
def test_telegram_router_local_build_defaults_to_cluster_architecture():
dockerfile = (
ROOT / "dockerfiles" / "Dockerfile.hermes-chat-router"
).read_text(encoding="utf-8")
assert "ARG TARGETOS=linux" in dockerfile
assert "ARG TARGETARCH=arm64" in dockerfile
assert "GOOS=${TARGETOS} GOARCH=${TARGETARCH}" in dockerfile
def test_chat_oauth_allows_stale_service_worker_retirement():
documents = _documents(HERMES / "oauth2-proxy.yaml")
deployment = next(
document
for document in documents
if document["kind"] == "Deployment"
and document["metadata"]["name"] == "oauth2-proxy-hermes-chat"
)
args = deployment["spec"]["template"]["spec"]["containers"][0]["args"]
assert "--skip-auth-route=GET=^/sw[.]js([?].*)?$" in args
assert "--custom-templates-dir=/etc/oauth2-proxy/templates" in args
template = (HERMES / "oauth2-proxy-templates" / "error.html").read_text()
assert 'http-equiv="refresh"' not in template
assert "Unable to find a valid CSRF token" in template
assert "expired or was already used" in template
assert "sessionStorage" in template
assert "Automatic recovery paused" in template
assert "/start?rd=/" in template
container = deployment["spec"]["template"]["spec"]["containers"][0]
assert "v7.15.3@sha256:10a1165743a192e" in container["image"]
assert "--cookie-csrf-per-request=true" in args
assert "--cookie-csrf-per-request-limit=8" in args
assert "--trusted-proxy-ip=10.42.0.0/16" in args
assert "--api-route=^/api/" in args
assert "--api-route=^/health$" in args
assert "--cookie-expire=168h" in args
assert "--cookie-refresh=19m" in args
assert "--session-store-type=redis" in args
assert any(
arg.startswith("--redis-connection-url=redis://hermes-oauth-sessions.")
for arg in args
)
agent = _documents(HERMES / "agent-deployment.yaml")[0]
agent_pod = agent["spec"]["template"]["spec"]
agent_oauth = next(
container for container in agent_pod["containers"]
if container["name"] == "oauth2-proxy"
)
assert "--custom-templates-dir=/etc/oauth2-proxy/templates" in agent_oauth["args"]
assert {
"name": "oauth-templates",
"mountPath": "/etc/oauth2-proxy/templates",
"readOnly": True,
} in agent_oauth["volumeMounts"]
agent_template_volume = next(
volume for volume in agent_pod["volumes"]
if volume["name"] == "oauth-templates"
)
assert agent_template_volume["configMap"]["name"] == (
"hermes-chat-oauth-templates"
)
def test_webui_recovers_auth_and_labels_session_scoped_controls():
dockerfile = (ROOT / "dockerfiles" / "Dockerfile.hermes-webui").read_text()
assert "res.status===401||res.status===403" in dockerfile
assert "window.location.assign('/oauth2/start?rd='" in dockerfile
assert "childrenExpanded?'':''" in dockerfile
assert "'atlas/auto/maximum': 'Automatic · Maximum'" in dockerfile
assert "hermes-webui-telegram-project-patch.py" in dockerfile
telegram_project_patch = (
ROOT / "dockerfiles" / "hermes-webui-telegram-project-patch.py"
).read_text()
assert "TELEGRAM_PROJECT_NAME = 'Telegram'" in telegram_project_patch
assert "session_key.startswith('telegram-topic-')" in telegram_project_patch
router = (ROOT / "dockerfiles" / "hermes-webui-router.js").read_text()
assert "'atlas/auto/fast':'Automatic · Fast'" in router
assert "'atlas/manual/codex/sol':'Codex · SOL'" in router
assert "'atlas/manual/claude/opus':'Claude · Opus'" in router
assert "watchModelOptions('modelSelect')" in router
assert "watchModelOptions('settingsModel')" in router
def test_chat_voice_uses_private_jetson_services_and_shared_auto_route():
statefulset = _documents(HERMES / "chat-statefulset.yaml")[0]
containers = statefulset["spec"]["template"]["spec"]["containers"]
webui = next(item for item in containers if item["name"] == "webui")
env = {item["name"]: item["value"] for item in webui["env"]}
assert env["HERMES_STT_URL"] == (
"http://hermes-stt.hermes.svc.cluster.local:9000/v1/audio/transcriptions"
)
assert env["HERMES_WEBUI_ATLAS_TTS_URL"] == (
"http://hermes-tts.hermes.svc.cluster.local:9001/v1/audio/speech"
)
assert "hermes_stt_client.py" in env["HERMES_LOCAL_STT_COMMAND"]
configmap = _documents(HERMES / "chat-configmap.yaml")[0]
config = yaml.safe_load(configmap["data"]["config.yaml"])
assert config["stt"] == {
"enabled": True,
"provider": "local_command",
"local": {"model": "small", "language": "auto"},
}
dockerfile = (ROOT / "dockerfiles" / "Dockerfile.hermes-webui").read_text()
assert "hermes-webui-atlas-patch.py" in dockerfile
assert "hermes-webui-atlas-voice.js" in dockerfile
voice_script = (ROOT / "dockerfiles" / "hermes-webui-atlas-voice.js").read_text()
assert "/api/transcribe/capability" in voice_script
assert "/api/transcribe" in voice_script
assert "/api/tts" in voice_script
assert "speakResponse(generation)" in voice_script
assert "window._splitForTTS(text,280)" in voice_script
assert "pending=fetchSpeech(chunks[index+1])" in voice_script
assert "restartSoon(token,450)" in voice_script
assert "constraints.voiceIsolation=true" in voice_script
assert "highpass.frequency.value=140" in voice_script
assert "Math.max(0.04,noiseFloor*2.4+0.006)" in voice_script
assert "while(preRoll.length>3) preRoll.shift()" in voice_script
stt_server = (ROOT / "dockerfiles" / "hermes-jetson-stt-server.py").read_text()
assert "def _repetitive_token" in stt_server
assert "compression_ratio_threshold=2.0" in stt_server
assert "no_speech_threshold=0.5" in stt_server
def test_voice_transcript_filter_removes_fan_hallucinations(monkeypatch):
server_path = ROOT / "dockerfiles" / "hermes-jetson-stt-server.py"
spec = importlib.util.spec_from_file_location("hermes_jetson_stt_server", server_path)
assert spec and spec.loader
module = importlib.util.module_from_spec(spec)
monkeypatch.setitem(sys.modules, "cgi", SimpleNamespace())
monkeypatch.setitem(
sys.modules,
"torch",
SimpleNamespace(cuda=SimpleNamespace(is_available=lambda: False)),
)
monkeypatch.setitem(sys.modules, "whisper", SimpleNamespace())
spec.loader.exec_module(module)
result = {
"segments": [
{
"text": " ththththththththth Testing.",
"no_speech_prob": 0.12,
"avg_logprob": -0.2,
},
{
"text": " background hum",
"no_speech_prob": 0.82,
"avg_logprob": -0.9,
},
]
}
assert module._clean_transcript(result) == "Testing."
def test_voice_models_are_baked_and_runtime_has_no_public_egress():
stt_dockerfile = (ROOT / "dockerfiles" / "Dockerfile.hermes-jetson-stt").read_text()
tts_dockerfile = (ROOT / "dockerfiles" / "Dockerfile.hermes-jetson-tts").read_text()
assert "ADD --checksum=sha256:aff26ae4" in stt_dockerfile
assert "ADD --checksum=sha256:9ecf7799" in stt_dockerfile
assert "--chmod=0444" in stt_dockerfile
assert "chmod 0555 /opt/models /opt/models/whisper" in stt_dockerfile
assert "HERMES_STT_CACHE=/opt/models/whisper" in stt_dockerfile
assert "ADD --checksum=sha256:4cabf7c3" in tts_dockerfile
assert "ADD --checksum=sha256:db42b97d" in tts_dockerfile
assert "ADD --checksum=sha256:b3a6e47b57b8c7fbe6a0ce2518161a50f59a9cdd8a50835c02cb02bdd6206c18" in tts_dockerfile
assert "ADD --checksum=sha256:95a23eb4d42909d38df73bb9ac7f45f597dbfcde2d1bf9526fdeaf5466977d77" in tts_dockerfile
assert "ADD --checksum=sha256:8ff38212d23da300bbe3705c645e6e5b9475f0bfde01558eb17813e22acaaaaa" in tts_dockerfile
assert "ADD --checksum=sha256:c2ec28bb38e2b59e93b959b3e40348c1afebbd272f30fed5d41205d08e98a9d7" in tts_dockerfile
assert "ADD --checksum=sha256:3ef40a71ea63852cd8ab7e6fa7d2ecdcfa67a0b47c9c48e3f10e02ee02083ea0" in tts_dockerfile
assert "ADD --checksum=sha256:1afc81f703c0e4cb3b4d7c0dca096b8b54a98806807f0170cf5eb5557723c12d" in tts_dockerfile
assert tts_dockerfile.count("--chmod=0444") == 12
assert "/opt/models/piper/en_US-amy-medium.onnx" in tts_dockerfile
assert "/opt/models/piper/ru_RU-irina-medium.onnx" in tts_dockerfile
assert "/opt/models/piper/es_MX-claude-high.onnx" in tts_dockerfile
assert "chmod 0555 /opt/models /opt/models/piper" in tts_dockerfile
assert "HERMES_TTS_CACHE=/opt/models/piper" in tts_dockerfile
assert "HERMES_TTS_VOICE=en_US-amy-medium" in tts_dockerfile
tts_server = (ROOT / "dockerfiles" / "hermes-jetson-tts-server.py").read_text()
assert "download_voice" not in tts_server
assert "baked Piper voice is missing" in tts_server
assert "session_options.intra_op_num_threads = threads" in tts_server
assert 'LANGUAGE_VOICE_MAP = {' in tts_server
assert '"en": "en_US-amy-medium"' in tts_server
assert '"ru": "ru_RU-irina-medium"' in tts_server
assert '"es": "es_MX-claude-high"' in tts_server
policies = _documents(HERMES / "networkpolicy.yaml")
voice_policy = next(
item for item in policies if item["metadata"]["name"] == "hermes-private-voice"
)
assert voice_policy["spec"]["policyTypes"] == ["Ingress", "Egress"]
assert not any(
"ipBlock" in destination
for rule in voice_policy["spec"]["egress"]
for destination in rule.get("to", [])
)
def test_voice_workloads_have_deliberate_xavier_placement():
documents = _documents(HERMES / "voice-deployment.yaml")
deployments = {
item["metadata"]["name"]: item
for item in documents
if item["kind"] == "Deployment"
}
stt = deployments["hermes-stt"]["spec"]["template"]["spec"]
tts = deployments["hermes-tts"]["spec"]["template"]["spec"]
assert "@sha256:" in stt["containers"][0]["image"]
assert "@sha256:" in tts["containers"][0]["image"]
assert stt["nodeSelector"] == {"kubernetes.io/hostname": "titan-21"}
assert tts["nodeSelector"] == {"kubernetes.io/hostname": "titan-21"}
assert stt["automountServiceAccountToken"] is False
assert tts["automountServiceAccountToken"] is False
assert stt["enableServiceLinks"] is False
assert tts["enableServiceLinks"] is False
assert stt["runtimeClassName"] == "nvidia"
assert stt["securityContext"]["supplementalGroups"] == [44]
stt_resources = stt["containers"][0]["resources"]
stt_env = {
item["name"]: item["value"] for item in stt["containers"][0]["env"]
}
assert stt_env["NVIDIA_DRIVER_CAPABILITIES"] == "compute,utility"
assert stt_resources["requests"]["nvidia.com/gpu.shared"] == 1
assert stt_resources["limits"]["nvidia.com/gpu.shared"] == 1
assert "nvidia.com/gpu.shared" not in tts["containers"][0]["resources"]["requests"]
tts_env = {
item["name"]: item["value"] for item in tts["containers"][0]["env"]
}
assert tts_env["HERMES_TTS_VOICE"] == "en_US-lessac-medium"
assert tts_env["HERMES_TTS_ONNX_THREADS"] == "2"
assert tts["containers"][0]["resources"]["limits"]["cpu"] == "4"
assert all("hostPath" not in volume for volume in stt["volumes"])
assert all("hostPath" not in volume for volume in tts["volumes"])