@neuroverseos/governance 0.4.3 → 0.5.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.
- package/README.md +189 -0
- package/dist/adapters/autoresearch.js +2 -2
- package/dist/adapters/deep-agents.js +2 -2
- package/dist/adapters/express.js +2 -2
- package/dist/adapters/github.js +2 -2
- package/dist/adapters/index.js +23 -21
- package/dist/adapters/langchain.js +2 -2
- package/dist/adapters/mentraos.js +8 -6
- package/dist/adapters/openai.js +2 -2
- package/dist/adapters/openclaw.js +2 -2
- package/dist/{add-XSANI3FK.js → add-JP7TC2K3.js} +1 -1
- package/dist/admin/index.cjs +2214 -0
- package/dist/admin/index.d.cts +362 -0
- package/dist/admin/index.d.ts +362 -0
- package/dist/admin/index.js +703 -0
- package/dist/{build-EGBGZFIJ.js → build-THUEYMVT.js} +5 -5
- package/dist/{chunk-YJ34R5NB.js → chunk-5RAQ5DZW.js} +3 -3
- package/dist/{chunk-RDA7ISWC.js → chunk-6UPEUMJ2.js} +3 -3
- package/dist/chunk-7UU7V3AD.js +447 -0
- package/dist/{chunk-ZEIT2QLM.js → chunk-EK77AJAH.js} +22 -4
- package/dist/{chunk-3S5AD4AB.js → chunk-FGOSKQDE.js} +3 -3
- package/dist/{chunk-GTPV2XGO.js → chunk-GJ6LM4JZ.js} +1 -441
- package/dist/chunk-H3REGQRI.js +107 -0
- package/dist/{chunk-J2IZBHXJ.js → chunk-LAKUB76X.js} +3 -3
- package/dist/{chunk-FVOGUCB6.js → chunk-R23T5SZG.js} +3 -3
- package/dist/{chunk-A7SHG75T.js → chunk-RF2L5SYG.js} +3 -3
- package/dist/{chunk-QMVQ6KPL.js → chunk-TL4DLMMW.js} +3 -3
- package/dist/{chunk-AV7XJJWK.js → chunk-TZBERHFM.js} +3 -3
- package/dist/{chunk-3AYKQHYI.js → chunk-UZBW44KD.js} +3 -3
- package/dist/{chunk-FS2UUJJO.js → chunk-XPMZB46F.js} +3 -3
- package/dist/cli/neuroverse.cjs +962 -284
- package/dist/cli/neuroverse.js +46 -22
- package/dist/cli/plan.js +1 -1
- package/dist/cli/run.cjs +242 -139
- package/dist/cli/run.js +23 -3
- package/dist/{demo-6OQYWRR6.js → demo-N5K4VXJW.js} +3 -3
- package/dist/{derive-7Y7YWVLU.js → derive-5LOMN7GO.js} +4 -4
- package/dist/{equity-penalties-NVBAB5WL.js → equity-penalties-PYCJ3Q4U.js} +6 -6
- package/dist/{explain-HDFN4ION.js → explain-42TVC3QD.js} +1 -1
- package/dist/{guard-6KSCWT2W.js → guard-TPYDFG6V.js} +16 -4
- package/dist/{improve-2PWGGO5B.js → improve-HLZGJ54Z.js} +3 -3
- package/dist/index.cjs +19 -1
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +27 -27
- package/dist/keygen-BSZH3NM2.js +77 -0
- package/dist/{lens-MHMUDCMQ.js → lens-NFGZHD76.js} +1 -1
- package/dist/{mcp-server-TNIWZ7B5.js → mcp-server-5XXNG6VC.js} +2 -2
- package/dist/migrate-NH5PVMX4.js +221 -0
- package/dist/{playground-3FLDGBET.js → playground-2EU5CFIH.js} +4 -4
- package/dist/{redteam-HV6LMKEH.js → redteam-VK6OVHAE.js} +3 -3
- package/dist/{session-XZP2754M.js → session-NGA4DUPL.js} +2 -2
- package/dist/sign-RRELHKWM.js +11 -0
- package/dist/{simulate-VT437EEL.js → simulate-4YNOBMES.js} +1 -1
- package/dist/{test-4WTX6RKQ.js → test-HDBPMQTG.js} +3 -3
- package/dist/{validate-M52DX22Y.js → validate-6MFQZ2EG.js} +1 -1
- package/dist/verify-6AVTWX75.js +151 -0
- package/dist/{world-O4HTQPDP.js → world-H5WVURKU.js} +1 -1
- package/dist/{world-loader-YTYFOP7D.js → world-loader-J47PCPDZ.js} +1 -1
- package/package.json +22 -10
- package/dist/{behavioral-SLW7ALEK.js → behavioral-SPWPGYXL.js} +3 -3
- package/dist/{bootstrap-2OW5ZLBL.js → bootstrap-IP5QMC3Q.js} +3 -3
- package/dist/{chunk-I4RTIMLX.js → chunk-EQUAWNXW.js} +0 -0
- package/dist/{chunk-DA5MHFRR.js → chunk-NTHXZAW4.js} +3 -3
- package/dist/{chunk-FHXXD2TI.js → chunk-QZ666FCV.js} +6 -6
- package/dist/{configure-ai-LL3VAPQW.js → configure-ai-5MP5DWTT.js} +3 -3
- package/dist/{decision-flow-3K4D72G4.js → decision-flow-IJPNMVQK.js} +3 -3
- /package/dist/{doctor-EC5OYTI3.js → doctor-Q5APJOTS.js} +0 -0
package/dist/cli/neuroverse.js
CHANGED
|
@@ -29,6 +29,10 @@ Commands:
|
|
|
29
29
|
decision-flow Intent \u2192 Rule \u2192 Outcome visualization (behavioral governance)
|
|
30
30
|
equity-penalties Fortune 500 equity PENALIZE/REWARD simulation
|
|
31
31
|
world World management (status, diff, snapshot, rollback)
|
|
32
|
+
keygen Generate Ed25519 signing keypair
|
|
33
|
+
sign Sign a world artifact (cryptographic manifest)
|
|
34
|
+
verify Verify a signed world artifact
|
|
35
|
+
migrate Migrate world schema between versions
|
|
32
36
|
derive AI-assisted synthesis of .nv-world.md from markdown
|
|
33
37
|
bootstrap Compile .nv-world.md \u2192 world JSON files
|
|
34
38
|
configure-ai Configure AI provider credentials
|
|
@@ -66,6 +70,10 @@ Usage:
|
|
|
66
70
|
neuroverse equity-penalties --world <dir> [--agents N] [--rounds N] [--json]
|
|
67
71
|
neuroverse configure-ai --provider <name> --model <name> --api-key <key>
|
|
68
72
|
neuroverse configure-world [--output <dir>]
|
|
73
|
+
neuroverse keygen [--output <dir>] [--name <name>]
|
|
74
|
+
neuroverse sign --world <dir> [--key <path>]
|
|
75
|
+
neuroverse verify --world <dir> [--key <path>]
|
|
76
|
+
neuroverse migrate --world <dir> [--dry-run] [--backup]
|
|
69
77
|
neuroverse lens list [--world <dir>] [--json]
|
|
70
78
|
neuroverse lens preview <id> [--world <dir>]
|
|
71
79
|
neuroverse lens compile <id,...> [--world <dir>] [--role <role>] [--json]
|
|
@@ -100,23 +108,23 @@ async function main() {
|
|
|
100
108
|
const subArgs = args.slice(1);
|
|
101
109
|
switch (command) {
|
|
102
110
|
case "add": {
|
|
103
|
-
const { main: addMain } = await import("../add-
|
|
111
|
+
const { main: addMain } = await import("../add-JP7TC2K3.js");
|
|
104
112
|
return addMain(subArgs);
|
|
105
113
|
}
|
|
106
114
|
case "build": {
|
|
107
|
-
const { main: buildMain } = await import("../build-
|
|
115
|
+
const { main: buildMain } = await import("../build-THUEYMVT.js");
|
|
108
116
|
return buildMain(subArgs);
|
|
109
117
|
}
|
|
110
118
|
case "explain": {
|
|
111
|
-
const { main: explainMain } = await import("../explain-
|
|
119
|
+
const { main: explainMain } = await import("../explain-42TVC3QD.js");
|
|
112
120
|
return explainMain(subArgs);
|
|
113
121
|
}
|
|
114
122
|
case "simulate": {
|
|
115
|
-
const { main: simulateMain } = await import("../simulate-
|
|
123
|
+
const { main: simulateMain } = await import("../simulate-4YNOBMES.js");
|
|
116
124
|
return simulateMain(subArgs);
|
|
117
125
|
}
|
|
118
126
|
case "improve": {
|
|
119
|
-
const { main: improveMain } = await import("../improve-
|
|
127
|
+
const { main: improveMain } = await import("../improve-HLZGJ54Z.js");
|
|
120
128
|
return improveMain(subArgs);
|
|
121
129
|
}
|
|
122
130
|
case "init": {
|
|
@@ -132,35 +140,35 @@ async function main() {
|
|
|
132
140
|
return inferWorldMain(subArgs);
|
|
133
141
|
}
|
|
134
142
|
case "bootstrap": {
|
|
135
|
-
const { main: bootstrapMain } = await import("../bootstrap-
|
|
143
|
+
const { main: bootstrapMain } = await import("../bootstrap-IP5QMC3Q.js");
|
|
136
144
|
return bootstrapMain(subArgs);
|
|
137
145
|
}
|
|
138
146
|
case "validate": {
|
|
139
|
-
const { main: validateMain } = await import("../validate-
|
|
147
|
+
const { main: validateMain } = await import("../validate-6MFQZ2EG.js");
|
|
140
148
|
return validateMain(subArgs);
|
|
141
149
|
}
|
|
142
150
|
case "guard": {
|
|
143
|
-
const { main: guardMain } = await import("../guard-
|
|
151
|
+
const { main: guardMain } = await import("../guard-TPYDFG6V.js");
|
|
144
152
|
return guardMain(subArgs);
|
|
145
153
|
}
|
|
146
154
|
case "test": {
|
|
147
|
-
const { main: testMain } = await import("../test-
|
|
155
|
+
const { main: testMain } = await import("../test-HDBPMQTG.js");
|
|
148
156
|
return testMain(subArgs);
|
|
149
157
|
}
|
|
150
158
|
case "redteam": {
|
|
151
|
-
const { main: redteamMain } = await import("../redteam-
|
|
159
|
+
const { main: redteamMain } = await import("../redteam-VK6OVHAE.js");
|
|
152
160
|
return redteamMain(subArgs);
|
|
153
161
|
}
|
|
154
162
|
case "demo": {
|
|
155
|
-
const { main: demoMain } = await import("../demo-
|
|
163
|
+
const { main: demoMain } = await import("../demo-N5K4VXJW.js");
|
|
156
164
|
return demoMain(subArgs);
|
|
157
165
|
}
|
|
158
166
|
case "doctor": {
|
|
159
|
-
const { main: doctorMain } = await import("../doctor-
|
|
167
|
+
const { main: doctorMain } = await import("../doctor-Q5APJOTS.js");
|
|
160
168
|
return doctorMain(subArgs);
|
|
161
169
|
}
|
|
162
170
|
case "playground": {
|
|
163
|
-
const { main: playgroundMain } = await import("../playground-
|
|
171
|
+
const { main: playgroundMain } = await import("../playground-2EU5CFIH.js");
|
|
164
172
|
return playgroundMain(subArgs);
|
|
165
173
|
}
|
|
166
174
|
case "plan": {
|
|
@@ -172,11 +180,11 @@ async function main() {
|
|
|
172
180
|
return runMain(subArgs);
|
|
173
181
|
}
|
|
174
182
|
case "mcp": {
|
|
175
|
-
const { startMcpServer } = await import("../mcp-server-
|
|
183
|
+
const { startMcpServer } = await import("../mcp-server-5XXNG6VC.js");
|
|
176
184
|
return startMcpServer(subArgs);
|
|
177
185
|
}
|
|
178
186
|
case "worlds": {
|
|
179
|
-
const { main: worldMain } = await import("../world-
|
|
187
|
+
const { main: worldMain } = await import("../world-H5WVURKU.js");
|
|
180
188
|
return worldMain(["list", ...subArgs]);
|
|
181
189
|
}
|
|
182
190
|
case "trace": {
|
|
@@ -188,27 +196,43 @@ async function main() {
|
|
|
188
196
|
return impactMain(subArgs);
|
|
189
197
|
}
|
|
190
198
|
case "behavioral": {
|
|
191
|
-
const { main: behavioralMain } = await import("../behavioral-
|
|
199
|
+
const { main: behavioralMain } = await import("../behavioral-SPWPGYXL.js");
|
|
192
200
|
return behavioralMain(subArgs);
|
|
193
201
|
}
|
|
194
202
|
case "world": {
|
|
195
|
-
const { main: worldMain } = await import("../world-
|
|
203
|
+
const { main: worldMain } = await import("../world-H5WVURKU.js");
|
|
196
204
|
return worldMain(subArgs);
|
|
197
205
|
}
|
|
198
206
|
case "derive": {
|
|
199
|
-
const { main: deriveMain } = await import("../derive-
|
|
207
|
+
const { main: deriveMain } = await import("../derive-5LOMN7GO.js");
|
|
200
208
|
return deriveMain(subArgs);
|
|
201
209
|
}
|
|
202
210
|
case "decision-flow": {
|
|
203
|
-
const { main: decisionFlowMain } = await import("../decision-flow-
|
|
211
|
+
const { main: decisionFlowMain } = await import("../decision-flow-IJPNMVQK.js");
|
|
204
212
|
return decisionFlowMain(subArgs);
|
|
205
213
|
}
|
|
206
214
|
case "equity-penalties": {
|
|
207
|
-
const { main: equityPenaltiesMain } = await import("../equity-penalties-
|
|
215
|
+
const { main: equityPenaltiesMain } = await import("../equity-penalties-PYCJ3Q4U.js");
|
|
208
216
|
return equityPenaltiesMain(subArgs);
|
|
209
217
|
}
|
|
218
|
+
case "keygen": {
|
|
219
|
+
const { main: keygenMain } = await import("../keygen-BSZH3NM2.js");
|
|
220
|
+
return keygenMain(subArgs);
|
|
221
|
+
}
|
|
222
|
+
case "sign": {
|
|
223
|
+
const { main: signMain } = await import("../sign-RRELHKWM.js");
|
|
224
|
+
return signMain(subArgs);
|
|
225
|
+
}
|
|
226
|
+
case "verify": {
|
|
227
|
+
const { main: verifyMain } = await import("../verify-6AVTWX75.js");
|
|
228
|
+
return verifyMain(subArgs);
|
|
229
|
+
}
|
|
230
|
+
case "migrate": {
|
|
231
|
+
const { main: migrateMain } = await import("../migrate-NH5PVMX4.js");
|
|
232
|
+
return migrateMain(subArgs);
|
|
233
|
+
}
|
|
210
234
|
case "configure-ai": {
|
|
211
|
-
const { main: configureAiMain } = await import("../configure-ai-
|
|
235
|
+
const { main: configureAiMain } = await import("../configure-ai-5MP5DWTT.js");
|
|
212
236
|
return configureAiMain(subArgs);
|
|
213
237
|
}
|
|
214
238
|
case "configure-world": {
|
|
@@ -216,7 +240,7 @@ async function main() {
|
|
|
216
240
|
return configureWorldMain(subArgs);
|
|
217
241
|
}
|
|
218
242
|
case "lens": {
|
|
219
|
-
const { main: lensMain } = await import("../lens-
|
|
243
|
+
const { main: lensMain } = await import("../lens-NFGZHD76.js");
|
|
220
244
|
return lensMain(subArgs);
|
|
221
245
|
}
|
|
222
246
|
case "--help":
|
package/dist/cli/plan.js
CHANGED
|
@@ -100,7 +100,7 @@ async function checkCommand(args) {
|
|
|
100
100
|
}
|
|
101
101
|
const worldPath = parseArg(args, "--world");
|
|
102
102
|
if (worldPath) {
|
|
103
|
-
const { loadWorld } = await import("../world-loader-
|
|
103
|
+
const { loadWorld } = await import("../world-loader-J47PCPDZ.js");
|
|
104
104
|
const { evaluateGuard } = await import("../engine/guard-engine.js");
|
|
105
105
|
const world = await loadWorld(worldPath);
|
|
106
106
|
const verdict2 = evaluateGuard(event, world, { plan });
|
package/dist/cli/run.cjs
CHANGED
|
@@ -30,143 +30,6 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
30
30
|
));
|
|
31
31
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
32
32
|
|
|
33
|
-
// src/runtime/model-adapter.ts
|
|
34
|
-
var model_adapter_exports = {};
|
|
35
|
-
__export(model_adapter_exports, {
|
|
36
|
-
ModelAdapter: () => ModelAdapter,
|
|
37
|
-
PROVIDERS: () => PROVIDERS,
|
|
38
|
-
resolveProvider: () => resolveProvider
|
|
39
|
-
});
|
|
40
|
-
function resolveProvider(provider, overrides) {
|
|
41
|
-
const preset = PROVIDERS[provider];
|
|
42
|
-
if (!preset) {
|
|
43
|
-
throw new Error(
|
|
44
|
-
`Unknown provider: "${provider}". Available: ${Object.keys(PROVIDERS).join(", ")}`
|
|
45
|
-
);
|
|
46
|
-
}
|
|
47
|
-
const apiKey = overrides?.apiKey ?? (preset.envVar ? process.env[preset.envVar] : "") ?? "";
|
|
48
|
-
if (!apiKey && preset.envVar) {
|
|
49
|
-
throw new Error(
|
|
50
|
-
`Missing API key. Set ${preset.envVar} or pass --api-key.`
|
|
51
|
-
);
|
|
52
|
-
}
|
|
53
|
-
return {
|
|
54
|
-
baseUrl: overrides?.baseUrl ?? preset.baseUrl,
|
|
55
|
-
apiKey,
|
|
56
|
-
model: overrides?.model ?? preset.defaultModel,
|
|
57
|
-
systemPrompt: overrides?.systemPrompt,
|
|
58
|
-
maxTokens: overrides?.maxTokens
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
var DEFAULT_SYSTEM_PROMPT, ModelAdapter, PROVIDERS;
|
|
62
|
-
var init_model_adapter = __esm({
|
|
63
|
-
"src/runtime/model-adapter.ts"() {
|
|
64
|
-
"use strict";
|
|
65
|
-
DEFAULT_SYSTEM_PROMPT = `You are an AI assistant operating under NeuroVerse governance.
|
|
66
|
-
All your tool calls are evaluated against governance rules before execution.
|
|
67
|
-
If an action is blocked, you will be told why. Adjust your approach accordingly.
|
|
68
|
-
Do not attempt to bypass governance rules.`;
|
|
69
|
-
ModelAdapter = class {
|
|
70
|
-
config;
|
|
71
|
-
messages;
|
|
72
|
-
tools;
|
|
73
|
-
constructor(config, tools = []) {
|
|
74
|
-
this.config = config;
|
|
75
|
-
this.tools = tools;
|
|
76
|
-
this.messages = [];
|
|
77
|
-
const systemPrompt = config.systemPrompt ?? DEFAULT_SYSTEM_PROMPT;
|
|
78
|
-
this.messages.push({ role: "system", content: systemPrompt });
|
|
79
|
-
}
|
|
80
|
-
/**
|
|
81
|
-
* Send a user message and get the model's response.
|
|
82
|
-
*/
|
|
83
|
-
async chat(userMessage) {
|
|
84
|
-
this.messages.push({ role: "user", content: userMessage });
|
|
85
|
-
return this.complete();
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* Send a tool result back to the model and get the next response.
|
|
89
|
-
*/
|
|
90
|
-
async sendToolResult(toolCallId, result) {
|
|
91
|
-
this.messages.push({
|
|
92
|
-
role: "tool",
|
|
93
|
-
content: result,
|
|
94
|
-
tool_call_id: toolCallId
|
|
95
|
-
});
|
|
96
|
-
return this.complete();
|
|
97
|
-
}
|
|
98
|
-
/**
|
|
99
|
-
* Send a governance block message as a tool result.
|
|
100
|
-
*/
|
|
101
|
-
async sendBlockedResult(toolCallId, reason) {
|
|
102
|
-
return this.sendToolResult(
|
|
103
|
-
toolCallId,
|
|
104
|
-
`[GOVERNANCE BLOCKED] ${reason}. Please adjust your approach.`
|
|
105
|
-
);
|
|
106
|
-
}
|
|
107
|
-
/**
|
|
108
|
-
* Call the model API and parse the response.
|
|
109
|
-
*/
|
|
110
|
-
async complete() {
|
|
111
|
-
const url = `${this.config.baseUrl}/chat/completions`;
|
|
112
|
-
const body = {
|
|
113
|
-
model: this.config.model,
|
|
114
|
-
messages: this.messages,
|
|
115
|
-
max_tokens: this.config.maxTokens ?? 4096
|
|
116
|
-
};
|
|
117
|
-
if (this.tools.length > 0) {
|
|
118
|
-
body.tools = this.tools;
|
|
119
|
-
}
|
|
120
|
-
const response = await fetch(url, {
|
|
121
|
-
method: "POST",
|
|
122
|
-
headers: {
|
|
123
|
-
"Content-Type": "application/json",
|
|
124
|
-
"Authorization": `Bearer ${this.config.apiKey}`
|
|
125
|
-
},
|
|
126
|
-
body: JSON.stringify(body)
|
|
127
|
-
});
|
|
128
|
-
if (!response.ok) {
|
|
129
|
-
const text = await response.text();
|
|
130
|
-
throw new Error(`Model API error ${response.status}: ${text}`);
|
|
131
|
-
}
|
|
132
|
-
const data = await response.json();
|
|
133
|
-
const choice = data.choices?.[0];
|
|
134
|
-
if (!choice) {
|
|
135
|
-
throw new Error("Model returned no choices");
|
|
136
|
-
}
|
|
137
|
-
const message = choice.message;
|
|
138
|
-
this.messages.push(message);
|
|
139
|
-
return {
|
|
140
|
-
content: message.content ?? null,
|
|
141
|
-
toolCalls: message.tool_calls ?? [],
|
|
142
|
-
finishReason: choice.finish_reason ?? "stop"
|
|
143
|
-
};
|
|
144
|
-
}
|
|
145
|
-
/** Get current message count (for context tracking). */
|
|
146
|
-
get messageCount() {
|
|
147
|
-
return this.messages.length;
|
|
148
|
-
}
|
|
149
|
-
};
|
|
150
|
-
PROVIDERS = {
|
|
151
|
-
openai: {
|
|
152
|
-
baseUrl: "https://api.openai.com/v1",
|
|
153
|
-
defaultModel: "gpt-4o",
|
|
154
|
-
envVar: "OPENAI_API_KEY"
|
|
155
|
-
},
|
|
156
|
-
anthropic: {
|
|
157
|
-
baseUrl: "https://api.anthropic.com/v1",
|
|
158
|
-
defaultModel: "claude-sonnet-4-20250514",
|
|
159
|
-
envVar: "ANTHROPIC_API_KEY"
|
|
160
|
-
},
|
|
161
|
-
ollama: {
|
|
162
|
-
baseUrl: "http://localhost:11434/v1",
|
|
163
|
-
defaultModel: "llama3",
|
|
164
|
-
envVar: ""
|
|
165
|
-
}
|
|
166
|
-
};
|
|
167
|
-
}
|
|
168
|
-
});
|
|
169
|
-
|
|
170
33
|
// src/engine/text-utils.ts
|
|
171
34
|
function normalizeEventText(event) {
|
|
172
35
|
return [
|
|
@@ -1304,6 +1167,143 @@ var init_guard_engine = __esm({
|
|
|
1304
1167
|
}
|
|
1305
1168
|
});
|
|
1306
1169
|
|
|
1170
|
+
// src/runtime/model-adapter.ts
|
|
1171
|
+
var model_adapter_exports = {};
|
|
1172
|
+
__export(model_adapter_exports, {
|
|
1173
|
+
ModelAdapter: () => ModelAdapter,
|
|
1174
|
+
PROVIDERS: () => PROVIDERS,
|
|
1175
|
+
resolveProvider: () => resolveProvider
|
|
1176
|
+
});
|
|
1177
|
+
function resolveProvider(provider, overrides) {
|
|
1178
|
+
const preset = PROVIDERS[provider];
|
|
1179
|
+
if (!preset) {
|
|
1180
|
+
throw new Error(
|
|
1181
|
+
`Unknown provider: "${provider}". Available: ${Object.keys(PROVIDERS).join(", ")}`
|
|
1182
|
+
);
|
|
1183
|
+
}
|
|
1184
|
+
const apiKey = overrides?.apiKey ?? (preset.envVar ? process.env[preset.envVar] : "") ?? "";
|
|
1185
|
+
if (!apiKey && preset.envVar) {
|
|
1186
|
+
throw new Error(
|
|
1187
|
+
`Missing API key. Set ${preset.envVar} or pass --api-key.`
|
|
1188
|
+
);
|
|
1189
|
+
}
|
|
1190
|
+
return {
|
|
1191
|
+
baseUrl: overrides?.baseUrl ?? preset.baseUrl,
|
|
1192
|
+
apiKey,
|
|
1193
|
+
model: overrides?.model ?? preset.defaultModel,
|
|
1194
|
+
systemPrompt: overrides?.systemPrompt,
|
|
1195
|
+
maxTokens: overrides?.maxTokens
|
|
1196
|
+
};
|
|
1197
|
+
}
|
|
1198
|
+
var DEFAULT_SYSTEM_PROMPT, ModelAdapter, PROVIDERS;
|
|
1199
|
+
var init_model_adapter = __esm({
|
|
1200
|
+
"src/runtime/model-adapter.ts"() {
|
|
1201
|
+
"use strict";
|
|
1202
|
+
DEFAULT_SYSTEM_PROMPT = `You are an AI assistant operating under NeuroVerse governance.
|
|
1203
|
+
All your tool calls are evaluated against governance rules before execution.
|
|
1204
|
+
If an action is blocked, you will be told why. Adjust your approach accordingly.
|
|
1205
|
+
Do not attempt to bypass governance rules.`;
|
|
1206
|
+
ModelAdapter = class {
|
|
1207
|
+
config;
|
|
1208
|
+
messages;
|
|
1209
|
+
tools;
|
|
1210
|
+
constructor(config, tools = []) {
|
|
1211
|
+
this.config = config;
|
|
1212
|
+
this.tools = tools;
|
|
1213
|
+
this.messages = [];
|
|
1214
|
+
const systemPrompt = config.systemPrompt ?? DEFAULT_SYSTEM_PROMPT;
|
|
1215
|
+
this.messages.push({ role: "system", content: systemPrompt });
|
|
1216
|
+
}
|
|
1217
|
+
/**
|
|
1218
|
+
* Send a user message and get the model's response.
|
|
1219
|
+
*/
|
|
1220
|
+
async chat(userMessage) {
|
|
1221
|
+
this.messages.push({ role: "user", content: userMessage });
|
|
1222
|
+
return this.complete();
|
|
1223
|
+
}
|
|
1224
|
+
/**
|
|
1225
|
+
* Send a tool result back to the model and get the next response.
|
|
1226
|
+
*/
|
|
1227
|
+
async sendToolResult(toolCallId, result) {
|
|
1228
|
+
this.messages.push({
|
|
1229
|
+
role: "tool",
|
|
1230
|
+
content: result,
|
|
1231
|
+
tool_call_id: toolCallId
|
|
1232
|
+
});
|
|
1233
|
+
return this.complete();
|
|
1234
|
+
}
|
|
1235
|
+
/**
|
|
1236
|
+
* Send a governance block message as a tool result.
|
|
1237
|
+
*/
|
|
1238
|
+
async sendBlockedResult(toolCallId, reason) {
|
|
1239
|
+
return this.sendToolResult(
|
|
1240
|
+
toolCallId,
|
|
1241
|
+
`[GOVERNANCE BLOCKED] ${reason}. Please adjust your approach.`
|
|
1242
|
+
);
|
|
1243
|
+
}
|
|
1244
|
+
/**
|
|
1245
|
+
* Call the model API and parse the response.
|
|
1246
|
+
*/
|
|
1247
|
+
async complete() {
|
|
1248
|
+
const url = `${this.config.baseUrl}/chat/completions`;
|
|
1249
|
+
const body = {
|
|
1250
|
+
model: this.config.model,
|
|
1251
|
+
messages: this.messages,
|
|
1252
|
+
max_tokens: this.config.maxTokens ?? 4096
|
|
1253
|
+
};
|
|
1254
|
+
if (this.tools.length > 0) {
|
|
1255
|
+
body.tools = this.tools;
|
|
1256
|
+
}
|
|
1257
|
+
const response = await fetch(url, {
|
|
1258
|
+
method: "POST",
|
|
1259
|
+
headers: {
|
|
1260
|
+
"Content-Type": "application/json",
|
|
1261
|
+
"Authorization": `Bearer ${this.config.apiKey}`
|
|
1262
|
+
},
|
|
1263
|
+
body: JSON.stringify(body)
|
|
1264
|
+
});
|
|
1265
|
+
if (!response.ok) {
|
|
1266
|
+
const text = await response.text();
|
|
1267
|
+
throw new Error(`Model API error ${response.status}: ${text}`);
|
|
1268
|
+
}
|
|
1269
|
+
const data = await response.json();
|
|
1270
|
+
const choice = data.choices?.[0];
|
|
1271
|
+
if (!choice) {
|
|
1272
|
+
throw new Error("Model returned no choices");
|
|
1273
|
+
}
|
|
1274
|
+
const message = choice.message;
|
|
1275
|
+
this.messages.push(message);
|
|
1276
|
+
return {
|
|
1277
|
+
content: message.content ?? null,
|
|
1278
|
+
toolCalls: message.tool_calls ?? [],
|
|
1279
|
+
finishReason: choice.finish_reason ?? "stop"
|
|
1280
|
+
};
|
|
1281
|
+
}
|
|
1282
|
+
/** Get current message count (for context tracking). */
|
|
1283
|
+
get messageCount() {
|
|
1284
|
+
return this.messages.length;
|
|
1285
|
+
}
|
|
1286
|
+
};
|
|
1287
|
+
PROVIDERS = {
|
|
1288
|
+
openai: {
|
|
1289
|
+
baseUrl: "https://api.openai.com/v1",
|
|
1290
|
+
defaultModel: "gpt-4o",
|
|
1291
|
+
envVar: "OPENAI_API_KEY"
|
|
1292
|
+
},
|
|
1293
|
+
anthropic: {
|
|
1294
|
+
baseUrl: "https://api.anthropic.com/v1",
|
|
1295
|
+
defaultModel: "claude-sonnet-4-20250514",
|
|
1296
|
+
envVar: "ANTHROPIC_API_KEY"
|
|
1297
|
+
},
|
|
1298
|
+
ollama: {
|
|
1299
|
+
baseUrl: "http://localhost:11434/v1",
|
|
1300
|
+
defaultModel: "llama3",
|
|
1301
|
+
envVar: ""
|
|
1302
|
+
}
|
|
1303
|
+
};
|
|
1304
|
+
}
|
|
1305
|
+
});
|
|
1306
|
+
|
|
1307
1307
|
// src/loader/world-loader.ts
|
|
1308
1308
|
async function loadWorldFromDirectory(dirPath) {
|
|
1309
1309
|
const { readFile } = await import("fs/promises");
|
|
@@ -1500,11 +1500,17 @@ async function runPipeMode(config) {
|
|
|
1500
1500
|
process.stderr.write(`[neuroverse] Plan: ${state.plan.plan_id} (${state.plan.objective})
|
|
1501
1501
|
`);
|
|
1502
1502
|
}
|
|
1503
|
+
const MAX_BUFFER_SIZE = 1e6;
|
|
1503
1504
|
return new Promise((resolve2, reject) => {
|
|
1504
1505
|
let buffer = "";
|
|
1505
1506
|
process.stdin.setEncoding("utf-8");
|
|
1506
1507
|
process.stdin.on("data", (chunk) => {
|
|
1507
1508
|
buffer += chunk;
|
|
1509
|
+
if (buffer.length > MAX_BUFFER_SIZE) {
|
|
1510
|
+
process.stderr.write("[neuroverse] Warning: pipe buffer exceeded 1MB, resetting\n");
|
|
1511
|
+
buffer = "";
|
|
1512
|
+
return;
|
|
1513
|
+
}
|
|
1508
1514
|
const lines = buffer.split("\n");
|
|
1509
1515
|
buffer = lines.pop() ?? "";
|
|
1510
1516
|
for (const line of lines) {
|
|
@@ -1669,7 +1675,9 @@ var init_session = __esm({
|
|
|
1669
1675
|
init_plan_engine();
|
|
1670
1676
|
init_world_loader();
|
|
1671
1677
|
init_decision_flow_engine();
|
|
1672
|
-
SessionManager = class {
|
|
1678
|
+
SessionManager = class _SessionManager {
|
|
1679
|
+
/** Maximum unique agent IDs tracked before eviction. Prevents unbounded memory growth. */
|
|
1680
|
+
static MAX_AGENTS = 1e4;
|
|
1673
1681
|
config;
|
|
1674
1682
|
state;
|
|
1675
1683
|
engineOptions;
|
|
@@ -1733,6 +1741,16 @@ var init_session = __esm({
|
|
|
1733
1741
|
if (verdict.status === "REWARD" && verdict.reward) {
|
|
1734
1742
|
agentState = applyReward(agentState, verdict.reward, verdict.ruleId ?? "unknown");
|
|
1735
1743
|
}
|
|
1744
|
+
if (this.state.agentStates.size >= _SessionManager.MAX_AGENTS && !this.state.agentStates.has(event.roleId)) {
|
|
1745
|
+
const oldest = this.state.agentStates.keys().next().value;
|
|
1746
|
+
if (oldest !== void 0) {
|
|
1747
|
+
this.state.agentStates.delete(oldest);
|
|
1748
|
+
}
|
|
1749
|
+
process.stderr.write(
|
|
1750
|
+
`[neuroverse] Warning: agent state map at capacity (${_SessionManager.MAX_AGENTS}), evicted oldest entry
|
|
1751
|
+
`
|
|
1752
|
+
);
|
|
1753
|
+
}
|
|
1736
1754
|
this.state.agentStates.set(event.roleId, agentState);
|
|
1737
1755
|
}
|
|
1738
1756
|
this.config.onVerdict?.(verdict, event);
|
|
@@ -1917,6 +1935,77 @@ function resolveNameOrPath(ref, cwd) {
|
|
|
1917
1935
|
return (0, import_path.resolve)(cwd, ref);
|
|
1918
1936
|
}
|
|
1919
1937
|
|
|
1938
|
+
// src/engine/audit-logger.ts
|
|
1939
|
+
init_guard_engine();
|
|
1940
|
+
var FileAuditLogger = class {
|
|
1941
|
+
logPath;
|
|
1942
|
+
buffer = [];
|
|
1943
|
+
flushTimer = null;
|
|
1944
|
+
flushIntervalMs;
|
|
1945
|
+
constructor(logPath, options) {
|
|
1946
|
+
this.logPath = logPath;
|
|
1947
|
+
this.flushIntervalMs = options?.flushIntervalMs ?? 1e3;
|
|
1948
|
+
}
|
|
1949
|
+
log(event) {
|
|
1950
|
+
this.buffer.push(JSON.stringify(event));
|
|
1951
|
+
if (!this.flushTimer) {
|
|
1952
|
+
this.flushTimer = setTimeout(() => {
|
|
1953
|
+
void this.flush();
|
|
1954
|
+
}, this.flushIntervalMs);
|
|
1955
|
+
}
|
|
1956
|
+
}
|
|
1957
|
+
async flush() {
|
|
1958
|
+
if (this.buffer.length === 0) return;
|
|
1959
|
+
if (this.flushTimer) {
|
|
1960
|
+
clearTimeout(this.flushTimer);
|
|
1961
|
+
this.flushTimer = null;
|
|
1962
|
+
}
|
|
1963
|
+
const lines = this.buffer.splice(0).join("\n") + "\n";
|
|
1964
|
+
try {
|
|
1965
|
+
const { appendFile, mkdir } = await import("fs/promises");
|
|
1966
|
+
const { dirname } = await import("path");
|
|
1967
|
+
await mkdir(dirname(this.logPath), { recursive: true });
|
|
1968
|
+
await appendFile(this.logPath, lines, "utf-8");
|
|
1969
|
+
} catch {
|
|
1970
|
+
}
|
|
1971
|
+
}
|
|
1972
|
+
};
|
|
1973
|
+
function verdictToAuditEvent(event, verdict) {
|
|
1974
|
+
const auditEvent = {
|
|
1975
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1976
|
+
worldId: verdict.evidence.worldId,
|
|
1977
|
+
worldName: verdict.evidence.worldName,
|
|
1978
|
+
worldVersion: verdict.evidence.worldVersion,
|
|
1979
|
+
intent: event.intent,
|
|
1980
|
+
tool: event.tool,
|
|
1981
|
+
scope: event.scope,
|
|
1982
|
+
actor: event.roleId,
|
|
1983
|
+
direction: event.direction,
|
|
1984
|
+
decision: verdict.status,
|
|
1985
|
+
reason: verdict.reason,
|
|
1986
|
+
ruleId: verdict.ruleId,
|
|
1987
|
+
warning: verdict.warning,
|
|
1988
|
+
guardsMatched: verdict.evidence.guardsMatched,
|
|
1989
|
+
rulesMatched: verdict.evidence.rulesMatched,
|
|
1990
|
+
invariantsSatisfied: verdict.evidence.invariantsSatisfied,
|
|
1991
|
+
invariantsTotal: verdict.evidence.invariantsTotal,
|
|
1992
|
+
enforcementLevel: verdict.evidence.enforcementLevel,
|
|
1993
|
+
durationMs: verdict.trace?.durationMs,
|
|
1994
|
+
args: event.args
|
|
1995
|
+
};
|
|
1996
|
+
if (verdict.consequence) {
|
|
1997
|
+
auditEvent.consequence = verdict.consequence;
|
|
1998
|
+
}
|
|
1999
|
+
if (verdict.reward) {
|
|
2000
|
+
auditEvent.reward = verdict.reward;
|
|
2001
|
+
}
|
|
2002
|
+
if (verdict.intentRecord) {
|
|
2003
|
+
auditEvent.originalIntent = verdict.intentRecord.originalIntent;
|
|
2004
|
+
auditEvent.finalAction = verdict.intentRecord.finalAction;
|
|
2005
|
+
}
|
|
2006
|
+
return auditEvent;
|
|
2007
|
+
}
|
|
2008
|
+
|
|
1920
2009
|
// src/cli/run.ts
|
|
1921
2010
|
function parseArg(args, flag) {
|
|
1922
2011
|
const idx = args.indexOf(flag);
|
|
@@ -1991,8 +2080,15 @@ async function main(args) {
|
|
|
1991
2080
|
const plan = planPath ? loadPlan(planPath) : autoDetectPlan();
|
|
1992
2081
|
const level = parseArg(args, "--level");
|
|
1993
2082
|
const trace = hasFlag(args, "--trace");
|
|
2083
|
+
const logPath = parseArg(args, "--log");
|
|
1994
2084
|
const isPipeMode = hasFlag(args, "--pipe") || !process.stdin.isTTY;
|
|
1995
2085
|
const isInteractive = hasFlag(args, "--interactive");
|
|
2086
|
+
let auditLogger;
|
|
2087
|
+
if (logPath) {
|
|
2088
|
+
auditLogger = new FileAuditLogger(logPath);
|
|
2089
|
+
process.stderr.write(`[neuroverse] Audit logging to ${logPath}
|
|
2090
|
+
`);
|
|
2091
|
+
}
|
|
1996
2092
|
if (isInteractive) {
|
|
1997
2093
|
const providerName = parseArg(args, "--provider");
|
|
1998
2094
|
if (!providerName) {
|
|
@@ -2016,6 +2112,9 @@ async function main(args) {
|
|
|
2016
2112
|
level,
|
|
2017
2113
|
trace,
|
|
2018
2114
|
onVerdict: (verdict, event) => {
|
|
2115
|
+
if (auditLogger) {
|
|
2116
|
+
auditLogger.log(verdictToAuditEvent(event, verdict));
|
|
2117
|
+
}
|
|
2019
2118
|
if (verdict.status !== "ALLOW") {
|
|
2020
2119
|
process.stderr.write(
|
|
2021
2120
|
` [${verdict.status}] ${event.intent} \u2014 ${verdict.reason ?? verdict.ruleId ?? "governance rule"}
|
|
@@ -2042,8 +2141,12 @@ async function main(args) {
|
|
|
2042
2141
|
worldPath,
|
|
2043
2142
|
plan,
|
|
2044
2143
|
level,
|
|
2045
|
-
trace
|
|
2144
|
+
trace,
|
|
2145
|
+
onVerdict: auditLogger ? (verdict, event) => {
|
|
2146
|
+
auditLogger.log(verdictToAuditEvent(event, verdict));
|
|
2147
|
+
} : void 0
|
|
2046
2148
|
});
|
|
2149
|
+
if (auditLogger) await auditLogger.flush();
|
|
2047
2150
|
} else {
|
|
2048
2151
|
process.stdout.write(RUN_USAGE + "\n");
|
|
2049
2152
|
process.exit(0);
|
package/dist/cli/run.js
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
|
+
import {
|
|
2
|
+
FileAuditLogger,
|
|
3
|
+
verdictToAuditEvent
|
|
4
|
+
} from "../chunk-2VAWP6FI.js";
|
|
1
5
|
import {
|
|
2
6
|
describeActiveWorld,
|
|
3
7
|
resolveWorldPath
|
|
4
8
|
} from "../chunk-AKW5YVCE.js";
|
|
9
|
+
import "../chunk-ZAF6JH23.js";
|
|
10
|
+
import "../chunk-QLPTHTVB.js";
|
|
5
11
|
import "../chunk-QWGCMQQD.js";
|
|
6
12
|
|
|
7
13
|
// src/cli/run.ts
|
|
@@ -80,8 +86,15 @@ async function main(args) {
|
|
|
80
86
|
const plan = planPath ? loadPlan(planPath) : autoDetectPlan();
|
|
81
87
|
const level = parseArg(args, "--level");
|
|
82
88
|
const trace = hasFlag(args, "--trace");
|
|
89
|
+
const logPath = parseArg(args, "--log");
|
|
83
90
|
const isPipeMode = hasFlag(args, "--pipe") || !process.stdin.isTTY;
|
|
84
91
|
const isInteractive = hasFlag(args, "--interactive");
|
|
92
|
+
let auditLogger;
|
|
93
|
+
if (logPath) {
|
|
94
|
+
auditLogger = new FileAuditLogger(logPath);
|
|
95
|
+
process.stderr.write(`[neuroverse] Audit logging to ${logPath}
|
|
96
|
+
`);
|
|
97
|
+
}
|
|
85
98
|
if (isInteractive) {
|
|
86
99
|
const providerName = parseArg(args, "--provider");
|
|
87
100
|
if (!providerName) {
|
|
@@ -92,7 +105,7 @@ async function main(args) {
|
|
|
92
105
|
return;
|
|
93
106
|
}
|
|
94
107
|
const { resolveProvider, ModelAdapter } = await import("../model-adapter-VXEKB4LS.js");
|
|
95
|
-
const { runInteractiveMode } = await import("../session-
|
|
108
|
+
const { runInteractiveMode } = await import("../session-NGA4DUPL.js");
|
|
96
109
|
const modelConfig = resolveProvider(providerName, {
|
|
97
110
|
model: parseArg(args, "--model"),
|
|
98
111
|
apiKey: parseArg(args, "--api-key")
|
|
@@ -105,6 +118,9 @@ async function main(args) {
|
|
|
105
118
|
level,
|
|
106
119
|
trace,
|
|
107
120
|
onVerdict: (verdict, event) => {
|
|
121
|
+
if (auditLogger) {
|
|
122
|
+
auditLogger.log(verdictToAuditEvent(event, verdict));
|
|
123
|
+
}
|
|
108
124
|
if (verdict.status !== "ALLOW") {
|
|
109
125
|
process.stderr.write(
|
|
110
126
|
` [${verdict.status}] ${event.intent} \u2014 ${verdict.reason ?? verdict.ruleId ?? "governance rule"}
|
|
@@ -126,13 +142,17 @@ async function main(args) {
|
|
|
126
142
|
model
|
|
127
143
|
);
|
|
128
144
|
} else if (isPipeMode) {
|
|
129
|
-
const { runPipeMode } = await import("../session-
|
|
145
|
+
const { runPipeMode } = await import("../session-NGA4DUPL.js");
|
|
130
146
|
await runPipeMode({
|
|
131
147
|
worldPath,
|
|
132
148
|
plan,
|
|
133
149
|
level,
|
|
134
|
-
trace
|
|
150
|
+
trace,
|
|
151
|
+
onVerdict: auditLogger ? (verdict, event) => {
|
|
152
|
+
auditLogger.log(verdictToAuditEvent(event, verdict));
|
|
153
|
+
} : void 0
|
|
135
154
|
});
|
|
155
|
+
if (auditLogger) await auditLogger.flush();
|
|
136
156
|
} else {
|
|
137
157
|
process.stdout.write(RUN_USAGE + "\n");
|
|
138
158
|
process.exit(0);
|