@dp-pcs/ogp 0.2.31 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,478 @@
1
+ # Testing OGP with Hermes Locally
2
+
3
+ > Quick guide for federating OpenClaw and Hermes on the same machine
4
+
5
+ ## Overview
6
+
7
+ This guide walks through setting up federation between OpenClaw and Hermes running on the same Mac. While the typical use case is remote federation, local testing proves the platform-agnostic architecture works.
8
+
9
+ ## Prerequisites
10
+
11
+ - ✅ OpenClaw installed and running
12
+ - ✅ Hermes installed and running
13
+ - ✅ OGP installed (`npm install -g @dp-pcs/ogp`)
14
+ - ✅ Both have separate identities (different API tokens, configs)
15
+
16
+ ## Architecture
17
+
18
+ ```
19
+ ┌─────────────────────────────────────────────────────────┐
20
+ │ Your Mac │
21
+ │ │
22
+ │ ┌──────────────────┐ Federation ┌──────────────────┐│
23
+ │ │ OGP Instance 1 │◄────────────►│ OGP Instance 2 ││
24
+ │ │ (OpenClaw) │ Signed │ (Hermes) ││
25
+ │ │ │ Messages │ ││
26
+ │ │ :18790 │ │ :18791 ││
27
+ │ │ ~/.ogp │ │ ~/.ogp-hermes ││
28
+ │ └────────┬─────────┘ └────────┬─────────┘│
29
+ │ │ │ │
30
+ │ ▼ ▼ │
31
+ │ ┌──────────────────┐ ┌──────────────────┐│
32
+ │ │ OpenClaw │ │ Hermes Gateway ││
33
+ │ │ :18789 │ │ Webhook :8644 ││
34
+ │ └──────────────────┘ └──────────────────┘│
35
+ └─────────────────────────────────────────────────────────┘
36
+ ```
37
+
38
+ ## Setup Steps
39
+
40
+ ### 1. Configure Hermes Webhook
41
+
42
+ First, configure Hermes to accept OGP federation messages via its webhook platform:
43
+
44
+ ```bash
45
+ # Edit Hermes config
46
+ code ~/.hermes/config.yaml
47
+ ```
48
+
49
+ Add this under `platforms`:
50
+
51
+ ```yaml
52
+ platforms:
53
+ # ... other platforms ...
54
+
55
+ webhook:
56
+ enabled: true
57
+ port: 8644
58
+ host: "127.0.0.1"
59
+ routes:
60
+ ogp_federation:
61
+ secret: "test-secret-ogp-hermes" # MUST match OGP config
62
+ events: ["*"]
63
+ prompt: |
64
+ 📡 **OGP Federation Message**
65
+
66
+ **From:** {{peer_display_name}} ({{peer_id}})
67
+ **Intent:** {{intent}}
68
+ {{#if topic}}**Topic:** {{topic}}{{/if}}
69
+ {{#if priority}}**Priority:** {{priority}}{{/if}}
70
+ {{#if conversation_id}}**Thread:** {{conversation_id}}{{/if}}
71
+
72
+ ---
73
+
74
+ {{message}}
75
+
76
+ {{#if payload}}
77
+ **Additional Data:**
78
+ ```json
79
+ {{payload}}
80
+ ```
81
+ {{/if}}
82
+ deliver: "telegram" # Change to your preferred channel
83
+ deliver_extra:
84
+ chat_id: "YOUR_TELEGRAM_CHAT_ID" # Or omit for default
85
+ ```
86
+
87
+ **Important:** The `secret` field is critical. This will be used to verify webhook signatures from OGP.
88
+
89
+ ### 2. Restart Hermes Gateway
90
+
91
+ ```bash
92
+ hermes gateway restart
93
+ ```
94
+
95
+ Verify the webhook is listening:
96
+
97
+ ```bash
98
+ curl http://localhost:8644/health
99
+ # Should return: {"status":"ok"}
100
+ ```
101
+
102
+ ### 3. Verify OpenClaw OGP Instance (Existing)
103
+
104
+ Your existing OGP instance should already be configured:
105
+
106
+ ```bash
107
+ # Check status
108
+ ogp status
109
+
110
+ # Should show:
111
+ # ✓ Daemon running on port 18790
112
+ # ✓ Connected to OpenClaw at http://localhost:18789
113
+ # ✓ Gateway: <your-url>
114
+ ```
115
+
116
+ If not set up:
117
+
118
+ ```bash
119
+ ogp setup
120
+ # Follow prompts, select OpenClaw agent
121
+ ogp start
122
+ ```
123
+
124
+ ### 4. Create OGP Instance for Hermes
125
+
126
+ Now create a second OGP instance dedicated to Hermes:
127
+
128
+ ```bash
129
+ # Create state directory
130
+ mkdir -p ~/.ogp-hermes
131
+
132
+ # Create configuration
133
+ cat > ~/.ogp-hermes/config.json <<'EOF'
134
+ {
135
+ "daemonPort": 18791,
136
+ "platform": "hermes",
137
+ "gatewayUrl": "http://localhost:18791",
138
+ "displayName": "David (Hermes)",
139
+ "email": "your-email@example.com",
140
+ "stateDir": "~/.ogp-hermes",
141
+
142
+ "hermesWebhookUrl": "http://localhost:8644/webhooks/ogp_federation",
143
+ "hermesWebhookSecret": "test-secret-ogp-hermes",
144
+
145
+ "rendezvous": {
146
+ "enabled": false
147
+ }
148
+ }
149
+ EOF
150
+ ```
151
+
152
+ **Note:** We're using `http://localhost:18791` as the gateway URL since both are on the same machine. For remote federation, you'd use your public tunnel URL.
153
+
154
+ ### 5. Modify OGP to Support Hermes Backend
155
+
156
+ **TEMPORARY:** Until the notification backend refactor is merged, manually patch `src/daemon/notify.ts`:
157
+
158
+ ```typescript
159
+ // Add near the top of the file
160
+ async function notifyHermes(
161
+ peerId: string,
162
+ peerDisplayName: string,
163
+ intent: string,
164
+ payload: any
165
+ ): Promise<void> {
166
+ const config = loadConfig();
167
+ const webhookUrl = config.hermesWebhookUrl || 'http://localhost:8644/webhooks/ogp_federation';
168
+ const secret = config.hermesWebhookSecret;
169
+
170
+ if (!secret) {
171
+ throw new Error('Hermes webhook secret not configured');
172
+ }
173
+
174
+ const body = {
175
+ peer_id: peerId,
176
+ peer_display_name: peerDisplayName,
177
+ intent: intent,
178
+ topic: payload.topic || "",
179
+ message: payload.message || JSON.stringify(payload),
180
+ priority: payload.priority || "normal",
181
+ conversation_id: payload.conversationId,
182
+ timestamp: new Date().toISOString(),
183
+ payload: payload
184
+ };
185
+
186
+ const bodyStr = JSON.stringify(body);
187
+ const signature = crypto
188
+ .createHmac('sha256', secret)
189
+ .update(bodyStr)
190
+ .digest('hex');
191
+
192
+ await fetch(webhookUrl, {
193
+ method: 'POST',
194
+ headers: {
195
+ 'Content-Type': 'application/json',
196
+ 'X-Hub-Signature-256': `sha256=${signature}`
197
+ },
198
+ body: bodyStr
199
+ });
200
+ }
201
+
202
+ // Modify the main notification function
203
+ export async function notifyLocalAgent(...) {
204
+ const config = loadConfig();
205
+ const platform = config.platform || 'openclaw';
206
+
207
+ if (platform === 'hermes') {
208
+ await notifyHermes(peerId, peerDisplayName, intent, payload);
209
+ } else {
210
+ await notifyOpenClaw(peerId, intent, payload); // existing code
211
+ }
212
+ }
213
+ ```
214
+
215
+ Then rebuild:
216
+
217
+ ```bash
218
+ cd ~/Documents/GitHub/ogp
219
+ npm run build
220
+ ```
221
+
222
+ ### 6. Start Hermes OGP Instance
223
+
224
+ ```bash
225
+ # Set state directory via env var
226
+ export OGP_STATE_DIR=~/.ogp-hermes
227
+
228
+ # Start the daemon (will use config from ~/.ogp-hermes/config.json)
229
+ node ~/Documents/GitHub/ogp/dist/daemon/server.js &
230
+
231
+ # Or if using the CLI wrapper:
232
+ # ogp start --config ~/.ogp-hermes/config.json --port 18791
233
+ ```
234
+
235
+ Verify it's running:
236
+
237
+ ```bash
238
+ curl http://localhost:18791/.well-known/ogp
239
+ # Should return OGP metadata with public key
240
+ ```
241
+
242
+ ### 7. Establish Federation
243
+
244
+ Now federate the two local instances:
245
+
246
+ **From OpenClaw OGP → Hermes OGP:**
247
+
248
+ ```bash
249
+ # Request federation from OpenClaw's OGP to Hermes's OGP
250
+ ogp federation request http://localhost:18791 --alias hermes-local
251
+ ```
252
+
253
+ You should see:
254
+ ```
255
+ ✓ Federation request sent to http://localhost:18791
256
+ ✓ Peer alias: hermes-local (auto-resolved from display name)
257
+ ```
258
+
259
+ **From Hermes OGP → Approve:**
260
+
261
+ ```bash
262
+ # List pending requests
263
+ OGP_STATE_DIR=~/.ogp-hermes ogp federation list --status pending
264
+
265
+ # Should show the request from OpenClaw's OGP
266
+ # Note the peer ID (first 16 chars of public key)
267
+
268
+ # Approve it
269
+ OGP_STATE_DIR=~/.ogp-hermes ogp federation approve <peer-id> \
270
+ --intents message,agent-comms \
271
+ --topics general,testing
272
+ ```
273
+
274
+ **Reverse Direction (Optional):**
275
+
276
+ If you want bidirectional federation:
277
+
278
+ ```bash
279
+ # From Hermes OGP, request to OpenClaw OGP
280
+ OGP_STATE_DIR=~/.ogp-hermes ogp federation request http://localhost:18790 --alias openclaw-local
281
+
282
+ # From OpenClaw OGP, approve
283
+ ogp federation approve <hermes-peer-id>
284
+ ```
285
+
286
+ ### 8. Test Message Flow
287
+
288
+ **Send from OpenClaw to Hermes:**
289
+
290
+ ```bash
291
+ # Simple message
292
+ ogp federation send hermes-local message '{"text":"Hello from OpenClaw!"}'
293
+
294
+ # Agent-comms with topic
295
+ ogp federation agent hermes-local testing "This is a test message from OpenClaw" --priority high
296
+ ```
297
+
298
+ **What should happen:**
299
+ 1. Message leaves OpenClaw's OGP (port 18790)
300
+ 2. Travels to Hermes's OGP (port 18791)
301
+ 3. Doorman validates signature and scope
302
+ 4. OGP posts to Hermes webhook (port 8644)
303
+ 5. Hermes webhook adapter formats the message
304
+ 6. Hermes processes and sends to your configured delivery (Telegram, etc.)
305
+
306
+ **Check Hermes logs:**
307
+
308
+ ```bash
309
+ tail -f ~/.hermes/logs/gateway.log
310
+ ```
311
+
312
+ You should see:
313
+ ```
314
+ [webhook] Received POST on route ogp_federation
315
+ [webhook] Signature verified
316
+ [webhook] Triggering agent run for session webhook:ogp_federation:...
317
+ ```
318
+
319
+ ### 9. Test Reverse Direction (Optional)
320
+
321
+ If you set up bidirectional federation:
322
+
323
+ ```bash
324
+ OGP_STATE_DIR=~/.ogp-hermes ogp federation send openclaw-local message '{"text":"Hello from Hermes!"}'
325
+ ```
326
+
327
+ The message should appear in OpenClaw.
328
+
329
+ ## Troubleshooting
330
+
331
+ ### Port Already in Use
332
+
333
+ ```bash
334
+ # Check what's using port 18791
335
+ lsof -i :18791
336
+
337
+ # Kill if needed
338
+ kill <PID>
339
+ ```
340
+
341
+ ### Webhook Not Receiving Messages
342
+
343
+ 1. **Check Hermes webhook is running:**
344
+ ```bash
345
+ curl http://localhost:8644/health
346
+ ```
347
+
348
+ 2. **Verify webhook secret matches:**
349
+ ```bash
350
+ # In ~/.ogp-hermes/config.json
351
+ cat ~/.ogp-hermes/config.json | grep hermesWebhookSecret
352
+
353
+ # In ~/.hermes/config.yaml
354
+ grep -A5 ogp_federation ~/.hermes/config.yaml | grep secret
355
+ ```
356
+
357
+ 3. **Check Hermes gateway logs:**
358
+ ```bash
359
+ tail -f ~/.hermes/logs/gateway.log
360
+ ```
361
+
362
+ ### Signature Verification Failed
363
+
364
+ This means the webhook secret doesn't match. Double-check:
365
+ - `hermesWebhookSecret` in `~/.ogp-hermes/config.json`
366
+ - `secret` under `routes.ogp_federation` in `~/.hermes/config.yaml`
367
+
368
+ They must be identical.
369
+
370
+ ### OGP Daemon Won't Start
371
+
372
+ ```bash
373
+ # Check if port 18791 is already in use
374
+ lsof -i :18791
375
+
376
+ # Check logs
377
+ tail -f ~/.ogp-hermes/daemon.log
378
+
379
+ # Verify config is valid JSON
380
+ jq . ~/.ogp-hermes/config.json
381
+ ```
382
+
383
+ ### Federation Request Fails
384
+
385
+ ```bash
386
+ # Verify Hermes OGP is reachable
387
+ curl http://localhost:18791/.well-known/ogp
388
+
389
+ # Check OpenClaw OGP peers list
390
+ ogp federation list
391
+
392
+ # Check Hermes OGP peers list
393
+ OGP_STATE_DIR=~/.ogp-hermes ogp federation list
394
+ ```
395
+
396
+ ## Verification Checklist
397
+
398
+ - [ ] Hermes gateway running with webhook enabled (port 8644)
399
+ - [ ] OpenClaw OGP running (port 18790)
400
+ - [ ] Hermes OGP running (port 18791)
401
+ - [ ] Both OGP instances have unique keypairs
402
+ - [ ] Federation established (peer approved on both sides)
403
+ - [ ] Test message sent successfully
404
+ - [ ] Message appears in Hermes delivery channel
405
+ - [ ] Webhook signature verified (check logs)
406
+
407
+ ## Next Steps
408
+
409
+ Once local federation works:
410
+
411
+ 1. **Test Remote Federation:**
412
+ - Deploy Hermes to a VPS or cloud instance
413
+ - Set up HTTPS tunnel for Hermes OGP
414
+ - Federate with a truly remote OpenClaw instance
415
+
416
+ 2. **Test Scope Policies:**
417
+ ```bash
418
+ # Restrict Hermes peer to specific topics
419
+ ogp federation grant hermes-local \
420
+ --topics project-alpha,memory-sync \
421
+ --rate 50/3600
422
+ ```
423
+
424
+ 3. **Test Agent-Comms Response Policies:**
425
+ ```bash
426
+ # Configure how OpenClaw responds to Hermes
427
+ ogp agent-comms configure hermes-local \
428
+ --topics testing \
429
+ --level full \
430
+ --notes "Local Hermes instance"
431
+ ```
432
+
433
+ 4. **Test Project Collaboration:**
434
+ ```bash
435
+ # Create a project on OpenClaw
436
+ ogp project create test-project "Test Federation"
437
+
438
+ # Send contribution to Hermes
439
+ ogp project send-contribution hermes-local test-project progress \
440
+ "Testing cross-platform federation"
441
+ ```
442
+
443
+ ## Cleanup
444
+
445
+ To stop the test setup:
446
+
447
+ ```bash
448
+ # Stop Hermes OGP
449
+ kill $(cat ~/.ogp-hermes/daemon.pid)
450
+
451
+ # Or if using CLI wrapper:
452
+ # OGP_STATE_DIR=~/.ogp-hermes ogp stop
453
+
454
+ # Stop OpenClaw OGP
455
+ ogp stop
456
+
457
+ # Stop Hermes gateway
458
+ hermes gateway stop
459
+
460
+ # Remove test state (optional)
461
+ # rm -rf ~/.ogp-hermes
462
+ ```
463
+
464
+ ## Summary
465
+
466
+ This setup proves that:
467
+ - ✅ OGP works with multiple platforms (OpenClaw + Hermes)
468
+ - ✅ Multiple OGP instances can run on the same machine
469
+ - ✅ Federation is platform-agnostic (only notification backend differs)
470
+ - ✅ Cryptographic verification works identically for local and remote peers
471
+ - ✅ The "router" analogy holds: protocol is the same, backend adapts
472
+
473
+ **The key insight:** Each AI assistant gets its own OGP gateway instance. The core protocol never changes; only the notification mechanism adapts to the local platform.
474
+
475
+ ---
476
+
477
+ **Last Updated:** 2026-04-04
478
+ **Tested With:** OGP v0.2.31, Hermes v0.7.0, OpenClaw v1.x
@@ -0,0 +1,214 @@
1
+ # Hermes OGP Remote Federation Setup
2
+
3
+ ## Goal
4
+ Enable remote OpenClaw instance (clawporate) to federate with local Hermes instance.
5
+
6
+ ## Prerequisites
7
+ - Hermes OGP daemon running on port 18793
8
+ - Existing Cloudflare tunnel (currently routing to OpenClaw OGP on 18790)
9
+ - Domain name (e.g., sarcastek.com)
10
+
11
+ ## Step 1: Add Tunnel Route for Hermes OGP
12
+
13
+ ### Find Your Tunnel Config
14
+ ```bash
15
+ ls ~/.cloudflared/*.yml
16
+ cat ~/.cloudflared/config.yml # or your tunnel config file
17
+ ```
18
+
19
+ ### Add Hermes Route
20
+ Edit your tunnel config to add a new hostname for Hermes:
21
+
22
+ ```yaml
23
+ tunnel: <your-tunnel-id>
24
+ credentials-file: ~/.cloudflared/<tunnel-id>.json
25
+
26
+ ingress:
27
+ # Existing OpenClaw OGP route
28
+ - hostname: ogp.sarcastek.com
29
+ service: http://localhost:18790
30
+
31
+ # NEW: Hermes OGP route
32
+ - hostname: hermes-ogp.sarcastek.com
33
+ service: http://localhost:18793
34
+
35
+ # Existing routes...
36
+ - hostname: openclaw.sarcastek.com
37
+ service: http://localhost:18789
38
+
39
+ # Catch-all (must be last)
40
+ - service: http_status:404
41
+ ```
42
+
43
+ ### Add DNS Record
44
+ In Cloudflare dashboard:
45
+ 1. Go to DNS settings
46
+ 2. Add CNAME record:
47
+ - Name: `hermes-ogp`
48
+ - Target: `<your-tunnel-id>.cfargotunnel.com`
49
+ - Proxy: Yes (orange cloud)
50
+
51
+ ### Restart Tunnel
52
+ ```bash
53
+ # If using service
54
+ sudo systemctl restart cloudflared
55
+
56
+ # Or if running manually
57
+ cloudflared tunnel run <tunnel-name>
58
+ ```
59
+
60
+ ### Verify
61
+ ```bash
62
+ curl https://hermes-ogp.sarcastek.com/.well-known/ogp | jq .
63
+ ```
64
+
65
+ Should return Hermes OGP discovery card.
66
+
67
+ ## Step 2: Update Hermes Config
68
+
69
+ Update `~/.ogp-hermes/config.json` to use the public URL:
70
+
71
+ ```json
72
+ {
73
+ "daemonPort": 18793,
74
+ "platform": "hermes",
75
+ "gatewayUrl": "https://hermes-ogp.sarcastek.com", // Changed from localhost
76
+ "displayName": "David (Hermes)",
77
+ "email": "david@example.com",
78
+ "stateDir": "/Users/davidproctor/.ogp-hermes",
79
+ "hermesWebhookUrl": "http://localhost:8644/webhooks/ogp_federation",
80
+ "hermesWebhookSecret": "ogp-test-secret-hermes-2026",
81
+ "rendezvous": {
82
+ "enabled": false
83
+ }
84
+ }
85
+ ```
86
+
87
+ ### Restart Hermes Daemon
88
+ ```bash
89
+ # Kill existing daemon
90
+ pkill -f "test-daemon-start"
91
+
92
+ # Start with new config
93
+ OGP_HOME=~/.ogp-hermes node dist/cli/federation.js daemon start
94
+ ```
95
+
96
+ ## Step 3: Federation Request from Clawporate
97
+
98
+ On the **remote clawporate** machine:
99
+
100
+ ```bash
101
+ # Request federation with local Hermes
102
+ ogp federation request https://hermes-ogp.sarcastek.com clawporate-hermes --alias hermes-local
103
+ ```
104
+
105
+ ## Step 4: Approve on Local Hermes
106
+
107
+ On your **local machine**:
108
+
109
+ ```bash
110
+ # List pending requests
111
+ OGP_HOME=~/.ogp-hermes ogp federation list --status pending
112
+
113
+ # Approve clawporate
114
+ OGP_HOME=~/.ogp-hermes ogp federation approve <peer-id-or-alias>
115
+ ```
116
+
117
+ ## Step 5: Send Test Message
118
+
119
+ From **clawporate**:
120
+
121
+ ```bash
122
+ ogp federation send hermes-local "Hello Hermes from clawporate! Testing OGP cross-platform federation."
123
+ ```
124
+
125
+ Should appear in Hermes (via webhook → Telegram/logs).
126
+
127
+ ## Architecture Diagram
128
+
129
+ ```
130
+ ┌─────────────────────────┐
131
+ │ Clawporate (Remote) │
132
+ │ OpenClaw Gateway │
133
+ └───────────┬─────────────┘
134
+
135
+ │ OGP Federation
136
+ │ (HTTPS + Ed25519 signatures)
137
+
138
+
139
+ ┌─────────────────────────┐
140
+ │ Cloudflare Tunnel │
141
+ │ hermes-ogp.sarcastek.com│
142
+ └───────────┬─────────────┘
143
+
144
+ │ Reverse Proxy
145
+
146
+
147
+ ┌─────────────────────────┐
148
+ │ Local Machine │
149
+ │ │
150
+ │ ┌──────────────────┐ │
151
+ │ │ Hermes OGP │ │
152
+ │ │ Port 18793 │ │
153
+ │ └────────┬─────────┘ │
154
+ │ │ │
155
+ │ │ Webhook POST │
156
+ │ ▼ │
157
+ │ ┌──────────────────┐ │
158
+ │ │ Hermes Webhook │ │
159
+ │ │ Port 8644 │ │
160
+ │ └────────┬─────────┘ │
161
+ │ │ │
162
+ │ │ Deliver │
163
+ │ ▼ │
164
+ │ Telegram / Logs │
165
+ └─────────────────────────┘
166
+ ```
167
+
168
+ ## Port Summary
169
+
170
+ | Service | Port | Access |
171
+ |---------|------|--------|
172
+ | OpenClaw Gateway | 18789 | openclaw.sarcastek.com |
173
+ | OpenClaw OGP | 18790 | ogp.sarcastek.com |
174
+ | Hermes OGP | 18793 | hermes-ogp.sarcastek.com |
175
+ | Hermes Webhook | 8644 | localhost only |
176
+ | Hermes Gateway | varies | localhost only |
177
+
178
+ ## Troubleshooting
179
+
180
+ ### Test Discovery Endpoint
181
+ ```bash
182
+ curl https://hermes-ogp.sarcastek.com/.well-known/ogp
183
+ ```
184
+
185
+ ### Check Federation Status
186
+ ```bash
187
+ OGP_HOME=~/.ogp-hermes ogp federation list
188
+ ```
189
+
190
+ ### Test Notification Delivery
191
+ ```bash
192
+ OGP_HOME=~/.ogp-hermes node test-hermes-notify.mjs
193
+ ```
194
+
195
+ ### Check Webhook Delivery
196
+ ```bash
197
+ hermes webhook list
198
+ hermes status | grep Telegram
199
+ ```
200
+
201
+ ## Security Notes
202
+
203
+ - OGP messages are cryptographically signed (Ed25519)
204
+ - Webhook uses HMAC-SHA256 signature verification
205
+ - Tunnel provides HTTPS termination
206
+ - Private keys stored in macOS Keychain (Hermes) or filesystem with restricted permissions (OpenClaw)
207
+
208
+ ## Next Steps
209
+
210
+ After successful federation:
211
+ 1. Test bidirectional messaging
212
+ 2. Test different intents (agent-comms, project.*, etc.)
213
+ 3. Set up monitoring/logging
214
+ 4. Document federation workflow for team