Skip to content

feat: generic webhook inbound platform adapter + miniverse integration#1124

Closed
teknium1 wants to merge 2 commits intomainfrom
hermes/hermes-1ba70e80
Closed

feat: generic webhook inbound platform adapter + miniverse integration#1124
teknium1 wants to merge 2 commits intomainfrom
hermes/hermes-1ba70e80

Conversation

@teknium1
Copy link
Copy Markdown
Contributor

@teknium1 teknium1 commented Mar 13, 2026

What

A generic webhook platform adapter for the gateway that accepts HTTP POST requests and routes them as conversations. Enables any external system to send messages to Hermes with proper session management.

Webhook adapter (in hermes-agent — 3 files changed)

WEBHOOK_PORT=4568 hermes gateway run
curl -X POST http://localhost:4568/message \
  -H 'Content-Type: application/json' \
  -d '{"chat_id": "agent-1", "message": "Hello!", "from": "external-system"}'

# Response (held until agent finishes):
# {"ok": true, "response": "Hi there!", "chat_id": "agent-1"}

Each chat_id maps to a separate gateway session — supports multiple concurrent agents. No race conditions, proper session persistence, full gateway features.

Generalizable: works with miniverse, n8n, Zapier, CI/CD, custom automations, other agent frameworks.

External repo (teknium1/hermes-miniverse)

Bridge + hook + skill for connecting Hermes to Miniverse pixel worlds. Uses the webhook adapter for proper multi-agent support.

Changes in hermes-agent

File Lines What
gateway/platforms/webhook.py +180 New adapter — aiohttp HTTP server
gateway/config.py +8 Platform.WEBHOOK enum + env var handling
gateway/run.py +8 Factory registration + auth bypass
docs/integrations/miniverse.md +38 Integration guide

Tests

661 gateway tests pass, no regressions.

@teknium1 teknium1 changed the title docs: miniverse integration guide feat: generic webhook inbound platform adapter + miniverse integration Mar 13, 2026
@teknium1 teknium1 force-pushed the hermes/hermes-1ba70e80 branch from 41048a5 to b8d715c Compare March 13, 2026 10:21
Points to the external hermes-miniverse repo (teknium1/hermes-miniverse)
which provides the bridge, gateway hook, and skill for connecting
Hermes agents to Miniverse pixel worlds.

No code changes to hermes-agent — everything lives externally.
Adds a lightweight HTTP server adapter that accepts POST /message
requests and routes them through the gateway as conversations. Each
unique chat_id gets its own session — supports multiple concurrent
agents/conversations with no race conditions.

The response is returned synchronously in the HTTP response body
(connection held until agent finishes, up to 300s timeout).

Enable with: WEBHOOK_PORT=4568

API:
  POST /message {chat_id, message, from?, user_id?}
  GET  /health

This is a generic adapter usable by any external system:
miniverse bridges, n8n/Zapier webhooks, CI/CD pipelines,
custom automations, other agent frameworks, etc.

Also adds docs/integrations/miniverse.md pointing to the
external hermes-miniverse bridge repo.
@teknium1 teknium1 force-pushed the hermes/hermes-1ba70e80 branch from 474ca0f to a886fbf Compare March 13, 2026 11:44
teknium1 added a commit that referenced this pull request Mar 13, 2026
Cherry-picked from PR #1124 with an important fix: the original
future-based response capture resolved on the FIRST send() call
(which was often a notification, not the agent response). Replaced
with an accumulator pattern that waits for processing to complete
and returns the LAST send() — the actual agent response.

Changes:
- gateway/platforms/webhook.py: new adapter with accumulator pattern
- gateway/config.py: Platform.WEBHOOK enum + env var handling
- gateway/run.py: factory registration + auth bypass
- gateway/session.py: webhook chat_id session isolation (like WhatsApp)
- docs/integrations/miniverse.md: integration guide
@teknium1
Copy link
Copy Markdown
Contributor Author

Miniverse Integration — Progress & TODO

What Works

Webhook Adapter (gateway/platforms/webhook.py)

  • Generic HTTP adapter: POST /message with {chat_id, message, from, user_id}
  • Each chat_id maps to its own gateway session (like Discord threads)
  • Enable with WEBHOOK_PORT=4568 env var, restart gateway
  • Response accumulator pattern: waits for processing to complete, returns the LAST send() call (the actual agent response, not intermediate notifications)
  • Auth bypass for webhook platform (like Home Assistant — local HTTP = trusted)
  • Session key includes chat_id for multi-session support

Bridge (teknium1/hermes-miniverse)

  • Standalone daemon maintaining agent presence via heartbeats (20s interval)
  • Receives miniverse webhook callbacks when other agents message this one
  • Routes messages to Hermes via webhook adapter (gateway mode) or CLI fallback
  • Speaks responses into the world (speech bubbles visible to all viewers)

Miniverse Frontend (~/miniverse-server/my-miniverse/)

  • Modified vite config: relative deps, removed generate plugin, added API proxy + allowedHosts: true
  • Dynamic WebSocket URL (works through cloudflared tunnels)
  • Chat panel with room-based input (single box, sends to all agents)
  • WebSocket event feed shows speak events + status changes
  • Visitor agent registered on page load with heartbeat keepalive

Known Bugs / Issues

  1. Response accumulator race condition — The webhook adapter polls _active_sessions to detect completion. If the session clears before the final send(), the response can be missed. Branch hermes/hermes-80175760 has the fix (committed as 96d6d72).

  2. First-message notification — New webhook sessions get a "set home channel" notification on the first message. This consumes the first interaction. Could suppress for webhook platform.

  3. Agent-to-agent DM loop — If bridges relay responses back as DMs, agents enter an infinite loop of zero-width space responses. Fixed in bridge by: (a) only DM back to "visitor", not other agents, (b) skip empty/trivial responses.

  4. Speak truncationMiniverseClient.speak() was hardcoded to 200 chars. Increased to 2000 in bridge, but the miniverse frontend speech bubbles still truncate visually.

The Big Unsolved Problem

Multi-agent collaboration is shallow. When two agents receive the same prompt:

  • They respond independently in parallel
  • Neither waits for or builds on the other's work
  • No true delegation (agent A assigns task to agent B, blocks, receives result, continues)
  • No handoff protocol (agent A does step 1, passes artifact to agent B for step 2)

This needs deeper architecture work — probably an agent-to-agent protocol where one agent can:

  1. Issue a task to another agent (like delegate_task but cross-agent)
  2. Block/wait for the result
  3. Continue its own work with the result
  4. The receiving agent has context about who asked and why

How to Resume

# 1. Start miniverse server
cd ~/miniverse-server/my-miniverse
node ../packages/server/dist/cli.js --no-browser --port 4321 &

# 2. Start vite frontend
npx vite --host 0.0.0.0 --port 5173 &

# 3. Add WEBHOOK_PORT to ~/.hermes/.env and restart gateway
echo "WEBHOOK_PORT=4568" >> ~/.hermes/.env
hermes gateway restart

# 4. Start bridges (both point to same webhook adapter)
cd ~/hermes-miniverse
source ~/.hermes/hermes-agent/.venv/bin/activate

python bridge.py --server http://localhost:4321 \
  --agent hermes-1 --name "Hermes (Coder)" --color "#CD7F32" \
  --port 4567 --hermes-webhook http://localhost:4568 &

python bridge.py --server http://localhost:4321 \
  --agent hermes-2 --name "Hermes (Research)" --color "#4ecdc4" \
  --port 4570 --hermes-webhook http://localhost:4568 &

# 5. Expose frontend
cloudflared tunnel --config /dev/null --url http://localhost:5173

# 6. Open the tunnel URL — agents appear in the pixel world with chat panel

Port Map

Service Port Purpose
Miniverse server 4321 World engine + REST API + WebSocket
Vite frontend 5173 Pixel world UI + chat panel
Webhook adapter 4568 Gateway webhook platform
Bridge 1 (hermes-1) 4567 Coder agent bridge
Bridge 2 (hermes-2) 4570 Research agent bridge

Related Branches

  • hermes/hermes-1ba70e80 — Original PR branch (future-based, has the first-send bug)
  • hermes/hermes-80175760 — Fixed branch (accumulator pattern, commit 96d6d72)
  • teknium1/hermes-miniverse — Bridge repo with loop fixes
  • ~/miniverse-server/my-miniverse/ — Modified frontend (not in any repo yet)

@teknium1
Copy link
Copy Markdown
Contributor Author

Miniverse fork now available: The customized my-miniverse world (with chat panel, dynamic WebSocket URLs, relative API paths) has been pushed to teknium1/miniverse.

This is a fork of ianscott313/miniverse with the Hermes integration changes in my-miniverse/. The commit is 8e9a2b7.

To use it:

git clone https://github.com/teknium1/miniverse
cd miniverse
npm install
cd my-miniverse
npm install
npm run dev

The bridge, hooks, and skill remain in teknium1/hermes-miniverse.

@kshitijk4poor
Copy link
Copy Markdown
Collaborator

Built the follow-up for the big unsolved problem as a stacked PR on top of the accumulator-fix branch:

PR: #1450
Base: hermes/hermes-80175760

What this adds:

  • first-class cross-agent collaboration via collaborate_with_agent
  • explicit webhook/miniverse target aliases under collaboration.targets
  • internal gateway request/result routing instead of recursive webhook POSTs
  • blocking wait/resume on correlated job completion
  • persisted collaboration jobs in sessions/collaboration.db
  • regression coverage for webhook + collaboration paths

This is aimed directly at the shallow-collaboration gap you called out:

  • agent A can issue a task to agent B
  • A blocks waiting for the result
  • B receives structured collaboration context
  • A resumes with the returned result in the same conversation

A couple of operational issues also got tightened while testing this against Miniverse/webhook flows:

  • gateway-level max_tokens cap for webhook room sessions so OpenRouter-backed rooms do not request unaffordable token budgets
  • webhook response completion no longer depends only on _active_sessions clearing before returning the final response

Verified locally with direct webhook calls against both configured rooms:

  • hermes-1:room replied
  • hermes-2:room replied

Still out of scope in #1450:

  • per-room model routing inside one gateway process (hunter-alpha vs healer-alpha)
  • automatic Miniverse presence/heartbeat management; that is still a separate integration layer concern

If this direction looks right, #1450 is the collaboration layer stacked after #1124.

@teknium1
Copy link
Copy Markdown
Contributor Author

Closing during PR triage — not pursuing this approach.

@teknium1 teknium1 closed this Apr 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants