Define Hermes router as named authenticated provider
This commit is contained in:
1 parent
9c1c0b8696
commit
fa9911eb3b
2 files changed
+32
-31
No files matched your search
@@ -2,12 +2,25 @@ _config_version: 38
|
|||||||
|
|
||||||
model:
|
model:
|
||||||
default: "qwen-medium"
|
default: "qwen-medium"
|
||||||
provider: "custom"
|
provider: "custom:router"
|
||||||
base_url: "http://router:8081/v1"
|
base_url: "http://router:8081/v1"
|
||||||
api_key: "${ROUTER_API_KEY}"
|
api_key: "${ROUTER_API_KEY}"
|
||||||
context_length: 160000
|
context_length: 160000
|
||||||
api_mode: "chat_completions"
|
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
|
# 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.
|
# use the audited operator/MUA MCPs instead of a Docker socket or host mount.
|
||||||
terminal:
|
terminal:
|
||||||
|
|||||||
@@ -14,9 +14,9 @@ fi
|
|||||||
# remain untouched.
|
# remain untouched.
|
||||||
python - "$config" <<'PY'
|
python - "$config" <<'PY'
|
||||||
import os
|
import os
|
||||||
import re
|
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
|
import yaml
|
||||||
|
|
||||||
path = sys.argv[1]
|
path = sys.argv[1]
|
||||||
router_key = os.environ.get("ROUTER_API_KEY", "").strip()
|
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")
|
raise SystemExit("HERMES_START_REFUSED: ROUTER_API_KEY is missing")
|
||||||
|
|
||||||
with open(path, "r", encoding="utf-8") as handle:
|
with open(path, "r", encoding="utf-8") as handle:
|
||||||
lines = handle.readlines()
|
config = yaml.safe_load(handle) or {}
|
||||||
|
|
||||||
try:
|
model = config.setdefault("model", {})
|
||||||
start = next(i for i, line in enumerate(lines) if re.match(r"^model:\s*(?:#.*)?$", line))
|
model.update({
|
||||||
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 = {
|
|
||||||
"default": "qwen-medium",
|
"default": "qwen-medium",
|
||||||
"provider": "custom",
|
"provider": "custom:router",
|
||||||
"base_url": "http://router:8081/v1",
|
"base_url": "http://router:8081/v1",
|
||||||
"api_key": router_key,
|
"api_key": router_key,
|
||||||
}
|
})
|
||||||
|
|
||||||
for field, value in managed.items():
|
providers = config.setdefault("providers", {})
|
||||||
rendered = f' {field}: "{value}"\n'
|
providers["router"] = {
|
||||||
match = next(
|
"name": "Athena Profile Router",
|
||||||
(i for i in range(start + 1, end) if re.match(rf"^\s+{re.escape(field)}:\s*", lines[i])),
|
"api": "http://router:8081/v1",
|
||||||
None,
|
"key_env": "ROUTER_API_KEY",
|
||||||
)
|
"transport": "chat_completions",
|
||||||
if match is None:
|
"default_model": "qwen-medium",
|
||||||
lines.insert(end, rendered)
|
"discover_models": True,
|
||||||
end += 1
|
}
|
||||||
else:
|
|
||||||
lines[match] = rendered
|
|
||||||
|
|
||||||
directory = os.path.dirname(path)
|
directory = os.path.dirname(path)
|
||||||
fd, temporary = tempfile.mkstemp(prefix=".config.yaml.", dir=directory, text=True)
|
fd, temporary = tempfile.mkstemp(prefix=".config.yaml.", dir=directory, text=True)
|
||||||
try:
|
try:
|
||||||
with os.fdopen(fd, "w", encoding="utf-8") as handle:
|
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()
|
handle.flush()
|
||||||
os.fsync(handle.fileno())
|
os.fsync(handle.fileno())
|
||||||
os.chmod(temporary, os.stat(path).st_mode & 0o777)
|
os.chmod(temporary, os.stat(path).st_mode & 0o777)
|
||||||
@@ -70,8 +58,8 @@ finally:
|
|||||||
os.unlink(temporary)
|
os.unlink(temporary)
|
||||||
PY
|
PY
|
||||||
|
|
||||||
grep -Eq '^[[:space:]]+provider:[[:space:]]+["'\'']?custom["'\'']?[[:space:]]*$' "$config" || {
|
grep -Eq '^[[:space:]]+provider:[[:space:]]+["'\'']?custom:router["'\'']?[[:space:]]*$' "$config" || {
|
||||||
echo "HERMES_START_REFUSED: provider is not custom" >&2
|
echo "HERMES_START_REFUSED: provider is not custom:router" >&2
|
||||||
exit 78
|
exit 78
|
||||||
}
|
}
|
||||||
grep -Eq '^[[:space:]]+base_url:[[:space:]]+["'\'']?http://router:8081/v1["'\'']?[[:space:]]*$' "$config" || {
|
grep -Eq '^[[:space:]]+base_url:[[:space:]]+["'\'']?http://router:8081/v1["'\'']?[[:space:]]*$' "$config" || {
|
||||||
|
|||||||
Reference in new issue
Block a user