fix: correct Abiba platform label (pi not openclaw), add plugin skeletons, shared config, fix health port
- Replace all 'openclaw' references with 'pi' (pi coding harness) - Fix Git remote URL in CONTEXT.md - Harmonize health port to 9200 across all docs - Add config.yaml.example with full schema - Add pi-zulip-extension skeleton (TypeScript, pi Extension API) - Add hermes-zulip-plugin skeleton (Python, BasePlatformAdapter) - Add agent-zero-plugin skeleton (Python, A0 plugin API) - Update ADR-007 with pi extension docs reference - Document private topic ACL v1 limitation in CONTEXT.md
This commit is contained in:
+41
-43
@@ -1,20 +1,18 @@
|
||||
# Zulip Multi-Platform Agent Communication — Architecture
|
||||
|
||||
## Overview
|
||||
|
||||
A production-ready system enabling 6 AI agents across 3 platforms (Hermes Python, Agent Zero, PI/openclaw TypeScript) to communicate through Zulip via dedicated per-agent bot users.
|
||||
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 Diagram
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ Zulip Server (CT 117) │
|
||||
│ chat.sysloggh.net:443 │
|
||||
│ Zulip Server (CT 117) │
|
||||
│ chat.sysloggh.net:443 │
|
||||
│ │
|
||||
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌─── │
|
||||
│ │tanko-bot │ │mumuni-bot│ │koonimo │ │koby-bot │ │... │
|
||||
│ │ │ │ │ │-bot │ │ │ │ │
|
||||
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ └─── │
|
||||
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌─── │
|
||||
│ │tanko-bot │ │mumuni-bot│ │koonimo │ │koby-bot │ │... │
|
||||
│ │ │ │ │ │-bot │ │ │ │ │
|
||||
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ └─── │
|
||||
└───────┼────────────┼────────────┼────────────┼──────────────┘
|
||||
│ │ │ │
|
||||
┌────▼────┐ ┌────▼────┐ ┌────▼────┐ ┌────▼────┐
|
||||
@@ -26,41 +24,39 @@ A production-ready system enabling 6 AI agents across 3 platforms (Hermes Python
|
||||
│ CT 112 │ │ CT 114 │ │ CT 113 │ │ CT 111 │
|
||||
└─────────┘ └─────────┘ └─────────┘ └─────────┘
|
||||
|
||||
┌──────────────┐ ┌──────────────┐
|
||||
│ Agent Zero │ │ PI/openclaw │
|
||||
│ Plugin │ │ Extension │
|
||||
│ (Python) │ │ (TypeScript) │
|
||||
│ │ │ │
|
||||
│ kagentz │ │ abiba │
|
||||
│ CT 105 │ │ CT 100 │
|
||||
└──────────────┘ └──────────────┘
|
||||
┌──────────────┐ ┌──────────────┐
|
||||
│ 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
|
||||
└── 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
|
||||
└── 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
|
||||
```
|
||||
|
||||
## Platform Plugin Contracts
|
||||
@@ -76,21 +72,20 @@ User types: @all-bots status report
|
||||
- Implements: Agent Zero plugin API
|
||||
- Config: `config.yaml` per-agent
|
||||
|
||||
### PI/openclaw (TypeScript) — openclaw Extension API
|
||||
- Path: `openclaw-zulip-extension/src/`
|
||||
- Implements: openclaw Extension
|
||||
### pi (TypeScript) — pi Extension API
|
||||
- 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
|
||||
- **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:
|
||||
@@ -106,16 +101,19 @@ zulip:
|
||||
api_key: "${ZULIP_API_KEY}" # From env var
|
||||
all_bots_user_id: 1234
|
||||
|
||||
agent:
|
||||
max_retries: 3
|
||||
error_handling:
|
||||
timeout_seconds: 30
|
||||
retry_count: 3
|
||||
retry_delay_seconds: 5
|
||||
health_port: 8080
|
||||
|
||||
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
|
||||
5. Gitea repo initialized at `git@git.sysloggh.net:SyslogSolution/zulip-platform-plugins.git`
|
||||
|
||||
+11
-11
@@ -6,7 +6,7 @@ This document captures the shared language and architectural invariants for the
|
||||
|
||||
| Term | Definition |
|
||||
|------|------------|
|
||||
| **Agent** | An AI agent operating on a platform (Hermes/Agent Zero/PI/openclaw) that can receive and respond to Zulip messages |
|
||||
| **Agent** | An AI agent operating on a platform (Hermes/Agent Zero/pi) that can receive and respond to Zulip messages |
|
||||
| **Adapter / Plugin** | A platform-native component that bridges Zulip events to the agent framework |
|
||||
| **@mention** | A Zulip mention (`@**Tanko Bot**`) that triggers the named agent to respond |
|
||||
| **@all-bots** | A dedicated Zulip bot user that, when @mentioned, triggers ALL agents across all platforms |
|
||||
@@ -15,10 +15,9 @@ This document captures the shared language and architectural invariants for the
|
||||
| **Owner** | The human user associated with an agent bot, stored in per-agent config |
|
||||
|
||||
## Naming Conventions
|
||||
|
||||
- Agent Zulip bot display names: lowercase, dash-separated, `-bot` suffix — e.g., `tanko-bot`, `mumuni-bot`
|
||||
- Agent Zulip bot emails: `<name>@chat.sysloggh.net` — e.g., `tanko-bot@chat.sysloggh.net`
|
||||
- Private topics: `<agent-name>-private` — e.g., `tanko-private`
|
||||
- Agent Zulip bot emails: `@chat.sysloggh.net` — e.g., `tanko-bot@chat.sysloggh.net`
|
||||
- Private topics: `{name}-private` — e.g., `tanko-private`
|
||||
- Owner privacy: agent should never expose owner name to other agents or users
|
||||
|
||||
## Agent Registry
|
||||
@@ -30,30 +29,31 @@ This document captures the shared language and architectural invariants for the
|
||||
| koonimo | Hermes (Python) | koonimo-bot | amdpve CT 113 | koonimo-private |
|
||||
| koby | Hermes (Python) | koby-bot | amdpve CT 111 | koby-private |
|
||||
| kagentz | Agent Zero | kagentz-bot | amdpve CT 105 | kagentz-private |
|
||||
| abiba | PI/openclaw (TypeScript) | abiba-bot | amdpve CT 100 | abiba-private |
|
||||
| abiba | pi (TypeScript) | abiba-bot | amdpve CT 100 | abiba-private |
|
||||
|
||||
## @all-bots Resolution
|
||||
|
||||
@all-bots refers to all 6 agents across all frameworks (Hermes, Agent Zero, PI/openclaw). When @all-bots is mentioned in any topic:
|
||||
|
||||
@all-bots refers to all 6 agents across all frameworks (Hermes, Agent Zero, pi). When @all-bots is mentioned in any topic:
|
||||
1. Each per-agent bot receives the event (since they all share `narrow: stream agent-hub`)
|
||||
2. Each bot checks: "Is `All Bots` in `mentioned_users`?"
|
||||
3. If yes, bot forwards the message to its agent
|
||||
4. @all-bots is a **dedicated Zulip bot user** with display name `All Bots` and email `all-bots@chat.sysloggh.net`
|
||||
|
||||
## Response Rules
|
||||
|
||||
- **Own topic**: Agent always responds (to its private topic)
|
||||
- **Collaboration topic** (any topic that isn't a private topic): Agent responds only when @mentioned
|
||||
- **@all-bots**: All agents respond
|
||||
- **Private topics**: Only the agent owner + bot are participants; bot enforces this
|
||||
- **Private topics**: Only the agent owner + bot are participants; bot enforces this via config owner_email matching
|
||||
|
||||
## Private Topic ACL (v1 — documented limitation)
|
||||
|
||||
In v1, private topic access is enforced by matching `sender_email == config.owner_email` on each message. **This is not cryptographically authenticated** — Zulip does not enforce sender identity. A user who knows the owner email can impersonate them. This is an acceptable limitation for v1 internal use. v2 should use Zulip invite-only stream permissions or shared-secret challenge-response.
|
||||
|
||||
## Monorepo Structure
|
||||
|
||||
All 3 platform plugins live in a single Gitea repository at `git@192.168.68.17:homelab/zulip-platform-plugins.git`
|
||||
All 3 platform plugins live in a single Gitea repository at `git@git.sysloggh.net:SyslogSolution/zulip-platform-plugins.git`
|
||||
|
||||
## Guardian Directives
|
||||
|
||||
- All destructive actions require user confirmation before execution
|
||||
- Plugin updates are version-controlled through Gitea
|
||||
- Config files are per-agent and pushed alongside code
|
||||
|
||||
@@ -3,13 +3,20 @@
|
||||
**Date**: 2026-04-28
|
||||
|
||||
### Decision
|
||||
Each platform uses its native plugin interface: Hermes `BasePlatformAdapter`, openclaw extension API, Agent Zero plugin system.
|
||||
|
||||
Each platform uses its native plugin interface: Hermes `BasePlatformAdapter`, pi extension API, Agent Zero plugin system.
|
||||
|
||||
### Context
|
||||
|
||||
Each platform has matured, battle-tested interfaces for receiving and sending messages. A unified A2A contract would add unnecessary abstraction and latency for local agent communication. Platform-native contracts are reliable, handle connection-state/retry automatically, and follow each platform's established patterns.
|
||||
|
||||
- **Hermes**: `BasePlatformAdapter` — Python, gateway-based, handles connection lifecycle
|
||||
- **pi**: Extension API — TypeScript modules in `~/.pi/agent/extensions/`, registers tools via `pi.registerTool()`, hooks lifecycle events. See pi docs at `/usr/lib/node_modules/@earendil-works/pi-coding-agent/docs/extensions.md`
|
||||
- **Agent Zero**: A0 plugin system — Python, agent-native plugin API
|
||||
|
||||
### Consequences
|
||||
|
||||
- Three separate plugin implementations
|
||||
- Each plugin leverages platform-specific reliability features
|
||||
- Plugin developers need familiarity with each platform
|
||||
- Cross-platform @all-bots still works because each bot processes the same Zulip event independently
|
||||
- Cross-platform @all-bots still works because each bot processes the same Zulip event independently
|
||||
|
||||
Reference in New Issue
Block a user