@neuroverseos/governance 0.1.6 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/README.md +279 -423
  2. package/dist/adapters/express.cjs +242 -2
  3. package/dist/adapters/express.d.cts +1 -1
  4. package/dist/adapters/express.d.ts +1 -1
  5. package/dist/adapters/express.js +5 -3
  6. package/dist/adapters/index.cjs +301 -5
  7. package/dist/adapters/index.d.cts +1 -1
  8. package/dist/adapters/index.d.ts +1 -1
  9. package/dist/adapters/index.js +8 -6
  10. package/dist/adapters/langchain.cjs +267 -3
  11. package/dist/adapters/langchain.d.cts +8 -1
  12. package/dist/adapters/langchain.d.ts +8 -1
  13. package/dist/adapters/langchain.js +5 -3
  14. package/dist/adapters/openai.cjs +267 -3
  15. package/dist/adapters/openai.d.cts +8 -1
  16. package/dist/adapters/openai.d.ts +8 -1
  17. package/dist/adapters/openai.js +5 -3
  18. package/dist/adapters/openclaw.cjs +267 -3
  19. package/dist/adapters/openclaw.d.cts +8 -1
  20. package/dist/adapters/openclaw.d.ts +8 -1
  21. package/dist/adapters/openclaw.js +5 -3
  22. package/dist/{bootstrap-H4HHKQ5G.js → bootstrap-GXVDZNF7.js} +2 -1
  23. package/dist/{build-73KAVHEY.js → build-P42YFKQV.js} +34 -3
  24. package/dist/{chunk-FYPYZFV5.js → chunk-2JQJ5U5X.js} +1 -1
  25. package/dist/chunk-37JG24WH.js +161 -0
  26. package/dist/chunk-5EDDNJU6.js +321 -0
  27. package/dist/{chunk-O5OMJMIE.js → chunk-7P3S7MAY.js} +502 -2
  28. package/dist/chunk-A5W4GNQO.js +130 -0
  29. package/dist/{chunk-ITJ3LCPG.js → chunk-ADV7Q2LJ.js} +1 -1
  30. package/dist/chunk-AKW5YVCE.js +96 -0
  31. package/dist/{chunk-EIUHJXBB.js → chunk-GR6DGCZ2.js} +1 -1
  32. package/dist/{chunk-EQXFOKH2.js → chunk-IVPKFJX3.js} +24 -3
  33. package/dist/{chunk-D7BGWV2J.js → chunk-NF5POFCI.js} +5 -3
  34. package/dist/chunk-OT6PXH54.js +61 -0
  35. package/dist/chunk-P74Y66ZV.js +205 -0
  36. package/dist/chunk-PAX2P6ZP.js +601 -0
  37. package/dist/{chunk-B4NF3OLW.js → chunk-PQBJBVSW.js} +56 -2
  38. package/dist/{chunk-T4X42QXC.js → chunk-Q6O7ZLO2.js} +0 -59
  39. package/dist/{chunk-FZQCRGUU.js → chunk-TINSRYXQ.js} +24 -3
  40. package/dist/{chunk-CROPZ75A.js → chunk-UPJNTSVM.js} +24 -3
  41. package/dist/chunk-YZFATT7X.js +9 -0
  42. package/dist/{chunk-Z2S2HIV5.js → chunk-ZL4AHY4X.js} +2 -2
  43. package/dist/cli/neuroverse.cjs +5287 -740
  44. package/dist/cli/neuroverse.js +69 -13
  45. package/dist/cli/plan.cjs +1554 -0
  46. package/dist/cli/plan.d.cts +20 -0
  47. package/dist/cli/plan.d.ts +20 -0
  48. package/dist/cli/plan.js +346 -0
  49. package/dist/cli/run.cjs +1716 -0
  50. package/dist/cli/run.d.cts +20 -0
  51. package/dist/cli/run.d.ts +20 -0
  52. package/dist/cli/run.js +143 -0
  53. package/dist/{configure-ai-46JVG56I.js → configure-ai-TK67ZWZL.js} +5 -2
  54. package/dist/{derive-6NAEWLM5.js → derive-TLIV4OOU.js} +6 -4
  55. package/dist/doctor-V72UM2TC.js +170 -0
  56. package/dist/{explain-3B3VB6TL.js → explain-IDCRWMPX.js} +2 -1
  57. package/dist/{guard-67Y66P3I.js → guard-WA3FCCIO.js} +20 -6
  58. package/dist/{guard-contract-D_RQz9kt.d.ts → guard-contract-D-2LQInm.d.cts} +144 -2
  59. package/dist/{guard-contract-D_RQz9kt.d.cts → guard-contract-D-2LQInm.d.ts} +144 -2
  60. package/dist/guard-engine-D7X4CVAE.js +10 -0
  61. package/dist/{impact-CHERK3O6.js → impact-BWULZ5RP.js} +5 -3
  62. package/dist/{improve-YG6I6ERG.js → improve-GPUBKTEA.js} +4 -3
  63. package/dist/index.cjs +2095 -89
  64. package/dist/index.d.cts +466 -12
  65. package/dist/index.d.ts +466 -12
  66. package/dist/index.js +70 -20
  67. package/dist/{init-Z66T6TDI.js → init-PKPIYHYE.js} +2 -0
  68. package/dist/mcp-server-YUOQP4M5.js +13 -0
  69. package/dist/model-adapter-BB7G4MFI.js +11 -0
  70. package/dist/playground-CBXMAW2B.js +550 -0
  71. package/dist/redteam-SSNABQ7W.js +357 -0
  72. package/dist/session-MWRBTCYX.js +14 -0
  73. package/dist/{simulate-ETHHINZ4.js → simulate-VDOYQFRO.js} +2 -1
  74. package/dist/test-3GZSG5FR.js +217 -0
  75. package/dist/{trace-3YODSSIP.js → trace-TM4Z7G73.js} +4 -2
  76. package/dist/{validate-UVE6GKQU.js → validate-LLBWVPGV.js} +15 -6
  77. package/dist/validate-engine-UIABSIHD.js +7 -0
  78. package/dist/{world-WLNHL5XC.js → world-LAXO6DOX.js} +87 -7
  79. package/dist/world-loader-HMPTOEA2.js +9 -0
  80. package/package.json +19 -5
  81. package/dist/validate-engine-657D75OG.js +0 -6
  82. /package/dist/{chunk-M3TZFGHO.js → chunk-JZPQGIKR.js} +0 -0
@@ -0,0 +1,321 @@
1
+ import {
2
+ evaluateGuard
3
+ } from "./chunk-PQBJBVSW.js";
4
+ import {
5
+ loadWorld
6
+ } from "./chunk-JZPQGIKR.js";
7
+ import {
8
+ advancePlan,
9
+ evaluatePlan,
10
+ getPlanProgress
11
+ } from "./chunk-P74Y66ZV.js";
12
+
13
+ // src/runtime/session.ts
14
+ async function defaultToolExecutor(name, args) {
15
+ return `Tool "${name}" executed successfully with args: ${JSON.stringify(args)}`;
16
+ }
17
+ var SessionManager = class {
18
+ config;
19
+ state;
20
+ engineOptions;
21
+ executor;
22
+ constructor(config) {
23
+ this.config = config;
24
+ this.executor = config.toolExecutor ?? defaultToolExecutor;
25
+ this.engineOptions = {
26
+ trace: config.trace ?? false,
27
+ level: config.level,
28
+ plan: config.plan
29
+ };
30
+ this.state = {
31
+ active: false,
32
+ world: config.world,
33
+ plan: config.plan,
34
+ progress: config.plan ? getPlanProgress(config.plan) : void 0,
35
+ actionsEvaluated: 0,
36
+ actionsAllowed: 0,
37
+ actionsBlocked: 0,
38
+ actionsPaused: 0
39
+ };
40
+ }
41
+ /**
42
+ * Initialize the session — load world from disk if needed.
43
+ */
44
+ async start() {
45
+ if (this.config.worldPath && !this.config.world) {
46
+ this.state.world = await loadWorld(this.config.worldPath);
47
+ }
48
+ if (!this.state.world) {
49
+ throw new Error("No world provided. Use --world or pass a world definition.");
50
+ }
51
+ this.state.active = true;
52
+ return this.getState();
53
+ }
54
+ /**
55
+ * Evaluate a single event against governance.
56
+ * Returns the verdict without executing anything.
57
+ */
58
+ evaluate(event) {
59
+ this.engineOptions.plan = this.state.plan;
60
+ const verdict = evaluateGuard(event, this.state.world, this.engineOptions);
61
+ this.state.actionsEvaluated++;
62
+ if (verdict.status === "ALLOW") this.state.actionsAllowed++;
63
+ if (verdict.status === "BLOCK") this.state.actionsBlocked++;
64
+ if (verdict.status === "PAUSE") this.state.actionsPaused++;
65
+ this.config.onVerdict?.(verdict, event);
66
+ return verdict;
67
+ }
68
+ /**
69
+ * Evaluate and execute a tool call.
70
+ * Returns the execution result or block reason.
71
+ */
72
+ async executeToolCall(toolCall) {
73
+ let args;
74
+ try {
75
+ args = JSON.parse(toolCall.function.arguments);
76
+ } catch {
77
+ args = { raw: toolCall.function.arguments };
78
+ }
79
+ const event = {
80
+ intent: toolCall.function.name,
81
+ tool: toolCall.function.name,
82
+ args,
83
+ direction: "input"
84
+ };
85
+ const verdict = this.evaluate(event);
86
+ if (verdict.status === "BLOCK") {
87
+ return { allowed: false, verdict };
88
+ }
89
+ if (verdict.status === "PAUSE") {
90
+ return { allowed: false, verdict };
91
+ }
92
+ const result = await this.executor(toolCall.function.name, args);
93
+ this.config.onToolResult?.(toolCall.function.name, result);
94
+ if (this.state.plan) {
95
+ const planVerdict = evaluatePlan(event, this.state.plan);
96
+ if (planVerdict.matchedStep) {
97
+ this.state.plan = advancePlan(this.state.plan, planVerdict.matchedStep);
98
+ this.engineOptions.plan = this.state.plan;
99
+ this.state.progress = getPlanProgress(this.state.plan);
100
+ this.config.onPlanProgress?.(this.state.progress);
101
+ if (this.state.progress.completed === this.state.progress.total) {
102
+ this.config.onPlanComplete?.();
103
+ }
104
+ }
105
+ }
106
+ return { allowed: true, verdict, result };
107
+ }
108
+ /**
109
+ * Process a model response — evaluate and execute all tool calls.
110
+ * Returns results for each tool call.
111
+ */
112
+ async processModelResponse(response, model) {
113
+ if (response.toolCalls.length === 0) {
114
+ return response;
115
+ }
116
+ for (const toolCall of response.toolCalls) {
117
+ const { allowed, verdict, result } = await this.executeToolCall(toolCall);
118
+ if (allowed && result) {
119
+ const nextResponse = await model.sendToolResult(toolCall.id, result);
120
+ if (nextResponse.toolCalls.length > 0) {
121
+ return this.processModelResponse(nextResponse, model);
122
+ }
123
+ return nextResponse;
124
+ } else {
125
+ const reason = verdict.reason ?? "Action blocked by governance.";
126
+ const nextResponse = await model.sendBlockedResult(toolCall.id, reason);
127
+ if (nextResponse.toolCalls.length > 0) {
128
+ return this.processModelResponse(nextResponse, model);
129
+ }
130
+ return nextResponse;
131
+ }
132
+ }
133
+ return response;
134
+ }
135
+ /** Get current session state. */
136
+ getState() {
137
+ return { ...this.state };
138
+ }
139
+ /** Stop the session. */
140
+ stop() {
141
+ this.state.active = false;
142
+ return this.getState();
143
+ }
144
+ };
145
+ async function runPipeMode(config) {
146
+ const session = new SessionManager(config);
147
+ await session.start();
148
+ const state = session.getState();
149
+ process.stderr.write(`[neuroverse] Pipe mode active
150
+ `);
151
+ process.stderr.write(`[neuroverse] World: ${state.world.world.name}
152
+ `);
153
+ if (state.plan) {
154
+ process.stderr.write(`[neuroverse] Plan: ${state.plan.plan_id} (${state.plan.objective})
155
+ `);
156
+ }
157
+ return new Promise((resolve, reject) => {
158
+ let buffer = "";
159
+ process.stdin.setEncoding("utf-8");
160
+ process.stdin.on("data", (chunk) => {
161
+ buffer += chunk;
162
+ const lines = buffer.split("\n");
163
+ buffer = lines.pop() ?? "";
164
+ for (const line of lines) {
165
+ const trimmed = line.trim();
166
+ if (!trimmed) continue;
167
+ try {
168
+ const event = JSON.parse(trimmed);
169
+ if (!event.intent) {
170
+ process.stderr.write(`[neuroverse] Warning: event missing "intent" field
171
+ `);
172
+ continue;
173
+ }
174
+ const verdict = session.evaluate(event);
175
+ process.stdout.write(JSON.stringify(verdict) + "\n");
176
+ } catch (err) {
177
+ process.stderr.write(`[neuroverse] Error parsing line: ${err}
178
+ `);
179
+ }
180
+ }
181
+ });
182
+ process.stdin.on("end", () => {
183
+ if (buffer.trim()) {
184
+ try {
185
+ const event = JSON.parse(buffer.trim());
186
+ if (event.intent) {
187
+ const verdict = session.evaluate(event);
188
+ process.stdout.write(JSON.stringify(verdict) + "\n");
189
+ }
190
+ } catch {
191
+ }
192
+ }
193
+ const finalState = session.stop();
194
+ process.stderr.write(
195
+ `[neuroverse] Session complete: ${finalState.actionsEvaluated} evaluated, ${finalState.actionsAllowed} allowed, ${finalState.actionsBlocked} blocked, ${finalState.actionsPaused} paused
196
+ `
197
+ );
198
+ resolve();
199
+ });
200
+ process.stdin.on("error", reject);
201
+ });
202
+ }
203
+ async function runInteractiveMode(config, model) {
204
+ const session = new SessionManager(config);
205
+ await session.start();
206
+ const state = session.getState();
207
+ process.stdout.write("\n");
208
+ process.stdout.write(` World: ${state.world.world.name}
209
+ `);
210
+ if (state.plan) {
211
+ process.stdout.write(` Plan: ${state.plan.plan_id}
212
+ `);
213
+ process.stdout.write(` Goal: ${state.plan.objective}
214
+ `);
215
+ process.stdout.write(` Steps: ${state.progress?.total ?? 0}
216
+ `);
217
+ }
218
+ process.stdout.write(` Type "exit" to end session.
219
+ `);
220
+ process.stdout.write("\n");
221
+ const readline = await import("readline");
222
+ const rl = readline.createInterface({
223
+ input: process.stdin,
224
+ output: process.stdout,
225
+ prompt: "> "
226
+ });
227
+ const printProgress = () => {
228
+ const s = session.getState();
229
+ if (s.progress) {
230
+ process.stdout.write(
231
+ ` [plan: ${s.progress.completed}/${s.progress.total} (${s.progress.percentage}%)]
232
+ `
233
+ );
234
+ }
235
+ };
236
+ rl.prompt();
237
+ rl.on("line", async (input) => {
238
+ const trimmed = input.trim();
239
+ if (!trimmed) {
240
+ rl.prompt();
241
+ return;
242
+ }
243
+ if (trimmed === "exit" || trimmed === "quit") {
244
+ const finalState = session.stop();
245
+ process.stdout.write("\n");
246
+ process.stdout.write(` Session complete.
247
+ `);
248
+ process.stdout.write(` Actions: ${finalState.actionsEvaluated} evaluated`);
249
+ process.stdout.write(`, ${finalState.actionsAllowed} allowed`);
250
+ process.stdout.write(`, ${finalState.actionsBlocked} blocked
251
+ `);
252
+ if (finalState.progress) {
253
+ process.stdout.write(
254
+ ` Plan: ${finalState.progress.completed}/${finalState.progress.total} steps completed
255
+ `
256
+ );
257
+ }
258
+ process.stdout.write("\n");
259
+ rl.close();
260
+ return;
261
+ }
262
+ if (trimmed === "status") {
263
+ const s = session.getState();
264
+ process.stdout.write(`
265
+ World: ${s.world.world.name}
266
+ `);
267
+ process.stdout.write(` Actions: ${s.actionsEvaluated} evaluated
268
+ `);
269
+ process.stdout.write(` Allowed: ${s.actionsAllowed} | Blocked: ${s.actionsBlocked} | Paused: ${s.actionsPaused}
270
+ `);
271
+ if (s.progress && s.plan) {
272
+ process.stdout.write(` Plan: ${s.plan.plan_id} \u2014 ${s.progress.completed}/${s.progress.total} (${s.progress.percentage}%)
273
+ `);
274
+ for (const step of s.plan.steps) {
275
+ const icon = step.status === "completed" ? "[x]" : "[ ]";
276
+ process.stdout.write(` ${icon} ${step.label}
277
+ `);
278
+ }
279
+ }
280
+ process.stdout.write("\n");
281
+ rl.prompt();
282
+ return;
283
+ }
284
+ try {
285
+ const response = await model.chat(trimmed);
286
+ if (response.toolCalls.length > 0) {
287
+ const finalResponse = await session.processModelResponse(response, model);
288
+ if (finalResponse.content) {
289
+ process.stdout.write(`
290
+ ${finalResponse.content}
291
+
292
+ `);
293
+ }
294
+ printProgress();
295
+ } else if (response.content) {
296
+ process.stdout.write(`
297
+ ${response.content}
298
+
299
+ `);
300
+ }
301
+ } catch (err) {
302
+ process.stderr.write(`
303
+ Error: ${err}
304
+
305
+ `);
306
+ }
307
+ rl.prompt();
308
+ });
309
+ rl.on("close", () => {
310
+ session.stop();
311
+ });
312
+ return new Promise((resolve) => {
313
+ rl.on("close", resolve);
314
+ });
315
+ }
316
+
317
+ export {
318
+ SessionManager,
319
+ runPipeMode,
320
+ runInteractiveMode
321
+ };