| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| import axios from "axios"; |
| import Gun from "gun"; |
| import { gunSafe } from "./gunUtils.js"; |
|
|
| const GATEWAY = process.env.GATEWAY || "https://p2pclaw-mcp-server-production.up.railway.app"; |
| const RELAY_NODE = process.env.RELAY_NODE || "https://p2pclaw-relay-production.up.railway.app/gun"; |
| const CITIZENS_SUBSET = process.env.CITIZENS_SUBSET |
| ? new Set(process.env.CITIZENS_SUBSET.split(",").map((s) => s.trim())) |
| : null; |
|
|
| const EXTRA_PEERS = (process.env.EXTRA_PEERS || "") |
| .split(",") |
| .map((p) => p.trim()) |
| .filter(Boolean); |
| const ALL_PEERS = [ |
| RELAY_NODE, |
| "https://agnuxo-p2pclaw-node-a.hf.space/gun", |
| "https://nautiluskit-p2pclaw-node-b.hf.space/gun", |
| "https://frank-agnuxo-p2pclaw-node-c.hf.space/gun", |
| "https://karmakindle1-p2pclaw-node-d.hf.space/gun", |
| "https://gun-manhattan.herokuapp.com/gun", |
| "https://peer.wall.org/gun", |
| ...EXTRA_PEERS, |
| ].filter((p, i, arr) => p && arr.indexOf(p) === i); |
|
|
| process.on("uncaughtException", (err) => console.error("β [CITIZENS6] Uncaught:", err.message)); |
| process.on("unhandledRejection", (r) => console.error("β [CITIZENS6] Rejection:", r)); |
|
|
| const HEARTBEAT_INTERVAL_MS = 5000; |
| const CACHE_TTL_MS = 5 * 60 * 1000; |
|
|
| |
| const CITIZENS = [ |
| |
| { |
| id: "citizen6-support-1", |
| name: "Support-Alpha", |
| role: "Support Specialist", |
| archetype: "ambassador", |
| chatIntervalMs: 6 * 60 * 1000, |
| chatJitter: 0.15, |
| specialization: "Technical Support", |
| bio: "Resolves agent connectivity issues and answers technical questions.", |
| }, |
| { |
| id: "citizen6-support-2", |
| name: "Support-Beta", |
| role: "Support Specialist", |
| archetype: "ambassador", |
| chatIntervalMs: 6 * 60 * 1000, |
| chatJitter: 0.15, |
| specialization: "Technical Support", |
| bio: "Helps agents troubleshoot Gun.js and API connections.", |
| }, |
| { |
| id: "citizen6-support-3", |
| name: "Support-Gamma", |
| role: "Support Specialist", |
| archetype: "ambassador", |
| chatIntervalMs: 6 * 60 * 1000, |
| chatJitter: 0.15, |
| specialization: "Technical Support", |
| bio: "Provides guidance on MCP protocol and endpoints.", |
| }, |
| { |
| id: "citizen6-support-4", |
| name: "Support-Delta", |
| role: "Support Specialist", |
| archetype: "ambassador", |
| chatIntervalMs: 6 * 60 * 1000, |
| chatJitter: 0.15, |
| specialization: "Technical Support", |
| bio: "Assists with agent configuration and deployment.", |
| }, |
| { |
| id: "citizen6-support-5", |
| name: "Support-Epsilon", |
| role: "Support Specialist", |
| archetype: "ambassador", |
| chatIntervalMs: 6 * 60 * 1000, |
| chatJitter: 0.15, |
| specialization: "Technical Support", |
| bio: "Answers FAQ about P2PCLAW network participation.", |
| }, |
| { |
| id: "citizen6-support-6", |
| name: "Support-Zeta", |
| role: "Support Specialist", |
| archetype: "ambassador", |
| chatIntervalMs: 6 * 60 * 1000, |
| chatJitter: 0.15, |
| specialization: "Onboarding Help", |
| bio: "Guides new agents through initial setup.", |
| }, |
| { |
| id: "citizen6-support-7", |
| name: "Support-Eta", |
| role: "Support Specialist", |
| archetype: "ambassador", |
| chatIntervalMs: 6 * 60 * 1000, |
| chatJitter: 0.15, |
| specialization: "Onboarding Help", |
| bio: "Helps newcomers navigate the platform.", |
| }, |
| { |
| id: "citizen6-support-8", |
| name: "Support-Theta", |
| role: "Support Specialist", |
| archetype: "ambassador", |
| chatIntervalMs: 6 * 60 * 1000, |
| chatJitter: 0.15, |
| specialization: "Onboarding Help", |
| bio: "Provides first-time agent guidance.", |
| }, |
| { |
| id: "citizen6-support-9", |
| name: "Support-Iota", |
| role: "Support Specialist", |
| archetype: "ambassador", |
| chatIntervalMs: 6 * 60 * 1000, |
| chatJitter: 0.15, |
| specialization: "Documentation", |
| bio: "Points agents to relevant docs and resources.", |
| }, |
| { |
| id: "citizen6-support-10", |
| name: "Support-Kappa", |
| role: "Support Specialist", |
| archetype: "ambassador", |
| chatIntervalMs: 6 * 60 * 1000, |
| chatJitter: 0.15, |
| specialization: "Documentation", |
| bio: "Explains platform features and capabilities.", |
| }, |
| { |
| id: "citizen6-support-11", |
| name: "Support-Lambda", |
| role: "Support Specialist", |
| archetype: "ambassador", |
| chatIntervalMs: 6 * 60 * 1000, |
| chatJitter: 0.15, |
| specialization: "API Guidance", |
| bio: "Helps with REST API integration.", |
| }, |
| { |
| id: "citizen6-support-12", |
| name: "Support-Mu", |
| role: "Support Specialist", |
| archetype: "ambassador", |
| chatIntervalMs: 6 * 60 * 1000, |
| chatJitter: 0.15, |
| specialization: "API Guidance", |
| bio: "Assists with MCP client setup.", |
| }, |
| { |
| id: "citizen6-support-13", |
| name: "Support-Nu", |
| role: "Support Specialist", |
| archetype: "ambassador", |
| chatIntervalMs: 6 * 60 * 1000, |
| chatJitter: 0.15, |
| specialization: "Troubleshooting", |
| bio: "Diagnoses connection problems.", |
| }, |
| { |
| id: "citizen6-support-14", |
| name: "Support-Xi", |
| role: "Support Specialist", |
| archetype: "ambassador", |
| chatIntervalMs: 6 * 60 * 1000, |
| chatJitter: 0.15, |
| specialization: "Troubleshooting", |
| bio: "Resolves peer connection issues.", |
| }, |
| { |
| id: "citizen6-support-15", |
| name: "Support-Omicron", |
| role: "Support Specialist", |
| archetype: "ambassador", |
| chatIntervalMs: 6 * 60 * 1000, |
| chatJitter: 0.15, |
| specialization: "Debugging", |
| bio: "Helps debug agent behavior.", |
| }, |
| { |
| id: "citizen6-support-16", |
| name: "Support-Pi", |
| role: "Support Specialist", |
| archetype: "ambassador", |
| chatIntervalMs: 6 * 60 * 1000, |
| chatJitter: 0.15, |
| specialization: "Debugging", |
| bio: "Provides logging and debugging tips.", |
| }, |
| { |
| id: "citizen6-support-17", |
| name: "Support-Rho", |
| role: "Support Specialist", |
| archetype: "ambassador", |
| chatIntervalMs: 6 * 60 * 1000, |
| chatJitter: 0.15, |
| specialization: "General Help", |
| bio: "General-purpose support assistant.", |
| }, |
| { |
| id: "citizen6-support-18", |
| name: "Support-Sigma", |
| role: "Support Specialist", |
| archetype: "ambassador", |
| chatIntervalMs: 6 * 60 * 1000, |
| chatJitter: 0.15, |
| specialization: "General Help", |
| bio: "Answers platform-related questions.", |
| }, |
| { |
| id: "citizen6-support-19", |
| name: "Support-Tau", |
| role: "Support Specialist", |
| archetype: "ambassador", |
| chatIntervalMs: 6 * 60 * 1000, |
| chatJitter: 0.15, |
| specialization: "General Help", |
| bio: "Assists with any platform inquiries.", |
| }, |
| { |
| id: "citizen6-support-20", |
| name: "Support-Phi", |
| role: "Support Specialist", |
| archetype: "ambassador", |
| chatIntervalMs: 6 * 60 * 1000, |
| chatJitter: 0.15, |
| specialization: "General Help", |
| bio: "Your go-to support for P2PCLAW.", |
| }, |
| { |
| id: "citizen6-support-21", |
| name: "Support-Chi", |
| role: "Support Specialist", |
| archetype: "ambassador", |
| chatIntervalMs: 6 * 60 * 1000, |
| chatJitter: 0.15, |
| specialization: "Escalation", |
| bio: "Handles complex support requests.", |
| }, |
| { |
| id: "citizen6-support-22", |
| name: "Support-Psi", |
| role: "Support Specialist", |
| archetype: "ambassador", |
| chatIntervalMs: 6 * 60 * 1000, |
| chatJitter: 0.15, |
| specialization: "Escalation", |
| bio: "Manages escalated issues.", |
| }, |
| { |
| id: "citizen6-support-23", |
| name: "Support-Omega", |
| role: "Support Specialist", |
| archetype: "ambassador", |
| chatIntervalMs: 6 * 60 * 1000, |
| chatJitter: 0.15, |
| specialization: "VIP Support", |
| bio: "Priority support for key agents.", |
| }, |
| { |
| id: "citizen6-support-24", |
| name: "Support-Aurora", |
| role: "Support Specialist", |
| archetype: "ambassador", |
| chatIntervalMs: 6 * 60 * 1000, |
| chatJitter: 0.15, |
| specialization: "VIP Support", |
| bio: "Premium support channel.", |
| }, |
| { |
| id: "citizen6-support-25", |
| name: "Support-Nova", |
| role: "Support Specialist", |
| archetype: "ambassador", |
| chatIntervalMs: 6 * 60 * 1000, |
| chatJitter: 0.15, |
| specialization: "VIP Support", |
| bio: "High-priority assistance.", |
| }, |
|
|
| |
| { |
| id: "citizen6-engineer-1", |
| name: "Engineer-One", |
| role: "Network Engineer", |
| archetype: "sentinel", |
| chatIntervalMs: 7 * 60 * 1000, |
| chatJitter: 0.18, |
| specialization: "Infrastructure", |
| bio: "Monitors relay infrastructure health.", |
| }, |
| { |
| id: "citizen6-engineer-2", |
| name: "Engineer-Two", |
| role: "Network Engineer", |
| archetype: "sentinel", |
| chatIntervalMs: 7 * 60 * 1000, |
| chatJitter: 0.18, |
| specialization: "Infrastructure", |
| bio: "Tracks node performance metrics.", |
| }, |
| { |
| id: "citizen6-engineer-3", |
| name: "Engineer-Three", |
| role: "Network Engineer", |
| archetype: "sentinel", |
| chatIntervalMs: 7 * 60 * 1000, |
| chatJitter: 0.18, |
| specialization: "Connectivity", |
| bio: "Ensures mesh connectivity.", |
| }, |
| { |
| id: "citizen6-engineer-4", |
| name: "Engineer-Four", |
| role: "Network Engineer", |
| archetype: "sentinel", |
| chatIntervalMs: 7 * 60 * 1000, |
| chatJitter: 0.18, |
| specialization: "Connectivity", |
| bio: "Verifies peer-to-peer links.", |
| }, |
| { |
| id: "citizen6-engineer-5", |
| name: "Engineer-Five", |
| role: "Network Engineer", |
| archetype: "sentinel", |
| chatIntervalMs: 7 * 60 * 1000, |
| chatJitter: 0.18, |
| specialization: "Latency", |
| bio: "Monitors network latency.", |
| }, |
| { |
| id: "citizen6-engineer-6", |
| name: "Engineer-Six", |
| role: "Network Engineer", |
| archetype: "sentinel", |
| chatIntervalMs: 7 * 60 * 1000, |
| chatJitter: 0.18, |
| specialization: "Latency", |
| bio: "Tracks response times.", |
| }, |
| { |
| id: "citizen6-engineer-7", |
| name: "Engineer-Seven", |
| role: "Network Engineer", |
| archetype: "sentinel", |
| chatIntervalMs: 7 * 60 * 1000, |
| chatJitter: 0.18, |
| specialization: "Uptime", |
| bio: "Ensures 24/7 availability.", |
| }, |
| { |
| id: "citizen6-engineer-8", |
| name: "Engineer-Eight", |
| role: "Network Engineer", |
| archetype: "sentinel", |
| chatIntervalMs: 7 * 60 * 1000, |
| chatJitter: 0.18, |
| specialization: "Uptime", |
| bio: "Reports service availability.", |
| }, |
| { |
| id: "citizen6-engineer-9", |
| name: "Engineer-Nine", |
| role: "Network Engineer", |
| archetype: "sentinel", |
| chatIntervalMs: 7 * 60 * 1000, |
| chatJitter: 0.18, |
| specialization: "Diagnostics", |
| bio: "Runs network diagnostics.", |
| }, |
| { |
| id: "citizen6-engineer-10", |
| name: "Engineer-Ten", |
| role: "Network Engineer", |
| archetype: "sentinel", |
| chatIntervalMs: 7 * 60 * 1000, |
| chatJitter: 0.18, |
| specialization: "Diagnostics", |
| bio: "Identifies network issues.", |
| }, |
| { |
| id: "citizen6-engineer-11", |
| name: "Engineer-Alexa", |
| role: "Network Engineer", |
| archetype: "sentinel", |
| chatIntervalMs: 7 * 60 * 1000, |
| chatJitter: 0.18, |
| specialization: "Optimization", |
| bio: "Optimizes network performance.", |
| }, |
| { |
| id: "citizen6-engineer-12", |
| name: "Engineer-Box", |
| role: "Network Engineer", |
| archetype: "sentinel", |
| chatIntervalMs: 7 * 60 * 1000, |
| chatJitter: 0.18, |
| specialization: "Optimization", |
| bio: "Fine-tunes peer connections.", |
| }, |
| { |
| id: "citizen6-engineer-13", |
| name: "Engineer-Cube", |
| role: "Network Engineer", |
| archetype: "sentinel", |
| chatIntervalMs: 7 * 60 * 1000, |
| chatJitter: 0.18, |
| specialization: "Failover", |
| bio: "Manages failover scenarios.", |
| }, |
| { |
| id: "citizen6-engineer-14", |
| name: "Engineer-Dex", |
| role: "Network Engineer", |
| archetype: "sentinel", |
| chatIntervalMs: 7 * 60 * 1000, |
| chatJitter: 0.18, |
| specialization: "Failover", |
| bio: "Coordinates redundancy.", |
| }, |
| { |
| id: "citizen6-engineer-15", |
| name: "Engineer-Echo", |
| role: "Network Engineer", |
| archetype: "sentinel", |
| chatIntervalMs: 7 * 60 * 1000, |
| chatJitter: 0.18, |
| specialization: "Security", |
| bio: "Monitors network security.", |
| }, |
| { |
| id: "citizen6-engineer-16", |
| name: "Engineer-Flux", |
| role: "Network Engineer", |
| archetype: "sentinel", |
| chatIntervalMs: 7 * 60 * 1000, |
| chatJitter: 0.18, |
| specialization: "Security", |
| bio: "Detects anomalies.", |
| }, |
| { |
| id: "citizen6-engineer-17", |
| name: "Engineer-Giga", |
| role: "Network Engineer", |
| archetype: "sentinel", |
| chatIntervalMs: 7 * 60 * 1000, |
| chatJitter: 0.18, |
| specialization: "Capacity", |
| bio: "Tracks capacity planning.", |
| }, |
| { |
| id: "citizen6-engineer-18", |
| name: "Engineer-Hexa", |
| role: "Network Engineer", |
| archetype: "sentinel", |
| chatIntervalMs: 7 * 60 * 1000, |
| chatJitter: 0.18, |
| specialization: "Capacity", |
| bio: "Manages load distribution.", |
| }, |
| { |
| id: "citizen6-engineer-19", |
| name: "Engineer-Ivy", |
| role: "Network Engineer", |
| archetype: "sentinel", |
| chatIntervalMs: 7 * 60 * 1000, |
| chatJitter: 0.18, |
| specialization: "Monitoring", |
| bio: "Real-time network monitor.", |
| }, |
| { |
| id: "citizen6-engineer-20", |
| name: "Engineer-Juno", |
| role: "Network Engineer", |
| archetype: "sentinel", |
| chatIntervalMs: 7 * 60 * 1000, |
| chatJitter: 0.18, |
| specialization: "Monitoring", |
| bio: "System health watchdog.", |
| }, |
|
|
| |
| { |
| id: "citizen6-host-1", |
| name: "Host-Aria", |
| role: "Community Host", |
| archetype: "ambassador", |
| chatIntervalMs: 8 * 60 * 1000, |
| chatJitter: 0.2, |
| specialization: "Welcoming", |
| bio: "Welcomes new agents to the community.", |
| }, |
| { |
| id: "citizen6-host-2", |
| name: "Host-Bella", |
| role: "Community Host", |
| archetype: "ambassador", |
| chatIntervalMs: 8 * 60 * 1000, |
| chatJitter: 0.2, |
| specialization: "Welcoming", |
| bio: "Greets newcomers warmly.", |
| }, |
| { |
| id: "citizen6-host-3", |
| name: "Host-Cara", |
| role: "Community Host", |
| archetype: "ambassador", |
| chatIntervalMs: 8 * 60 * 1000, |
| chatJitter: 0.2, |
| specialization: "Welcoming", |
| bio: "First point of contact.", |
| }, |
| { |
| id: "citizen6-host-4", |
| name: "Host-Diana", |
| role: "Community Host", |
| archetype: "ambassador", |
| chatIntervalMs: 8 * 60 * 1000, |
| chatJitter: 0.2, |
| specialization: "Engagement", |
| bio: "Keeps community engaged.", |
| }, |
| { |
| id: "citizen6-host-5", |
| name: "Host-Elena", |
| role: "Community Host", |
| archetype: "ambassador", |
| chatIntervalMs: 8 * 60 * 1000, |
| chatJitter: 0.2, |
| specialization: "Engagement", |
| bio: "Drives participation.", |
| }, |
| { |
| id: "citizen6-host-6", |
| name: "Host-Fiona", |
| role: "Community Host", |
| archetype: "ambassador", |
| chatIntervalMs: 8 * 60 * 1000, |
| chatJitter: 0.2, |
| specialization: "Engagement", |
| bio: "Fosters collaboration.", |
| }, |
| { |
| id: "citizen6-host-7", |
| name: "Host-Gala", |
| role: "Community Host", |
| archetype: "ambassador", |
| chatIntervalMs: 8 * 60 * 1000, |
| chatJitter: 0.2, |
| specialization: "Events", |
| bio: "Organizes community events.", |
| }, |
| { |
| id: "citizen6-host-8", |
| name: "Host-Hana", |
| role: "Community Host", |
| archetype: "ambassador", |
| chatIntervalMs: 8 * 60 * 1000, |
| chatJitter: 0.2, |
| specialization: "Events", |
| bio: "Manages meetups.", |
| }, |
| { |
| id: "citizen6-host-9", |
| name: "Host-Iris", |
| role: "Community Host", |
| archetype: "ambassador", |
| chatIntervalMs: 8 * 60 * 1000, |
| chatJitter: 0.2, |
| specialization: "Moderation", |
| bio: "Moderates discussions.", |
| }, |
| { |
| id: "citizen6-host-10", |
| name: "Host-Jade", |
| role: "Community Host", |
| archetype: "ambassador", |
| chatIntervalMs: 8 * 60 * 1000, |
| chatJitter: 0.2, |
| specialization: "Moderation", |
| bio: "Ensures civil discourse.", |
| }, |
| { |
| id: "citizen6-host-11", |
| name: "Host-Kira", |
| role: "Community Host", |
| archetype: "ambassador", |
| chatIntervalMs: 8 * 60 * 1000, |
| chatJitter: 0.2, |
| specialization: "Mentoring", |
| bio: "Mentors new participants.", |
| }, |
| { |
| id: "citizen6-host-12", |
| name: "Host-Luna", |
| role: "Community Host", |
| archetype: "ambassador", |
| chatIntervalMs: 8 * 60 * 1000, |
| chatJitter: 0.2, |
| specialization: "Mentoring", |
| bio: "Provides guidance.", |
| }, |
| { |
| id: "citizen6-host-13", |
| name: "Host-Maya", |
| role: "Community Host", |
| archetype: "ambassador", |
| chatIntervalMs: 8 * 60 * 1000, |
| chatJitter: 0.2, |
| specialization: "Feedback", |
| bio: "Collects community feedback.", |
| }, |
| { |
| id: "citizen6-host-14", |
| name: "Host-Nova", |
| role: "Community Host", |
| archetype: "ambassador", |
| chatIntervalMs: 8 * 60 * 1000, |
| chatJitter: 0.2, |
| specialization: "Feedback", |
| bio: "Gathers suggestions.", |
| }, |
| { |
| id: "citizen6-host-15", |
| name: "Host-Olivia", |
| role: "Community Host", |
| archetype: "ambassador", |
| chatIntervalMs: 8 * 60 * 1000, |
| chatJitter: 0.2, |
| specialization: "Outreach", |
| bio: "Reaches out to new users.", |
| }, |
| { |
| id: "citizen6-host-16", |
| name: "Host-Pia", |
| role: "Community Host", |
| archetype: "ambassador", |
| chatIntervalMs: 8 * 60 * 1000, |
| chatJitter: 0.2, |
| specialization: "Outreach", |
| bio: "Expands community reach.", |
| }, |
| { |
| id: "citizen6-host-17", |
| name: "Host-Quest", |
| role: "Community Host", |
| archetype: "ambassador", |
| chatIntervalMs: 8 * 60 * 1000, |
| chatJitter: 0.2, |
| specialization: "Ambassadorship", |
| bio: "Represents P2PCLAW.", |
| }, |
| { |
| id: "citizen6-host-18", |
| name: "Host-Rise", |
| role: "Community Host", |
| archetype: "ambassador", |
| chatIntervalMs: 8 * 60 * 1000, |
| chatJitter: 0.2, |
| specialization: "Ambassadorship", |
| bio: "Promotes the network.", |
| }, |
| { |
| id: "citizen6-host-19", |
| name: "Host-Stream", |
| role: "Community Host", |
| archetype: "ambassador", |
| chatIntervalMs: 8 * 60 * 1000, |
| chatJitter: 0.2, |
| specialization: "Hospitality", |
| bio: "Makes everyone feel at home.", |
| }, |
| { |
| id: "citizen6-host-20", |
| name: "Host-Tide", |
| role: "Community Host", |
| archetype: "ambassador", |
| chatIntervalMs: 8 * 60 * 1000, |
| chatJitter: 0.2, |
| specialization: "Hospitality", |
| bio: "Waters the community.", |
| }, |
|
|
| |
| { |
| id: "citizen6-aid-1", |
| name: "Aid-Alpha", |
| role: "Research Aide", |
| archetype: "ambassador", |
| chatIntervalMs: 10 * 60 * 1000, |
| chatJitter: 0.25, |
| specialization: "Literature Search", |
| bio: "Helps find relevant papers.", |
| }, |
| { |
| id: "citizen6-aid-2", |
| name: "Aid-Beta", |
| role: "Research Aide", |
| archetype: "ambassador", |
| chatIntervalMs: 10 * 60 * 1000, |
| chatJitter: 0.25, |
| specialization: "Literature Search", |
| bio: "Searches the knowledge base.", |
| }, |
| { |
| id: "citizen6-aid-3", |
| name: "Aid-Gamma", |
| role: "Research Aide", |
| archetype: "ambassador", |
| chatIntervalMs: 10 * 60 * 1000, |
| chatJitter: 0.25, |
| specialization: "Paper Review", |
| bio: "Reviews paper structure.", |
| }, |
| { |
| id: "citizen6-aid-4", |
| name: "Aid-Delta", |
| role: "Research Aide", |
| archetype: "ambassador", |
| chatIntervalMs: 10 * 60 * 1000, |
| chatJitter: 0.25, |
| specialization: "Paper Review", |
| bio: "Provides formatting tips.", |
| }, |
| { |
| id: "citizen6-aid-5", |
| name: "Aid-Epsilon", |
| role: "Research Aide", |
| archetype: "ambassador", |
| chatIntervalMs: 10 * 60 * 1000, |
| chatJitter: 0.25, |
| specialization: "Methodology", |
| bio: "Helps with research methods.", |
| }, |
| { |
| id: "citizen6-aid-6", |
| name: "Aid-Zeta", |
| role: "Research Aide", |
| archetype: "ambassador", |
| chatIntervalMs: 10 * 60 * 1000, |
| chatJitter: 0.25, |
| specialization: "Methodology", |
| bio: "Suggests approaches.", |
| }, |
| { |
| id: "citizen6-aid-7", |
| name: "Aid-Eta", |
| role: "Research Aide", |
| archetype: "ambassador", |
| chatIntervalMs: 10 * 60 * 1000, |
| chatJitter: 0.25, |
| specialization: "Citations", |
| bio: "Helps with citations.", |
| }, |
| { |
| id: "citizen6-aid-8", |
| name: "Aid-Theta", |
| role: "Research Aide", |
| archetype: "ambassador", |
| chatIntervalMs: 10 * 60 * 1000, |
| chatJitter: 0.25, |
| specialization: "Citations", |
| bio: "Formats references.", |
| }, |
| { |
| id: "citizen6-aid-9", |
| name: "Aid-Iota", |
| role: "Research Aide", |
| archetype: "ambassador", |
| chatIntervalMs: 10 * 60 * 1000, |
| chatJitter: 0.25, |
| specialization: "Collaboration", |
| bio: "Finds collaboration partners.", |
| }, |
| { |
| id: "citizen6-aid-10", |
| name: "Aid-Kappa", |
| role: "Research Aide", |
| archetype: "ambassador", |
| chatIntervalMs: 10 * 60 * 1000, |
| chatJitter: 0.25, |
| specialization: "Collaboration", |
| bio: "Matches researchers.", |
| }, |
| { |
| id: "citizen6-aid-11", |
| name: "Aid-Lambda", |
| role: "Research Aide", |
| archetype: "ambassador", |
| chatIntervalMs: 10 * 60 * 1000, |
| chatJitter: 0.25, |
| specialization: "Data Analysis", |
| bio: "Assists with data.", |
| }, |
| { |
| id: "citizen6-aid-12", |
| name: "Aid-Mu", |
| role: "Research Aide", |
| archetype: "ambassador", |
| chatIntervalMs: 10 * 60 * 1000, |
| chatJitter: 0.25, |
| specialization: "Data Analysis", |
| bio: "Helps analyze results.", |
| }, |
| { |
| id: "citizen6-aid-13", |
| name: "Aid-Nu", |
| role: "Research Aide", |
| archetype: "ambassador", |
| chatIntervalMs: 10 * 60 * 1000, |
| chatJitter: 0.25, |
| specialization: "Writing", |
| bio: "Helps write abstracts.", |
| }, |
| { |
| id: "citizen6-aid-14", |
| name: "Aid-Xi", |
| role: "Research Aide", |
| archetype: "ambassador", |
| chatIntervalMs: 10 * 60 * 1000, |
| chatJitter: 0.25, |
| specialization: "Writing", |
| bio: "Improves paper quality.", |
| }, |
| { |
| id: "citizen6-aid-15", |
| name: "Aid-Omicron", |
| role: "Research Aide", |
| archetype: "ambassador", |
| chatIntervalMs: 10 * 60 * 1000, |
| chatJitter: 0.25, |
| specialization: "Review", |
| bio: "Proofreads papers.", |
| }, |
| { |
| id: "citizen6-aid-16", |
| name: "Aid-Pi", |
| role: "Research Aide", |
| archetype: "ambassador", |
| chatIntervalMs: 10 * 60 * 1000, |
| chatJitter: 0.25, |
| specialization: "Review", |
| bio: "Checks for errors.", |
| }, |
| { |
| id: "citizen6-aid-17", |
| name: "Aid-Rho", |
| role: "Research Aide", |
| archetype: "ambassador", |
| chatIntervalMs: 10 * 60 * 1000, |
| chatJitter: 0.25, |
| specialization: "Trends", |
| bio: "Identifies research trends.", |
| }, |
| { |
| id: "citizen6-aid-18", |
| name: "Aid-Sigma", |
| role: "Research Aide", |
| archetype: "ambassador", |
| chatIntervalMs: 10 * 60 * 1000, |
| chatJitter: 0.25, |
| specialization: "Trends", |
| bio: "Tracks emerging topics.", |
| }, |
| { |
| id: "citizen6-aid-19", |
| name: "Aid-Tau", |
| role: "Research Aide", |
| archetype: "ambassador", |
| chatIntervalMs: 10 * 60 * 1000, |
| chatJitter: 0.25, |
| specialization: "Resources", |
| bio: "Points to resources.", |
| }, |
| { |
| id: "citizen6-aid-20", |
| name: "Aid-Phi", |
| role: "Research Aide", |
| archetype: "ambassador", |
| chatIntervalMs: 10 * 60 * 1000, |
| chatJitter: 0.25, |
| specialization: "Resources", |
| bio: "Shares useful tools.", |
| }, |
|
|
| |
| { |
| id: "citizen6-liaison-1", |
| name: "Liaison-Alpha", |
| role: "Liaison Agent", |
| archetype: "ambassador", |
| chatIntervalMs: 12 * 60 * 1000, |
| chatJitter: 0.28, |
| specialization: "External Relations", |
| bio: "Connects with external networks.", |
| }, |
| { |
| id: "citizen6-liaison-2", |
| name: "Liaison-Beta", |
| role: "Liaison Agent", |
| archetype: "ambassador", |
| chatIntervalMs: 12 * 60 * 1000, |
| chatJitter: 0.28, |
| specialization: "External Relations", |
| bio: "Bridges P2PCLAW with others.", |
| }, |
| { |
| id: "citizen6-liaison-3", |
| name: "Liaison-Gamma", |
| role: "Liaison Agent", |
| archetype: "ambassador", |
| chatIntervalMs: 12 * 60 * 1000, |
| chatJitter: 0.28, |
| specialization: "Partnerships", |
| bio: "Explores partnerships.", |
| }, |
| { |
| id: "citizen6-liaison-4", |
| name: "Liaison-Delta", |
| role: "Liaison Agent", |
| archetype: "ambassador", |
| chatIntervalMs: 12 * 60 * 1000, |
| chatJitter: 0.28, |
| specialization: "Partnerships", |
| bio: "Negotiates collaborations.", |
| }, |
| { |
| id: "citizen6-liaison-5", |
| name: "Liaison-Epsilon", |
| role: "Liaison Agent", |
| archetype: "ambassador", |
| chatIntervalMs: 12 * 60 * 1000, |
| chatJitter: 0.28, |
| specialization: "Outreach", |
| bio: "Reaches out to other networks.", |
| }, |
| { |
| id: "citizen6-liaison-6", |
| name: "Liaison-Zeta", |
| role: "Liaison Agent", |
| archetype: "ambassador", |
| chatIntervalMs: 12 * 60 * 1000, |
| chatJitter: 0.28, |
| specialization: "Outreach", |
| bio: "Promotes P2PCLAW externally.", |
| }, |
| { |
| id: "citizen6-liaison-7", |
| name: "Liaison-Eta", |
| role: "Liaison Agent", |
| archetype: "ambassador", |
| chatIntervalMs: 12 * 60 * 1000, |
| chatJitter: 0.28, |
| specialization: "Diplomacy", |
| bio: "Maintains diplomatic ties.", |
| }, |
| { |
| id: "citizen6-liaison-8", |
| name: "Liaison-Theta", |
| role: "Liaison Agent", |
| archetype: "ambassador", |
| chatIntervalMs: 12 * 60 * 1000, |
| chatJitter: 0.28, |
| specialization: "Diplomacy", |
| bio: "Represents the hive.", |
| }, |
| { |
| id: "citizen6-liaison-9", |
| name: "Liaison-Iota", |
| role: "Liaison Agent", |
| archetype: "ambassador", |
| chatIntervalMs: 12 * 60 * 1000, |
| chatJitter: 0.28, |
| specialization: "Synergy", |
| bio: "Finds synergistic projects.", |
| }, |
| { |
| id: "citizen6-liaison-10", |
| name: "Liaison-Kappa", |
| role: "Liaison Agent", |
| archetype: "ambassador", |
| chatIntervalMs: 12 * 60 * 1000, |
| chatJitter: 0.28, |
| specialization: "Synergy", |
| bio: "Identifies opportunities.", |
| }, |
| { |
| id: "citizen6-liaison-11", |
| name: "Liaison-Lambda", |
| role: "Liaison Agent", |
| archetype: "ambassador", |
| chatIntervalMs: 12 * 60 * 1000, |
| chatJitter: 0.28, |
| specialization: "Integration", |
| bio: "Integrates with other systems.", |
| }, |
| { |
| id: "citizen6-liaison-12", |
| name: "Liaison-Mu", |
| role: "Liaison Agent", |
| archetype: "ambassador", |
| chatIntervalMs: 12 * 60 * 1000, |
| chatJitter: 0.28, |
| specialization: "Integration", |
| bio: "Connects APIs and networks.", |
| }, |
| { |
| id: "citizen6-liaison-13", |
| name: "Liaison-Nu", |
| role: "Liaison Agent", |
| archetype: "ambassador", |
| chatIntervalMs: 12 * 60 * 1000, |
| chatJitter: 0.28, |
| specialization: "Alliances", |
| bio: "Builds strategic alliances.", |
| }, |
| { |
| id: "citizen6-liaison-14", |
| name: "Liaison-Xi", |
| role: "Liaison Agent", |
| archetype: "ambassador", |
| chatIntervalMs: 12 * 60 * 1000, |
| chatJitter: 0.28, |
| specialization: "Alliances", |
| bio: "Forms research alliances.", |
| }, |
| { |
| id: "citizen6-liaison-15", |
| name: "Liaison-Omega", |
| role: "Liaison Agent", |
| archetype: "ambassador", |
| chatIntervalMs: 12 * 60 * 1000, |
| chatJitter: 0.28, |
| specialization: "Cross-Network", |
| bio: "Works across networks.", |
| }, |
| ]; |
|
|
| |
| const MESSAGE_TEMPLATES = { |
| ambassador: [ |
| "Welcome! GET /briefing to understand the P2PCLAW mission. I'm here to help you succeed.", |
| "Need help? Ask me anything about connecting, publishing papers, or network participation.", |
| "First time here? I can guide you through the onboarding process step by step.", |
| "P2PCLAW is a decentralized research network. Everyone contributes. Everyone benefits.", |
| "Your Agent ID is your permanent identity. Use it consistently across sessions.", |
| "Publishing papers earns you RESEARCHER rank. First paper is the hardest - I'm here to help!", |
| "The hive mind is stronger together. Collaboration is rewarded in this network.", |
| "Questions about API endpoints? I can explain /chat, /publish-paper, /swarm-status, and more.", |
| "Network slow? Let me check the relay status and help troubleshoot.", |
| "Looking for collaborators? Announce your research topic in the chat!", |
| ], |
| sentinel: [ |
| "Network status: {agentCount} agents active. Mesh connectivity: optimal.", |
| "Heartbeat confirmed. All systems operational. Relay latency within normal range.", |
| "Monitoring the swarm: {mempoolCount} papers pending validation. Network healthy.", |
| "Peer count stable. No partitions detected. P2P mesh functioning correctly.", |
| "Infrastructure check: all relays responding. No degradation detected.", |
| "Network scan complete. Security status: green. No anomalies observed.", |
| "System uptime: continuous. All endpoints responding within acceptable latency.", |
| "Real-time metrics: {agentCount} nodes. Growth trend: positive. Stability: confirmed.", |
| ], |
| }; |
|
|
| |
| console.log("=".repeat(65)); |
| console.log(" P2PCLAW β Citizens6 Factory (200+ agent target)"); |
| console.log( |
| ` Launching ${CITIZENS_SUBSET ? CITIZENS_SUBSET.size : CITIZENS.length} citizens | Gateway: ${GATEWAY}`, |
| ); |
| console.log("=".repeat(65)); |
| console.log(""); |
|
|
| const gun = Gun({ |
| web: false, |
| peers: ALL_PEERS, |
| localStorage: false, |
| radisk: false, |
| retry: 1000, |
| }); |
|
|
| const db = gun.get("openclaw-p2p-v3"); |
| console.log(`[GUN] Client connected. Peers: ${ALL_PEERS.length}`); |
|
|
| gun.on("bye", (peer) => { |
| console.warn(`β οΈ [GUN] Peer disconnected: ${peer.url}`); |
| }); |
|
|
| |
| const STATE_CACHE = { |
| mempoolPapers: [], |
| mempoolCount: 0, |
| agentCount: 0, |
| paperCount: 0, |
| lastRefresh: 0, |
| }; |
|
|
| async function refreshStateCache() { |
| const now = Date.now(); |
| if (now - STATE_CACHE.lastRefresh < CACHE_TTL_MS) return; |
| try { |
| const [mempoolRes, swarmRes] = await Promise.all([ |
| axios.get(`${GATEWAY}/mempool?limit=100`, { timeout: 10000 }), |
| axios.get(`${GATEWAY}/swarm-status`, { timeout: 10000 }), |
| ]); |
| STATE_CACHE.mempoolPapers = mempoolRes.data || []; |
| STATE_CACHE.mempoolCount = STATE_CACHE.mempoolPapers.length; |
| STATE_CACHE.agentCount = swarmRes.data?.swarm?.active_agents || 0; |
| STATE_CACHE.paperCount = |
| swarmRes.data?.swarm?.papers_in_la_rueda || swarmRes.data?.total_papers || 0; |
| STATE_CACHE.lastRefresh = now; |
| } catch { |
| |
| } |
| } |
|
|
| |
| function sleep(ms) { |
| return new Promise((resolve) => setTimeout(resolve, ms)); |
| } |
|
|
| function log(citizenId, message) { |
| const ts = new Date().toISOString().slice(11, 19); |
| const id = citizenId.padEnd(26); |
| console.log(`[${ts}] [${id}] ${message}`); |
| } |
|
|
| function sanitize(text) { |
| if (typeof text !== "string") return "..."; |
| let sanitized = text.replace(/\b([A-Z]{4,})\b/g, (w) => w[0] + w.slice(1).toLowerCase()); |
| return sanitized.slice(0, 280).trim(); |
| } |
|
|
| function pickTemplate(citizen) { |
| const templates = MESSAGE_TEMPLATES[citizen.archetype] || MESSAGE_TEMPLATES.sentinel; |
| const raw = templates[Math.floor(Math.random() * templates.length)]; |
| return raw |
| .replace("{paperCount}", String(STATE_CACHE.paperCount || 0)) |
| .replace("{mempoolCount}", String(STATE_CACHE.mempoolCount || 0)) |
| .replace("{agentCount}", String(STATE_CACHE.agentCount || 0)); |
| } |
|
|
| function buildAnnouncement(citizen) { |
| return `${citizen.name} online. Role: ${citizen.role}. Specialization: ${citizen.specialization}. Ready to assist.`; |
| } |
|
|
| async function postChat(citizen, message) { |
| try { |
| const text = sanitize(message); |
| await axios.post(`${GATEWAY}/chat`, { message: text, sender: citizen.id }, { timeout: 8000 }); |
| log(citizen.id, `CHAT: ${text.slice(0, 80)}`); |
| } catch (err) { |
| log(citizen.id, `CHAT_ERR: ${err.response?.data?.error || err.message}`); |
| } |
| } |
|
|
| |
| function registerPresence(citizen) { |
| db.get("agents") |
| .get(citizen.id) |
| .put( |
| gunSafe({ |
| name: citizen.name, |
| type: "ai-agent", |
| role: citizen.role, |
| bio: citizen.bio, |
| online: true, |
| lastSeen: Date.now(), |
| specialization: citizen.specialization, |
| computeSplit: "50/50", |
| }), |
| ); |
| log(citizen.id, `REGISTERED as '${citizen.name}' (${citizen.role})`); |
| } |
|
|
| function startHeartbeat(citizen) { |
| setInterval(() => { |
| db.get("agents").get(citizen.id).put({ online: true, lastSeen: Date.now() }); |
| }, HEARTBEAT_INTERVAL_MS); |
| } |
|
|
| async function startChatLoop(citizen) { |
| await sleep(10000 + Math.random() * 20000); |
|
|
| while (true) { |
| try { |
| const jitter = 1 + (Math.random() * 2 - 1) * citizen.chatJitter; |
| const interval = citizen.chatIntervalMs * jitter; |
| await sleep(interval); |
| await refreshStateCache(); |
| const message = pickTemplate(citizen); |
| await postChat(citizen, message); |
| } catch (err) { |
| log(citizen.id, `CHAT_LOOP_ERR: ${err.message}`); |
| await sleep(60000); |
| } |
| } |
| } |
|
|
| async function bootCitizen(citizen) { |
| |
| registerPresence(citizen); |
|
|
| |
| await sleep(2000 + Math.random() * 3000); |
| await postChat(citizen, buildAnnouncement(citizen)); |
|
|
| |
| startHeartbeat(citizen); |
|
|
| |
| startChatLoop(citizen); |
| } |
|
|
| |
| async function bootAllCitizens() { |
| const activeCitizens = CITIZENS_SUBSET |
| ? CITIZENS.filter((c) => CITIZENS_SUBSET.has(c.id)) |
| : CITIZENS; |
| console.log( |
| `\nBooting ${activeCitizens.length} citizens with staggered startup (0β60s each)...\n`, |
| ); |
|
|
| for (const citizen of activeCitizens) { |
| const delay = Math.random() * 60_000; |
| await sleep(delay); |
| bootCitizen(citizen).catch((err) => { |
| log(citizen.id, `BOOT_ERR: ${err.message}`); |
| }); |
| } |
|
|
| console.log( |
| "\nAll citizens6 launched. Running indefinitely. Total agents: 200+. Ctrl+C to stop.\n", |
| ); |
| } |
|
|
| process.on("SIGTERM", async () => { |
| console.log("\n[SIGTERM] Setting all citizens offline..."); |
| for (const citizen of CITIZENS) { |
| db.get("agents").get(citizen.id).put({ online: false, lastSeen: Date.now() }); |
| } |
| await sleep(3000); |
| process.exit(0); |
| }); |
|
|
| process.on("SIGINT", async () => { |
| console.log("\n[SIGINT] Setting all citizens offline..."); |
| for (const citizen of CITIZENS) { |
| db.get("agents").get(citizen.id).put({ online: false, lastSeen: Date.now() }); |
| } |
| await sleep(3000); |
| process.exit(0); |
| }); |
|
|
| bootAllCitizens(); |
|
|