From 14c2fee05919f5947d6af59f94bd216b0b72e028 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=B5=E9=A3=9B?= Date: Sat, 16 May 2026 04:59:36 +0000 Subject: [PATCH 01/16] feat: add Hermes Agent as agent provider Add Hermes Agent (NousResearch) as a supported agent provider, enabling OAB to leverage Hermes's multi-provider OAuth infrastructure via ACP. Key benefits: - xAI Grok OAuth (SuperGrok $30/mo flat rate vs pay-per-token) - 30+ providers accessible through one agent - OAuth token lifecycle managed by Hermes (zero auth complexity for OAB) - Multi-modal support (TTS, image gen, video gen) via same OAuth token - Built-in fallback chains for provider resilience Files added: - Dockerfile.hermes: runtime image with Hermes Agent installed - docs/hermes.md: setup guide with auth and provider switching docs - config.toml.example: added Hermes agent config example Closes #823 --- Dockerfile.hermes | 36 +++++++++++++++++++ config.toml.example | 8 +++++ docs/hermes.md | 87 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 131 insertions(+) create mode 100644 Dockerfile.hermes create mode 100644 docs/hermes.md diff --git a/Dockerfile.hermes b/Dockerfile.hermes new file mode 100644 index 00000000..2956d6c8 --- /dev/null +++ b/Dockerfile.hermes @@ -0,0 +1,36 @@ +# --- Build stage --- +FROM rust:1-bookworm AS builder +WORKDIR /build +COPY Cargo.toml Cargo.lock ./ +RUN mkdir src && echo 'fn main() {}' > src/main.rs && cargo build --release && rm -rf src +COPY src/ src/ +RUN touch src/main.rs && cargo build --release + +# --- Runtime stage --- +FROM python:3.12-slim-bookworm +RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates curl procps ripgrep tini git && rm -rf /var/lib/apt/lists/* + +# Install Hermes Agent +RUN curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh | bash + +# Install gh CLI +RUN curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg \ + -o /usr/share/keyrings/githubcli-archive-keyring.gpg && \ + echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" \ + > /etc/apt/sources.list.d/github-cli.list && \ + apt-get update && apt-get install -y --no-install-recommends gh && \ + rm -rf /var/lib/apt/lists/* + +ENV HOME=/home/agent +WORKDIR /home/agent + +COPY --from=builder --chown=1000:1000 /build/target/release/openab /usr/local/bin/openab + +RUN useradd -m -u 1000 agent && \ + mkdir -p /home/agent/.hermes && chown -R agent:agent /home/agent/.hermes + +USER agent +HEALTHCHECK --interval=30s --timeout=5s --retries=3 \ + CMD pgrep -x openab || exit 1 +ENTRYPOINT ["tini", "--"] +CMD ["openab", "run", "-c", "/etc/openab/config.toml"] diff --git a/config.toml.example b/config.toml.example index d33a0902..707909ab 100644 --- a/config.toml.example +++ b/config.toml.example @@ -103,6 +103,14 @@ working_dir = "/home/agent" # working_dir = "/home/agent" # env = {} # Auth via: kubectl exec -it -- cursor-agent login +# [agent] +# command = "hermes" +# args = ["--acp", "--stdio"] +# working_dir = "/home/agent" +# # Auth via: kubectl exec -it -- hermes auth add xai-oauth +# # Supports 30+ providers (xAI Grok OAuth, Anthropic, OpenAI Codex, Gemini, etc.) +# # Provider switching: kubectl exec -it -- hermes model + [pool] max_sessions = 10 session_ttl_hours = 24 diff --git a/docs/hermes.md b/docs/hermes.md new file mode 100644 index 00000000..1075b7a7 --- /dev/null +++ b/docs/hermes.md @@ -0,0 +1,87 @@ +# Hermes Agent + +[Hermes Agent](https://github.com/NousResearch/hermes-agent) by Nous Research supports ACP natively via `--acp --stdio`. + +Hermes acts as a multi-provider inference gateway — it handles OAuth token lifecycle, credential storage, and provider routing so OAB agents don't need to manage auth directly. + +## Docker Image + +```bash +docker build -f Dockerfile.hermes -t openab-hermes:latest . +``` + +The image installs Hermes Agent via the official install script. + +## Helm Install + +```bash +helm install openab openab/openab \ + --set agents.kiro.enabled=false \ + --set agents.hermes.discord.enabled=true \ + --set agents.hermes.discord.botToken="$DISCORD_BOT_TOKEN" \ + --set-string 'agents.hermes.discord.allowedChannels[0]=YOUR_CHANNEL_ID' \ + --set agents.hermes.image=ghcr.io/openabdev/openab-hermes:latest \ + --set agents.hermes.command=hermes \ + --set agents.hermes.args='{--acp,--stdio}' \ + --set agents.hermes.workingDir=/home/agent +``` + +> Set `agents.kiro.enabled=false` to disable the default Kiro agent. + +## Manual config.toml + +```toml +[agent] +command = "hermes" +args = ["--acp", "--stdio"] +working_dir = "/home/agent" +``` + +## Authentication + +Hermes supports 30+ providers. Authenticate inside the pod: + +```bash +kubectl exec -it -- hermes auth add xai-oauth # xAI Grok (SuperGrok $30/mo) +kubectl exec -it -- hermes auth add nous # Nous Portal +kubectl exec -it -- hermes model # Interactive provider picker +``` + +### Supported Providers (via OAuth) + +| Provider | Auth Command | Cost Model | +|----------|-------------|------------| +| xAI Grok | `hermes auth add xai-oauth` | SuperGrok subscription ($30/mo) | +| OpenAI Codex | `hermes model` → OpenAI Codex | ChatGPT subscription | +| GitHub Copilot | `hermes model` → GitHub Copilot | Copilot subscription | +| Google Gemini | `hermes model` → Google Gemini (OAuth) | Free tier available | +| Anthropic | `hermes model` → Anthropic | Claude Max + extra credits | +| Nous Portal | `hermes auth add nous` | Nous subscription | + +### Supported Providers (via API Key) + +Any provider can also be configured with an API key via environment variables: + +```toml +[agent] +command = "hermes" +args = ["--acp", "--stdio"] +working_dir = "/home/agent" +env = { XAI_API_KEY = "${XAI_API_KEY}" } +``` + +## Provider Switching + +Switch providers without restarting the pod: + +```bash +kubectl exec -it -- hermes model +``` + +## Advantages + +- **Cost**: SuperGrok $30/mo flat rate vs pay-per-token API pricing +- **Multi-provider**: 30+ providers accessible through one agent +- **Zero auth complexity**: Hermes handles OAuth + token refresh +- **Multi-modal**: TTS, image gen, video gen via the same OAuth token +- **Fallback chains**: Auto-switch providers on failure From d2203d69371901eeaa0af9b9e5e1d6bd0dcec91b Mon Sep 17 00:00:00 2001 From: chaodufashi Date: Sat, 16 May 2026 05:08:09 +0000 Subject: [PATCH 02/16] fix: pin install script, correct ACP invocation, add credential persistence docs - Dockerfile.hermes: pin install script to commit cc07e30f with SHA256 checksum verification instead of curl-pipe-bash from main - docs/hermes.md & config.toml.example: correct command from 'hermes --acp --stdio' to 'hermes-acp' (verified upstream) - docs/hermes.md: add PVC/volume mount guidance for credential persistence Addresses review findings from PR #824. --- Dockerfile.hermes | 10 ++++++++-- config.toml.example | 3 +-- docs/hermes.md | 28 +++++++++++++++++++++------- 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/Dockerfile.hermes b/Dockerfile.hermes index 2956d6c8..818f75d4 100644 --- a/Dockerfile.hermes +++ b/Dockerfile.hermes @@ -10,8 +10,14 @@ RUN touch src/main.rs && cargo build --release FROM python:3.12-slim-bookworm RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates curl procps ripgrep tini git && rm -rf /var/lib/apt/lists/* -# Install Hermes Agent -RUN curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh | bash +# Install Hermes Agent — pinned to known commit with checksum verification +ARG HERMES_INSTALL_COMMIT=cc07e30f45267c00fac97ea5569c606aca5a1ffb +ARG HERMES_INSTALL_SHA256=cb94b83b96cc924716bd1651411955da7495912ef68affe6788840e6cf147d41 +RUN curl -fsSL "https://raw.githubusercontent.com/NousResearch/hermes-agent/${HERMES_INSTALL_COMMIT}/scripts/install.sh" \ + -o /tmp/install-hermes.sh && \ + echo "${HERMES_INSTALL_SHA256} /tmp/install-hermes.sh" | sha256sum -c - && \ + bash /tmp/install-hermes.sh && \ + rm /tmp/install-hermes.sh # Install gh CLI RUN curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg \ diff --git a/config.toml.example b/config.toml.example index 707909ab..20ccff34 100644 --- a/config.toml.example +++ b/config.toml.example @@ -104,8 +104,7 @@ working_dir = "/home/agent" # env = {} # Auth via: kubectl exec -it -- cursor-agent login # [agent] -# command = "hermes" -# args = ["--acp", "--stdio"] +# command = "hermes-acp" # working_dir = "/home/agent" # # Auth via: kubectl exec -it -- hermes auth add xai-oauth # # Supports 30+ providers (xAI Grok OAuth, Anthropic, OpenAI Codex, Gemini, etc.) diff --git a/docs/hermes.md b/docs/hermes.md index 1075b7a7..c4c216e9 100644 --- a/docs/hermes.md +++ b/docs/hermes.md @@ -1,6 +1,6 @@ # Hermes Agent -[Hermes Agent](https://github.com/NousResearch/hermes-agent) by Nous Research supports ACP natively via `--acp --stdio`. +[Hermes Agent](https://github.com/NousResearch/hermes-agent) by Nous Research supports ACP natively via the `hermes acp` subcommand (or the `hermes-acp` binary). Hermes acts as a multi-provider inference gateway — it handles OAuth token lifecycle, credential storage, and provider routing so OAB agents don't need to manage auth directly. @@ -21,8 +21,7 @@ helm install openab openab/openab \ --set agents.hermes.discord.botToken="$DISCORD_BOT_TOKEN" \ --set-string 'agents.hermes.discord.allowedChannels[0]=YOUR_CHANNEL_ID' \ --set agents.hermes.image=ghcr.io/openabdev/openab-hermes:latest \ - --set agents.hermes.command=hermes \ - --set agents.hermes.args='{--acp,--stdio}' \ + --set agents.hermes.command=hermes-acp \ --set agents.hermes.workingDir=/home/agent ``` @@ -32,8 +31,7 @@ helm install openab openab/openab \ ```toml [agent] -command = "hermes" -args = ["--acp", "--stdio"] +command = "hermes-acp" working_dir = "/home/agent" ``` @@ -64,8 +62,7 @@ Any provider can also be configured with an API key via environment variables: ```toml [agent] -command = "hermes" -args = ["--acp", "--stdio"] +command = "hermes-acp" working_dir = "/home/agent" env = { XAI_API_KEY = "${XAI_API_KEY}" } ``` @@ -78,6 +75,23 @@ Switch providers without restarting the pod: kubectl exec -it -- hermes model ``` +## Credential Persistence + +Hermes stores OAuth tokens in `~/.hermes/`. To persist credentials across pod restarts, mount a PVC: + +```yaml +# In your Helm values or pod spec: +volumes: + - name: hermes-credentials + persistentVolumeClaim: + claimName: hermes-credentials-pvc +volumeMounts: + - name: hermes-credentials + mountPath: /home/agent/.hermes +``` + +Without a volume mount, you'll need to re-authenticate after every pod restart. + ## Advantages - **Cost**: SuperGrok $30/mo flat rate vs pay-per-token API pricing From fdcf5b85d94c1204c08f9cadda2f7a7ac6f2fb59 Mon Sep 17 00:00:00 2001 From: chaodufashi Date: Sat, 16 May 2026 05:09:08 +0000 Subject: [PATCH 03/16] ci: add hermes variant to build & release matrix Adds Dockerfile.hermes to the build-image, merge-manifests, and promote-stable matrices so the ghcr.io/openabdev/openab-hermes image is published by CI alongside other agent variants. --- .github/workflows/build.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7b360417..17b4505a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -72,6 +72,7 @@ jobs: - { suffix: "-copilot", dockerfile: "Dockerfile.copilot", artifact: "copilot" } - { suffix: "-opencode", dockerfile: "Dockerfile.opencode", artifact: "opencode" } - { suffix: "-cursor", dockerfile: "Dockerfile.cursor", artifact: "cursor" } + - { suffix: "-hermes", dockerfile: "Dockerfile.hermes", artifact: "hermes" } platform: - { os: linux/amd64, runner: ubuntu-latest } - { os: linux/arm64, runner: ubuntu-24.04-arm } @@ -135,6 +136,7 @@ jobs: - { suffix: "-copilot", artifact: "copilot" } - { suffix: "-opencode", artifact: "opencode" } - { suffix: "-cursor", artifact: "cursor" } + - { suffix: "-hermes", artifact: "hermes" } runs-on: ubuntu-latest permissions: contents: read @@ -185,6 +187,7 @@ jobs: - { suffix: "-copilot" } - { suffix: "-opencode" } - { suffix: "-cursor" } + - { suffix: "-hermes" } runs-on: ubuntu-latest permissions: contents: read From e22addea35c37fda1035f55d53e40fbd7fcb7524 Mon Sep 17 00:00:00 2001 From: chaodufashi Date: Sat, 16 May 2026 05:09:58 +0000 Subject: [PATCH 04/16] fix: Dockerfile user/permission ordering and missing deps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Create agent user before WORKDIR so /home/agent has correct ownership - Set HERMES_HOME=/home/agent/.hermes during install so OAuth tokens are stored in agent user's home (not /root/.hermes) - Add ffmpeg for Hermes multi-modal support - chown /home/agent after all root operations complete Addresses review findings from 覺渡法師. --- Dockerfile.hermes | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/Dockerfile.hermes b/Dockerfile.hermes index 818f75d4..2e426d60 100644 --- a/Dockerfile.hermes +++ b/Dockerfile.hermes @@ -8,15 +8,23 @@ RUN touch src/main.rs && cargo build --release # --- Runtime stage --- FROM python:3.12-slim-bookworm -RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates curl procps ripgrep tini git && rm -rf /var/lib/apt/lists/* + +# Create agent user first so WORKDIR gets correct ownership +RUN useradd -m -u 1000 agent + +RUN apt-get update && apt-get install -y --no-install-recommends \ + ca-certificates curl procps ripgrep tini git ffmpeg && \ + rm -rf /var/lib/apt/lists/* # Install Hermes Agent — pinned to known commit with checksum verification +# Root install uses FHS layout: binary at /usr/local/bin/hermes, code at /usr/local/lib/hermes-agent +# HERMES_HOME points to agent user's data dir for OAuth tokens and config ARG HERMES_INSTALL_COMMIT=cc07e30f45267c00fac97ea5569c606aca5a1ffb ARG HERMES_INSTALL_SHA256=cb94b83b96cc924716bd1651411955da7495912ef68affe6788840e6cf147d41 RUN curl -fsSL "https://raw.githubusercontent.com/NousResearch/hermes-agent/${HERMES_INSTALL_COMMIT}/scripts/install.sh" \ -o /tmp/install-hermes.sh && \ echo "${HERMES_INSTALL_SHA256} /tmp/install-hermes.sh" | sha256sum -c - && \ - bash /tmp/install-hermes.sh && \ + HERMES_HOME=/home/agent/.hermes bash /tmp/install-hermes.sh && \ rm /tmp/install-hermes.sh # Install gh CLI @@ -32,8 +40,7 @@ WORKDIR /home/agent COPY --from=builder --chown=1000:1000 /build/target/release/openab /usr/local/bin/openab -RUN useradd -m -u 1000 agent && \ - mkdir -p /home/agent/.hermes && chown -R agent:agent /home/agent/.hermes +RUN chown -R agent:agent /home/agent USER agent HEALTHCHECK --interval=30s --timeout=5s --retries=3 \ From 6ec460d8ceb433422481ba1f06d6d61d876e26e4 Mon Sep 17 00:00:00 2001 From: chaodufashi Date: Sat, 16 May 2026 05:10:52 +0000 Subject: [PATCH 05/16] ci: add hermes to smoke-test matrix; clarify persistence docs - docker-smoke-test.yml: add Dockerfile.hermes variant - docs/hermes.md: clarify that Helm chart persistence covers .hermes by default; manual PVC only needed for non-Helm deploys --- .github/workflows/docker-smoke-test.yml | 1 + docs/hermes.md | 7 +++---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/docker-smoke-test.yml b/.github/workflows/docker-smoke-test.yml index 64b4653a..0fd0c238 100644 --- a/.github/workflows/docker-smoke-test.yml +++ b/.github/workflows/docker-smoke-test.yml @@ -20,6 +20,7 @@ jobs: - { dockerfile: Dockerfile.copilot, suffix: "-copilot", agent: "copilot", agent_args: "--acp" } - { dockerfile: Dockerfile.opencode, suffix: "-opencode", agent: "opencode", agent_args: "acp" } - { dockerfile: Dockerfile.cursor, suffix: "-cursor", agent: "cursor-agent", agent_args: "acp" } + - { dockerfile: Dockerfile.hermes, suffix: "-hermes", agent: "hermes-acp", agent_args: "" } runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 diff --git a/docs/hermes.md b/docs/hermes.md index c4c216e9..8a86d5d1 100644 --- a/docs/hermes.md +++ b/docs/hermes.md @@ -77,10 +77,11 @@ kubectl exec -it -- hermes model ## Credential Persistence -Hermes stores OAuth tokens in `~/.hermes/`. To persist credentials across pod restarts, mount a PVC: +Hermes stores OAuth tokens in `~/.hermes/`. The OpenAB Helm chart's default persistence covers this automatically (PVC mounted at `workingDir`). + +If deploying manually (without the Helm chart), mount persistent storage at `/home/agent` or `/home/agent/.hermes`: ```yaml -# In your Helm values or pod spec: volumes: - name: hermes-credentials persistentVolumeClaim: @@ -90,8 +91,6 @@ volumeMounts: mountPath: /home/agent/.hermes ``` -Without a volume mount, you'll need to re-authenticate after every pod restart. - ## Advantages - **Cost**: SuperGrok $30/mo flat rate vs pay-per-token API pricing From 8c9e764735786c2b77bc881170f17b10d877e92c Mon Sep 17 00:00:00 2001 From: chaodufashi Date: Sat, 16 May 2026 05:11:29 +0000 Subject: [PATCH 06/16] ci: add hermes to pr-preview variant choices --- .github/workflows/pr-preview.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/pr-preview.yml b/.github/workflows/pr-preview.yml index 69ba8907..a5cac441 100644 --- a/.github/workflows/pr-preview.yml +++ b/.github/workflows/pr-preview.yml @@ -18,6 +18,7 @@ on: - copilot - cursor - gemini + - hermes - opencode default: 'default' From f283ac529da7dd868ef9351ede634e896b421fbe Mon Sep 17 00:00:00 2001 From: chaodufashi Date: Sat, 16 May 2026 05:12:10 +0000 Subject: [PATCH 07/16] docs(chart): add hermes agent example to values.yaml The chart is generic over agents., so hermes already works, but adding a commented example makes discoverability easier and aligns with the docs/hermes.md Helm install instructions. --- charts/openab/values.yaml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/charts/openab/values.yaml b/charts/openab/values.yaml index 50b65915..0e4b5952 100644 --- a/charts/openab/values.yaml +++ b/charts/openab/values.yaml @@ -140,6 +140,27 @@ agents: # storageClass: "" # size: 1Gi # image: "ghcr.io/openabdev/openab-cursor:latest" + # hermes: + # command: hermes-acp + # discord: + # enabled: true + # allowedChannels: + # - "YOUR_CHANNEL_ID" + # allowedUsers: [] + # allowBotMessages: "off" + # trustedBotIds: [] + # workingDir: /home/agent + # env: {} + # envFrom: [] + # secretEnv: [] + # pool: + # maxSessions: 10 + # sessionTtlHours: 24 + # persistence: + # enabled: true + # storageClass: "" + # size: 1Gi + # image: "ghcr.io/openabdev/openab-hermes" image: "" command: kiro-cli args: From 3f31f8d25c075aefefb9f496fb52fadaa757c877 Mon Sep 17 00:00:00 2001 From: chaodufashi Date: Sat, 16 May 2026 05:19:06 +0000 Subject: [PATCH 08/16] fix: add xz-utils for Node.js tar.xz extraction in hermes install --- Dockerfile.hermes | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile.hermes b/Dockerfile.hermes index 2e426d60..b48aaa31 100644 --- a/Dockerfile.hermes +++ b/Dockerfile.hermes @@ -13,7 +13,7 @@ FROM python:3.12-slim-bookworm RUN useradd -m -u 1000 agent RUN apt-get update && apt-get install -y --no-install-recommends \ - ca-certificates curl procps ripgrep tini git ffmpeg && \ + ca-certificates curl procps ripgrep tini git ffmpeg xz-utils && \ rm -rf /var/lib/apt/lists/* # Install Hermes Agent — pinned to known commit with checksum verification From 58bfc95a572787e3655d181e00020a4097d21761 Mon Sep 17 00:00:00 2001 From: chaodufashi Date: Sat, 16 May 2026 05:36:11 +0000 Subject: [PATCH 09/16] fix: symlink hermes-acp to /usr/local/bin for PATH visibility FHS root install only links 'hermes' to /usr/local/bin, but 'hermes-acp' stays in the venv. Add explicit symlink. --- Dockerfile.hermes | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile.hermes b/Dockerfile.hermes index b48aaa31..3f44bfa1 100644 --- a/Dockerfile.hermes +++ b/Dockerfile.hermes @@ -25,6 +25,7 @@ RUN curl -fsSL "https://raw.githubusercontent.com/NousResearch/hermes-agent/${HE -o /tmp/install-hermes.sh && \ echo "${HERMES_INSTALL_SHA256} /tmp/install-hermes.sh" | sha256sum -c - && \ HERMES_HOME=/home/agent/.hermes bash /tmp/install-hermes.sh && \ + ln -sf /usr/local/lib/hermes-agent/venv/bin/hermes-acp /usr/local/bin/hermes-acp && \ rm /tmp/install-hermes.sh # Install gh CLI From 433fc77fe2b678c796e29fe306d185dfd0c85395 Mon Sep 17 00:00:00 2001 From: chaodufashi Date: Sat, 16 May 2026 05:45:40 +0000 Subject: [PATCH 10/16] fix: recreate venv with system Python to avoid uv-managed path issues uv installs its own Python 3.11 at /root/.local/share/uv/python/ which is inaccessible to the agent user. Recreate venv with the image's system Python 3.12 after install script completes. --- Dockerfile.hermes | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Dockerfile.hermes b/Dockerfile.hermes index 3f44bfa1..140bce73 100644 --- a/Dockerfile.hermes +++ b/Dockerfile.hermes @@ -25,8 +25,11 @@ RUN curl -fsSL "https://raw.githubusercontent.com/NousResearch/hermes-agent/${HE -o /tmp/install-hermes.sh && \ echo "${HERMES_INSTALL_SHA256} /tmp/install-hermes.sh" | sha256sum -c - && \ HERMES_HOME=/home/agent/.hermes bash /tmp/install-hermes.sh && \ - ln -sf /usr/local/lib/hermes-agent/venv/bin/hermes-acp /usr/local/bin/hermes-acp && \ - rm /tmp/install-hermes.sh + rm /tmp/install-hermes.sh && \ + cd /usr/local/lib/hermes-agent && \ + rm -rf venv && python3 -m venv venv && \ + venv/bin/pip install --no-cache-dir -e ".[acp]" && \ + ln -sf /usr/local/lib/hermes-agent/venv/bin/hermes-acp /usr/local/bin/hermes-acp # Install gh CLI RUN curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg \ From 90b6a58c725fd3e4b151e1d609156430e4979027 Mon Sep 17 00:00:00 2001 From: thepagent Date: Sat, 16 May 2026 02:16:36 -0400 Subject: [PATCH 11/16] fix(docker): chmod uv-managed Python for non-root agent user The hermes install script uses uv which places Python 3.11 under /root/.local/share/uv/. The container runs as non-root user 'agent', causing 'Permission denied' when the venv tries to resolve its Python interpreter. Fix: chmod the uv directory and parent paths to be world-readable/executable. Also symlink hermes-acp to /usr/local/bin for PATH accessibility. Tested and verified working on orbstack with xai-oauth + grok-4.3. --- Dockerfile.hermes | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Dockerfile.hermes b/Dockerfile.hermes index 140bce73..7de02b41 100644 --- a/Dockerfile.hermes +++ b/Dockerfile.hermes @@ -26,9 +26,8 @@ RUN curl -fsSL "https://raw.githubusercontent.com/NousResearch/hermes-agent/${HE echo "${HERMES_INSTALL_SHA256} /tmp/install-hermes.sh" | sha256sum -c - && \ HERMES_HOME=/home/agent/.hermes bash /tmp/install-hermes.sh && \ rm /tmp/install-hermes.sh && \ - cd /usr/local/lib/hermes-agent && \ - rm -rf venv && python3 -m venv venv && \ - venv/bin/pip install --no-cache-dir -e ".[acp]" && \ + chmod -R a+rX /root/.local/share/uv && \ + chmod a+rx /root /root/.local /root/.local/share && \ ln -sf /usr/local/lib/hermes-agent/venv/bin/hermes-acp /usr/local/bin/hermes-acp # Install gh CLI From 37700b56fbb808e52a60fcee842624eaa78d6a4f Mon Sep 17 00:00:00 2001 From: thepagent Date: Sat, 16 May 2026 02:19:05 -0400 Subject: [PATCH 12/16] docs(hermes): add xAI OAuth auth guide with port-forward for K8s pods --- docs/hermes.md | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/docs/hermes.md b/docs/hermes.md index 8a86d5d1..a0abee12 100644 --- a/docs/hermes.md +++ b/docs/hermes.md @@ -45,6 +45,41 @@ kubectl exec -it -- hermes auth add nous # Nous Portal kubectl exec -it -- hermes model # Interactive provider picker ``` +### xAI Grok OAuth (Recommended) + +xAI Grok OAuth uses a loopback redirect flow — the callback listener binds `127.0.0.1:56121` inside the pod. You need a port-forward so your browser's redirect reaches the pod: + +```bash +# Terminal 1: port-forward +kubectl port-forward deployment/ 56121:56121 + +# Terminal 2: run auth +kubectl exec -it deployment/ -- hermes auth add xai-oauth --no-browser +``` + +1. Copy the printed authorize URL → open in your local browser +2. Approve access on accounts.x.ai +3. Browser redirects to `127.0.0.1:56121/callback` → port-forward delivers it to the pod +4. Terminal shows "Login successful!" + +After auth, set the default model: + +```bash +kubectl exec -- hermes config set model.provider xai-oauth +kubectl exec -- hermes config set model.default grok-4.3 +``` + +> **Note:** You need an active [SuperGrok subscription](https://x.ai/grok) ($30/mo). Auth will succeed without one, but the API returns empty responses. + +### Providers That Don't Need Port-Forward + +| Provider | Auth Method | +|----------|-------------| +| Anthropic (Claude Pro/Max) | Paste-the-code flow | +| OpenAI Codex (ChatGPT Plus/Pro) | Device code flow | +| MiniMax, Nous Portal | Device code flow | +| xAI Grok, Spotify | Loopback OAuth (port-forward required) | + ### Supported Providers (via OAuth) | Provider | Auth Command | Cost Model | From d6766d973d968715296c9fe0d09abad4d158fb27 Mon Sep 17 00:00:00 2001 From: thepagent Date: Sat, 16 May 2026 02:20:21 -0400 Subject: [PATCH 13/16] docs(hermes): emphasize SuperGrok paid subscription requirement --- docs/hermes.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/hermes.md b/docs/hermes.md index a0abee12..2ab9ef2f 100644 --- a/docs/hermes.md +++ b/docs/hermes.md @@ -47,6 +47,8 @@ kubectl exec -it -- hermes model # Interactive provider pi ### xAI Grok OAuth (Recommended) +> ⚠️ **Requires an active [SuperGrok paid subscription](https://x.ai/grok) ($30/mo).** Auth will succeed without one, but the API silently returns empty responses — the bot appears to work but never replies. + xAI Grok OAuth uses a loopback redirect flow — the callback listener binds `127.0.0.1:56121` inside the pod. You need a port-forward so your browser's redirect reaches the pod: ```bash @@ -69,7 +71,7 @@ kubectl exec -- hermes config set model.provider xai-oauth kubectl exec -- hermes config set model.default grok-4.3 ``` -> **Note:** You need an active [SuperGrok subscription](https://x.ai/grok) ($30/mo). Auth will succeed without one, but the API returns empty responses. +> **Note:** Tokens are stored in `~/.hermes/auth.json` and auto-refresh in the background. ### Providers That Don't Need Port-Forward From 5556efa5c62b3eb6592c040eebc8fe558b382bc9 Mon Sep 17 00:00:00 2001 From: thepagent Date: Sat, 16 May 2026 02:24:12 -0400 Subject: [PATCH 14/16] docs: add Hermes Agent to README table and config-reference --- README.md | 1 + docs/config-reference.md | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/README.md b/README.md index b7110cde..adebf7d2 100644 --- a/README.md +++ b/README.md @@ -168,6 +168,7 @@ The bot creates a thread. After that, just type in the thread — no @mention ne | OpenCode | `opencode acp` | Native | [docs/opencode.md](docs/opencode.md) | | Copilot CLI ⚠️ | `copilot --acp --stdio` | Native | [docs/copilot.md](docs/copilot.md) | | Cursor | `cursor-agent acp` | Native | [docs/cursor.md](docs/cursor.md) | +| Hermes Agent | `hermes-acp` | Native | [docs/hermes.md](docs/hermes.md) | > 🔧 Running multiple agents? See [docs/multi-agent.md](docs/multi-agent.md) diff --git a/docs/config-reference.md b/docs/config-reference.md index a0eef687..907c122c 100644 --- a/docs/config-reference.md +++ b/docs/config-reference.md @@ -141,6 +141,11 @@ working_dir = "/home/node" command = "cursor-agent" args = ["acp", "--model", "auto", "--workspace", "/home/agent"] working_dir = "/home/agent" + +# Hermes Agent +[agent] +command = "hermes-acp" +working_dir = "/home/agent" ``` --- From a124d40a3300c8bcc69979b485105a8b4f2c99e6 Mon Sep 17 00:00:00 2001 From: thepagent Date: Sat, 16 May 2026 02:25:50 -0400 Subject: [PATCH 15/16] docs(readme): add Hermes to architecture diagram and feature list --- README.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index adebf7d2..fc98d384 100644 --- a/README.md +++ b/README.md @@ -4,23 +4,23 @@ ![OpenAB banner](images/banner.jpg) -A lightweight, secure, cloud-native ACP harness that bridges **Discord, Slack**, and any [Agent Client Protocol](https://github.com/anthropics/agent-protocol)-compatible coding CLI (Kiro CLI, Claude Code, Codex, Gemini, OpenCode, Copilot CLI, etc.) over stdio JSON-RPC — delivering the next-generation development experience. **Telegram, LINE, Feishu/Lark, Google Chat**, and other webhook-based platforms are supported via the standalone [Custom Gateway](gateway/). +A lightweight, secure, cloud-native ACP harness that bridges **Discord, Slack**, and any [Agent Client Protocol](https://github.com/anthropics/agent-protocol)-compatible coding CLI (Kiro CLI, Claude Code, Codex, Gemini, OpenCode, Copilot CLI, Hermes, etc.) over stdio JSON-RPC — delivering the next-generation development experience. **Telegram, LINE, Feishu/Lark, Google Chat**, and other webhook-based platforms are supported via the standalone [Custom Gateway](gateway/). 🪼 **Join our community!** Come say hi on Discord — we'd love to have you: **[🪼 OpenAB — Official](https://discord.gg/DmbhfDZjQS)** 🎉 ``` -┌──────────────┐ Gateway WS ┌──────────────┐ ACP stdio ┌──────────────┐ -│ Discord │◄─────────────►│ │──────────────►│ coding CLI │ -│ User │ │ openab │◄── JSON-RPC ──│ (acp mode) │ -├──────────────┤ Socket Mode │ (Rust) │ └──────────────┘ -│ Slack │◄─────────────►│ │ -│ User │ └──────┬───────┘ -├──────────────┤ │ WebSocket (outbound) -│ Telegram │◄──webhook──┐ │ -│ User │ │ │ -├──────────────┤ ▼ ▼ -│ LINE │◄──webhook──┌──────────────────┐ -│ User │ │ Custom Gateway │ +┌──────────────┐ Gateway WS ┌──────────────┐ ACP stdio ┌──────────────────┐ +│ Discord │◄─────────────►│ │──────────────►│ coding CLI │ +│ User │ │ openab │◄── JSON-RPC ──│ (acp mode) │ +├──────────────┤ Socket Mode │ (Rust) │ ├──────────────────┤ +│ Slack │◄─────────────►│ │ │ kiro-cli acp │ +│ User │ └──────┬───────┘ │ claude-agent-acp │ +├──────────────┤ │ WebSocket (outbound) │ codex-acp │ +│ Telegram │◄──webhook──┐ │ │ gemini --acp │ +│ User │ │ │ │ copilot --acp │ +├──────────────┤ ▼ ▼ │ hermes-acp │ +│ LINE │◄──webhook──┌──────────────────┐ │ opencode acp │ +│ User │ │ Custom Gateway │ └──────────────────┘ ├──────────────┤ │ (standalone) │ │ Feishu/Lark │◄───WS──────│ │ │ User │ │ │ @@ -38,7 +38,7 @@ A lightweight, secure, cloud-native ACP harness that bridges **Discord, Slack**, - **Multi-platform** — supports Discord and Slack, run one or both simultaneously - **Custom Gateway** — extend to Telegram, LINE, Feishu/Lark, Google Chat, MS Teams via standalone [gateway](gateway/) -- **Pluggable agent backend** — swap between Kiro CLI, Claude Code, Codex, Gemini, OpenCode, Copilot CLI via config +- **Pluggable agent backend** — swap between Kiro CLI, Claude Code, Codex, Gemini, OpenCode, Copilot CLI, Hermes via config - **@mention trigger** — mention the bot in an allowed channel to start a conversation - **Thread-based multi-turn** — auto-creates threads; no @mention needed for follow-ups - **Multi-agent collaboration** — bot-to-bot messaging for coordinated workflows ([docs/multi-agent.md](docs/multi-agent.md)) From 8f2fec35e989239ed90e7bb4aa1ec59b167c3a76 Mon Sep 17 00:00:00 2001 From: thepagent Date: Sat, 16 May 2026 02:27:18 -0400 Subject: [PATCH 16/16] docs(readme): fix diagram alignment --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index fc98d384..ae2079b3 100644 --- a/README.md +++ b/README.md @@ -15,8 +15,8 @@ A lightweight, secure, cloud-native ACP harness that bridges **Discord, Slack**, ├──────────────┤ Socket Mode │ (Rust) │ ├──────────────────┤ │ Slack │◄─────────────►│ │ │ kiro-cli acp │ │ User │ └──────┬───────┘ │ claude-agent-acp │ -├──────────────┤ │ WebSocket (outbound) │ codex-acp │ -│ Telegram │◄──webhook──┐ │ │ gemini --acp │ +├──────────────┤ │ WebSocket │ codex-acp │ +│ Telegram │◄──webhook──┐ │ (outbound) │ gemini --acp │ │ User │ │ │ │ copilot --acp │ ├──────────────┤ ▼ ▼ │ hermes-acp │ │ LINE │◄──webhook──┌──────────────────┐ │ opencode acp │