simplify Athena runtime and centralize MCP management

This commit is contained in:
Mikei386
2026-08-26 09:57:38 +02:00
parent 104c9904a5
commit ab671a6396
31 changed files with 918 additions and 419 deletions
+42 -49
View File
@@ -1,23 +1,26 @@
#!/usr/bin/env bash
set -Eeuo pipefail
HERMES_CONTAINER=${HERMES_CONTAINER:-mike-ai-hermes}
HERMES_CONTAINER=${HERMES_CONTAINER:-Hermes-Agent}
SECRETS_DIR=${SECRETS_DIR:-/etc/mike-ai}
HERMES_DATA_DIR=${HERMES_DATA_DIR:-/data/hermes}
HERMES_DATA_DIR=${HERMES_DATA_DIR:-/mnt/nvme-storage/appdata/Hermes-Agent}
STACK_DIR=${STACK_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)}
PROFILE_MATRIX=${PROFILE_MATRIX:-$STACK_DIR/config/profile-matrix.json}
die() { printf 'FEHLER: %s\n' "$*" >&2; exit 1; }
docker inspect "$HERMES_CONTAINER" >/dev/null 2>&1 || \
die "Hermes-Container fehlt: $HERMES_CONTAINER"
[[ -s $PROFILE_MATRIX ]] || die "Profilmatrix fehlt: $PROFILE_MATRIX"
deadline=$((SECONDS + 180))
until [[ $(docker inspect --format '{{if .State.Health}}{{.State.Health.Status}}{{else}}{{.State.Status}}{{end}}' \
"$HERMES_CONTAINER" 2>/dev/null || true) == healthy ]]; do
"$HERMES_CONTAINER" 2>/dev/null || true) =~ ^(healthy|running)$ ]]; do
(( SECONDS < deadline )) || die "Hermes wurde nicht rechtzeitig gesund."
sleep 2
done
create_profile() {
local name=$1 model=$2 context=$3 description=$4
local name=$1 model=$2 context=$3 description=$4 max_tokens=$5
if ! docker exec "$HERMES_CONTAINER" hermes profile show "$name" >/dev/null 2>&1; then
docker exec "$HERMES_CONTAINER" hermes profile create "$name" \
--clone-from default --description "$description"
@@ -26,23 +29,32 @@ create_profile() {
docker exec "$HERMES_CONTAINER" hermes -p "$name" config set model.context_length "$context"
# These are platform-wide latency and loop safeguards, not model-specific
# tuning. Enforce them on old profiles as well as newly cloned profiles.
docker exec "$HERMES_CONTAINER" hermes -p "$name" config set model.max_tokens 8192
docker exec "$HERMES_CONTAINER" hermes -p "$name" config set model.max_tokens "$max_tokens"
docker exec "$HERMES_CONTAINER" hermes -p "$name" config set agent.max_turns 64
docker exec "$HERMES_CONTAINER" hermes -p "$name" config set agent.reasoning_effort minimal
docker exec "$HERMES_CONTAINER" hermes -p "$name" config set agent.reasoning_effort low
docker exec "$HERMES_CONTAINER" hermes -p "$name" config set display.show_reasoning false
docker exec "$HERMES_CONTAINER" hermes -p "$name" config set auxiliary.title_generation.enabled false
docker exec "$HERMES_CONTAINER" hermes -p "$name" config unset compression.threshold_tokens || true
docker exec "$HERMES_CONTAINER" hermes -p "$name" config set compression.threshold 0.82
docker exec "$HERMES_CONTAINER" hermes -p "$name" config set compression.threshold 0.95
docker exec "$HERMES_CONTAINER" hermes -p "$name" config set compression.target_ratio 0.15
docker exec "$HERMES_CONTAINER" hermes -p "$name" config set compression.max_attempts 1
docker exec "$HERMES_CONTAINER" hermes -p "$name" config set compression.context_timeout_seconds 45
docker exec "$HERMES_CONTAINER" hermes -p "$name" config set compression.context_total_ceiling_seconds 120
docker exec "$HERMES_CONTAINER" hermes -p "$name" config set compression.protect_last_n 20
docker exec "$HERMES_CONTAINER" hermes -p "$name" config set compression.protect_first_n 0
docker exec "$HERMES_CONTAINER" hermes -p "$name" config set compression.micro_compact true
docker exec "$HERMES_CONTAINER" hermes -p "$name" config set compression.micro_compact_every_n_turns 5
docker exec "$HERMES_CONTAINER" hermes -p "$name" config set compression.micro_compact_defrag_threshold_tokens 2000
docker exec "$HERMES_CONTAINER" hermes -p "$name" config set compression.proactive_prune_tokens 32000
docker exec "$HERMES_CONTAINER" hermes -p "$name" config set compression.proactive_prune_min_result_chars 2000
docker exec "$HERMES_CONTAINER" hermes -p "$name" config set compression.proactive_prune_min_reclaim_tokens 2048
# The selected 27B profile performs production compaction. A separate small
# compressor was removed after it lost exact technical state in benchmarks.
docker exec "$HERMES_CONTAINER" hermes -p "$name" config unset auxiliary.compression || true
docker exec "$HERMES_CONTAINER" hermes -p "$name" config set auxiliary.compression.provider main
docker exec "$HERMES_CONTAINER" hermes -p "$name" config set auxiliary.compression.reasoning_effort none
docker exec "$HERMES_CONTAINER" hermes -p "$name" config set auxiliary.compression.timeout 120
docker exec "$HERMES_CONTAINER" hermes -p "$name" config set auxiliary.compression.max_concurrency 1
docker exec "$HERMES_CONTAINER" hermes -p "$name" config set platform_toolsets.cli \
'["web","terminal","file","skills","todo","memory","vision","tts"]'
[[ $(docker exec "$HERMES_CONTAINER" hermes -p "$name" config get model.default) == "$model" ]] || \
@@ -51,51 +63,32 @@ create_profile() {
die "Kontext von Profil $name konnte nicht verifiziert werden."
}
create_profile fast qwen-fast 76800 \
"Schnelles Qwen3.8-27B-Profil mit 76,8K Kontext fuer kurze Chats und schnelle Aufgaben."
create_profile medium qwen-medium 160000 \
"Ausgewogenes Qwen3.8-27B-Standardprofil mit 160K Kontext fuer Alltag und agentische Aufgaben."
create_profile large qwen-large 192000 \
"Grosses Qwen3.8-27B-Profil mit 192K Kontext fuer umfangreiche Dokumente und lange Aufgaben."
create_profile ultra qwen-ultra 262144 \
"Maximales Qwen3.8-27B-Profil mit 262K Kontext fuer sehr grosse Kontexte; langsamer als die Standardprofile."
create_profile uncensored qwen-uncensored 80000 \
"Unzensiertes Qwen3.8-27B-Profil mit 80K Kontext fuer spezielle Anfragen."
while IFS=$'\t' read -r name model context description max_tokens; do
create_profile "$name" "$model" "$context" "$description" "$max_tokens"
done < <(jq -r --argjson max "$(jq '.max_output_tokens' "$PROFILE_MATRIX")" \
'.profiles[] | [.id,.alias,(.context|tostring),(.description|gsub("[\\t\\n]";" ")),($max|tostring)] | @tsv' \
"$PROFILE_MATRIX")
# Existing profiles may predate managed secret rendering and therefore contain
# the literal ${ROUTER_API_KEY}. Repair only that exact placeholder; never log
# or commit the secret itself.
[[ -s $SECRETS_DIR/router-api-key ]] || die "Router-API-Key fehlt."
router_key=$(<"$SECRETS_DIR/router-api-key")
ROUTER_API_KEY="$router_key" HERMES_DATA_DIR="$HERMES_DATA_DIR" python3 <<'PY'
import os
import pathlib
root = pathlib.Path(os.environ["HERMES_DATA_DIR"]) / "profiles"
placeholder = "${ROUTER_API_KEY}"
paths = [pathlib.Path(os.environ["HERMES_DATA_DIR"]) / "config.yaml"]
paths.extend(sorted(root.glob("*/config.yaml")))
for path in paths:
if not path.exists():
continue
text = path.read_text()
if placeholder in text:
text = text.replace(placeholder, os.environ["ROUTER_API_KEY"], 1)
# Avoid collision with Hermes' disabled built-in `homeassistant` toolset.
# The collision filters the healthy external MCP out of agent snapshots.
text = text.replace(
"\n homeassistant:\n url: http://mcp-homeassistant:8000/mcp\n",
"\n homeassistant-admin:\n url: http://mcp-homeassistant:8000/mcp\n",
)
path.write_text(text)
PY
sync_args=(--registry "${STACK_DIR:-/opt/mike-ai/stack}/config/mcp-registry.json")
# The Unraid host deliberately has no system Python. Run the small declarative
# client renderer in the already version-pinned MCPHub image instead of adding
# host dependencies.
sync_args=(--registry /stack/config/mcp-registry.json)
mcphub_token=${MCPHUB_TOKEN_FILE:-/mnt/nvme-storage/appdata/MCPHub/client-token}
token_mount=()
if [[ -s $mcphub_token ]]; then
token_mount=(-v "$mcphub_token:/run/input/mcphub-token:ro")
sync_args+=(--mcphub-token-file /run/input/mcphub-token)
fi
while IFS= read -r config; do
sync_args+=(--hermes "$config")
sync_args+=(--hermes "/hermes/${config#"$HERMES_DATA_DIR"/}")
done < <(find "$HERMES_DATA_DIR" -name config.yaml -type f -print)
python3 "${STACK_DIR:-/opt/mike-ai/stack}/platform/mcp/sync-clients.py" "${sync_args[@]}"
docker run --rm --entrypoint python \
-v "$STACK_DIR:/stack:ro" \
-v "$HERMES_DATA_DIR:/hermes:rw" \
"${token_mount[@]}" \
casaderoll/mcphub:1.1.0 \
/stack/platform/mcp/sync-clients.py "${sync_args[@]}"
"${STACK_DIR:-/opt/mike-ai/stack}/platform/hermes/install-skills.sh"
"$STACK_DIR/platform/hermes/install-skills.sh"
docker exec "$HERMES_CONTAINER" hermes profile list
printf 'HERMES_PROFILES_OK\n'