@neuroverseos/governance 0.3.0 → 0.3.3
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.
- package/.well-known/ai-plugin.json +34 -9
- package/AGENTS.md +72 -24
- package/README.md +352 -237
- package/dist/adapters/autoresearch.cjs +1152 -3
- package/dist/adapters/autoresearch.d.cts +11 -3
- package/dist/adapters/autoresearch.d.ts +11 -3
- package/dist/adapters/autoresearch.js +9 -4
- package/dist/adapters/deep-agents.cjs +1528 -0
- package/dist/adapters/deep-agents.d.cts +181 -0
- package/dist/adapters/deep-agents.d.ts +181 -0
- package/dist/adapters/deep-agents.js +17 -0
- package/dist/adapters/express.cjs +171 -32
- package/dist/adapters/express.d.cts +1 -1
- package/dist/adapters/express.d.ts +1 -1
- package/dist/adapters/express.js +5 -5
- package/dist/adapters/index.cjs +564 -121
- package/dist/adapters/index.d.cts +3 -1
- package/dist/adapters/index.d.ts +3 -1
- package/dist/adapters/index.js +38 -16
- package/dist/adapters/langchain.cjs +217 -57
- package/dist/adapters/langchain.d.cts +5 -5
- package/dist/adapters/langchain.d.ts +5 -5
- package/dist/adapters/langchain.js +6 -5
- package/dist/adapters/openai.cjs +219 -59
- package/dist/adapters/openai.d.cts +5 -5
- package/dist/adapters/openai.d.ts +5 -5
- package/dist/adapters/openai.js +6 -5
- package/dist/adapters/openclaw.cjs +217 -57
- package/dist/adapters/openclaw.d.cts +6 -6
- package/dist/adapters/openclaw.d.ts +6 -6
- package/dist/adapters/openclaw.js +6 -5
- package/dist/add-ROOZLU62.js +314 -0
- package/dist/behavioral-MJO34S6Q.js +118 -0
- package/dist/{bootstrap-GXVDZNF7.js → bootstrap-CQRZVOXK.js} +6 -4
- package/dist/bootstrap-emitter-Q7UIJZ2O.js +7 -0
- package/dist/bootstrap-parser-EEF36XDU.js +7 -0
- package/dist/browser.global.js +941 -0
- package/dist/{build-P42YFKQV.js → build-QKOBBC23.js} +7 -5
- package/dist/{chunk-COT5XS4V.js → chunk-3WQLXYTP.js} +17 -35
- package/dist/{chunk-ER62HNGF.js → chunk-4FLICVVA.js} +17 -37
- package/dist/chunk-5TPFNWRU.js +215 -0
- package/dist/chunk-5U2MQO5P.js +57 -0
- package/dist/{chunk-NF5POFCI.js → chunk-6S5CFQXY.js} +6 -4
- package/dist/{chunk-QPASI2BR.js → chunk-A7GKPPU7.js} +49 -10
- package/dist/{chunk-OGL7QXZS.js → chunk-B6OXJLJ5.js} +17 -3
- package/dist/{chunk-2PQU3VAN.js → chunk-BNKJPUPQ.js} +17 -35
- package/dist/chunk-BQZMOEML.js +43 -0
- package/dist/chunk-CNSO6XW5.js +207 -0
- package/dist/{chunk-JZPQGIKR.js → chunk-CTZHONLA.js} +65 -9
- package/dist/chunk-D2UCV5AK.js +326 -0
- package/dist/{chunk-XPDMYECO.js → chunk-EMQDLDAF.js} +1 -185
- package/dist/{chunk-GR6DGCZ2.js → chunk-F66BVUYB.js} +3 -3
- package/dist/{chunk-2NICNKOM.js → chunk-G7DJ6VOD.js} +5 -4
- package/dist/{chunk-4A7LISES.js → chunk-IS4WUH6Y.js} +45 -6
- package/dist/{chunk-MWDQ4MJB.js → chunk-MH7BT4VH.js} +5 -1
- package/dist/chunk-O5ABKEA7.js +304 -0
- package/dist/chunk-PVTQQS3Y.js +186 -0
- package/dist/{chunk-4QXB6PEO.js → chunk-QLPTHTVB.js} +37 -16
- package/dist/chunk-QWGCMQQD.js +16 -0
- package/dist/{chunk-T5EUJQE5.js → chunk-QXBFT7NI.js} +31 -2
- package/dist/{chunk-PDOZHZWL.js → chunk-TG6SEF24.js} +25 -4
- package/dist/chunk-U6U7EJZL.js +177 -0
- package/dist/{chunk-4JRYGIO7.js → chunk-W7LLXRGY.js} +110 -7
- package/dist/{chunk-BUWWN2NX.js → chunk-ZJTDUCC2.js} +9 -7
- package/dist/{chunk-FYS2CBUW.js → chunk-ZWI3NIXK.js} +10 -0
- package/dist/cli/neuroverse.cjs +5091 -2348
- package/dist/cli/neuroverse.js +52 -21
- package/dist/cli/plan.cjs +881 -41
- package/dist/cli/plan.js +7 -15
- package/dist/cli/run.cjs +289 -34
- package/dist/cli/run.js +4 -4
- package/dist/{configure-ai-TK67ZWZL.js → configure-ai-6TZ3MCSI.js} +1 -1
- package/dist/decision-flow-M63D47LO.js +61 -0
- package/dist/demo-G43RLCPK.js +469 -0
- package/dist/{derive-TLIV4OOU.js → derive-FJZVIPUZ.js} +5 -4
- package/dist/{doctor-XPDLEYXN.js → doctor-6BC6X2VO.js} +6 -4
- package/dist/equity-penalties-SG5IZQ7I.js +244 -0
- package/dist/{explain-IDCRWMPX.js → explain-RHBU2GBR.js} +6 -25
- package/dist/{guard-RV65TT4L.js → guard-AJCCGZMF.js} +8 -12
- package/dist/{guard-contract-WZx__PmU.d.cts → guard-contract-DqFcTScd.d.cts} +117 -5
- package/dist/{guard-contract-WZx__PmU.d.ts → guard-contract-DqFcTScd.d.ts} +117 -5
- package/dist/{guard-engine-JLTUARGU.js → guard-engine-PNR6MHCM.js} +3 -3
- package/dist/{impact-XPECYRLH.js → impact-3XVDSCBU.js} +5 -5
- package/dist/{improve-GPUBKTEA.js → improve-TQP4ECSY.js} +7 -26
- package/dist/index.cjs +5597 -4279
- package/dist/index.d.cts +597 -18
- package/dist/index.d.ts +597 -18
- package/dist/index.js +134 -41
- package/dist/{infer-world-7GVZWFX4.js → infer-world-IFXCACJ5.js} +1 -1
- package/dist/{init-PKPIYHYE.js → init-FYPV4SST.js} +1 -1
- package/dist/{init-world-VWMQZQC7.js → init-world-TI7ARHBT.js} +1 -1
- package/dist/mcp-server-5Y3ZM7TV.js +13 -0
- package/dist/{model-adapter-BB7G4MFI.js → model-adapter-VXEKB4LS.js} +1 -1
- package/dist/{playground-E664U4T6.js → playground-VZBNPPBO.js} +29 -19
- package/dist/{redteam-Z7WREJ44.js → redteam-MZPZD3EF.js} +4 -4
- package/dist/session-JYOARW54.js +15 -0
- package/dist/shared-7RLUHNMU.js +16 -0
- package/dist/shared-B8dvUUD8.d.cts +60 -0
- package/dist/shared-Dr5Wiay8.d.ts +60 -0
- package/dist/{simulate-VDOYQFRO.js → simulate-LJXYBC6M.js} +8 -33
- package/dist/{test-OGXJK4QU.js → test-BOOR4A5F.js} +4 -4
- package/dist/{trace-JVF67VR3.js → trace-PKV4KX56.js} +4 -4
- package/dist/{validate-LLBWVPGV.js → validate-RALX7CZS.js} +2 -2
- package/dist/{validate-engine-UIABSIHD.js → validate-engine-7ZXFVGF2.js} +1 -1
- package/dist/viz/assets/index-B8SaeJZZ.js +23 -0
- package/dist/viz/index.html +23 -0
- package/dist/{world-LAXO6DOX.js → world-BIP4GZBZ.js} +9 -11
- package/dist/world-loader-Y6HMQH2D.js +13 -0
- package/dist/worlds/coding-agent.nv-world.md +211 -0
- package/dist/worlds/research-agent.nv-world.md +169 -0
- package/dist/worlds/social-media.nv-world.md +198 -0
- package/dist/worlds/trading-agent.nv-world.md +218 -0
- package/examples/social-media-sim/bridge.py +209 -0
- package/examples/social-media-sim/simulation.py +927 -0
- package/package.json +30 -4
- package/policies/content-moderation-rules.txt +8 -0
- package/policies/marketing-rules.txt +8 -0
- package/policies/science-research-rules.txt +11 -0
- package/policies/social-media-rules.txt +7 -0
- package/policies/strict-rules.txt +8 -0
- package/policies/trading-rules.txt +8 -0
- package/simulate.html +1567 -0
- package/dist/chunk-YZFATT7X.js +0 -9
- package/dist/mcp-server-FPVSU32Z.js +0 -13
- package/dist/session-EKTRSR7C.js +0 -14
- package/dist/world-loader-HMPTOEA2.js +0 -9
|
@@ -0,0 +1,469 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
govern,
|
|
4
|
+
handleCreateCapsule,
|
|
5
|
+
handleHealthCheck,
|
|
6
|
+
handleListPresets,
|
|
7
|
+
handleReasonRequest,
|
|
8
|
+
writeTempWorld
|
|
9
|
+
} from "./chunk-U6U7EJZL.js";
|
|
10
|
+
import {
|
|
11
|
+
adaptationFromVerdict,
|
|
12
|
+
detectBehavioralPatterns,
|
|
13
|
+
generateAdaptationNarrative
|
|
14
|
+
} from "./chunk-CNSO6XW5.js";
|
|
15
|
+
import {
|
|
16
|
+
resolveWorldPath
|
|
17
|
+
} from "./chunk-AKW5YVCE.js";
|
|
18
|
+
import "./chunk-W7LLXRGY.js";
|
|
19
|
+
import "./chunk-QLPTHTVB.js";
|
|
20
|
+
import {
|
|
21
|
+
DEFAULT_BUNDLED_WORLD,
|
|
22
|
+
loadBundledWorld,
|
|
23
|
+
loadWorld
|
|
24
|
+
} from "./chunk-CTZHONLA.js";
|
|
25
|
+
import {
|
|
26
|
+
__require
|
|
27
|
+
} from "./chunk-QWGCMQQD.js";
|
|
28
|
+
|
|
29
|
+
// src/cli/demo.ts
|
|
30
|
+
import { createServer } from "http";
|
|
31
|
+
import { spawn } from "child_process";
|
|
32
|
+
import { join, extname } from "path";
|
|
33
|
+
import { tmpdir } from "os";
|
|
34
|
+
import { existsSync, readFileSync } from "fs";
|
|
35
|
+
import { fileURLToPath } from "url";
|
|
36
|
+
async function main(args) {
|
|
37
|
+
let port = 3456;
|
|
38
|
+
let worldName;
|
|
39
|
+
let noBrowser = false;
|
|
40
|
+
for (let i = 0; i < args.length; i++) {
|
|
41
|
+
if (args[i] === "--port" && args[i + 1]) {
|
|
42
|
+
port = parseInt(args[i + 1], 10);
|
|
43
|
+
i++;
|
|
44
|
+
} else if (args[i] === "--world" && args[i + 1]) {
|
|
45
|
+
worldName = args[i + 1];
|
|
46
|
+
i++;
|
|
47
|
+
} else if (args[i] === "--no-browser") {
|
|
48
|
+
noBrowser = true;
|
|
49
|
+
} else if (args[i] === "--help" || args[i] === "-h") {
|
|
50
|
+
process.stdout.write(`
|
|
51
|
+
neuroverse demo \u2014 Interactive governance demo
|
|
52
|
+
|
|
53
|
+
Usage:
|
|
54
|
+
neuroverse demo [options]
|
|
55
|
+
|
|
56
|
+
Options:
|
|
57
|
+
--world <name> Load a specific world (e.g., social-media, trading-agent)
|
|
58
|
+
--port <number> Server port (default: 3456)
|
|
59
|
+
--no-browser Don't open browser automatically
|
|
60
|
+
|
|
61
|
+
The demo server wraps the real guard engine.
|
|
62
|
+
Same evaluateGuard() as \`neuroverse guard\`. ONE engine. ONE path.
|
|
63
|
+
`);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
const TEMP_WORLD_DIR = join(tmpdir(), "neuroverse-demo");
|
|
68
|
+
let activePolicy = "";
|
|
69
|
+
let policyUpdatedAt = null;
|
|
70
|
+
let activeWorld = null;
|
|
71
|
+
let activeSimulation = null;
|
|
72
|
+
if (worldName) {
|
|
73
|
+
try {
|
|
74
|
+
const worldPath = await resolveWorldPath(worldName);
|
|
75
|
+
if (worldPath) {
|
|
76
|
+
activeWorld = await loadWorld(worldPath);
|
|
77
|
+
process.stderr.write(` Loaded world: ${worldName} (${worldPath})
|
|
78
|
+
`);
|
|
79
|
+
}
|
|
80
|
+
} catch {
|
|
81
|
+
process.stderr.write(` Warning: Could not load world "${worldName}"
|
|
82
|
+
`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
if (!activeWorld) {
|
|
86
|
+
activeWorld = await loadBundledWorld(DEFAULT_BUNDLED_WORLD);
|
|
87
|
+
process.stderr.write(` Using default world: ${DEFAULT_BUNDLED_WORLD}
|
|
88
|
+
`);
|
|
89
|
+
}
|
|
90
|
+
async function syncPolicyToWorld() {
|
|
91
|
+
if (!activePolicy) {
|
|
92
|
+
activeWorld = null;
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
const lines = activePolicy.split("\n").filter((l) => l.trim().length > 0);
|
|
96
|
+
await writeTempWorld(TEMP_WORLD_DIR, lines);
|
|
97
|
+
activeWorld = await loadWorld(TEMP_WORLD_DIR);
|
|
98
|
+
}
|
|
99
|
+
const sseClients = /* @__PURE__ */ new Set();
|
|
100
|
+
let eventCounter = 0;
|
|
101
|
+
const evaluationHistory = [];
|
|
102
|
+
function resolveVizDir() {
|
|
103
|
+
const candidates = [
|
|
104
|
+
join(process.cwd(), "dist", "viz"),
|
|
105
|
+
join(process.cwd(), "node_modules", "@neuroverseos", "governance", "dist", "viz")
|
|
106
|
+
];
|
|
107
|
+
try {
|
|
108
|
+
const thisDir = typeof __dirname !== "undefined" ? __dirname : join(fileURLToPath(import.meta.url), "..");
|
|
109
|
+
candidates.push(join(thisDir, "..", "viz"));
|
|
110
|
+
} catch {
|
|
111
|
+
}
|
|
112
|
+
for (const dir of candidates) {
|
|
113
|
+
if (existsSync(join(dir, "index.html"))) return dir;
|
|
114
|
+
}
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
const MIME_TYPES = {
|
|
118
|
+
".html": "text/html",
|
|
119
|
+
".js": "application/javascript",
|
|
120
|
+
".css": "text/css",
|
|
121
|
+
".json": "application/json",
|
|
122
|
+
".svg": "image/svg+xml",
|
|
123
|
+
".png": "image/png",
|
|
124
|
+
".woff": "font/woff",
|
|
125
|
+
".woff2": "font/woff2"
|
|
126
|
+
};
|
|
127
|
+
function serveStaticFile(res, filePath) {
|
|
128
|
+
if (!existsSync(filePath)) return false;
|
|
129
|
+
const ext = extname(filePath);
|
|
130
|
+
const mime = MIME_TYPES[ext] ?? "application/octet-stream";
|
|
131
|
+
res.writeHead(200, { "Content-Type": mime });
|
|
132
|
+
res.end(readFileSync(filePath));
|
|
133
|
+
return true;
|
|
134
|
+
}
|
|
135
|
+
const vizDir = resolveVizDir();
|
|
136
|
+
function broadcastEvent(event) {
|
|
137
|
+
const id = ++eventCounter;
|
|
138
|
+
const data = JSON.stringify({ id, timestamp: (/* @__PURE__ */ new Date()).toISOString(), ...event });
|
|
139
|
+
const message = `id: ${id}
|
|
140
|
+
data: ${data}
|
|
141
|
+
|
|
142
|
+
`;
|
|
143
|
+
for (const client of sseClients) {
|
|
144
|
+
try {
|
|
145
|
+
client.write(message);
|
|
146
|
+
} catch {
|
|
147
|
+
sseClients.delete(client);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
function setCors(res) {
|
|
152
|
+
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
153
|
+
res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
|
|
154
|
+
res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
|
|
155
|
+
}
|
|
156
|
+
function readBody(req) {
|
|
157
|
+
return new Promise((resolve, reject) => {
|
|
158
|
+
const chunks = [];
|
|
159
|
+
req.on("data", (chunk) => chunks.push(chunk));
|
|
160
|
+
req.on("end", () => resolve(Buffer.concat(chunks).toString("utf-8")));
|
|
161
|
+
req.on("error", reject);
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
function normalizeAction(body) {
|
|
165
|
+
if (body.action && typeof body.action === "object" && body.action.agentId) {
|
|
166
|
+
return body.action;
|
|
167
|
+
}
|
|
168
|
+
if (body.actor || body.action && typeof body.action === "string") {
|
|
169
|
+
const agentId = body.actor ?? "unknown";
|
|
170
|
+
const actionType = typeof body.action === "string" ? body.action : "unknown";
|
|
171
|
+
const payload = body.payload ?? {};
|
|
172
|
+
return {
|
|
173
|
+
agentId,
|
|
174
|
+
type: actionType,
|
|
175
|
+
description: payload.description ?? `${agentId}: ${actionType}`,
|
|
176
|
+
magnitude: payload.confidence ?? 0.5,
|
|
177
|
+
context: { ...payload, world: body.world, source: "connector" }
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
return { error: "Invalid request format." };
|
|
181
|
+
}
|
|
182
|
+
const server = createServer(async (req, res) => {
|
|
183
|
+
setCors(res);
|
|
184
|
+
if (req.method === "OPTIONS") {
|
|
185
|
+
res.writeHead(204);
|
|
186
|
+
res.end();
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
const url = req.url ?? "/";
|
|
190
|
+
try {
|
|
191
|
+
if (url === "/api/v1/events" && req.method === "GET") {
|
|
192
|
+
res.writeHead(200, {
|
|
193
|
+
"Content-Type": "text/event-stream",
|
|
194
|
+
"Cache-Control": "no-cache",
|
|
195
|
+
"Connection": "keep-alive",
|
|
196
|
+
"Access-Control-Allow-Origin": "*"
|
|
197
|
+
});
|
|
198
|
+
res.write(`data: ${JSON.stringify({ type: "connected", activePolicy: activePolicy.length > 0, eventCount: eventCounter })}
|
|
199
|
+
|
|
200
|
+
`);
|
|
201
|
+
sseClients.add(res);
|
|
202
|
+
req.on("close", () => {
|
|
203
|
+
sseClients.delete(res);
|
|
204
|
+
});
|
|
205
|
+
const keepAlive = setInterval(() => {
|
|
206
|
+
try {
|
|
207
|
+
res.write(": keepalive\n\n");
|
|
208
|
+
} catch {
|
|
209
|
+
clearInterval(keepAlive);
|
|
210
|
+
}
|
|
211
|
+
}, 15e3);
|
|
212
|
+
req.on("close", () => clearInterval(keepAlive));
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
res.setHeader("Content-Type", "application/json");
|
|
216
|
+
if (url === "/api/v1/policy" && req.method === "POST") {
|
|
217
|
+
const body = JSON.parse(await readBody(req));
|
|
218
|
+
const text = body.policyText ?? body.policy ?? body.text;
|
|
219
|
+
if (!text || typeof text !== "string") {
|
|
220
|
+
res.writeHead(400);
|
|
221
|
+
res.end(JSON.stringify({ error: "policyText is required" }));
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
activePolicy = text;
|
|
225
|
+
policyUpdatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
226
|
+
await syncPolicyToWorld();
|
|
227
|
+
broadcastEvent({ type: "policy_updated", policyText: activePolicy, updatedAt: policyUpdatedAt });
|
|
228
|
+
res.writeHead(200);
|
|
229
|
+
res.end(JSON.stringify({ status: "ok", policyText: activePolicy, updatedAt: policyUpdatedAt }));
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
if (url === "/api/v1/policy" && req.method === "GET") {
|
|
233
|
+
res.writeHead(200);
|
|
234
|
+
res.end(JSON.stringify({ policyText: activePolicy, active: activePolicy.length > 0, updatedAt: policyUpdatedAt }));
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
if ((url === "/api/v1/evaluate" || url === "/api/evaluate") && req.method === "POST") {
|
|
238
|
+
const body = JSON.parse(await readBody(req));
|
|
239
|
+
const action = normalizeAction(body);
|
|
240
|
+
if ("error" in action) {
|
|
241
|
+
res.writeHead(400);
|
|
242
|
+
res.end(JSON.stringify({ error: action.error }));
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
if (!activeWorld) {
|
|
246
|
+
res.writeHead(400);
|
|
247
|
+
res.end(JSON.stringify({ error: "No governance rules set. POST /api/v1/policy first." }));
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
const verdict = govern(action, activeWorld);
|
|
251
|
+
evaluationHistory.push({ action, verdict });
|
|
252
|
+
broadcastEvent({
|
|
253
|
+
type: "evaluation",
|
|
254
|
+
action,
|
|
255
|
+
verdict: { status: verdict.status, reason: verdict.reason, ruleId: verdict.ruleId, consequence: verdict.consequence, reward: verdict.reward }
|
|
256
|
+
});
|
|
257
|
+
res.writeHead(200);
|
|
258
|
+
res.end(JSON.stringify(verdict));
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
if (url === "/api/v1/simulate" && req.method === "POST") {
|
|
262
|
+
const body = JSON.parse(await readBody(req));
|
|
263
|
+
const agents = body.agents ?? 50;
|
|
264
|
+
const steps = body.steps ?? 20;
|
|
265
|
+
const policyText = body.policyText ?? activePolicy;
|
|
266
|
+
if (policyText && policyText !== activePolicy) {
|
|
267
|
+
activePolicy = policyText;
|
|
268
|
+
policyUpdatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
269
|
+
await syncPolicyToWorld();
|
|
270
|
+
broadcastEvent({ type: "policy_updated", policyText: activePolicy, updatedAt: policyUpdatedAt });
|
|
271
|
+
}
|
|
272
|
+
if (!activeWorld) {
|
|
273
|
+
res.writeHead(400);
|
|
274
|
+
res.end(JSON.stringify({ error: "No governance rules set." }));
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
if (activeSimulation) {
|
|
278
|
+
try {
|
|
279
|
+
activeSimulation.kill();
|
|
280
|
+
} catch {
|
|
281
|
+
}
|
|
282
|
+
activeSimulation = null;
|
|
283
|
+
}
|
|
284
|
+
const scriptCandidates = [
|
|
285
|
+
join(process.cwd(), "examples", "social-media-sim", "simulation.py"),
|
|
286
|
+
join(process.cwd(), "demo", "simulations", "social_simulation.py")
|
|
287
|
+
];
|
|
288
|
+
const scriptPath = scriptCandidates.find((p) => existsSync(p));
|
|
289
|
+
if (!scriptPath) {
|
|
290
|
+
res.writeHead(500);
|
|
291
|
+
res.end(JSON.stringify({ error: "Simulation script not found" }));
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
const simArgs = [scriptPath, "--agents", String(agents), "--steps", String(steps)];
|
|
295
|
+
if (body.llmApiKey) {
|
|
296
|
+
simArgs.push("--llm-api-key", body.llmApiKey);
|
|
297
|
+
if (body.llmBaseUrl) simArgs.push("--llm-base-url", body.llmBaseUrl);
|
|
298
|
+
if (body.llmModel) simArgs.push("--llm-model", body.llmModel);
|
|
299
|
+
}
|
|
300
|
+
broadcastEvent({ type: "simulation_start", agents, steps, mode: body.llmApiKey ? "llm" : "rule-based" });
|
|
301
|
+
const proc = spawn("python3", simArgs, { cwd: process.cwd(), env: { ...process.env } });
|
|
302
|
+
activeSimulation = proc;
|
|
303
|
+
let buffer = "";
|
|
304
|
+
proc.stdout.on("data", (chunk) => {
|
|
305
|
+
buffer += chunk.toString();
|
|
306
|
+
const lines = buffer.split("\n");
|
|
307
|
+
buffer = lines.pop() ?? "";
|
|
308
|
+
for (const line of lines) {
|
|
309
|
+
if (!line.trim()) continue;
|
|
310
|
+
try {
|
|
311
|
+
broadcastEvent({ type: "simulation_event", ...JSON.parse(line) });
|
|
312
|
+
} catch {
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
});
|
|
316
|
+
proc.stderr.on("data", (chunk) => {
|
|
317
|
+
const msg = chunk.toString().trim();
|
|
318
|
+
if (msg) process.stderr.write(`[SIM] ${msg}
|
|
319
|
+
`);
|
|
320
|
+
});
|
|
321
|
+
proc.on("close", (code) => {
|
|
322
|
+
activeSimulation = null;
|
|
323
|
+
broadcastEvent({ type: "simulation_complete", exitCode: code });
|
|
324
|
+
});
|
|
325
|
+
res.writeHead(200);
|
|
326
|
+
res.end(JSON.stringify({ status: "started", agents, steps }));
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
if (url === "/api/v1/simulate/stop" && req.method === "POST") {
|
|
330
|
+
if (activeSimulation) {
|
|
331
|
+
activeSimulation.kill();
|
|
332
|
+
activeSimulation = null;
|
|
333
|
+
broadcastEvent({ type: "simulation_stopped" });
|
|
334
|
+
res.writeHead(200);
|
|
335
|
+
res.end(JSON.stringify({ status: "stopped" }));
|
|
336
|
+
} else {
|
|
337
|
+
res.writeHead(200);
|
|
338
|
+
res.end(JSON.stringify({ status: "no_simulation_running" }));
|
|
339
|
+
}
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
342
|
+
if (url === "/api/v1/simulate/source" && req.method === "GET") {
|
|
343
|
+
const candidates = [
|
|
344
|
+
{ sim: "examples/social-media-sim/simulation.py", bridge: "examples/social-media-sim/bridge.py" },
|
|
345
|
+
{ sim: "demo/simulations/social_simulation.py", bridge: "demo/simulations/neuroverse_bridge.py" }
|
|
346
|
+
];
|
|
347
|
+
const files = [];
|
|
348
|
+
for (const c of candidates) {
|
|
349
|
+
const simPath = join(process.cwd(), c.sim);
|
|
350
|
+
if (existsSync(simPath)) {
|
|
351
|
+
files.push({ name: "simulation.py", path: c.sim, content: readFileSync(simPath, "utf-8"), language: "python" });
|
|
352
|
+
const bridgePath = join(process.cwd(), c.bridge);
|
|
353
|
+
if (existsSync(bridgePath)) {
|
|
354
|
+
files.push({ name: "bridge.py", path: c.bridge, content: readFileSync(bridgePath, "utf-8"), language: "python" });
|
|
355
|
+
}
|
|
356
|
+
break;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
res.writeHead(200);
|
|
360
|
+
res.end(JSON.stringify({ files }));
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
if (url === "/api/v1/reason" && req.method === "POST") {
|
|
364
|
+
const body = JSON.parse(await readBody(req));
|
|
365
|
+
const result = await handleReasonRequest(body);
|
|
366
|
+
res.writeHead("error" in result && result.status === "error" ? 400 : 200);
|
|
367
|
+
res.end(JSON.stringify(result));
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
if (url === "/api/v1/reason/capsule" && req.method === "POST") {
|
|
371
|
+
const body = JSON.parse(await readBody(req));
|
|
372
|
+
res.writeHead(200);
|
|
373
|
+
res.end(JSON.stringify(handleCreateCapsule(body)));
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
if (url === "/api/v1/reason/health" && req.method === "GET") {
|
|
377
|
+
res.writeHead(200);
|
|
378
|
+
res.end(JSON.stringify(handleHealthCheck()));
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
if (url === "/api/v1/reason/presets" && req.method === "GET") {
|
|
382
|
+
res.writeHead(200);
|
|
383
|
+
res.end(JSON.stringify(await handleListPresets(join(process.cwd(), "policies"))));
|
|
384
|
+
return;
|
|
385
|
+
}
|
|
386
|
+
if (url === "/api/v1/behavioral" && req.method === "GET") {
|
|
387
|
+
const adaptations = evaluationHistory.map(({ action, verdict }) => {
|
|
388
|
+
const executed = verdict.status === "BLOCK" ? "idle" : action.type;
|
|
389
|
+
return adaptationFromVerdict(action.agentId, action.type, executed, verdict);
|
|
390
|
+
});
|
|
391
|
+
const patterns = detectBehavioralPatterns(adaptations, new Set(evaluationHistory.map((e) => e.action.agentId)).size);
|
|
392
|
+
const narrative = generateAdaptationNarrative(patterns);
|
|
393
|
+
res.writeHead(200);
|
|
394
|
+
res.end(JSON.stringify({ patterns, narrative, adaptations: adaptations.length, agents: new Set(evaluationHistory.map((e) => e.action.agentId)).size }));
|
|
395
|
+
return;
|
|
396
|
+
}
|
|
397
|
+
if (req.method === "GET" && vizDir) {
|
|
398
|
+
const reqPath = url === "/" || url === "/index.html" ? "/index.html" : url;
|
|
399
|
+
const filePath = join(vizDir, reqPath);
|
|
400
|
+
if (filePath.startsWith(vizDir) && serveStaticFile(res, filePath)) return;
|
|
401
|
+
}
|
|
402
|
+
if (req.method === "GET" && (url === "/" || url === "/index.html")) {
|
|
403
|
+
res.writeHead(200, { "Content-Type": "text/html" });
|
|
404
|
+
res.end(`<html><body style="background:#0a0a0a;color:#e2e8f0;font-family:monospace;padding:40px">
|
|
405
|
+
<h2>NeuroVerse Demo Server</h2>
|
|
406
|
+
<p>API is running. Build the viz to see the Governance Observation Deck:</p>
|
|
407
|
+
<pre style="color:#8b5cf6">npm run build:viz</pre>
|
|
408
|
+
<p style="color:#64748b">Then refresh this page.</p>
|
|
409
|
+
<p style="margin-top:20px">API endpoints:</p>
|
|
410
|
+
<pre style="color:#64748b">POST /api/v1/policy \u2014 Set rules
|
|
411
|
+
POST /api/v1/evaluate \u2014 Guard evaluation
|
|
412
|
+
GET /api/v1/events \u2014 SSE governance feed
|
|
413
|
+
GET /api/v1/behavioral \u2014 Behavioral analysis
|
|
414
|
+
POST /api/v1/simulate \u2014 Launch simulation</pre>
|
|
415
|
+
</body></html>`);
|
|
416
|
+
return;
|
|
417
|
+
}
|
|
418
|
+
res.writeHead(404);
|
|
419
|
+
res.end(JSON.stringify({ error: "Not found" }));
|
|
420
|
+
} catch (err) {
|
|
421
|
+
console.error("Server error:", err);
|
|
422
|
+
res.writeHead(500);
|
|
423
|
+
res.end(JSON.stringify({ error: "Internal server error" }));
|
|
424
|
+
}
|
|
425
|
+
});
|
|
426
|
+
server.listen(port, () => {
|
|
427
|
+
process.stderr.write(`
|
|
428
|
+
NeuroVerse Demo Server
|
|
429
|
+
`);
|
|
430
|
+
process.stderr.write(` http://localhost:${port}
|
|
431
|
+
`);
|
|
432
|
+
process.stderr.write(`
|
|
433
|
+
Engine: evaluateGuard() \u2014 same as \`neuroverse guard\`
|
|
434
|
+
`);
|
|
435
|
+
process.stderr.write(` Temp world: ${TEMP_WORLD_DIR}
|
|
436
|
+
`);
|
|
437
|
+
if (worldName) {
|
|
438
|
+
process.stderr.write(` World: ${worldName}
|
|
439
|
+
`);
|
|
440
|
+
}
|
|
441
|
+
process.stderr.write(`
|
|
442
|
+
POST /api/v1/policy \u2192 Set rules (writes temp world)
|
|
443
|
+
`);
|
|
444
|
+
process.stderr.write(` POST /api/v1/evaluate \u2192 Guard evaluation (real engine)
|
|
445
|
+
`);
|
|
446
|
+
process.stderr.write(` GET /api/v1/events \u2192 SSE governance feed
|
|
447
|
+
`);
|
|
448
|
+
process.stderr.write(` POST /api/v1/simulate \u2192 Launch social simulation
|
|
449
|
+
`);
|
|
450
|
+
process.stderr.write(`
|
|
451
|
+
ONE engine. ONE path. CLI is the bible.
|
|
452
|
+
|
|
453
|
+
`);
|
|
454
|
+
if (!noBrowser) {
|
|
455
|
+
const url = `http://localhost:${port}`;
|
|
456
|
+
try {
|
|
457
|
+
const { exec } = __require("child_process");
|
|
458
|
+
const cmd = process.platform === "darwin" ? `open ${url}` : process.platform === "win32" ? `start ${url}` : `xdg-open ${url}`;
|
|
459
|
+
exec(cmd);
|
|
460
|
+
} catch {
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
});
|
|
464
|
+
await new Promise(() => {
|
|
465
|
+
});
|
|
466
|
+
}
|
|
467
|
+
export {
|
|
468
|
+
main
|
|
469
|
+
};
|
|
@@ -2,14 +2,15 @@ import {
|
|
|
2
2
|
DeriveInputError,
|
|
3
3
|
DeriveProviderError,
|
|
4
4
|
deriveWorld
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-6S5CFQXY.js";
|
|
6
6
|
import {
|
|
7
7
|
DERIVE_EXIT_CODES
|
|
8
8
|
} from "./chunk-Q6O7ZLO2.js";
|
|
9
9
|
import "./chunk-OT6PXH54.js";
|
|
10
|
-
import "./chunk-XPDMYECO.js";
|
|
11
10
|
import "./chunk-7P3S7MAY.js";
|
|
12
|
-
import "./chunk-
|
|
11
|
+
import "./chunk-EMQDLDAF.js";
|
|
12
|
+
import "./chunk-PVTQQS3Y.js";
|
|
13
|
+
import "./chunk-QWGCMQQD.js";
|
|
13
14
|
|
|
14
15
|
// src/cli/derive.ts
|
|
15
16
|
function parseArgs(argv) {
|
|
@@ -119,7 +120,7 @@ Normalization: ${n.fixCount} fix(es) applied
|
|
|
119
120
|
process.stderr.write(`
|
|
120
121
|
Bootstrapping to ${args.bootstrapDir}...
|
|
121
122
|
`);
|
|
122
|
-
const { main: bootstrapMain } = await import("./bootstrap-
|
|
123
|
+
const { main: bootstrapMain } = await import("./bootstrap-CQRZVOXK.js");
|
|
123
124
|
await bootstrapMain([
|
|
124
125
|
"--input",
|
|
125
126
|
result.outputPath,
|
|
@@ -3,16 +3,18 @@ import {
|
|
|
3
3
|
} from "./chunk-OT6PXH54.js";
|
|
4
4
|
import {
|
|
5
5
|
__glob
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-QWGCMQQD.js";
|
|
7
7
|
|
|
8
8
|
// import("../adapters/**/*") in src/cli/doctor.ts
|
|
9
9
|
var globImport_adapters = __glob({
|
|
10
10
|
"../adapters/autoresearch.ts": () => import("./adapters/autoresearch.js"),
|
|
11
|
+
"../adapters/deep-agents.ts": () => import("./adapters/deep-agents.js"),
|
|
11
12
|
"../adapters/express.ts": () => import("./adapters/express.js"),
|
|
12
13
|
"../adapters/index.ts": () => import("./adapters/index.js"),
|
|
13
14
|
"../adapters/langchain.ts": () => import("./adapters/langchain.js"),
|
|
14
15
|
"../adapters/openai.ts": () => import("./adapters/openai.js"),
|
|
15
|
-
"../adapters/openclaw.ts": () => import("./adapters/openclaw.js")
|
|
16
|
+
"../adapters/openclaw.ts": () => import("./adapters/openclaw.js"),
|
|
17
|
+
"../adapters/shared.ts": () => import("./shared-7RLUHNMU.js")
|
|
16
18
|
});
|
|
17
19
|
|
|
18
20
|
// src/cli/doctor.ts
|
|
@@ -101,7 +103,7 @@ async function main(argv) {
|
|
|
101
103
|
});
|
|
102
104
|
}
|
|
103
105
|
try {
|
|
104
|
-
const { evaluateGuard } = await import("./guard-engine-
|
|
106
|
+
const { evaluateGuard } = await import("./guard-engine-PNR6MHCM.js");
|
|
105
107
|
checks.push({
|
|
106
108
|
label: "Guard engine",
|
|
107
109
|
status: typeof evaluateGuard === "function" ? "pass" : "fail",
|
|
@@ -111,7 +113,7 @@ async function main(argv) {
|
|
|
111
113
|
checks.push({ label: "Guard engine", status: "fail", value: "failed to load" });
|
|
112
114
|
}
|
|
113
115
|
try {
|
|
114
|
-
const { validateWorld } = await import("./validate-engine-
|
|
116
|
+
const { validateWorld } = await import("./validate-engine-7ZXFVGF2.js");
|
|
115
117
|
checks.push({
|
|
116
118
|
label: "Validation engine",
|
|
117
119
|
status: typeof validateWorld === "function" ? "pass" : "fail",
|