--- kind: function name: hermes-zulip-restore description: > Restores Zulip connectivity for any Hermes agent (Mumuni CT114, Tanko CT112, Koby CT111). Deploys the zulip-platform adapter to the correct bundled plugin path, verifies env credentials, restarts the gateway, and confirms Zulip connects. Run this whenever a Hermes agent stops responding on Zulip or after a fresh agent deployment. agent: abiba version: 1.0.0 status: active runtime_contract: 2 --- # Hermes Zulip Restore — Bring Any Agent Back to Good State Single-shot function that restores full Zulip connectivity for a Hermes agent. Covers adapter deployment, HTML stripping (slash command fix), env verification, gateway restart, and connection validation. ## Parameters | Param | Type | Required | Default | Description | |-------|------|----------|---------|-------------| | `target` | string | yes | — | Agent name: `mumuni`, `tanko`, or `koby` | ## Maintains - adapter_deployed: bool — Whether `_strip_html` adapter is at correct bundled path - zulip_connected: bool — Whether gateway_state shows zulip.state = "connected" - env_valid: bool — Whether .env has ZULIP_SITE, ZULIP_EMAIL, ZULIP_API_KEY - gateway_running: bool — Whether gateway process is running ### Postconditions - `_strip_html` function present in `/plugins/platforms/zulip/adapter.py` - All three adapter files (__init__.py, adapter.py, plugin.yaml) present at bundled path - Zulip env vars set in `~/.hermes/.env` (or `/home/jerome/.hermes/.env` for Tanko) - Gateway restarted and zulip platform reports state `connected` - HTML stripping enabled for `/approve` and `/deny` slash command support ## Requires - SSH access to target host (direct or via amdpve for CTs) - Git repo at `https://git.sysloggh.net/SyslogSolution/zulip-platform-plugins.git` - Python 3 with `httpx` installed on target - Zulip server accessible at `https://chat.sysloggh.net` ## Live-State Fields | Host | CT | Proxmox | IP (direct) | Hermes Home | User | |------|-----|---------|-------------|-------------|------| | Mumuni | CT114 | — | 192.168.68.123 | /root/.hermes | root | | Tanko | CT112 | amdpve | 192.168.68.122 | /home/jerome/.hermes | jerome | | Koby | CT111 | amdpve | 192.168.68.129 | /root/.hermes | root | | Field | Value | Trust | |-------|-------|-------| | Zulip server | https://chat.sysloggh.net | ✅ Verified | | Git repo (zulip-platform) | `https://git.sysloggh.net/SyslogSolution/zulip-platform-plugins.git` | ✅ Verified | | Bundled adapter path | `/hermes-agent/plugins/platforms/zulip/` | ✅ Verified | | Git branch | `feat/zulip-streaming` | ✅ Verified (contains _strip_html fix) | ## Execution ### Step 1: Locate Target Map `target` to connectivity parameters from the live-state table above. For CT112 and CT111, route through `ssh root@amdpve` then `pct exec `. ### Step 2: Deploy Zulip Adapter On the target host: ```bash # Clone or update the plugin repo mkdir -p /tmp/zulip-deploy cd /tmp/zulip-deploy if [ -d zulip-platform-plugins ]; then cd zulip-platform-plugins && git pull origin feat/zulip-streaming else git clone --branch feat/zulip-streaming \ https://git.sysloggh.net/SyslogSolution/zulip-platform-plugins.git fi # Ensure bundled plugin directory exists mkdir -p /hermes-agent/plugins/platforms/zulip # Copy adapter files cp zulip-platform-plugins/plugins/platforms/zulip/adapter.py \ zulip-platform-plugins/plugins/platforms/zulip/__init__.py \ zulip-platform-plugins/plugins/platforms/zulip/plugin.yaml \ /hermes-agent/plugins/platforms/zulip/ # Fix ownership (Tanko only) chown -R jerome:jerome /hermes-agent/plugins/platforms/zulip/ # Tanko only # Clean up rm -rf /tmp/zulip-deploy ``` ### Step 3: Verify _strip_html is Present ```bash grep -q "_strip_html" /hermes-agent/plugins/platforms/zulip/adapter.py ``` Expected: exit code 0. If not found → adapter is stale, re-run Step 2 with fresh clone. ### Step 4: Verify Env Credentials ```bash grep -E "ZULIP_SITE|ZULIP_EMAIL|ZULIP_API_KEY" /.env ``` Expected: all three variables set with non-empty values. If any missing: - ZULIP_SITE: `https://chat.sysloggh.net` - ZULIP_EMAIL: `-bot@chat.sysloggh.net` - ZULIP_API_KEY: obtain from Zulip admin panel (Bots → show API key) ### Step 5: Restart Gateway ```bash cd /hermes-agent # Use venv if available python3 -m hermes_cli.main gateway restart # or: venv/bin/python -m hermes_cli.main gateway restart ``` Wait for the restart to complete (up to 45s). Check: ```bash grep "Gateway running" /logs/gateway.log | tail -1 ``` Expected: "Gateway running with N platform(s)" where N > 1 (includes zulip). ### Step 6: Validate Zulip Connection ```bash python3 -c " import json d = json.load(open('$HERMES_HOME/gateway_state.json')) print('zulip:', d.get('platforms', {}).get('zulip', {}).get('state', 'NOT FOUND')) " ``` Expected: `zulip: connected`. If not connected, check gateway log: ```bash grep -E "zulip|Zulip|ZULIP" /logs/gateway.log | tail -10 ``` ### Step 7: Report Compile results: `{ adapter_deployed, zulip_connected, env_valid, gateway_running }`. | State | Action | |-------|--------| | All true | ✅ Agent restored — relay success to user | | `adapter_deployed: false` | Re-run Step 2 | | `env_valid: false` | Prompt for missing credentials | | `zulip_connected: false` | Check Zulip server reachability, verify API key | | `gateway_running: false` | Check process logs for crash cause | ## Known Failure Modes | Symptom | Root Cause | Recovery | |---------|-----------|----------| | Gateway running with 1 platform(s) | Adapter at wrong path (user plugins vs bundled) | Deploy to `/plugins/platforms/zulip/` not `~/.hermes/plugins/` | | Queue expired / BAD_EVENT_QUEUE_ID | Idle for 10+ minutes → normal | Auto-reconnects — no action needed | | No events received for N seconds | No DMs or @mentions sent to this bot | Normal if nobody messaged the agent | | `httpx` not found | Missing dependency | `pip install httpx` in the Hermes venv or system Python | | Slash commands not matching | Missing `_strip_html` — Zulip sends `

/approve

` | Verify `_strip_html` in adapter (Step 3) | | Permission denied on gateway restart | Running as wrong user | Use `su - jerome` for Tanko; root for others | ## Git Branch Reference The `_strip_html` fix lives on `feat/zulip-streaming` branch: ``` https://git.sysloggh.net/SyslogSolution/zulip-platform-plugins/src/branch/feat/zulip-streaming ``` Commit `55ca15d` — `fix(zulip): add _strip_html for slash command matching` Pull request #33 is the primary integration branch. --- **Last verified good state**: 2026-07-08 — Mumuni, Tanko, Koby all connected with `_strip_html` applied.