From 1c75f79db1578fe12839b656a236cd39de0957b7 Mon Sep 17 00:00:00 2001 From: ARIA Date: Sun, 19 Jul 2026 20:11:25 +0000 Subject: [PATCH] Hermes Agent selbst mit ins Compose: alles auf einer Maschine Stefan-Entscheidung: Hermes Agent (Nous Research) laeuft auf derselben Maschine wie der Claude-Max-Proxy, nicht mehr remote. Ergaenzt: - hermes-agent + hermes-agent-dashboard Services (offizielle Definition, gebaut aus separat geklontem hermes-agent-src/), network_mode: host - hermes-agent-config/config.yaml.example: seedet Hermes' model:-Block automatisch auf provider: custom -> unser hermes-gateway, per ${VAR}- Expansion aus .env (kein manuelles Config-Editieren mehr) - hermes-gateway bindet jetzt nur noch auf 127.0.0.1 statt 0.0.0.0, da Hermes lokal mitlaeuft und kein Remote-Zugriff mehr noetig ist - .gitignore fuer hermes-agent-src/, hermes-data/, .env (Secrets/Sourcecode gehoeren nicht ins Repo) - README auf Single-Machine-Architektur aktualisiert, inkl. Setup-Schritten und Einordnung des optionalen API_SERVER (fuer spaeteren mobilen Client, andere Richtung als unser Proxy) --- .env.example | 25 +++- .gitignore | 13 ++ README.md | 155 +++++++++++++++--------- docker-compose.yml | 117 +++++++++++++----- hermes-agent-config/config.yaml.example | 33 +++++ 5 files changed, 250 insertions(+), 93 deletions(-) create mode 100644 .gitignore create mode 100644 hermes-agent-config/config.yaml.example diff --git a/.env.example b/.env.example index 1484ddf..5be2805 100644 --- a/.env.example +++ b/.env.example @@ -1,12 +1,29 @@ # Nach /shared/projects/hermes_agent/.env kopieren und Werte anpassen. -# .env NICHT committen falls das Ganze mal in ein Git-Repo wandert. +# .env ist in .gitignore und wird NICHT committet. # Shared Secret zwischen hermes-gateway und Hermes Agent (config.yaml -> api_key). # Mindestens 32 zufaellige Zeichen, z.B. erzeugen mit: # openssl rand -hex 32 HERMES_GATEWAY_TOKEN= -# Port auf dem hermes-gateway auf dieser Maschine nach aussen lauscht. -# Hermes Agent (auf der anderen Maschine) zeigt in config.yaml auf -# http://:/v1 +# Port auf dem hermes-gateway auf dieser Maschine lauscht. Seit "alles auf +# einer Maschine" nur noch auf 127.0.0.1 gebunden (siehe docker-compose.yml) - +# Hermes Agent selbst (network_mode: host) erreicht das trotzdem ueber +# localhost, kein anderer Rechner kommt mehr direkt ran. HERMES_GATEWAY_PORT=8447 + +# UID/GID des Host-Users, dem hermes-data/agent-home gehoeren soll, damit +# Dateien die Hermes im Container schreibt (Sessions, Memory, Config) auf dem +# Host lesbar/schreibbar bleiben. Default 10000 (Hermes' eingebauter Default) +# ist ok wenn Dir das egal ist; setze es sonst auf `id -u`/`id -g` des Users +# der hermes-data/ auf dem Host verwaltet. +HERMES_UID=10000 +HERMES_GID=10000 + +# Optional: NUR setzen wenn Du Hermes' EIGENEN OpenAI-kompatiblen API-Server +# aktivierst (siehe API_SERVER_HOST/API_SERVER_KEY-Kommentar im +# hermes-agent-Service in docker-compose.yml) — z.B. um einen mobilen Client +# wie gpt_mobile/Maid/OpenWebUI direkt gegen Hermes sprechen zu lassen, statt +# nur ueber CLI/Dashboard. Andere Richtung als HERMES_GATEWAY_TOKEN oben! +# Mindestens 32 zufaellige Zeichen, z.B. openssl rand -hex 32. +# API_SERVER_KEY= diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5ee0677 --- /dev/null +++ b/.gitignore @@ -0,0 +1,13 @@ +# Echter Hermes-Agent-Sourcecode wird per README-Anleitung separat geklont +# (git clone https://github.com/NousResearch/hermes-agent.git hermes-agent-src) +# — eigenes Repo, gehoert nicht als Kopie/Submodule in dieses hier. +hermes-agent-src/ + +# Runtime-State: Claude-CLI-Login-Credentials, Hermes' ~/.hermes-Aequivalent +# (Sessions, Memory, ggf. Provider-API-Keys anderer Skills), Shared-Files. +# Enthaelt Secrets - niemals committen. +hermes-data/ +hermes-shared/ + +# Secrets +.env diff --git a/README.md b/README.md index 1159ab2..081a6ac 100644 --- a/README.md +++ b/README.md @@ -1,42 +1,45 @@ -# Hermes Agent — Claude-Max-Proxy Setup +# Hermes Agent — Claude-Max-Proxy + Hermes selbst, alles auf einer Maschine Repliziert den Proxy-Trick, den wir fuer ARIA nutzen: `claude-max-api-proxy` (npm) wrappt die Claude Code CLI — angemeldet mit deiner Claude-Max- Subscription — als OpenAI-kompatiblen `/v1/chat/completions`-Endpoint. [Hermes Agent](https://github.com/NousResearch/hermes-agent) (Nous Research, -CLI/Desktop-Agent, unterstuetzt laut Doku "your own endpoint" als -Model-Provider) kann darueber mit Claude reden, ohne API-Kosten — laeuft -ueber die Subscription, nicht ueber Anthropic-API-Billing. +CLI/Desktop-Agent) redet darueber mit Claude, ohne API-Kosten — laeuft ueber +die Subscription, nicht ueber Anthropic-API-Billing. -**Wichtig:** Hermes Agent selbst (das CLI/Desktop-Tool von Nous Research) -ist hier NICHT enthalten — Stefan deployt das selbst auf einer anderen -Maschine. Dieser Stack liefert nur die Proxy-Seite, die Hermes von dort -ansprechen kann. ARIA bleibt komplett unangetastet (eigenes Docker-Netz -`hermes-net`, eigenes Claude-CLI-Login-Volume, kein gemeinsamer Container). +**Entscheidung (Stefan):** Hermes Agent selbst laeuft auf DERSELBEN Maschine +wie dieser Proxy-Stack — alles was zu Hermes gehoert auf eine Box, minimale +Latenz, nur ein Rechner zum Pflegen. ARIA bleibt komplett unangetastet +(eigenes Docker-Netz `hermes-net`, eigenes Claude-CLI-Login-Volume, kein +gemeinsamer Container, laeuft ja ohnehin auf einer anderen Maschine als +Hermes). ## Architektur ``` -Hermes Agent (andere Maschine) - | HTTP(S), Authorization: Bearer +hermes-agent (Nous Research, network_mode: host) + | HTTP, Authorization: Bearer , http://localhost:8447/v1 v - hermes-gateway (Port ${HERMES_GATEWAY_PORT:-8447}, nach aussen exposed) + hermes-gateway (Port 8447, NUR auf 127.0.0.1 gebunden) | prueft Bearer-Token, sonst 401 v - hermes-proxy (Port 3456, NUR docker-intern erreichbar) + hermes-proxy (Port 3456, NUR docker-intern im hermes-net erreichbar) | claude-max-api-proxy -> Claude Code CLI (Claude-Max-Login) v Anthropic (ueber deine Claude-Max-Subscription) + +hermes-agent-dashboard (127.0.0.1:9119, Hermes' eigenes Web-UI/Setup) ``` -Warum das Gateway davor: `hermes-proxy` selbst hat keine Authentifizierung -(genau wie ARIAs Proxy) — das ist bei ARIA ok, weil der Proxy nie einen -Netzwerk-Port bekommt. Hermes laeuft aber auf einer anderen Maschine, der -Proxy muss also ueber Netzwerk erreichbar sein. Ohne Auth waere das ein frei -nutzbarer Claude-Max-Zugang fuer jeden der den Port erreicht. Das Gateway -(`proxy-patches/gateway.js`, pure Node, keine Extra-Deps) prueft dafuer den +Warum das Gateway trotzdem noch da ist, obwohl alles auf einer Maschine +laeuft: `hermes-proxy` selbst hat keine Authentifizierung (genau wie ARIAs +Proxy) — jeder andere Container im selben Docker-Host koennte sonst +unbemerkt Deine Claude-Max-Subscription mitbenutzen. Das Gateway +(`proxy-patches/gateway.js`, pure Node, keine Extra-Deps) prueft den `Authorization: Bearer `-Header gegen ein Shared Secret, bevor -irgendwas an `hermes-proxy` weitergeleitet wird. +irgendwas an `hermes-proxy` weitergeleitet wird. Seit "alles auf einer +Maschine" bindet das Gateway nur noch auf `127.0.0.1`, nicht mehr nach +aussen — kein anderer Rechner kommt mehr direkt ran. ## Was uebernommen wurde (1:1 aus ARIAs Proxy-Setup) @@ -51,66 +54,104 @@ irgendwas an `hermes-proxy` weitergeleitet wird. ## Setup -1. **`.env` anlegen:** +1. **Hermes-Agent-Sourcecode daneben klonen** (das offizielle Docker-Image + liegt nicht auf Docker Hub, sondern wird per `build:` aus dem Repo + gebaut): + ```bash + cd /pfad/zum/deploy-ziel + git clone https://github.com/NousResearch/hermes-agent.git hermes-agent-src + ``` + (dieser Clone ist in `.gitignore` — bleibt lokal, wandert nicht in unser Repo) + +2. **`.env` anlegen:** ```bash - cd /shared/projects/hermes_agent cp .env.example .env openssl rand -hex 32 # Ausgabe in .env bei HERMES_GATEWAY_TOKEN eintragen ``` -2. **Stack starten:** +3. **Model-Config fuer Hermes seeden** (einmalig, VOR dem ersten Start — + danach fasst Hermes die Datei nicht mehr an): + ```bash + mkdir -p hermes-data/agent-home + cp hermes-agent-config/config.yaml.example hermes-data/agent-home/config.yaml + ``` + Die Datei zeigt Hermes per `provider: custom` auf unseren + `hermes-gateway` (`http://localhost:${HERMES_GATEWAY_PORT}/v1`) — + `${HERMES_GATEWAY_PORT}`/`${HERMES_GATEWAY_TOKEN}` werden von Hermes selbst + beim Config-Laden aus den Container-Env-Vars expandiert, die kommen aus + Deiner `.env`. Kein manuelles Ausfuellen noetig. + +4. **Stack starten:** ```bash docker compose up -d ``` + Baut beim ersten Mal das Hermes-Image aus `hermes-agent-src` (dauert ein + paar Minuten), startet dann `hermes-proxy`, `hermes-gateway`, + `hermes-agent` (Gateway/Messaging-Prozess) und `hermes-agent-dashboard`. -3. **Einmalig Claude-CLI-Login** (oeffnet Browser-OAuth mit deiner Claude-Max-Subscription): +5. **Einmalig Claude-CLI-Login** (oeffnet Browser-OAuth mit deiner Claude-Max-Subscription): ```bash docker exec -it hermes-proxy claude ``` - Danach liegen die Credentials persistent in `hermes-data/claude-config/.credentials.json` + Danach liegen die Credentials persistent in `hermes-data/claude-config/` — ueberlebt Container-Restarts. -4. **Von der Hermes-Maschine aus testen:** +6. **Testen, dass der Proxy laeuft:** ```bash - curl -s http://:${HERMES_GATEWAY_PORT:-8447}/v1/chat/completions \ + curl -s http://127.0.0.1:${HERMES_GATEWAY_PORT:-8447}/v1/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer " \ - -d '{"model":"claude-sonnet-4","messages":[{"role":"user","content":"Sag Hallo"}]}' + -d '{"model":"sonnet","messages":[{"role":"user","content":"Sag Hallo"}]}' ``` - Ohne oder mit falschem Bearer-Token gibt's `401 unauthorized` — Gateway - arbeitet. + Ohne oder mit falschem Bearer-Token gibt's `401 unauthorized`. -5. **Hermes Agent konfigurieren** (auf der Ziel-Maschine, `~/.hermes/config.yaml`): - ```yaml - model: - provider: custom - model: "sonnet" - base_url: "http://:8447/v1" - api_key: "" +7. **Mit Hermes chatten:** + ```bash + docker exec -it hermes-agent hermes chat ``` - `base_url` hat laut Hermes-Doku Vorrang vor `provider` — funktioniert wie - bei selbst gehosteten/lokalen Endpoints (vLLM, Ollama etc.), die - Hermes-Doku beschreibt genau diesen Ansatz. Modellnamen `sonnet` / `opus` - / `haiku` werden vom Adapter (`openai-to-cli.js`, `MODEL_MAP`) auf die - `--model`-CLI-Flags gemappt. + oder das Dashboard per SSH-Tunnel oeffnen: + ```bash + ssh -L 9119:localhost:9119 + ``` + dann im Browser `http://localhost:9119`. + +## Mobiler Client (Android)? + +Zwei GRUNDVERSCHIEDENE Richtungen, nicht verwechseln: + +- **Unser Proxy oben** (`hermes-gateway` -> `hermes-proxy`): Claude ALS + Backend FUER Hermes. Kein Client redet direkt damit ausser Hermes selbst. +- **Hermes' EIGENER OpenAI-kompatibler API-Server** (`API_SERVER_HOST` / + `API_SERVER_KEY`, auskommentiert im `hermes-agent`-Service): Hermes ALS + Server FUER einen Chat-Client. Aktivieren + `API_SERVER_KEY` in `.env` + setzen, dann kann ein Client wie **gpt_mobile** oder **Maid** (Open Source, + Android, freier `base_url`+Key, kein Messenger — siehe Chat-Verlauf) sich + direkt gegen Hermes verbinden. Fuer sowas wie die ARIA-App (Wake-Word, + Sprachsteuerung, TTS) braeuchte man dagegen einen eigenen App-Build — kein + fertiges Produkt zum Runterladen. ## Sicherheitshinweis -Das Gateway schuetzt vor Fremdnutzung deiner Subscription (Bearer-Token- -Pflicht), **aber der Traffic selbst ist unverschluesseltes HTTP** — kein TLS -zwischen Hermes und dem Gateway. Solange beide Maschinen im selben -vertrauenswuerdigen LAN oder per VPN verbunden sind: unkritisch. Wenn die -Hermes-Maschine ueber offenes Internet zugreifen soll: Port NICHT direkt -exposen, sondern per SSH-Tunnel, WireGuard/Tailscale oder einen TLS- -Reverse-Proxy davorschalten. Sag Bescheid, dann bauen wir das nach, sobald -klar ist wie die beiden Maschinen tatsaechlich verbunden sind. +`hermes-gateway` bindet jetzt nur noch auf `127.0.0.1` — von aussen kommt +niemand mehr ran, solange Du nicht selbst was aendertst (z.B. fuer den +mobilen API-Server oben, oder falls Hermes doch mal auf eine zweite Maschine +zieht). Wenn Du `HERMES_GATEWAY_PORT` oder `API_SERVER_HOST` doch mal nach +aussen exposest: der Traffic ist unverschluesseltes HTTP, kein TLS. Nicht +direkt ins offene Internet haengen — SSH-Tunnel, WireGuard/Tailscale oder +einen TLS-Reverse-Proxy davorschalten. + +## Verzeichnisse (nicht committet, siehe .gitignore) + +- `hermes-agent-src/` — geklonter Hermes-Agent-Sourcecode (Docker-Build-Context) +- `hermes-data/claude-config/` — Claude-CLI-Login (Browser-OAuth-Session) +- `hermes-data/agent-home/` — Hermes' `~/.hermes`-Aequivalent: Config + (`config.yaml`, aus `hermes-agent-config/config.yaml.example` geseedet), + Sessions, Memory, Skills, `.env` +- `.env` — Secrets (Token, ggf. API_SERVER_KEY) ## Wo deployen? -Diese Compose-Datei ist ortsunabhaengig — lief bisher nirgends deployed, -liegt nur unter `/shared/projects/hermes_agent/` (Code-Editor-Sync). Du -kannst sie 1:1 dahin kopieren, wo der Proxy tatsaechlich laufen soll (z.B. -aria-wohnung als eigener isolierter Stack neben ARIA, oder eine ganz andere -Maschine mit Zugriff auf deine Claude-Max-Subscription). Wichtig ist nur: -egal wo, `HERMES_GATEWAY_PORT` muss von der Hermes-Maschine aus erreichbar -sein. +Diese Compose-Datei ist ortsunabhaengig. Stefan deployt sie selbst auf der +Ziel-Maschine (nicht aria-wohnung — komplett getrennt von ARIA). Repo klonen, +die drei Setup-Schritte oben (Hermes-Source klonen, `.env`, Config seeden), +dann `docker compose up -d`. diff --git a/docker-compose.yml b/docker-compose.yml index 9f03ed6..c45b2b8 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -72,30 +72,19 @@ services: # offen im Netz haengt. # Zum manuellen Testen direkt im Container: docker exec -it hermes-proxy curl -s localhost:3456/v1/chat/completions ... - # ─── Hermes Gateway (Auth + Netzwerk-Expose) ─────────────── - # Stefan deployt den eigentlichen Hermes-Agent-Client (Nous Research, - # https://github.com/NousResearch/hermes-agent, CLI/Desktop-App) SELBST - # auf einer ANDEREN Maschine — hier steht daher kein hermes-agent-Service, - # nur die Proxy-Seite, die Hermes von aussen ansprechen kann. + # ─── Hermes Gateway (Auth vor dem Claude-Proxy) ──────────── + # Stefan hat entschieden: Hermes Agent selbst laeuft auf DERSELBEN Maschine + # wie dieser Proxy-Stack (alles zu Hermes gehoerige auf eine Box). Trotzdem + # bleibt dieses Gateway davor — hermes-proxy selbst hat keine Authentifizierung + # (genau wie ARIAs Proxy) und ein anderer Container im selben Docker-Host + # (oder spaeter doch mal ein zweiter Rechner) soll nicht ungefragt an die + # Claude-Max-Subscription rankommen. Das Gateway (proxy-patches/gateway.js, + # pure Node, keine Extra-Deps) prueft den Authorization: Bearer + # Header, leitet nur bei Match an hermes-proxy weiter. Alles andere -> 401. # - # Weil "von aussen" heisst: der Proxy braucht einen echten Netzwerk-Port. - # hermes-proxy selbst hat aber keine Authentifizierung eingebaut (siehe - # Kommentar oben) — ein offener Port waere ein frei nutzbarer Claude-Max- - # Zugang fuer jeden der ihn erreicht. Deshalb dieses schlanke Gateway - # (proxy-patches/gateway.js, pure Node, keine Extra-Deps): prueft den - # Authorization: Bearer Header, leitet nur bei Match an - # hermes-proxy weiter. Alles andere -> 401. - # - # In Hermes' ~/.hermes/config.yaml traegst du ein: - # model: - # provider: custom - # model: "sonnet" # oder "opus" / "haiku" — siehe MODEL_MAP - # # in proxy-patches/openai-to-cli.js - # base_url: "http://:${HERMES_GATEWAY_PORT:-8447}/v1" - # api_key: "" - # OpenAI-kompatible Clients schicken api_key automatisch als - # "Authorization: Bearer " — genau das prueft das Gateway, kein - # Extra-Schritt auf Hermes-Seite noetig. + # Der Hermes-Agent-Service unten ist per ${HERMES_GATEWAY_TOKEN} + diesem + # Gateway vorverdrahtet (siehe hermes-agent-config/config.yaml.example) — + # kein manuelles config.yaml-Editieren mehr noetig. hermes-gateway: image: node:22-alpine container_name: hermes-gateway @@ -110,19 +99,83 @@ services: - UPSTREAM_PORT=3456 - LISTEN_PORT=8080 ports: - # Bindet auf ALLE Interfaces, damit Hermes von der anderen Maschine - # rankommt. HERMES_GATEWAY_PORT in .env setzen (Default 8447). - # WICHTIG (lies auch README "Sicherheitshinweis"): wenn diese Maschine - # direkt im Internet haengt statt in einem vertrauenswuerdigen - # LAN/VPN, den Port zusaetzlich per Firewall auf Hermes' IP - # einschraenken oder per VPN/SSH-Tunnel statt direktem Expose fahren - # — Bearer-Token schuetzt vor Fremdnutzung, aber der Traffic selbst - # laeuft hier unverschluesselt (HTTP, kein TLS). - - "${HERMES_GATEWAY_PORT:-8447}:8080" + # Seit "alles auf einer Maschine": nur noch auf localhost binden, nicht + # mehr auf allen Interfaces. Hermes Agent laeuft ja jetzt selbst hier + # (network_mode: host, siehe unten) und erreicht localhost direkt. + # Falls Du spaeter doch von einer ANDEREN Maschine ranwillst (z.B. fuer + # einen mobilen Client direkt gegen Hermes' eigenen API-Server, siehe + # Kommentar unten bei API_SERVER_*): "127.0.0.1:" vorne weglassen, dann + # bindet's wieder auf 0.0.0.0 — aber dann auch das Sicherheitshinweis- + # Kapitel im README zu TLS/VPN beachten. + - "127.0.0.1:${HERMES_GATEWAY_PORT:-8447}:8080" restart: unless-stopped networks: - hermes-net + # ─── Hermes Agent selbst (Nous Research) ─────────────────── + # Offizielle Service-Definition 1:1 aus NousResearch/hermes-agent/docker-compose.yml + # (nur umbenannt gateway->hermes-agent, dashboard->hermes-agent-dashboard, damit + # es nicht mit unserem eigenen "hermes-gateway" oben verwechselt wird — das ist + # ein GANZ ANDERES Ding: Hermes' eigener Gateway-Begriff meint die Messaging- + # Bruecke (Telegram/Discord/...) + optionalen OpenAI-API-Server, NICHT unseren + # Auth-Proxy vor Claude). + # + # VORAUSSETZUNG: der echte Hermes-Agent-Sourcecode muss danebenliegen, weil + # das Image nicht auf Docker Hub existiert, sondern per `build:` aus dem Repo + # gebaut wird. Einmalig VOR dem ersten `docker compose up -d`: + # git clone https://github.com/NousResearch/hermes-agent.git hermes-agent-src + # + # network_mode: host wie im Original — manche Messaging-Plattformen brauchen + # echte Host-Ports, und dadurch erreicht Hermes unser hermes-gateway einfach + # ueber "http://localhost:${HERMES_GATEWAY_PORT}/v1" statt ueber Docker-DNS. + hermes-agent: + build: ./hermes-agent-src + image: hermes-agent + container_name: hermes-agent + restart: unless-stopped + network_mode: host + depends_on: + - hermes-gateway + volumes: + # ~/.hermes-Aequivalent: Config, Sessions, Memory, Skills - alles persistent + # hier drin. hermes-agent-config/config.yaml.example wird VOR dem ersten + # Start einmalig hierher kopiert (siehe README) und dann von Hermes + # NICHT mehr angefasst (nur geseedet wenn's fehlt). + - ./hermes-data/agent-home:/opt/data + environment: + - HERMES_UID=${HERMES_UID:-10000} + - HERMES_GID=${HERMES_GID:-10000} + # Fuer die ${HERMES_GATEWAY_PORT}/${HERMES_GATEWAY_TOKEN}-Platzhalter in + # hermes-data/agent-home/config.yaml (Hermes expandiert ${VAR} beim + # Config-Laden aus os.environ — siehe hermes_cli/config.py _expand_env_vars). + - HERMES_GATEWAY_PORT=${HERMES_GATEWAY_PORT:-8447} + - HERMES_GATEWAY_TOKEN=${HERMES_GATEWAY_TOKEN:?HERMES_GATEWAY_TOKEN muss in .env gesetzt sein - siehe .env.example} + # Optional: Hermes' EIGENER OpenAI-kompatibler API-Server, falls Du spaeter + # einen mobilen Client (gpt_mobile, Maid, OpenWebUI, ...) direkt GEGEN + # Hermes sprechen lassen willst (andere Richtung als unser Proxy oben! + # Das hier ist Hermes ALS Server fuer einen Chat-Client, nicht Claude ALS + # Backend fuer Hermes). Zum Aktivieren beide Zeilen einkommentieren und + # API_SERVER_KEY in .env setzen: + # - API_SERVER_HOST=0.0.0.0 + # - API_SERVER_KEY=${API_SERVER_KEY} + command: ["gateway", "run"] + + hermes-agent-dashboard: + image: hermes-agent + container_name: hermes-agent-dashboard + restart: unless-stopped + network_mode: host + depends_on: + - hermes-agent + volumes: + - ./hermes-data/agent-home:/opt/data + environment: + - HERMES_UID=${HERMES_UID:-10000} + - HERMES_GID=${HERMES_GID:-10000} + # Bindet nur auf localhost (Hermes' eigene Empfehlung, speichert API-Keys). + # Fuer Zugriff von aussen: `ssh -L 9119:localhost:9119 `. + command: ["dashboard", "--host", "127.0.0.1", "--no-open"] + networks: hermes-net: driver: bridge diff --git a/hermes-agent-config/config.yaml.example b/hermes-agent-config/config.yaml.example new file mode 100644 index 0000000..7c2e280 --- /dev/null +++ b/hermes-agent-config/config.yaml.example @@ -0,0 +1,33 @@ +# Hermes Agent Model-Config — zeigt auf UNSEREN Claude-Max-Proxy statt auf +# OpenRouter/Nous Portal/direkte Provider-Keys. +# +# WICHTIG: das ist NICHT die volle ~/.hermes/config.yaml (die hat noch +# hunderte weitere optionale Blöcke — terminal, toolsets, memory, etc., siehe +# hermes-agent-src/cli-config.yaml.example fürs Referenz-Full-File). Diese +# Datei hier enthält bewusst NUR den model:-Block. Hermes seedet beim ersten +# Container-Start automatisch alle fehlenden Felder aus seinen eingebauten +# Defaults (Stage2-Hook: seed_one() kopiert cli-config.yaml.example NUR wenn +# config.yaml noch nicht existiert — diese Datei hier gewinnt also, wird +# NICHT überschrieben, solange sie schon liegt). +# +# ${HERMES_GATEWAY_PORT} / ${HERMES_GATEWAY_TOKEN} werden von Hermes selbst +# beim Config-Laden aus den Container-Env-Vars expandiert (nicht von Docker +# Compose) — die kommen im hermes-agent-Service aus .env durch. Deshalb hier +# NICHT hardcoden, auch nicht "zum Testen". +model: + # sonnet/opus/haiku werden vom Proxy-Adapter (proxy-patches/openai-to-cli.js, + # MODEL_MAP) auf die claude --model Flags gemappt. Unbekannte Namen fallen + # dort automatisch auf "opus" zurück. + default: "sonnet" + + # "custom" = jeder OpenAI-kompatible Endpoint, der nicht einer der + # named Provider (openrouter/nous/anthropic/...) ist — genau unser Fall. + provider: "custom" + + # localhost, weil Hermes Agent laut Stefan auf DERSELBEN Maschine läuft wie + # unser hermes-gateway (network_mode: host im hermes-agent-Service). + base_url: "http://localhost:${HERMES_GATEWAY_PORT}/v1" + + # Gateway prüft das als "Authorization: Bearer " — der OpenAI SDK + # (den Hermes intern nutzt) setzt den Header automatisch aus diesem Feld. + api_key: "${HERMES_GATEWAY_TOKEN}"