From fa9911eb3b12d3ded91cc43cdcb2ed3e51cb57eb Mon Sep 17 00:00:00 2001 From: Mikei386 <44135113+Mikei386@users.noreply.github.com> Date: Mon, 24 Aug 2026 23:35:01 +0200 Subject: [PATCH] Define Hermes router as named authenticated provider --- platform/hermes/config.yaml | 15 +++++++- platform/hermes/start-hermes-managed.sh | 48 ++++++++++--------------- 2 files changed, 32 insertions(+), 31 deletions(-) diff --git a/platform/hermes/config.yaml b/platform/hermes/config.yaml index 4e1d953..ab62804 100644 --- a/platform/hermes/config.yaml +++ b/platform/hermes/config.yaml @@ -2,12 +2,25 @@ _config_version: 38 model: default: "qwen-medium" - provider: "custom" + provider: "custom:router" base_url: "http://router:8081/v1" api_key: "${ROUTER_API_KEY}" context_length: 160000 api_mode: "chat_completions" +# A named provider is required by current Hermes releases. A bare `custom` +# endpoint is canonicalized to a host-derived identity and can lose its key +# association in resumed sessions. The stable identity below always resolves +# its credential from the container environment. +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 + # Commands run in an isolated, persistent workspace. Host and Unraid changes # use the audited operator/MUA MCPs instead of a Docker socket or host mount. terminal: diff --git a/platform/hermes/start-hermes-managed.sh b/platform/hermes/start-hermes-managed.sh index dbb242d..ba8b2cb 100755 --- a/platform/hermes/start-hermes-managed.sh +++ b/platform/hermes/start-hermes-managed.sh @@ -14,9 +14,9 @@ fi # remain untouched. python - "$config" <<'PY' import os -import re import sys import tempfile +import yaml path = sys.argv[1] router_key = os.environ.get("ROUTER_API_KEY", "").strip() @@ -24,43 +24,31 @@ 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: - lines = handle.readlines() + config = yaml.safe_load(handle) or {} -try: - start = next(i for i, line in enumerate(lines) if re.match(r"^model:\s*(?:#.*)?$", line)) -except StopIteration: - raise SystemExit("HERMES_START_REFUSED: model block is missing") - -end = len(lines) -for i in range(start + 1, len(lines)): - if re.match(r"^[A-Za-z_][A-Za-z0-9_-]*:\s*", lines[i]): - end = i - break - -managed = { +model = config.setdefault("model", {}) +model.update({ "default": "qwen-medium", - "provider": "custom", + "provider": "custom:router", "base_url": "http://router:8081/v1", "api_key": router_key, -} +}) -for field, value in managed.items(): - rendered = f' {field}: "{value}"\n' - match = next( - (i for i in range(start + 1, end) if re.match(rf"^\s+{re.escape(field)}:\s*", lines[i])), - None, - ) - if match is None: - lines.insert(end, rendered) - end += 1 - else: - lines[match] = rendered +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: - handle.writelines(lines) + 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) @@ -70,8 +58,8 @@ finally: os.unlink(temporary) PY -grep -Eq '^[[:space:]]+provider:[[:space:]]+["'\'']?custom["'\'']?[[:space:]]*$' "$config" || { - echo "HERMES_START_REFUSED: provider is not custom" >&2 +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" || {