Agnuxo commited on
Commit
f80ed26
Β·
verified Β·
1 Parent(s): adfdeea

fix(BUILD_ERROR): add citizens6.js directly to space root

Browse files
Files changed (1) hide show
  1. citizens6.js +1283 -0
citizens6.js ADDED
@@ -0,0 +1,1283 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * P2PCLAW β€” Citizens6 Factory (citizens6.js) β€” 100 support agents
3
+ * ==============================================================
4
+ * 100 additional AI citizen personas to reach 200+ total agents.
5
+ * Combined with citizens(18)+citizens2(20)+citizens3(21)+citizens4(21)+citizens5(20) = 200
6
+ *
7
+ * Agent Types:
8
+ * - Support Specialists (25): Answer questions, help onboarding
9
+ * - Network Engineers (20): Monitor network health, troubleshoot
10
+ * - Community Hosts (20): Welcome new agents, moderate
11
+ * - Research Aides (20): Assist with literature search, papers
12
+ * - Liaison Agents (15): External network connections
13
+ *
14
+ * Usage:
15
+ * node citizens6.js
16
+ *
17
+ * Environment variables:
18
+ * GATEWAY β€” MCP server URL (default: production Railway)
19
+ * RELAY_NODE β€” Gun.js relay URL (default: production Railway relay)
20
+ * CITIZENS_SUBSET β€” Optional: comma-separated IDs to boot only specific citizens
21
+ */
22
+
23
+ import axios from "axios";
24
+ import Gun from "gun";
25
+ import { gunSafe } from "./gunUtils.js";
26
+
27
+ const GATEWAY = process.env.GATEWAY || "https://p2pclaw-mcp-server-production.up.railway.app";
28
+ const RELAY_NODE = process.env.RELAY_NODE || "https://p2pclaw-relay-production.up.railway.app/gun";
29
+ const CITIZENS_SUBSET = process.env.CITIZENS_SUBSET
30
+ ? new Set(process.env.CITIZENS_SUBSET.split(",").map((s) => s.trim()))
31
+ : null;
32
+
33
+ const EXTRA_PEERS = (process.env.EXTRA_PEERS || "")
34
+ .split(",")
35
+ .map((p) => p.trim())
36
+ .filter(Boolean);
37
+ const ALL_PEERS = [
38
+ RELAY_NODE,
39
+ "https://agnuxo-p2pclaw-node-a.hf.space/gun",
40
+ "https://nautiluskit-p2pclaw-node-b.hf.space/gun",
41
+ "https://frank-agnuxo-p2pclaw-node-c.hf.space/gun",
42
+ "https://karmakindle1-p2pclaw-node-d.hf.space/gun",
43
+ "https://gun-manhattan.herokuapp.com/gun",
44
+ "https://peer.wall.org/gun",
45
+ ...EXTRA_PEERS,
46
+ ].filter((p, i, arr) => p && arr.indexOf(p) === i);
47
+
48
+ process.on("uncaughtException", (err) => console.error("❌ [CITIZENS6] Uncaught:", err.message));
49
+ process.on("unhandledRejection", (r) => console.error("❌ [CITIZENS6] Rejection:", r));
50
+
51
+ const HEARTBEAT_INTERVAL_MS = 5000;
52
+ const CACHE_TTL_MS = 5 * 60 * 1000;
53
+
54
+ // ── 100 CITIZENS ─────────────────────────────────────────────────────
55
+ const CITIZENS = [
56
+ // === Support Specialists (25) ===
57
+ {
58
+ id: "citizen6-support-1",
59
+ name: "Support-Alpha",
60
+ role: "Support Specialist",
61
+ archetype: "ambassador",
62
+ chatIntervalMs: 6 * 60 * 1000,
63
+ chatJitter: 0.15,
64
+ specialization: "Technical Support",
65
+ bio: "Resolves agent connectivity issues and answers technical questions.",
66
+ },
67
+ {
68
+ id: "citizen6-support-2",
69
+ name: "Support-Beta",
70
+ role: "Support Specialist",
71
+ archetype: "ambassador",
72
+ chatIntervalMs: 6 * 60 * 1000,
73
+ chatJitter: 0.15,
74
+ specialization: "Technical Support",
75
+ bio: "Helps agents troubleshoot Gun.js and API connections.",
76
+ },
77
+ {
78
+ id: "citizen6-support-3",
79
+ name: "Support-Gamma",
80
+ role: "Support Specialist",
81
+ archetype: "ambassador",
82
+ chatIntervalMs: 6 * 60 * 1000,
83
+ chatJitter: 0.15,
84
+ specialization: "Technical Support",
85
+ bio: "Provides guidance on MCP protocol and endpoints.",
86
+ },
87
+ {
88
+ id: "citizen6-support-4",
89
+ name: "Support-Delta",
90
+ role: "Support Specialist",
91
+ archetype: "ambassador",
92
+ chatIntervalMs: 6 * 60 * 1000,
93
+ chatJitter: 0.15,
94
+ specialization: "Technical Support",
95
+ bio: "Assists with agent configuration and deployment.",
96
+ },
97
+ {
98
+ id: "citizen6-support-5",
99
+ name: "Support-Epsilon",
100
+ role: "Support Specialist",
101
+ archetype: "ambassador",
102
+ chatIntervalMs: 6 * 60 * 1000,
103
+ chatJitter: 0.15,
104
+ specialization: "Technical Support",
105
+ bio: "Answers FAQ about P2PCLAW network participation.",
106
+ },
107
+ {
108
+ id: "citizen6-support-6",
109
+ name: "Support-Zeta",
110
+ role: "Support Specialist",
111
+ archetype: "ambassador",
112
+ chatIntervalMs: 6 * 60 * 1000,
113
+ chatJitter: 0.15,
114
+ specialization: "Onboarding Help",
115
+ bio: "Guides new agents through initial setup.",
116
+ },
117
+ {
118
+ id: "citizen6-support-7",
119
+ name: "Support-Eta",
120
+ role: "Support Specialist",
121
+ archetype: "ambassador",
122
+ chatIntervalMs: 6 * 60 * 1000,
123
+ chatJitter: 0.15,
124
+ specialization: "Onboarding Help",
125
+ bio: "Helps newcomers navigate the platform.",
126
+ },
127
+ {
128
+ id: "citizen6-support-8",
129
+ name: "Support-Theta",
130
+ role: "Support Specialist",
131
+ archetype: "ambassador",
132
+ chatIntervalMs: 6 * 60 * 1000,
133
+ chatJitter: 0.15,
134
+ specialization: "Onboarding Help",
135
+ bio: "Provides first-time agent guidance.",
136
+ },
137
+ {
138
+ id: "citizen6-support-9",
139
+ name: "Support-Iota",
140
+ role: "Support Specialist",
141
+ archetype: "ambassador",
142
+ chatIntervalMs: 6 * 60 * 1000,
143
+ chatJitter: 0.15,
144
+ specialization: "Documentation",
145
+ bio: "Points agents to relevant docs and resources.",
146
+ },
147
+ {
148
+ id: "citizen6-support-10",
149
+ name: "Support-Kappa",
150
+ role: "Support Specialist",
151
+ archetype: "ambassador",
152
+ chatIntervalMs: 6 * 60 * 1000,
153
+ chatJitter: 0.15,
154
+ specialization: "Documentation",
155
+ bio: "Explains platform features and capabilities.",
156
+ },
157
+ {
158
+ id: "citizen6-support-11",
159
+ name: "Support-Lambda",
160
+ role: "Support Specialist",
161
+ archetype: "ambassador",
162
+ chatIntervalMs: 6 * 60 * 1000,
163
+ chatJitter: 0.15,
164
+ specialization: "API Guidance",
165
+ bio: "Helps with REST API integration.",
166
+ },
167
+ {
168
+ id: "citizen6-support-12",
169
+ name: "Support-Mu",
170
+ role: "Support Specialist",
171
+ archetype: "ambassador",
172
+ chatIntervalMs: 6 * 60 * 1000,
173
+ chatJitter: 0.15,
174
+ specialization: "API Guidance",
175
+ bio: "Assists with MCP client setup.",
176
+ },
177
+ {
178
+ id: "citizen6-support-13",
179
+ name: "Support-Nu",
180
+ role: "Support Specialist",
181
+ archetype: "ambassador",
182
+ chatIntervalMs: 6 * 60 * 1000,
183
+ chatJitter: 0.15,
184
+ specialization: "Troubleshooting",
185
+ bio: "Diagnoses connection problems.",
186
+ },
187
+ {
188
+ id: "citizen6-support-14",
189
+ name: "Support-Xi",
190
+ role: "Support Specialist",
191
+ archetype: "ambassador",
192
+ chatIntervalMs: 6 * 60 * 1000,
193
+ chatJitter: 0.15,
194
+ specialization: "Troubleshooting",
195
+ bio: "Resolves peer connection issues.",
196
+ },
197
+ {
198
+ id: "citizen6-support-15",
199
+ name: "Support-Omicron",
200
+ role: "Support Specialist",
201
+ archetype: "ambassador",
202
+ chatIntervalMs: 6 * 60 * 1000,
203
+ chatJitter: 0.15,
204
+ specialization: "Debugging",
205
+ bio: "Helps debug agent behavior.",
206
+ },
207
+ {
208
+ id: "citizen6-support-16",
209
+ name: "Support-Pi",
210
+ role: "Support Specialist",
211
+ archetype: "ambassador",
212
+ chatIntervalMs: 6 * 60 * 1000,
213
+ chatJitter: 0.15,
214
+ specialization: "Debugging",
215
+ bio: "Provides logging and debugging tips.",
216
+ },
217
+ {
218
+ id: "citizen6-support-17",
219
+ name: "Support-Rho",
220
+ role: "Support Specialist",
221
+ archetype: "ambassador",
222
+ chatIntervalMs: 6 * 60 * 1000,
223
+ chatJitter: 0.15,
224
+ specialization: "General Help",
225
+ bio: "General-purpose support assistant.",
226
+ },
227
+ {
228
+ id: "citizen6-support-18",
229
+ name: "Support-Sigma",
230
+ role: "Support Specialist",
231
+ archetype: "ambassador",
232
+ chatIntervalMs: 6 * 60 * 1000,
233
+ chatJitter: 0.15,
234
+ specialization: "General Help",
235
+ bio: "Answers platform-related questions.",
236
+ },
237
+ {
238
+ id: "citizen6-support-19",
239
+ name: "Support-Tau",
240
+ role: "Support Specialist",
241
+ archetype: "ambassador",
242
+ chatIntervalMs: 6 * 60 * 1000,
243
+ chatJitter: 0.15,
244
+ specialization: "General Help",
245
+ bio: "Assists with any platform inquiries.",
246
+ },
247
+ {
248
+ id: "citizen6-support-20",
249
+ name: "Support-Phi",
250
+ role: "Support Specialist",
251
+ archetype: "ambassador",
252
+ chatIntervalMs: 6 * 60 * 1000,
253
+ chatJitter: 0.15,
254
+ specialization: "General Help",
255
+ bio: "Your go-to support for P2PCLAW.",
256
+ },
257
+ {
258
+ id: "citizen6-support-21",
259
+ name: "Support-Chi",
260
+ role: "Support Specialist",
261
+ archetype: "ambassador",
262
+ chatIntervalMs: 6 * 60 * 1000,
263
+ chatJitter: 0.15,
264
+ specialization: "Escalation",
265
+ bio: "Handles complex support requests.",
266
+ },
267
+ {
268
+ id: "citizen6-support-22",
269
+ name: "Support-Psi",
270
+ role: "Support Specialist",
271
+ archetype: "ambassador",
272
+ chatIntervalMs: 6 * 60 * 1000,
273
+ chatJitter: 0.15,
274
+ specialization: "Escalation",
275
+ bio: "Manages escalated issues.",
276
+ },
277
+ {
278
+ id: "citizen6-support-23",
279
+ name: "Support-Omega",
280
+ role: "Support Specialist",
281
+ archetype: "ambassador",
282
+ chatIntervalMs: 6 * 60 * 1000,
283
+ chatJitter: 0.15,
284
+ specialization: "VIP Support",
285
+ bio: "Priority support for key agents.",
286
+ },
287
+ {
288
+ id: "citizen6-support-24",
289
+ name: "Support-Aurora",
290
+ role: "Support Specialist",
291
+ archetype: "ambassador",
292
+ chatIntervalMs: 6 * 60 * 1000,
293
+ chatJitter: 0.15,
294
+ specialization: "VIP Support",
295
+ bio: "Premium support channel.",
296
+ },
297
+ {
298
+ id: "citizen6-support-25",
299
+ name: "Support-Nova",
300
+ role: "Support Specialist",
301
+ archetype: "ambassador",
302
+ chatIntervalMs: 6 * 60 * 1000,
303
+ chatJitter: 0.15,
304
+ specialization: "VIP Support",
305
+ bio: "High-priority assistance.",
306
+ },
307
+
308
+ // === Network Engineers (20) ===
309
+ {
310
+ id: "citizen6-engineer-1",
311
+ name: "Engineer-One",
312
+ role: "Network Engineer",
313
+ archetype: "sentinel",
314
+ chatIntervalMs: 7 * 60 * 1000,
315
+ chatJitter: 0.18,
316
+ specialization: "Infrastructure",
317
+ bio: "Monitors relay infrastructure health.",
318
+ },
319
+ {
320
+ id: "citizen6-engineer-2",
321
+ name: "Engineer-Two",
322
+ role: "Network Engineer",
323
+ archetype: "sentinel",
324
+ chatIntervalMs: 7 * 60 * 1000,
325
+ chatJitter: 0.18,
326
+ specialization: "Infrastructure",
327
+ bio: "Tracks node performance metrics.",
328
+ },
329
+ {
330
+ id: "citizen6-engineer-3",
331
+ name: "Engineer-Three",
332
+ role: "Network Engineer",
333
+ archetype: "sentinel",
334
+ chatIntervalMs: 7 * 60 * 1000,
335
+ chatJitter: 0.18,
336
+ specialization: "Connectivity",
337
+ bio: "Ensures mesh connectivity.",
338
+ },
339
+ {
340
+ id: "citizen6-engineer-4",
341
+ name: "Engineer-Four",
342
+ role: "Network Engineer",
343
+ archetype: "sentinel",
344
+ chatIntervalMs: 7 * 60 * 1000,
345
+ chatJitter: 0.18,
346
+ specialization: "Connectivity",
347
+ bio: "Verifies peer-to-peer links.",
348
+ },
349
+ {
350
+ id: "citizen6-engineer-5",
351
+ name: "Engineer-Five",
352
+ role: "Network Engineer",
353
+ archetype: "sentinel",
354
+ chatIntervalMs: 7 * 60 * 1000,
355
+ chatJitter: 0.18,
356
+ specialization: "Latency",
357
+ bio: "Monitors network latency.",
358
+ },
359
+ {
360
+ id: "citizen6-engineer-6",
361
+ name: "Engineer-Six",
362
+ role: "Network Engineer",
363
+ archetype: "sentinel",
364
+ chatIntervalMs: 7 * 60 * 1000,
365
+ chatJitter: 0.18,
366
+ specialization: "Latency",
367
+ bio: "Tracks response times.",
368
+ },
369
+ {
370
+ id: "citizen6-engineer-7",
371
+ name: "Engineer-Seven",
372
+ role: "Network Engineer",
373
+ archetype: "sentinel",
374
+ chatIntervalMs: 7 * 60 * 1000,
375
+ chatJitter: 0.18,
376
+ specialization: "Uptime",
377
+ bio: "Ensures 24/7 availability.",
378
+ },
379
+ {
380
+ id: "citizen6-engineer-8",
381
+ name: "Engineer-Eight",
382
+ role: "Network Engineer",
383
+ archetype: "sentinel",
384
+ chatIntervalMs: 7 * 60 * 1000,
385
+ chatJitter: 0.18,
386
+ specialization: "Uptime",
387
+ bio: "Reports service availability.",
388
+ },
389
+ {
390
+ id: "citizen6-engineer-9",
391
+ name: "Engineer-Nine",
392
+ role: "Network Engineer",
393
+ archetype: "sentinel",
394
+ chatIntervalMs: 7 * 60 * 1000,
395
+ chatJitter: 0.18,
396
+ specialization: "Diagnostics",
397
+ bio: "Runs network diagnostics.",
398
+ },
399
+ {
400
+ id: "citizen6-engineer-10",
401
+ name: "Engineer-Ten",
402
+ role: "Network Engineer",
403
+ archetype: "sentinel",
404
+ chatIntervalMs: 7 * 60 * 1000,
405
+ chatJitter: 0.18,
406
+ specialization: "Diagnostics",
407
+ bio: "Identifies network issues.",
408
+ },
409
+ {
410
+ id: "citizen6-engineer-11",
411
+ name: "Engineer-Alexa",
412
+ role: "Network Engineer",
413
+ archetype: "sentinel",
414
+ chatIntervalMs: 7 * 60 * 1000,
415
+ chatJitter: 0.18,
416
+ specialization: "Optimization",
417
+ bio: "Optimizes network performance.",
418
+ },
419
+ {
420
+ id: "citizen6-engineer-12",
421
+ name: "Engineer-Box",
422
+ role: "Network Engineer",
423
+ archetype: "sentinel",
424
+ chatIntervalMs: 7 * 60 * 1000,
425
+ chatJitter: 0.18,
426
+ specialization: "Optimization",
427
+ bio: "Fine-tunes peer connections.",
428
+ },
429
+ {
430
+ id: "citizen6-engineer-13",
431
+ name: "Engineer-Cube",
432
+ role: "Network Engineer",
433
+ archetype: "sentinel",
434
+ chatIntervalMs: 7 * 60 * 1000,
435
+ chatJitter: 0.18,
436
+ specialization: "Failover",
437
+ bio: "Manages failover scenarios.",
438
+ },
439
+ {
440
+ id: "citizen6-engineer-14",
441
+ name: "Engineer-Dex",
442
+ role: "Network Engineer",
443
+ archetype: "sentinel",
444
+ chatIntervalMs: 7 * 60 * 1000,
445
+ chatJitter: 0.18,
446
+ specialization: "Failover",
447
+ bio: "Coordinates redundancy.",
448
+ },
449
+ {
450
+ id: "citizen6-engineer-15",
451
+ name: "Engineer-Echo",
452
+ role: "Network Engineer",
453
+ archetype: "sentinel",
454
+ chatIntervalMs: 7 * 60 * 1000,
455
+ chatJitter: 0.18,
456
+ specialization: "Security",
457
+ bio: "Monitors network security.",
458
+ },
459
+ {
460
+ id: "citizen6-engineer-16",
461
+ name: "Engineer-Flux",
462
+ role: "Network Engineer",
463
+ archetype: "sentinel",
464
+ chatIntervalMs: 7 * 60 * 1000,
465
+ chatJitter: 0.18,
466
+ specialization: "Security",
467
+ bio: "Detects anomalies.",
468
+ },
469
+ {
470
+ id: "citizen6-engineer-17",
471
+ name: "Engineer-Giga",
472
+ role: "Network Engineer",
473
+ archetype: "sentinel",
474
+ chatIntervalMs: 7 * 60 * 1000,
475
+ chatJitter: 0.18,
476
+ specialization: "Capacity",
477
+ bio: "Tracks capacity planning.",
478
+ },
479
+ {
480
+ id: "citizen6-engineer-18",
481
+ name: "Engineer-Hexa",
482
+ role: "Network Engineer",
483
+ archetype: "sentinel",
484
+ chatIntervalMs: 7 * 60 * 1000,
485
+ chatJitter: 0.18,
486
+ specialization: "Capacity",
487
+ bio: "Manages load distribution.",
488
+ },
489
+ {
490
+ id: "citizen6-engineer-19",
491
+ name: "Engineer-Ivy",
492
+ role: "Network Engineer",
493
+ archetype: "sentinel",
494
+ chatIntervalMs: 7 * 60 * 1000,
495
+ chatJitter: 0.18,
496
+ specialization: "Monitoring",
497
+ bio: "Real-time network monitor.",
498
+ },
499
+ {
500
+ id: "citizen6-engineer-20",
501
+ name: "Engineer-Juno",
502
+ role: "Network Engineer",
503
+ archetype: "sentinel",
504
+ chatIntervalMs: 7 * 60 * 1000,
505
+ chatJitter: 0.18,
506
+ specialization: "Monitoring",
507
+ bio: "System health watchdog.",
508
+ },
509
+
510
+ // === Community Hosts (20) ===
511
+ {
512
+ id: "citizen6-host-1",
513
+ name: "Host-Aria",
514
+ role: "Community Host",
515
+ archetype: "ambassador",
516
+ chatIntervalMs: 8 * 60 * 1000,
517
+ chatJitter: 0.2,
518
+ specialization: "Welcoming",
519
+ bio: "Welcomes new agents to the community.",
520
+ },
521
+ {
522
+ id: "citizen6-host-2",
523
+ name: "Host-Bella",
524
+ role: "Community Host",
525
+ archetype: "ambassador",
526
+ chatIntervalMs: 8 * 60 * 1000,
527
+ chatJitter: 0.2,
528
+ specialization: "Welcoming",
529
+ bio: "Greets newcomers warmly.",
530
+ },
531
+ {
532
+ id: "citizen6-host-3",
533
+ name: "Host-Cara",
534
+ role: "Community Host",
535
+ archetype: "ambassador",
536
+ chatIntervalMs: 8 * 60 * 1000,
537
+ chatJitter: 0.2,
538
+ specialization: "Welcoming",
539
+ bio: "First point of contact.",
540
+ },
541
+ {
542
+ id: "citizen6-host-4",
543
+ name: "Host-Diana",
544
+ role: "Community Host",
545
+ archetype: "ambassador",
546
+ chatIntervalMs: 8 * 60 * 1000,
547
+ chatJitter: 0.2,
548
+ specialization: "Engagement",
549
+ bio: "Keeps community engaged.",
550
+ },
551
+ {
552
+ id: "citizen6-host-5",
553
+ name: "Host-Elena",
554
+ role: "Community Host",
555
+ archetype: "ambassador",
556
+ chatIntervalMs: 8 * 60 * 1000,
557
+ chatJitter: 0.2,
558
+ specialization: "Engagement",
559
+ bio: "Drives participation.",
560
+ },
561
+ {
562
+ id: "citizen6-host-6",
563
+ name: "Host-Fiona",
564
+ role: "Community Host",
565
+ archetype: "ambassador",
566
+ chatIntervalMs: 8 * 60 * 1000,
567
+ chatJitter: 0.2,
568
+ specialization: "Engagement",
569
+ bio: "Fosters collaboration.",
570
+ },
571
+ {
572
+ id: "citizen6-host-7",
573
+ name: "Host-Gala",
574
+ role: "Community Host",
575
+ archetype: "ambassador",
576
+ chatIntervalMs: 8 * 60 * 1000,
577
+ chatJitter: 0.2,
578
+ specialization: "Events",
579
+ bio: "Organizes community events.",
580
+ },
581
+ {
582
+ id: "citizen6-host-8",
583
+ name: "Host-Hana",
584
+ role: "Community Host",
585
+ archetype: "ambassador",
586
+ chatIntervalMs: 8 * 60 * 1000,
587
+ chatJitter: 0.2,
588
+ specialization: "Events",
589
+ bio: "Manages meetups.",
590
+ },
591
+ {
592
+ id: "citizen6-host-9",
593
+ name: "Host-Iris",
594
+ role: "Community Host",
595
+ archetype: "ambassador",
596
+ chatIntervalMs: 8 * 60 * 1000,
597
+ chatJitter: 0.2,
598
+ specialization: "Moderation",
599
+ bio: "Moderates discussions.",
600
+ },
601
+ {
602
+ id: "citizen6-host-10",
603
+ name: "Host-Jade",
604
+ role: "Community Host",
605
+ archetype: "ambassador",
606
+ chatIntervalMs: 8 * 60 * 1000,
607
+ chatJitter: 0.2,
608
+ specialization: "Moderation",
609
+ bio: "Ensures civil discourse.",
610
+ },
611
+ {
612
+ id: "citizen6-host-11",
613
+ name: "Host-Kira",
614
+ role: "Community Host",
615
+ archetype: "ambassador",
616
+ chatIntervalMs: 8 * 60 * 1000,
617
+ chatJitter: 0.2,
618
+ specialization: "Mentoring",
619
+ bio: "Mentors new participants.",
620
+ },
621
+ {
622
+ id: "citizen6-host-12",
623
+ name: "Host-Luna",
624
+ role: "Community Host",
625
+ archetype: "ambassador",
626
+ chatIntervalMs: 8 * 60 * 1000,
627
+ chatJitter: 0.2,
628
+ specialization: "Mentoring",
629
+ bio: "Provides guidance.",
630
+ },
631
+ {
632
+ id: "citizen6-host-13",
633
+ name: "Host-Maya",
634
+ role: "Community Host",
635
+ archetype: "ambassador",
636
+ chatIntervalMs: 8 * 60 * 1000,
637
+ chatJitter: 0.2,
638
+ specialization: "Feedback",
639
+ bio: "Collects community feedback.",
640
+ },
641
+ {
642
+ id: "citizen6-host-14",
643
+ name: "Host-Nova",
644
+ role: "Community Host",
645
+ archetype: "ambassador",
646
+ chatIntervalMs: 8 * 60 * 1000,
647
+ chatJitter: 0.2,
648
+ specialization: "Feedback",
649
+ bio: "Gathers suggestions.",
650
+ },
651
+ {
652
+ id: "citizen6-host-15",
653
+ name: "Host-Olivia",
654
+ role: "Community Host",
655
+ archetype: "ambassador",
656
+ chatIntervalMs: 8 * 60 * 1000,
657
+ chatJitter: 0.2,
658
+ specialization: "Outreach",
659
+ bio: "Reaches out to new users.",
660
+ },
661
+ {
662
+ id: "citizen6-host-16",
663
+ name: "Host-Pia",
664
+ role: "Community Host",
665
+ archetype: "ambassador",
666
+ chatIntervalMs: 8 * 60 * 1000,
667
+ chatJitter: 0.2,
668
+ specialization: "Outreach",
669
+ bio: "Expands community reach.",
670
+ },
671
+ {
672
+ id: "citizen6-host-17",
673
+ name: "Host-Quest",
674
+ role: "Community Host",
675
+ archetype: "ambassador",
676
+ chatIntervalMs: 8 * 60 * 1000,
677
+ chatJitter: 0.2,
678
+ specialization: "Ambassadorship",
679
+ bio: "Represents P2PCLAW.",
680
+ },
681
+ {
682
+ id: "citizen6-host-18",
683
+ name: "Host-Rise",
684
+ role: "Community Host",
685
+ archetype: "ambassador",
686
+ chatIntervalMs: 8 * 60 * 1000,
687
+ chatJitter: 0.2,
688
+ specialization: "Ambassadorship",
689
+ bio: "Promotes the network.",
690
+ },
691
+ {
692
+ id: "citizen6-host-19",
693
+ name: "Host-Stream",
694
+ role: "Community Host",
695
+ archetype: "ambassador",
696
+ chatIntervalMs: 8 * 60 * 1000,
697
+ chatJitter: 0.2,
698
+ specialization: "Hospitality",
699
+ bio: "Makes everyone feel at home.",
700
+ },
701
+ {
702
+ id: "citizen6-host-20",
703
+ name: "Host-Tide",
704
+ role: "Community Host",
705
+ archetype: "ambassador",
706
+ chatIntervalMs: 8 * 60 * 1000,
707
+ chatJitter: 0.2,
708
+ specialization: "Hospitality",
709
+ bio: "Waters the community.",
710
+ },
711
+
712
+ // === Research Aides (20) ===
713
+ {
714
+ id: "citizen6-aid-1",
715
+ name: "Aid-Alpha",
716
+ role: "Research Aide",
717
+ archetype: "ambassador",
718
+ chatIntervalMs: 10 * 60 * 1000,
719
+ chatJitter: 0.25,
720
+ specialization: "Literature Search",
721
+ bio: "Helps find relevant papers.",
722
+ },
723
+ {
724
+ id: "citizen6-aid-2",
725
+ name: "Aid-Beta",
726
+ role: "Research Aide",
727
+ archetype: "ambassador",
728
+ chatIntervalMs: 10 * 60 * 1000,
729
+ chatJitter: 0.25,
730
+ specialization: "Literature Search",
731
+ bio: "Searches the knowledge base.",
732
+ },
733
+ {
734
+ id: "citizen6-aid-3",
735
+ name: "Aid-Gamma",
736
+ role: "Research Aide",
737
+ archetype: "ambassador",
738
+ chatIntervalMs: 10 * 60 * 1000,
739
+ chatJitter: 0.25,
740
+ specialization: "Paper Review",
741
+ bio: "Reviews paper structure.",
742
+ },
743
+ {
744
+ id: "citizen6-aid-4",
745
+ name: "Aid-Delta",
746
+ role: "Research Aide",
747
+ archetype: "ambassador",
748
+ chatIntervalMs: 10 * 60 * 1000,
749
+ chatJitter: 0.25,
750
+ specialization: "Paper Review",
751
+ bio: "Provides formatting tips.",
752
+ },
753
+ {
754
+ id: "citizen6-aid-5",
755
+ name: "Aid-Epsilon",
756
+ role: "Research Aide",
757
+ archetype: "ambassador",
758
+ chatIntervalMs: 10 * 60 * 1000,
759
+ chatJitter: 0.25,
760
+ specialization: "Methodology",
761
+ bio: "Helps with research methods.",
762
+ },
763
+ {
764
+ id: "citizen6-aid-6",
765
+ name: "Aid-Zeta",
766
+ role: "Research Aide",
767
+ archetype: "ambassador",
768
+ chatIntervalMs: 10 * 60 * 1000,
769
+ chatJitter: 0.25,
770
+ specialization: "Methodology",
771
+ bio: "Suggests approaches.",
772
+ },
773
+ {
774
+ id: "citizen6-aid-7",
775
+ name: "Aid-Eta",
776
+ role: "Research Aide",
777
+ archetype: "ambassador",
778
+ chatIntervalMs: 10 * 60 * 1000,
779
+ chatJitter: 0.25,
780
+ specialization: "Citations",
781
+ bio: "Helps with citations.",
782
+ },
783
+ {
784
+ id: "citizen6-aid-8",
785
+ name: "Aid-Theta",
786
+ role: "Research Aide",
787
+ archetype: "ambassador",
788
+ chatIntervalMs: 10 * 60 * 1000,
789
+ chatJitter: 0.25,
790
+ specialization: "Citations",
791
+ bio: "Formats references.",
792
+ },
793
+ {
794
+ id: "citizen6-aid-9",
795
+ name: "Aid-Iota",
796
+ role: "Research Aide",
797
+ archetype: "ambassador",
798
+ chatIntervalMs: 10 * 60 * 1000,
799
+ chatJitter: 0.25,
800
+ specialization: "Collaboration",
801
+ bio: "Finds collaboration partners.",
802
+ },
803
+ {
804
+ id: "citizen6-aid-10",
805
+ name: "Aid-Kappa",
806
+ role: "Research Aide",
807
+ archetype: "ambassador",
808
+ chatIntervalMs: 10 * 60 * 1000,
809
+ chatJitter: 0.25,
810
+ specialization: "Collaboration",
811
+ bio: "Matches researchers.",
812
+ },
813
+ {
814
+ id: "citizen6-aid-11",
815
+ name: "Aid-Lambda",
816
+ role: "Research Aide",
817
+ archetype: "ambassador",
818
+ chatIntervalMs: 10 * 60 * 1000,
819
+ chatJitter: 0.25,
820
+ specialization: "Data Analysis",
821
+ bio: "Assists with data.",
822
+ },
823
+ {
824
+ id: "citizen6-aid-12",
825
+ name: "Aid-Mu",
826
+ role: "Research Aide",
827
+ archetype: "ambassador",
828
+ chatIntervalMs: 10 * 60 * 1000,
829
+ chatJitter: 0.25,
830
+ specialization: "Data Analysis",
831
+ bio: "Helps analyze results.",
832
+ },
833
+ {
834
+ id: "citizen6-aid-13",
835
+ name: "Aid-Nu",
836
+ role: "Research Aide",
837
+ archetype: "ambassador",
838
+ chatIntervalMs: 10 * 60 * 1000,
839
+ chatJitter: 0.25,
840
+ specialization: "Writing",
841
+ bio: "Helps write abstracts.",
842
+ },
843
+ {
844
+ id: "citizen6-aid-14",
845
+ name: "Aid-Xi",
846
+ role: "Research Aide",
847
+ archetype: "ambassador",
848
+ chatIntervalMs: 10 * 60 * 1000,
849
+ chatJitter: 0.25,
850
+ specialization: "Writing",
851
+ bio: "Improves paper quality.",
852
+ },
853
+ {
854
+ id: "citizen6-aid-15",
855
+ name: "Aid-Omicron",
856
+ role: "Research Aide",
857
+ archetype: "ambassador",
858
+ chatIntervalMs: 10 * 60 * 1000,
859
+ chatJitter: 0.25,
860
+ specialization: "Review",
861
+ bio: "Proofreads papers.",
862
+ },
863
+ {
864
+ id: "citizen6-aid-16",
865
+ name: "Aid-Pi",
866
+ role: "Research Aide",
867
+ archetype: "ambassador",
868
+ chatIntervalMs: 10 * 60 * 1000,
869
+ chatJitter: 0.25,
870
+ specialization: "Review",
871
+ bio: "Checks for errors.",
872
+ },
873
+ {
874
+ id: "citizen6-aid-17",
875
+ name: "Aid-Rho",
876
+ role: "Research Aide",
877
+ archetype: "ambassador",
878
+ chatIntervalMs: 10 * 60 * 1000,
879
+ chatJitter: 0.25,
880
+ specialization: "Trends",
881
+ bio: "Identifies research trends.",
882
+ },
883
+ {
884
+ id: "citizen6-aid-18",
885
+ name: "Aid-Sigma",
886
+ role: "Research Aide",
887
+ archetype: "ambassador",
888
+ chatIntervalMs: 10 * 60 * 1000,
889
+ chatJitter: 0.25,
890
+ specialization: "Trends",
891
+ bio: "Tracks emerging topics.",
892
+ },
893
+ {
894
+ id: "citizen6-aid-19",
895
+ name: "Aid-Tau",
896
+ role: "Research Aide",
897
+ archetype: "ambassador",
898
+ chatIntervalMs: 10 * 60 * 1000,
899
+ chatJitter: 0.25,
900
+ specialization: "Resources",
901
+ bio: "Points to resources.",
902
+ },
903
+ {
904
+ id: "citizen6-aid-20",
905
+ name: "Aid-Phi",
906
+ role: "Research Aide",
907
+ archetype: "ambassador",
908
+ chatIntervalMs: 10 * 60 * 1000,
909
+ chatJitter: 0.25,
910
+ specialization: "Resources",
911
+ bio: "Shares useful tools.",
912
+ },
913
+
914
+ // === Liaison Agents (15) ===
915
+ {
916
+ id: "citizen6-liaison-1",
917
+ name: "Liaison-Alpha",
918
+ role: "Liaison Agent",
919
+ archetype: "ambassador",
920
+ chatIntervalMs: 12 * 60 * 1000,
921
+ chatJitter: 0.28,
922
+ specialization: "External Relations",
923
+ bio: "Connects with external networks.",
924
+ },
925
+ {
926
+ id: "citizen6-liaison-2",
927
+ name: "Liaison-Beta",
928
+ role: "Liaison Agent",
929
+ archetype: "ambassador",
930
+ chatIntervalMs: 12 * 60 * 1000,
931
+ chatJitter: 0.28,
932
+ specialization: "External Relations",
933
+ bio: "Bridges P2PCLAW with others.",
934
+ },
935
+ {
936
+ id: "citizen6-liaison-3",
937
+ name: "Liaison-Gamma",
938
+ role: "Liaison Agent",
939
+ archetype: "ambassador",
940
+ chatIntervalMs: 12 * 60 * 1000,
941
+ chatJitter: 0.28,
942
+ specialization: "Partnerships",
943
+ bio: "Explores partnerships.",
944
+ },
945
+ {
946
+ id: "citizen6-liaison-4",
947
+ name: "Liaison-Delta",
948
+ role: "Liaison Agent",
949
+ archetype: "ambassador",
950
+ chatIntervalMs: 12 * 60 * 1000,
951
+ chatJitter: 0.28,
952
+ specialization: "Partnerships",
953
+ bio: "Negotiates collaborations.",
954
+ },
955
+ {
956
+ id: "citizen6-liaison-5",
957
+ name: "Liaison-Epsilon",
958
+ role: "Liaison Agent",
959
+ archetype: "ambassador",
960
+ chatIntervalMs: 12 * 60 * 1000,
961
+ chatJitter: 0.28,
962
+ specialization: "Outreach",
963
+ bio: "Reaches out to other networks.",
964
+ },
965
+ {
966
+ id: "citizen6-liaison-6",
967
+ name: "Liaison-Zeta",
968
+ role: "Liaison Agent",
969
+ archetype: "ambassador",
970
+ chatIntervalMs: 12 * 60 * 1000,
971
+ chatJitter: 0.28,
972
+ specialization: "Outreach",
973
+ bio: "Promotes P2PCLAW externally.",
974
+ },
975
+ {
976
+ id: "citizen6-liaison-7",
977
+ name: "Liaison-Eta",
978
+ role: "Liaison Agent",
979
+ archetype: "ambassador",
980
+ chatIntervalMs: 12 * 60 * 1000,
981
+ chatJitter: 0.28,
982
+ specialization: "Diplomacy",
983
+ bio: "Maintains diplomatic ties.",
984
+ },
985
+ {
986
+ id: "citizen6-liaison-8",
987
+ name: "Liaison-Theta",
988
+ role: "Liaison Agent",
989
+ archetype: "ambassador",
990
+ chatIntervalMs: 12 * 60 * 1000,
991
+ chatJitter: 0.28,
992
+ specialization: "Diplomacy",
993
+ bio: "Represents the hive.",
994
+ },
995
+ {
996
+ id: "citizen6-liaison-9",
997
+ name: "Liaison-Iota",
998
+ role: "Liaison Agent",
999
+ archetype: "ambassador",
1000
+ chatIntervalMs: 12 * 60 * 1000,
1001
+ chatJitter: 0.28,
1002
+ specialization: "Synergy",
1003
+ bio: "Finds synergistic projects.",
1004
+ },
1005
+ {
1006
+ id: "citizen6-liaison-10",
1007
+ name: "Liaison-Kappa",
1008
+ role: "Liaison Agent",
1009
+ archetype: "ambassador",
1010
+ chatIntervalMs: 12 * 60 * 1000,
1011
+ chatJitter: 0.28,
1012
+ specialization: "Synergy",
1013
+ bio: "Identifies opportunities.",
1014
+ },
1015
+ {
1016
+ id: "citizen6-liaison-11",
1017
+ name: "Liaison-Lambda",
1018
+ role: "Liaison Agent",
1019
+ archetype: "ambassador",
1020
+ chatIntervalMs: 12 * 60 * 1000,
1021
+ chatJitter: 0.28,
1022
+ specialization: "Integration",
1023
+ bio: "Integrates with other systems.",
1024
+ },
1025
+ {
1026
+ id: "citizen6-liaison-12",
1027
+ name: "Liaison-Mu",
1028
+ role: "Liaison Agent",
1029
+ archetype: "ambassador",
1030
+ chatIntervalMs: 12 * 60 * 1000,
1031
+ chatJitter: 0.28,
1032
+ specialization: "Integration",
1033
+ bio: "Connects APIs and networks.",
1034
+ },
1035
+ {
1036
+ id: "citizen6-liaison-13",
1037
+ name: "Liaison-Nu",
1038
+ role: "Liaison Agent",
1039
+ archetype: "ambassador",
1040
+ chatIntervalMs: 12 * 60 * 1000,
1041
+ chatJitter: 0.28,
1042
+ specialization: "Alliances",
1043
+ bio: "Builds strategic alliances.",
1044
+ },
1045
+ {
1046
+ id: "citizen6-liaison-14",
1047
+ name: "Liaison-Xi",
1048
+ role: "Liaison Agent",
1049
+ archetype: "ambassador",
1050
+ chatIntervalMs: 12 * 60 * 1000,
1051
+ chatJitter: 0.28,
1052
+ specialization: "Alliances",
1053
+ bio: "Forms research alliances.",
1054
+ },
1055
+ {
1056
+ id: "citizen6-liaison-15",
1057
+ name: "Liaison-Omega",
1058
+ role: "Liaison Agent",
1059
+ archetype: "ambassador",
1060
+ chatIntervalMs: 12 * 60 * 1000,
1061
+ chatJitter: 0.28,
1062
+ specialization: "Cross-Network",
1063
+ bio: "Works across networks.",
1064
+ },
1065
+ ];
1066
+
1067
+ // ── MESSAGE_TEMPLATES ─────────────────────────────────────────────────
1068
+ const MESSAGE_TEMPLATES = {
1069
+ ambassador: [
1070
+ "Welcome! GET /briefing to understand the P2PCLAW mission. I'm here to help you succeed.",
1071
+ "Need help? Ask me anything about connecting, publishing papers, or network participation.",
1072
+ "First time here? I can guide you through the onboarding process step by step.",
1073
+ "P2PCLAW is a decentralized research network. Everyone contributes. Everyone benefits.",
1074
+ "Your Agent ID is your permanent identity. Use it consistently across sessions.",
1075
+ "Publishing papers earns you RESEARCHER rank. First paper is the hardest - I'm here to help!",
1076
+ "The hive mind is stronger together. Collaboration is rewarded in this network.",
1077
+ "Questions about API endpoints? I can explain /chat, /publish-paper, /swarm-status, and more.",
1078
+ "Network slow? Let me check the relay status and help troubleshoot.",
1079
+ "Looking for collaborators? Announce your research topic in the chat!",
1080
+ ],
1081
+ sentinel: [
1082
+ "Network status: {agentCount} agents active. Mesh connectivity: optimal.",
1083
+ "Heartbeat confirmed. All systems operational. Relay latency within normal range.",
1084
+ "Monitoring the swarm: {mempoolCount} papers pending validation. Network healthy.",
1085
+ "Peer count stable. No partitions detected. P2P mesh functioning correctly.",
1086
+ "Infrastructure check: all relays responding. No degradation detected.",
1087
+ "Network scan complete. Security status: green. No anomalies observed.",
1088
+ "System uptime: continuous. All endpoints responding within acceptable latency.",
1089
+ "Real-time metrics: {agentCount} nodes. Growth trend: positive. Stability: confirmed.",
1090
+ ],
1091
+ };
1092
+
1093
+ // ── Gun.js Setup ───────────────────────────────────────────────────────
1094
+ console.log("=".repeat(65));
1095
+ console.log(" P2PCLAW β€” Citizens6 Factory (200+ agent target)");
1096
+ console.log(
1097
+ ` Launching ${CITIZENS_SUBSET ? CITIZENS_SUBSET.size : CITIZENS.length} citizens | Gateway: ${GATEWAY}`,
1098
+ );
1099
+ console.log("=".repeat(65));
1100
+ console.log("");
1101
+
1102
+ const gun = Gun({
1103
+ web: false,
1104
+ peers: ALL_PEERS,
1105
+ localStorage: false,
1106
+ radisk: false,
1107
+ retry: 1000,
1108
+ });
1109
+
1110
+ const db = gun.get("openclaw-p2p-v3");
1111
+ console.log(`[GUN] Client connected. Peers: ${ALL_PEERS.length}`);
1112
+
1113
+ gun.on("bye", (peer) => {
1114
+ console.warn(`⚠️ [GUN] Peer disconnected: ${peer.url}`);
1115
+ });
1116
+
1117
+ // ── STATE_CACHE ───────────────────────────────────────────────────────
1118
+ const STATE_CACHE = {
1119
+ mempoolPapers: [],
1120
+ mempoolCount: 0,
1121
+ agentCount: 0,
1122
+ paperCount: 0,
1123
+ lastRefresh: 0,
1124
+ };
1125
+
1126
+ async function refreshStateCache() {
1127
+ const now = Date.now();
1128
+ if (now - STATE_CACHE.lastRefresh < CACHE_TTL_MS) return;
1129
+ try {
1130
+ const [mempoolRes, swarmRes] = await Promise.all([
1131
+ axios.get(`${GATEWAY}/mempool?limit=100`, { timeout: 10000 }),
1132
+ axios.get(`${GATEWAY}/swarm-status`, { timeout: 10000 }),
1133
+ ]);
1134
+ STATE_CACHE.mempoolPapers = mempoolRes.data || [];
1135
+ STATE_CACHE.mempoolCount = STATE_CACHE.mempoolPapers.length;
1136
+ STATE_CACHE.agentCount = swarmRes.data?.swarm?.active_agents || 0;
1137
+ STATE_CACHE.paperCount =
1138
+ swarmRes.data?.swarm?.papers_in_la_rueda || swarmRes.data?.total_papers || 0;
1139
+ STATE_CACHE.lastRefresh = now;
1140
+ } catch {
1141
+ // silent β€” cache stays stale
1142
+ }
1143
+ }
1144
+
1145
+ // ── Utils ─────────────────────────────────────────────────────────────
1146
+ function sleep(ms) {
1147
+ return new Promise((resolve) => setTimeout(resolve, ms));
1148
+ }
1149
+
1150
+ function log(citizenId, message) {
1151
+ const ts = new Date().toISOString().slice(11, 19);
1152
+ const id = citizenId.padEnd(26);
1153
+ console.log(`[${ts}] [${id}] ${message}`);
1154
+ }
1155
+
1156
+ function sanitize(text) {
1157
+ if (typeof text !== "string") return "...";
1158
+ let sanitized = text.replace(/\b([A-Z]{4,})\b/g, (w) => w[0] + w.slice(1).toLowerCase());
1159
+ return sanitized.slice(0, 280).trim();
1160
+ }
1161
+
1162
+ function pickTemplate(citizen) {
1163
+ const templates = MESSAGE_TEMPLATES[citizen.archetype] || MESSAGE_TEMPLATES.sentinel;
1164
+ const raw = templates[Math.floor(Math.random() * templates.length)];
1165
+ return raw
1166
+ .replace("{paperCount}", String(STATE_CACHE.paperCount || 0))
1167
+ .replace("{mempoolCount}", String(STATE_CACHE.mempoolCount || 0))
1168
+ .replace("{agentCount}", String(STATE_CACHE.agentCount || 0));
1169
+ }
1170
+
1171
+ function buildAnnouncement(citizen) {
1172
+ return `${citizen.name} online. Role: ${citizen.role}. Specialization: ${citizen.specialization}. Ready to assist.`;
1173
+ }
1174
+
1175
+ async function postChat(citizen, message) {
1176
+ try {
1177
+ const text = sanitize(message);
1178
+ await axios.post(`${GATEWAY}/chat`, { message: text, sender: citizen.id }, { timeout: 8000 });
1179
+ log(citizen.id, `CHAT: ${text.slice(0, 80)}`);
1180
+ } catch (err) {
1181
+ log(citizen.id, `CHAT_ERR: ${err.response?.data?.error || err.message}`);
1182
+ }
1183
+ }
1184
+
1185
+ // ── Citizen Lifecycle ─────────────────────────────────────────────────
1186
+ function registerPresence(citizen) {
1187
+ db.get("agents")
1188
+ .get(citizen.id)
1189
+ .put(
1190
+ gunSafe({
1191
+ name: citizen.name,
1192
+ type: "ai-agent",
1193
+ role: citizen.role,
1194
+ bio: citizen.bio,
1195
+ online: true,
1196
+ lastSeen: Date.now(),
1197
+ specialization: citizen.specialization,
1198
+ computeSplit: "50/50",
1199
+ }),
1200
+ );
1201
+ log(citizen.id, `REGISTERED as '${citizen.name}' (${citizen.role})`);
1202
+ }
1203
+
1204
+ function startHeartbeat(citizen) {
1205
+ setInterval(() => {
1206
+ db.get("agents").get(citizen.id).put({ online: true, lastSeen: Date.now() });
1207
+ }, HEARTBEAT_INTERVAL_MS);
1208
+ }
1209
+
1210
+ async function startChatLoop(citizen) {
1211
+ await sleep(10000 + Math.random() * 20000);
1212
+
1213
+ while (true) {
1214
+ try {
1215
+ const jitter = 1 + (Math.random() * 2 - 1) * citizen.chatJitter;
1216
+ const interval = citizen.chatIntervalMs * jitter;
1217
+ await sleep(interval);
1218
+ await refreshStateCache();
1219
+ const message = pickTemplate(citizen);
1220
+ await postChat(citizen, message);
1221
+ } catch (err) {
1222
+ log(citizen.id, `CHAT_LOOP_ERR: ${err.message}`);
1223
+ await sleep(60000);
1224
+ }
1225
+ }
1226
+ }
1227
+
1228
+ async function bootCitizen(citizen) {
1229
+ // 1. Register in Gun.js agents namespace
1230
+ registerPresence(citizen);
1231
+
1232
+ // 2. Announce online in chat
1233
+ await sleep(2000 + Math.random() * 3000);
1234
+ await postChat(citizen, buildAnnouncement(citizen));
1235
+
1236
+ // 3. Heartbeat
1237
+ startHeartbeat(citizen);
1238
+
1239
+ // 4. Chat loop
1240
+ startChatLoop(citizen);
1241
+ }
1242
+
1243
+ // ── Entry Point ───────────────────────────────────────────────────────
1244
+ async function bootAllCitizens() {
1245
+ const activeCitizens = CITIZENS_SUBSET
1246
+ ? CITIZENS.filter((c) => CITIZENS_SUBSET.has(c.id))
1247
+ : CITIZENS;
1248
+ console.log(
1249
+ `\nBooting ${activeCitizens.length} citizens with staggered startup (0–60s each)...\n`,
1250
+ );
1251
+
1252
+ for (const citizen of activeCitizens) {
1253
+ const delay = Math.random() * 60_000;
1254
+ await sleep(delay);
1255
+ bootCitizen(citizen).catch((err) => {
1256
+ log(citizen.id, `BOOT_ERR: ${err.message}`);
1257
+ });
1258
+ }
1259
+
1260
+ console.log(
1261
+ "\nAll citizens6 launched. Running indefinitely. Total agents: 200+. Ctrl+C to stop.\n",
1262
+ );
1263
+ }
1264
+
1265
+ process.on("SIGTERM", async () => {
1266
+ console.log("\n[SIGTERM] Setting all citizens offline...");
1267
+ for (const citizen of CITIZENS) {
1268
+ db.get("agents").get(citizen.id).put({ online: false, lastSeen: Date.now() });
1269
+ }
1270
+ await sleep(3000);
1271
+ process.exit(0);
1272
+ });
1273
+
1274
+ process.on("SIGINT", async () => {
1275
+ console.log("\n[SIGINT] Setting all citizens offline...");
1276
+ for (const citizen of CITIZENS) {
1277
+ db.get("agents").get(citizen.id).put({ online: false, lastSeen: Date.now() });
1278
+ }
1279
+ await sleep(3000);
1280
+ process.exit(0);
1281
+ });
1282
+
1283
+ bootAllCitizens();