83 lines
2.4 KiB
Bash
Executable File
83 lines
2.4 KiB
Bash
Executable File
#!/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 re
|
|
import sys
|
|
import tempfile
|
|
|
|
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:
|
|
lines = handle.readlines()
|
|
|
|
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 = {
|
|
"default": "qwen-medium",
|
|
"provider": "custom",
|
|
"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
|
|
|
|
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)
|
|
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["'\'']?[[:space:]]*$' "$config" || {
|
|
echo "HERMES_START_REFUSED: provider is not custom" >&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
|
|
}
|
|
|
|
exec hermes gateway run
|