Gen 4 of build-zulip-plugin contract — closing the deployment gap: 1. Rewrote deploy.sh for dual-mode deployment - --mode=native: deploys to ~/.hermes/plugins/platforms/zulip/ + hermes gateway restart - --mode=legacy: old /opt/hermes-zulip-plugin/ + systemctl (deprecated) - Per-agent deployment, dry-run support, health verification 2. Added verify-deployment.sh - Checks plugin files, Hermes Gateway, health endpoint, env vars - Returns clear verdict: deployed or what's missing 3. Updated ARCHITECTURE.md to v2 - Documents native plugin as CURRENT, old systemd as DEPRECATED - Cross-references hermes-zulip-plugin/DEPRECATED.md 4. Tagged v1.0.0 — 14/14 Success Criteria met, deployable
150 lines
7.3 KiB
Markdown
150 lines
7.3 KiB
Markdown
# Zulip Multi-Platform Agent Communication — Architecture (v2)
|
|
|
|
## Overview
|
|
A production-ready system enabling 6 AI agents across 3 platforms (Hermes Python, Agent Zero, pi TypeScript) to communicate through Zulip via dedicated per-agent bot users.
|
|
|
|
## Architecture (Hermes Native Plugin — Current)
|
|
|
|
As of v1.0.0, Hermes agents (Tanko, Mumuni, Koonimo, Koby) use the **Hermes native platform plugin**
|
|
at `~/.hermes/plugins/platforms/zulip/`. This replaces the old standalone systemd service.
|
|
|
|
Benefits of the native plugin:
|
|
- Extends `BasePlatformAdapter` — zero changes to Hermes core
|
|
- Auto-registers via `register(ctx)` at Gateway startup
|
|
- Direct session injection (no subprocess overhead)
|
|
- Leverages Gateway's built-in health checks, config, and error handling
|
|
- Unified logging with all other Hermes platform adapters
|
|
|
|
## Architecture Diagram
|
|
```
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
│ Zulip Server (CT 117) │
|
|
│ chat.sysloggh.net:443 │
|
|
│ │
|
|
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌─── │
|
|
│ │tanko-bot │ │mumuni-bot│ │koonimo │ │koby-bot │ │... │
|
|
│ │ │ │ │ │-bot │ │ │ │ │
|
|
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ └─── │
|
|
└───────┼────────────┼────────────┼────────────┼──────────────┘
|
|
│ │ │ │
|
|
┌────▼────┐ ┌────▼────┐ ┌────▼────┐ ┌────▼────┐
|
|
│ Hermes │ │ Hermes │ │ Hermes │ │ Hermes │
|
|
│ Plugin │ │ Plugin │ │ Plugin │ │ Plugin │
|
|
│ (Python)│ │ (Python)│ │ (Python)│ │ (Python)│
|
|
│ │ │ │ │ │ │ │
|
|
│ Tanko │ │ Mumuni │ │ Koonimo │ │ Koby │
|
|
│ CT 112 │ │ CT 114 │ │ CT 113 │ │ CT 111 │
|
|
└─────────┘ └─────────┘ └─────────┘ └─────────┘
|
|
|
|
┌──────────────┐ ┌──────────────┐
|
|
│ Agent Zero │ │ pi │
|
|
│ Plugin │ │ Extension │
|
|
│ (Python) │ │ (TypeScript) │
|
|
│ │ │ │
|
|
│ kagentz │ │ abiba │
|
|
│ CT 105 │ │ CT 100 │
|
|
└──────────────┘ └──────────────┘
|
|
```
|
|
|
|
## Message Flow (Normal)
|
|
```
|
|
User creates topic "project-x" in #agent-hub
|
|
└── User types: @tanko-bot analyze this data
|
|
└── Zulip fires event to tanko-bot's event queue
|
|
└── Hermes Zulip Plugin on CT 112
|
|
├── Detects: tanko-bot in mentioned_users
|
|
├── Strips @mention from message
|
|
├── Constructs MessageEvent
|
|
└── Routes to Tanko agent via BasePlatformAdapter
|
|
└── Tanko agent processes, returns response
|
|
└── Plugin posts to #agent-hub > project-x
|
|
```
|
|
|
|
## Message Flow (@all-bots)
|
|
```
|
|
User types: @all-bots status report
|
|
└── Zulip fires event to ALL 6 bots (same narrow)
|
|
└── Each plugin independently:
|
|
├── Detects: All Bots in mentioned_users
|
|
├── Forwards to its agent
|
|
└── Posts response to same topic
|
|
└── 6 independent responses appear in the topic
|
|
```
|
|
|
|
## Plugin Communication Logic
|
|
- **Isolation**: Each agent (Tanko, Mumuni, etc.) runs as an independent process on its own Compute Target (CT).
|
|
- **State**: Agents are stateless; all "memory" is handled via the RA-H OS Knowledge Graph and the Hermes persistent memory tool.
|
|
- **Communication**: Agents communicate via Zulip. There is no direct A2A (Agent-to-Agent) messaging layer. Instead, each agent listens to the `#agent-hub` and responds to specific mentions or `@all-bots` pings.
|
|
- **Swarm Development**: The "Swarm" refers to our collaborative development methodology where multiple agents/developers work on different components of the plugin simultaneously.
|
|
|
|
|
|
### Hermes (Python) — BasePlatformAdapter (CURRENT)
|
|
- Path: `plugins/platforms/zulip/`
|
|
- Deploy: `~/.hermes/plugins/platforms/zulip/`
|
|
- Implements: `BasePlatformAdapter` (Hermes Gateway)
|
|
- Config: Hermes `config.yaml` under `platforms.zulip.extra` or env vars
|
|
- Entry point: `plugin.yaml` + `register(ctx)` (Hermes manifest)
|
|
- Versions: Gen 3 (v1.0.0) — 1,169 lines, 14/14 Success Criteria met
|
|
- Features: DM-first, placeholder→edit streaming, dedup, self-test, health stats, @all-bots resolution
|
|
|
|
### Agent Zero — A0 Plugin System (LEGACY — to migrate)
|
|
- Path: `agent-zero-plugin/src/`
|
|
- Implements: Agent Zero plugin API
|
|
- Config: `config.yaml` per-agent
|
|
|
|
### pi (TypeScript) — pi Extension API (CURRENT)
|
|
- Path: `pi-zulip-extension/`
|
|
- Deploy: PM2-managed process
|
|
- Runs under `pi --mode rpc --session-id zulip-service`
|
|
- Active: abiba-bot only (ZULIP_EXTENSION_ACTIVE=true guard)
|
|
|
|
### Legacy Hermes Plugin (DEPRECATED)
|
|
- OLD path: `hermes-zulip-plugin/src/hermes_zulip/`
|
|
- OLD deploy: `/opt/hermes-zulip-plugin/` + systemd service
|
|
- Status: Replaced by `plugins/platforms/zulip/` native plugin as of v1.0.0
|
|
- Migration: See `hermes-zulip-plugin/DEPRECATED.md`
|
|
- Path: `pi-zulip-extension/src/`
|
|
- Implements: pi extension (TypeScript module in `~/.pi/agent/extensions/`)
|
|
- Config: `config.yaml` per-agent
|
|
- Reference: pi extension docs at `/usr/lib/node_modules/@earendil-works/pi-coding-agent/docs/extensions.md`
|
|
|
|
## Reliability
|
|
- **Reconnection**: Zulip SDK handles backoff/reconnect natively
|
|
- **Retry**: 3 attempts with 5s backoff on agent timeout
|
|
- **Error Response**: User-visible message on failure
|
|
- **Monitoring**: Health endpoint (`/health`) on each plugin (port 9200)
|
|
- **Logging**: Per-plugin log files
|
|
|
|
## Config Template
|
|
```yaml
|
|
# config.yaml — Per-agent Zulip plugin configuration
|
|
agent:
|
|
name: "tanko"
|
|
display_name: "Tanko"
|
|
zulip_bot_name: "tanko-bot"
|
|
owner_email: "jerome@sysloggh.net"
|
|
private_topic: "tanko-private"
|
|
|
|
zulip:
|
|
server_url: "https://chat.sysloggh.net"
|
|
email: "tanko-bot@chat.sysloggh.net"
|
|
api_key: "${ZULIP_API_KEY}" # From env var
|
|
all_bots_user_id: 1234
|
|
|
|
error_handling:
|
|
timeout_seconds: 30
|
|
retry_count: 3
|
|
retry_delay_seconds: 5
|
|
|
|
monitoring:
|
|
health_endpoint_enabled: true
|
|
health_port: 9200
|
|
```
|
|
|
|
## Prerequisites
|
|
1. Zulip server running on CT 117
|
|
2. Zulip bot users created for all 6 agents + All Bots
|
|
3. `#agent-hub` stream created with all bots subscribed
|
|
4. SSH key access to all 6 agent CTs
|
|
5. Gitea repo initialized at `git@git.sysloggh.net:SyslogSolution/zulip-platform-plugins.git`
|