"""Hermes chat config contracts.""" from __future__ import annotations from test_hermes_chat_support import ( HERMES, ROOT, _documents, yaml, ) 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 "already supplied through `GIT_ASKPASS`" 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 "runtime-only `GIT_ASKPASS`" in soul assert "`scm.bstein.dev` is Gitea, not GitHub" in instructions assert "Never load or follow a GitHub/`gh`" in instructions assert "/opt/coordinator/gitea_api.py METHOD /api/v1/..." 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" )