#!/usr/bin/env sh set -eu config=/opt/data/config.yaml if [ ! -r "$config" ]; then echo "HERMES_START_REFUSED: managed config is not readable" >&2 exit 78 fi # Hermes Desktop can persist a model selection back into config.yaml. A bad # selection must never be able to detach the central gateway from Athena's # authenticated profile router. Repair only the managed model block from the # container secret on every start; all user settings, sessions and MCP entries # remain untouched. python - "$config" <<'PY' import os import sys import tempfile import yaml path = sys.argv[1] router_key = os.environ.get("ROUTER_API_KEY", "").strip() if not router_key or router_key.startswith("${"): raise SystemExit("HERMES_START_REFUSED: ROUTER_API_KEY is missing") with open(path, "r", encoding="utf-8") as handle: config = yaml.safe_load(handle) or {} model = config.setdefault("model", {}) model.update({ "default": "qwen-medium", "provider": "custom:router", "base_url": "http://router:8081/v1", "api_key": router_key, }) providers = config.setdefault("providers", {}) providers["router"] = { "name": "Athena Profile Router", "api": "http://router:8081/v1", "key_env": "ROUTER_API_KEY", "transport": "chat_completions", "default_model": "qwen-medium", "discover_models": True, } directory = os.path.dirname(path) fd, temporary = tempfile.mkstemp(prefix=".config.yaml.", dir=directory, text=True) try: with os.fdopen(fd, "w", encoding="utf-8") as handle: yaml.safe_dump(config, handle, sort_keys=False, allow_unicode=True) handle.flush() os.fsync(handle.fileno()) os.chmod(temporary, os.stat(path).st_mode & 0o777) os.replace(temporary, path) finally: if os.path.exists(temporary): os.unlink(temporary) PY grep -Eq '^[[:space:]]+provider:[[:space:]]+["'\'']?custom:router["'\'']?[[:space:]]*$' "$config" || { echo "HERMES_START_REFUSED: provider is not custom:router" >&2 exit 78 } grep -Eq '^[[:space:]]+base_url:[[:space:]]+["'\'']?http://router:8081/v1["'\'']?[[:space:]]*$' "$config" || { echo "HERMES_START_REFUSED: local router URL is missing" >&2 exit 78 } # Hermes 0.20.5 does not refresh the API agent from the live MCP registry. # The image build applies the narrow workaround as root. At runtime this is # an idempotent, fail-closed verification and must never need to write files. python /usr/local/lib/mike-ai/patch-api-mcp-refresh.py exec hermes gateway run