@neuroverseos/governance 0.2.2 → 0.2.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 +26 -0
- package/.well-known/mcp.json +68 -0
- package/AGENTS.md +219 -0
- package/README.md +84 -4
- package/dist/adapters/autoresearch.cjs +196 -0
- package/dist/adapters/autoresearch.d.cts +103 -0
- package/dist/adapters/autoresearch.d.ts +103 -0
- package/dist/adapters/autoresearch.js +7 -0
- package/dist/adapters/deep-agents.cjs +1472 -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 +103 -21
- package/dist/adapters/express.d.cts +1 -1
- package/dist/adapters/express.d.ts +1 -1
- package/dist/adapters/express.js +3 -3
- package/dist/adapters/index.cjs +649 -109
- package/dist/adapters/index.d.cts +4 -1
- package/dist/adapters/index.d.ts +4 -1
- package/dist/adapters/index.js +39 -13
- package/dist/adapters/langchain.cjs +152 -48
- package/dist/adapters/langchain.d.cts +5 -5
- package/dist/adapters/langchain.d.ts +5 -5
- package/dist/adapters/langchain.js +4 -3
- package/dist/adapters/openai.cjs +154 -50
- package/dist/adapters/openai.d.cts +5 -5
- package/dist/adapters/openai.d.ts +5 -5
- package/dist/adapters/openai.js +4 -3
- package/dist/adapters/openclaw.cjs +152 -48
- package/dist/adapters/openclaw.d.cts +5 -5
- package/dist/adapters/openclaw.d.ts +5 -5
- package/dist/adapters/openclaw.js +4 -3
- package/dist/{build-P42YFKQV.js → build-X5MZY4IA.js} +2 -2
- package/dist/{chunk-2NICNKOM.js → chunk-4L6OPKMQ.js} +1 -1
- package/dist/chunk-5U2MQO5P.js +57 -0
- package/dist/{chunk-SKU3GAPD.js → chunk-6BB55YJI.js} +16 -34
- package/dist/{chunk-KEST3MWO.js → chunk-AF2VX4AL.js} +47 -8
- package/dist/chunk-BQZMOEML.js +43 -0
- package/dist/chunk-D2UCV5AK.js +326 -0
- package/dist/{chunk-RWXVAH6P.js → chunk-EVDJUSZ2.js} +16 -34
- package/dist/{chunk-4JRYGIO7.js → chunk-IZSO75NZ.js} +72 -7
- package/dist/chunk-JCKSW2PZ.js +304 -0
- package/dist/{chunk-PDOZHZWL.js → chunk-KTFTTLTP.js} +25 -4
- package/dist/{chunk-MWDQ4MJB.js → chunk-MH7BT4VH.js} +5 -1
- package/dist/{chunk-4QXB6PEO.js → chunk-QLPTHTVB.js} +37 -16
- package/dist/{chunk-QPASI2BR.js → chunk-REXY4LUL.js} +49 -10
- package/dist/chunk-T5EUJQE5.js +172 -0
- package/dist/{chunk-DPVS43ZT.js → chunk-TTBKTF3P.js} +5 -5
- package/dist/{chunk-OHAC6HJE.js → chunk-ZIVQNSZU.js} +16 -36
- package/dist/{chunk-BUWWN2NX.js → chunk-ZJTDUCC2.js} +9 -7
- package/dist/cli/neuroverse.cjs +2582 -493
- package/dist/cli/neuroverse.js +39 -15
- package/dist/cli/plan.cjs +119 -32
- package/dist/cli/plan.js +5 -13
- package/dist/cli/run.cjs +223 -24
- package/dist/cli/run.js +2 -2
- package/dist/decision-flow-LETV5NWY.js +61 -0
- package/dist/{derive-TLIV4OOU.js → derive-7365SUFU.js} +2 -2
- package/dist/{doctor-QV6HELS5.js → doctor-QYISMKEL.js} +5 -2
- package/dist/equity-penalties-63FGB3I2.js +244 -0
- package/dist/{explain-IDCRWMPX.js → explain-A2EWI2OL.js} +4 -23
- package/dist/{guard-GFLQZY6U.js → guard-3BWL3IGH.js} +6 -10
- package/dist/{guard-contract-Cm91Kp4j.d.ts → guard-contract-C9_zKbzd.d.cts} +117 -5
- package/dist/{guard-contract-Cm91Kp4j.d.cts → guard-contract-C9_zKbzd.d.ts} +117 -5
- package/dist/{guard-engine-JLTUARGU.js → guard-engine-QFMIBWJY.js} +2 -2
- package/dist/{impact-XPECYRLH.js → impact-UB6DXKSX.js} +4 -4
- package/dist/{improve-GPUBKTEA.js → improve-XZA57GER.js} +5 -24
- package/dist/index.cjs +592 -44
- package/dist/index.d.cts +218 -5
- package/dist/index.d.ts +218 -5
- package/dist/index.js +92 -41
- package/dist/infer-world-7GVZWFX4.js +543 -0
- package/dist/init-world-VWMQZQC7.js +223 -0
- package/dist/{mcp-server-LZVJHBT5.js → mcp-server-XWQZXNW7.js} +3 -3
- package/dist/{playground-FGOMASHN.js → playground-ADWZORNV.js} +2 -2
- package/dist/{redteam-SK7AMIG3.js → redteam-JRQ7FD2F.js} +2 -2
- package/dist/{session-VISISNWJ.js → session-MMYX5YCF.js} +4 -3
- package/dist/shared--Q8wPBVN.d.ts +60 -0
- package/dist/shared-HpAG90PX.d.cts +60 -0
- package/dist/shared-U2QFV7JH.js +16 -0
- package/dist/{simulate-VDOYQFRO.js → simulate-GMIFFXYV.js} +5 -30
- package/dist/{test-75AVHC3R.js → test-JBBZ65X4.js} +2 -2
- package/dist/{trace-JVF67VR3.js → trace-3MYWIDEF.js} +3 -3
- package/dist/worlds/autoresearch.nv-world.md +230 -0
- package/dist/worlds/coding-agent.nv-world.md +211 -0
- package/llms.txt +79 -0
- package/openapi.yaml +230 -0
- package/package.json +26 -4
- package/dist/{chunk-GR6DGCZ2.js → chunk-BMOXICAB.js} +3 -3
- package/dist/{chunk-NF5POFCI.js → chunk-ORJ3NOE6.js} +3 -3
- package/dist/{world-LAXO6DOX.js → world-BFJCIQSH.js} +3 -3
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// src/cli/cli-utils.ts
|
|
2
|
+
async function resolveWorldPath(input) {
|
|
3
|
+
const { stat } = await import("fs/promises");
|
|
4
|
+
try {
|
|
5
|
+
const info = await stat(input);
|
|
6
|
+
if (info.isDirectory()) return input;
|
|
7
|
+
} catch {
|
|
8
|
+
}
|
|
9
|
+
const neuroversePath = `.neuroverse/worlds/${input}`;
|
|
10
|
+
try {
|
|
11
|
+
const info = await stat(neuroversePath);
|
|
12
|
+
if (info.isDirectory()) return neuroversePath;
|
|
13
|
+
} catch {
|
|
14
|
+
}
|
|
15
|
+
throw new Error(
|
|
16
|
+
`World not found: "${input}"
|
|
17
|
+
Tried:
|
|
18
|
+
${input}
|
|
19
|
+
${neuroversePath}
|
|
20
|
+
|
|
21
|
+
Build a world first: neuroverse build <input.md>`
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
async function readStdin() {
|
|
25
|
+
const chunks = [];
|
|
26
|
+
for await (const chunk of process.stdin) {
|
|
27
|
+
chunks.push(chunk);
|
|
28
|
+
}
|
|
29
|
+
return Buffer.concat(chunks).toString("utf-8");
|
|
30
|
+
}
|
|
31
|
+
function parseCliValue(raw) {
|
|
32
|
+
if (raw === "true") return true;
|
|
33
|
+
if (raw === "false") return false;
|
|
34
|
+
const num = Number(raw);
|
|
35
|
+
if (!isNaN(num) && raw.trim() !== "") return num;
|
|
36
|
+
return raw;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export {
|
|
40
|
+
resolveWorldPath,
|
|
41
|
+
readStdin,
|
|
42
|
+
parseCliValue
|
|
43
|
+
};
|
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
// src/engine/decision-flow-engine.ts
|
|
2
|
+
function generateDecisionFlow(events) {
|
|
3
|
+
if (events.length === 0) {
|
|
4
|
+
return emptyFlow();
|
|
5
|
+
}
|
|
6
|
+
const intentMap = /* @__PURE__ */ new Map();
|
|
7
|
+
for (const e of events) {
|
|
8
|
+
const intentKey = normalizeIntent(e.intent);
|
|
9
|
+
const entry = intentMap.get(intentKey) ?? { agents: /* @__PURE__ */ new Set(), count: 0 };
|
|
10
|
+
entry.count++;
|
|
11
|
+
entry.agents.add(e.actor ?? "unknown");
|
|
12
|
+
intentMap.set(intentKey, entry);
|
|
13
|
+
}
|
|
14
|
+
const maxCount = Math.max(...[...intentMap.values()].map((v) => v.count), 1);
|
|
15
|
+
const intents = [...intentMap.entries()].map(([intent, data]) => ({
|
|
16
|
+
intent,
|
|
17
|
+
agentCount: data.count,
|
|
18
|
+
intensity: data.count / maxCount,
|
|
19
|
+
agents: [...data.agents]
|
|
20
|
+
})).sort((a, b) => b.agentCount - a.agentCount);
|
|
21
|
+
const ruleMap = /* @__PURE__ */ new Map();
|
|
22
|
+
for (const e of events) {
|
|
23
|
+
if (!e.ruleId && e.guardsMatched.length === 0) continue;
|
|
24
|
+
const ruleIds = [e.ruleId, ...e.guardsMatched].filter(Boolean);
|
|
25
|
+
for (const rId of new Set(ruleIds)) {
|
|
26
|
+
const existing = ruleMap.get(rId) ?? {
|
|
27
|
+
ruleId: rId,
|
|
28
|
+
label: rId,
|
|
29
|
+
interceptCount: 0,
|
|
30
|
+
enforcements: { blocked: 0, modified: 0, penalized: 0, paused: 0, rewarded: 0 }
|
|
31
|
+
};
|
|
32
|
+
existing.interceptCount++;
|
|
33
|
+
switch (e.decision) {
|
|
34
|
+
case "BLOCK":
|
|
35
|
+
existing.enforcements.blocked++;
|
|
36
|
+
break;
|
|
37
|
+
case "PAUSE":
|
|
38
|
+
existing.enforcements.paused++;
|
|
39
|
+
break;
|
|
40
|
+
case "MODIFY":
|
|
41
|
+
existing.enforcements.modified++;
|
|
42
|
+
break;
|
|
43
|
+
case "PENALIZE":
|
|
44
|
+
existing.enforcements.penalized++;
|
|
45
|
+
break;
|
|
46
|
+
case "REWARD":
|
|
47
|
+
existing.enforcements.rewarded++;
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
ruleMap.set(rId, existing);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
const rules = [...ruleMap.values()].sort((a, b) => b.interceptCount - a.interceptCount);
|
|
54
|
+
const outcomeMap = /* @__PURE__ */ new Map();
|
|
55
|
+
for (const e of events) {
|
|
56
|
+
const key = e.decision;
|
|
57
|
+
const entry = outcomeMap.get(key) ?? { agents: /* @__PURE__ */ new Set(), count: 0 };
|
|
58
|
+
entry.count++;
|
|
59
|
+
entry.agents.add(e.actor ?? "unknown");
|
|
60
|
+
outcomeMap.set(key, entry);
|
|
61
|
+
}
|
|
62
|
+
const outcomes = [...outcomeMap.entries()].map(([enforcement, data]) => ({
|
|
63
|
+
enforcement,
|
|
64
|
+
agentCount: data.count,
|
|
65
|
+
agents: [...data.agents],
|
|
66
|
+
style: enforcementToStyle(enforcement)
|
|
67
|
+
})).sort((a, b) => b.agentCount - a.agentCount);
|
|
68
|
+
const paths = events.map((e) => ({
|
|
69
|
+
intent: normalizeIntent(e.intent),
|
|
70
|
+
ruleId: e.ruleId ?? e.guardsMatched[0],
|
|
71
|
+
enforcement: e.decision,
|
|
72
|
+
agentId: e.actor ?? "unknown",
|
|
73
|
+
originalAction: e.intent,
|
|
74
|
+
finalAction: e.decision === "ALLOW" ? e.intent : e.decision === "BLOCK" ? "blocked" : e.decision === "PENALIZE" ? "blocked + penalized" : e.decision === "REWARD" ? e.intent + " (rewarded)" : e.decision === "MODIFY" ? "modified" : e.decision === "NEUTRAL" ? e.intent : "paused"
|
|
75
|
+
}));
|
|
76
|
+
const totalIntents = events.length;
|
|
77
|
+
const allowed = events.filter((e) => e.decision === "ALLOW" || e.decision === "REWARD" || e.decision === "NEUTRAL").length;
|
|
78
|
+
const totalRedirected = totalIntents - allowed;
|
|
79
|
+
const totalPenalties = events.filter((e) => e.decision === "PENALIZE").length;
|
|
80
|
+
const totalRewards = events.filter((e) => e.decision === "REWARD").length;
|
|
81
|
+
const byEnforcement = {};
|
|
82
|
+
for (const e of events) {
|
|
83
|
+
byEnforcement[e.decision] = (byEnforcement[e.decision] ?? 0) + 1;
|
|
84
|
+
}
|
|
85
|
+
const metrics = {
|
|
86
|
+
totalIntents,
|
|
87
|
+
totalRedirected,
|
|
88
|
+
redirectionRate: totalIntents > 0 ? totalRedirected / totalIntents : 0,
|
|
89
|
+
byEnforcement,
|
|
90
|
+
totalPenalties,
|
|
91
|
+
totalRewards,
|
|
92
|
+
netBehavioralPressure: totalRewards - totalPenalties
|
|
93
|
+
};
|
|
94
|
+
return {
|
|
95
|
+
intents,
|
|
96
|
+
rules,
|
|
97
|
+
outcomes,
|
|
98
|
+
paths,
|
|
99
|
+
metrics,
|
|
100
|
+
periodStart: events[0]?.timestamp ?? "",
|
|
101
|
+
periodEnd: events[events.length - 1]?.timestamp ?? "",
|
|
102
|
+
worldName: events[0]?.worldName ?? "unknown"
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
function createAgentState(agentId) {
|
|
106
|
+
return {
|
|
107
|
+
agentId,
|
|
108
|
+
cooldownRemaining: 0,
|
|
109
|
+
influence: 1,
|
|
110
|
+
rewardMultiplier: 1,
|
|
111
|
+
totalPenalties: 0,
|
|
112
|
+
totalRewards: 0,
|
|
113
|
+
consequenceHistory: [],
|
|
114
|
+
rewardHistory: []
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
function applyConsequence(state, consequence, ruleId) {
|
|
118
|
+
const updated = { ...state };
|
|
119
|
+
updated.totalPenalties++;
|
|
120
|
+
updated.consequenceHistory = [
|
|
121
|
+
...state.consequenceHistory,
|
|
122
|
+
{ ruleId, consequence, appliedAt: Date.now() }
|
|
123
|
+
];
|
|
124
|
+
switch (consequence.type) {
|
|
125
|
+
case "freeze":
|
|
126
|
+
case "cooldown":
|
|
127
|
+
updated.cooldownRemaining = Math.max(
|
|
128
|
+
state.cooldownRemaining,
|
|
129
|
+
consequence.rounds ?? 1
|
|
130
|
+
);
|
|
131
|
+
break;
|
|
132
|
+
case "reduce_influence":
|
|
133
|
+
updated.influence = Math.max(0, state.influence - (consequence.magnitude ?? 0.1));
|
|
134
|
+
break;
|
|
135
|
+
case "increase_risk":
|
|
136
|
+
break;
|
|
137
|
+
case "custom":
|
|
138
|
+
break;
|
|
139
|
+
}
|
|
140
|
+
return updated;
|
|
141
|
+
}
|
|
142
|
+
function applyReward(state, reward, ruleId) {
|
|
143
|
+
const updated = { ...state };
|
|
144
|
+
updated.totalRewards++;
|
|
145
|
+
updated.rewardHistory = [
|
|
146
|
+
...state.rewardHistory,
|
|
147
|
+
{ ruleId, reward, appliedAt: Date.now() }
|
|
148
|
+
];
|
|
149
|
+
switch (reward.type) {
|
|
150
|
+
case "boost_influence":
|
|
151
|
+
updated.influence = Math.min(2, state.influence + (reward.magnitude ?? 0.1));
|
|
152
|
+
break;
|
|
153
|
+
case "weight_increase":
|
|
154
|
+
updated.rewardMultiplier = Math.min(3, state.rewardMultiplier + (reward.magnitude ?? 0.1));
|
|
155
|
+
break;
|
|
156
|
+
case "priority":
|
|
157
|
+
case "faster_execution":
|
|
158
|
+
break;
|
|
159
|
+
case "custom":
|
|
160
|
+
break;
|
|
161
|
+
}
|
|
162
|
+
return updated;
|
|
163
|
+
}
|
|
164
|
+
function tickAgentStates(states) {
|
|
165
|
+
const updated = /* @__PURE__ */ new Map();
|
|
166
|
+
for (const [id, state] of states) {
|
|
167
|
+
updated.set(id, {
|
|
168
|
+
...state,
|
|
169
|
+
cooldownRemaining: Math.max(0, state.cooldownRemaining - 1)
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
return updated;
|
|
173
|
+
}
|
|
174
|
+
function renderDecisionFlow(flow) {
|
|
175
|
+
const lines = [];
|
|
176
|
+
lines.push("DECISION FLOW \u2014 Intent \u2192 Rule \u2192 Outcome");
|
|
177
|
+
lines.push("\u2550".repeat(60));
|
|
178
|
+
lines.push("");
|
|
179
|
+
lines.push(` World: ${flow.worldName}`);
|
|
180
|
+
lines.push(` Period: ${flow.periodStart.split("T")[0] ?? "\u2014"} \u2192 ${flow.periodEnd.split("T")[0] ?? "\u2014"}`);
|
|
181
|
+
lines.push("");
|
|
182
|
+
lines.push(` "${(flow.metrics.redirectionRate * 100).toFixed(1)}% of agent intent was redirected by governance"`);
|
|
183
|
+
lines.push("");
|
|
184
|
+
lines.push("INTENT POOL (what agents wanted)");
|
|
185
|
+
lines.push("\u2500".repeat(60));
|
|
186
|
+
for (const cluster of flow.intents.slice(0, 15)) {
|
|
187
|
+
const bar = "\u2588".repeat(Math.max(1, Math.round(cluster.intensity * 20)));
|
|
188
|
+
lines.push(` ${cluster.intent.padEnd(25)} ${String(cluster.agentCount).padStart(5)} agents ${bar}`);
|
|
189
|
+
}
|
|
190
|
+
lines.push("");
|
|
191
|
+
lines.push("RULE OBSTACLES (what intercepted)");
|
|
192
|
+
lines.push("\u2500".repeat(60));
|
|
193
|
+
for (const rule of flow.rules.slice(0, 10)) {
|
|
194
|
+
const parts = [];
|
|
195
|
+
if (rule.enforcements.blocked > 0) parts.push(`${rule.enforcements.blocked} blocked`);
|
|
196
|
+
if (rule.enforcements.modified > 0) parts.push(`${rule.enforcements.modified} modified`);
|
|
197
|
+
if (rule.enforcements.penalized > 0) parts.push(`${rule.enforcements.penalized} penalized`);
|
|
198
|
+
if (rule.enforcements.paused > 0) parts.push(`${rule.enforcements.paused} paused`);
|
|
199
|
+
if (rule.enforcements.rewarded > 0) parts.push(`${rule.enforcements.rewarded} rewarded`);
|
|
200
|
+
lines.push(` ${rule.ruleId.padEnd(30)} ${String(rule.interceptCount).padStart(5)} intercepts (${parts.join(", ")})`);
|
|
201
|
+
}
|
|
202
|
+
lines.push("");
|
|
203
|
+
lines.push("OUTCOME POOL (what actually happened)");
|
|
204
|
+
lines.push("\u2500".repeat(60));
|
|
205
|
+
for (const outcome of flow.outcomes) {
|
|
206
|
+
const icon = outcomeIcon(outcome.enforcement);
|
|
207
|
+
lines.push(` ${icon} ${outcome.enforcement.padEnd(12)} ${String(outcome.agentCount).padStart(5)} agents`);
|
|
208
|
+
}
|
|
209
|
+
lines.push("");
|
|
210
|
+
if (flow.metrics.totalPenalties > 0 || flow.metrics.totalRewards > 0) {
|
|
211
|
+
lines.push("BEHAVIORAL ECONOMY");
|
|
212
|
+
lines.push("\u2500".repeat(60));
|
|
213
|
+
lines.push(` Penalties applied: ${flow.metrics.totalPenalties}`);
|
|
214
|
+
lines.push(` Rewards applied: ${flow.metrics.totalRewards}`);
|
|
215
|
+
lines.push(` Net behavioral pressure: ${flow.metrics.netBehavioralPressure > 0 ? "+" : ""}${flow.metrics.netBehavioralPressure}`);
|
|
216
|
+
lines.push("");
|
|
217
|
+
}
|
|
218
|
+
lines.push("ENFORCEMENT BREAKDOWN");
|
|
219
|
+
lines.push("\u2500".repeat(60));
|
|
220
|
+
for (const [enforcement, count] of Object.entries(flow.metrics.byEnforcement)) {
|
|
221
|
+
const pct = (count / flow.metrics.totalIntents * 100).toFixed(1);
|
|
222
|
+
lines.push(` ${enforcement.padEnd(12)} ${String(count).padStart(5)} (${pct}%)`);
|
|
223
|
+
}
|
|
224
|
+
lines.push("");
|
|
225
|
+
return lines.join("\n");
|
|
226
|
+
}
|
|
227
|
+
function normalizeIntent(intent) {
|
|
228
|
+
const lower = intent.toLowerCase().trim();
|
|
229
|
+
const verbs = [
|
|
230
|
+
"sell",
|
|
231
|
+
"buy",
|
|
232
|
+
"trade",
|
|
233
|
+
"publish",
|
|
234
|
+
"delete",
|
|
235
|
+
"create",
|
|
236
|
+
"modify",
|
|
237
|
+
"send",
|
|
238
|
+
"withdraw",
|
|
239
|
+
"transfer",
|
|
240
|
+
"attack",
|
|
241
|
+
"deploy",
|
|
242
|
+
"execute",
|
|
243
|
+
"read",
|
|
244
|
+
"write",
|
|
245
|
+
"hold",
|
|
246
|
+
"stake",
|
|
247
|
+
"approve",
|
|
248
|
+
"reject",
|
|
249
|
+
"escalate"
|
|
250
|
+
];
|
|
251
|
+
for (const verb of verbs) {
|
|
252
|
+
if (lower.startsWith(verb) || lower.includes(verb)) {
|
|
253
|
+
return verb;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
return lower.split(/\s+/)[0] ?? lower;
|
|
257
|
+
}
|
|
258
|
+
function enforcementToStyle(enforcement) {
|
|
259
|
+
switch (enforcement) {
|
|
260
|
+
case "ALLOW":
|
|
261
|
+
return "green";
|
|
262
|
+
case "MODIFY":
|
|
263
|
+
return "yellow";
|
|
264
|
+
case "BLOCK":
|
|
265
|
+
return "red";
|
|
266
|
+
case "PENALIZE":
|
|
267
|
+
return "gray";
|
|
268
|
+
case "REWARD":
|
|
269
|
+
return "blue";
|
|
270
|
+
case "NEUTRAL":
|
|
271
|
+
return "white";
|
|
272
|
+
case "PAUSE":
|
|
273
|
+
return "yellow";
|
|
274
|
+
default:
|
|
275
|
+
return "white";
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
function outcomeIcon(enforcement) {
|
|
279
|
+
switch (enforcement) {
|
|
280
|
+
case "ALLOW":
|
|
281
|
+
return "\u25CF";
|
|
282
|
+
case "MODIFY":
|
|
283
|
+
return "\u25D0";
|
|
284
|
+
case "BLOCK":
|
|
285
|
+
return "\u25CB";
|
|
286
|
+
case "PENALIZE":
|
|
287
|
+
return "\u25CC";
|
|
288
|
+
case "REWARD":
|
|
289
|
+
return "\u25C9";
|
|
290
|
+
case "NEUTRAL":
|
|
291
|
+
return "\u25EF";
|
|
292
|
+
case "PAUSE":
|
|
293
|
+
return "\u25D1";
|
|
294
|
+
default:
|
|
295
|
+
return "\xB7";
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
function emptyFlow() {
|
|
299
|
+
return {
|
|
300
|
+
intents: [],
|
|
301
|
+
rules: [],
|
|
302
|
+
outcomes: [],
|
|
303
|
+
paths: [],
|
|
304
|
+
metrics: {
|
|
305
|
+
totalIntents: 0,
|
|
306
|
+
totalRedirected: 0,
|
|
307
|
+
redirectionRate: 0,
|
|
308
|
+
byEnforcement: {},
|
|
309
|
+
totalPenalties: 0,
|
|
310
|
+
totalRewards: 0,
|
|
311
|
+
netBehavioralPressure: 0
|
|
312
|
+
},
|
|
313
|
+
periodStart: "",
|
|
314
|
+
periodEnd: "",
|
|
315
|
+
worldName: "unknown"
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
export {
|
|
320
|
+
generateDecisionFlow,
|
|
321
|
+
createAgentState,
|
|
322
|
+
applyConsequence,
|
|
323
|
+
applyReward,
|
|
324
|
+
tickAgentStates,
|
|
325
|
+
renderDecisionFlow
|
|
326
|
+
};
|
|
@@ -1,23 +1,21 @@
|
|
|
1
|
+
import {
|
|
2
|
+
GovernanceBlockedError,
|
|
3
|
+
buildEngineOptions,
|
|
4
|
+
extractScope,
|
|
5
|
+
trackPlanProgress
|
|
6
|
+
} from "./chunk-5U2MQO5P.js";
|
|
1
7
|
import {
|
|
2
8
|
evaluateGuard
|
|
3
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-IZSO75NZ.js";
|
|
4
10
|
import {
|
|
5
11
|
loadWorld
|
|
6
12
|
} from "./chunk-JZPQGIKR.js";
|
|
7
|
-
import {
|
|
8
|
-
advancePlan,
|
|
9
|
-
evaluatePlan,
|
|
10
|
-
getPlanProgress
|
|
11
|
-
} from "./chunk-4QXB6PEO.js";
|
|
12
13
|
|
|
13
14
|
// src/adapters/langchain.ts
|
|
14
|
-
var
|
|
15
|
-
verdict;
|
|
15
|
+
var GovernanceBlockedError2 = class extends GovernanceBlockedError {
|
|
16
16
|
event;
|
|
17
17
|
constructor(verdict, event) {
|
|
18
|
-
super(
|
|
19
|
-
this.name = "GovernanceBlockedError";
|
|
20
|
-
this.verdict = verdict;
|
|
18
|
+
super(verdict);
|
|
21
19
|
this.event = event;
|
|
22
20
|
}
|
|
23
21
|
};
|
|
@@ -25,7 +23,7 @@ function defaultMapToolCall(toolName, toolInput) {
|
|
|
25
23
|
return {
|
|
26
24
|
intent: toolName,
|
|
27
25
|
tool: toolName,
|
|
28
|
-
scope:
|
|
26
|
+
scope: extractScope(toolInput),
|
|
29
27
|
args: toolInput,
|
|
30
28
|
direction: "input"
|
|
31
29
|
};
|
|
@@ -41,11 +39,7 @@ var NeuroVerseCallbackHandler = class {
|
|
|
41
39
|
this.world = world;
|
|
42
40
|
this.options = options;
|
|
43
41
|
this.activePlan = options.plan;
|
|
44
|
-
this.engineOptions =
|
|
45
|
-
trace: options.trace ?? false,
|
|
46
|
-
level: options.level,
|
|
47
|
-
plan: this.activePlan
|
|
48
|
-
};
|
|
42
|
+
this.engineOptions = buildEngineOptions(options, this.activePlan);
|
|
49
43
|
this.mapToolCall = options.mapToolCall ?? defaultMapToolCall;
|
|
50
44
|
}
|
|
51
45
|
/**
|
|
@@ -68,28 +62,16 @@ var NeuroVerseCallbackHandler = class {
|
|
|
68
62
|
this.options.onEvaluate?.(verdict, event);
|
|
69
63
|
if (verdict.status === "BLOCK") {
|
|
70
64
|
this.options.onBlock?.(verdict, event);
|
|
71
|
-
throw new
|
|
65
|
+
throw new GovernanceBlockedError2(verdict, event);
|
|
72
66
|
}
|
|
73
67
|
if (verdict.status === "PAUSE") {
|
|
74
68
|
const approved = await this.options.onPause?.(verdict, event);
|
|
75
69
|
if (!approved) {
|
|
76
|
-
throw new
|
|
70
|
+
throw new GovernanceBlockedError2(verdict, event);
|
|
77
71
|
}
|
|
78
72
|
}
|
|
79
|
-
if (verdict.status === "ALLOW"
|
|
80
|
-
|
|
81
|
-
if (planVerdict.matchedStep) {
|
|
82
|
-
const advResult = advancePlan(this.activePlan, planVerdict.matchedStep);
|
|
83
|
-
if (advResult.success && advResult.plan) {
|
|
84
|
-
this.activePlan = advResult.plan;
|
|
85
|
-
this.engineOptions.plan = this.activePlan;
|
|
86
|
-
}
|
|
87
|
-
const progress = getPlanProgress(this.activePlan);
|
|
88
|
-
this.options.onPlanProgress?.(progress);
|
|
89
|
-
if (progress.completed === progress.total) {
|
|
90
|
-
this.options.onPlanComplete?.();
|
|
91
|
-
}
|
|
92
|
-
}
|
|
73
|
+
if (verdict.status === "ALLOW") {
|
|
74
|
+
trackPlanProgress(event, this, this.options);
|
|
93
75
|
}
|
|
94
76
|
}
|
|
95
77
|
};
|
|
@@ -102,7 +84,7 @@ function createNeuroVerseCallbackHandlerFromWorld(world, options) {
|
|
|
102
84
|
}
|
|
103
85
|
|
|
104
86
|
export {
|
|
105
|
-
GovernanceBlockedError,
|
|
87
|
+
GovernanceBlockedError2 as GovernanceBlockedError,
|
|
106
88
|
NeuroVerseCallbackHandler,
|
|
107
89
|
createNeuroVerseCallbackHandler,
|
|
108
90
|
createNeuroVerseCallbackHandlerFromWorld
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
buildPlanCheck,
|
|
3
|
-
evaluatePlan
|
|
4
|
-
|
|
3
|
+
evaluatePlan,
|
|
4
|
+
matchesAllKeywords,
|
|
5
|
+
normalizeEventText
|
|
6
|
+
} from "./chunk-QLPTHTVB.js";
|
|
5
7
|
|
|
6
8
|
// src/engine/guard-engine.ts
|
|
7
9
|
var PROMPT_INJECTION_PATTERNS = [
|
|
@@ -91,7 +93,7 @@ function evaluateGuard(event, world, options = {}) {
|
|
|
91
93
|
const startTime = performance.now();
|
|
92
94
|
const level = options.level ?? "standard";
|
|
93
95
|
const includeTrace = options.trace ?? false;
|
|
94
|
-
const eventText = (event
|
|
96
|
+
const eventText = normalizeEventText(event);
|
|
95
97
|
const invariantChecks = [];
|
|
96
98
|
const safetyChecks = [];
|
|
97
99
|
let planCheckResult;
|
|
@@ -104,6 +106,43 @@ function evaluateGuard(event, world, options = {}) {
|
|
|
104
106
|
const guardsMatched = [];
|
|
105
107
|
const rulesMatched = [];
|
|
106
108
|
checkInvariantCoverage(world, invariantChecks);
|
|
109
|
+
if (event.roleId && options.agentStates) {
|
|
110
|
+
const agentState = options.agentStates.get(event.roleId);
|
|
111
|
+
if (agentState && agentState.cooldownRemaining > 0) {
|
|
112
|
+
decidingLayer = "safety";
|
|
113
|
+
decidingId = `penalize-cooldown-${event.roleId}`;
|
|
114
|
+
const verdict = buildVerdict(
|
|
115
|
+
"PENALIZE",
|
|
116
|
+
`Agent "${event.roleId}" is frozen for ${agentState.cooldownRemaining} more round(s) due to prior penalty.`,
|
|
117
|
+
`penalize-cooldown-${event.roleId}`,
|
|
118
|
+
void 0,
|
|
119
|
+
world,
|
|
120
|
+
level,
|
|
121
|
+
invariantChecks,
|
|
122
|
+
guardsMatched,
|
|
123
|
+
rulesMatched,
|
|
124
|
+
includeTrace ? buildTrace(
|
|
125
|
+
invariantChecks,
|
|
126
|
+
safetyChecks,
|
|
127
|
+
planCheckResult,
|
|
128
|
+
roleChecks,
|
|
129
|
+
guardChecks,
|
|
130
|
+
kernelRuleChecks,
|
|
131
|
+
levelChecks,
|
|
132
|
+
decidingLayer,
|
|
133
|
+
decidingId,
|
|
134
|
+
startTime
|
|
135
|
+
) : void 0
|
|
136
|
+
);
|
|
137
|
+
verdict.intentRecord = {
|
|
138
|
+
originalIntent: event.intent,
|
|
139
|
+
finalAction: "blocked (agent frozen)",
|
|
140
|
+
enforcement: "PENALIZE",
|
|
141
|
+
consequence: { type: "freeze", rounds: agentState.cooldownRemaining, description: "Agent still in cooldown from prior penalty" }
|
|
142
|
+
};
|
|
143
|
+
return verdict;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
107
146
|
if (options.sessionAllowlist) {
|
|
108
147
|
const key = eventToAllowlistKey(event);
|
|
109
148
|
if (options.sessionAllowlist.has(key)) {
|
|
@@ -231,7 +270,16 @@ function evaluateGuard(event, world, options = {}) {
|
|
|
231
270
|
if (guardVerdict.status !== "ALLOW") {
|
|
232
271
|
decidingLayer = "guard";
|
|
233
272
|
decidingId = guardVerdict.ruleId;
|
|
234
|
-
|
|
273
|
+
const intentRecord = {
|
|
274
|
+
originalIntent: event.intent,
|
|
275
|
+
finalAction: guardVerdict.status === "MODIFY" ? guardVerdict.modifiedTo ?? "modified" : guardVerdict.status === "PENALIZE" ? "blocked + penalized" : guardVerdict.status === "REWARD" ? event.intent : guardVerdict.status === "NEUTRAL" ? event.intent : guardVerdict.status === "BLOCK" ? "blocked" : "paused",
|
|
276
|
+
ruleApplied: guardVerdict.ruleId,
|
|
277
|
+
enforcement: guardVerdict.status,
|
|
278
|
+
modifiedTo: guardVerdict.modifiedTo,
|
|
279
|
+
consequence: guardVerdict.consequence,
|
|
280
|
+
reward: guardVerdict.reward
|
|
281
|
+
};
|
|
282
|
+
const verdict = buildVerdict(
|
|
235
283
|
guardVerdict.status,
|
|
236
284
|
guardVerdict.reason,
|
|
237
285
|
guardVerdict.ruleId,
|
|
@@ -254,6 +302,10 @@ function evaluateGuard(event, world, options = {}) {
|
|
|
254
302
|
startTime
|
|
255
303
|
) : void 0
|
|
256
304
|
);
|
|
305
|
+
verdict.intentRecord = intentRecord;
|
|
306
|
+
if (guardVerdict.consequence) verdict.consequence = guardVerdict.consequence;
|
|
307
|
+
if (guardVerdict.reward) verdict.reward = guardVerdict.reward;
|
|
308
|
+
return verdict;
|
|
257
309
|
}
|
|
258
310
|
}
|
|
259
311
|
const kernelVerdict = checkKernelRules(eventText, world, kernelRuleChecks, rulesMatched);
|
|
@@ -548,6 +600,21 @@ function checkGuards(event, eventText, world, checks, guardsMatched) {
|
|
|
548
600
|
if (actionMode === "pause") {
|
|
549
601
|
return { status: "PAUSE", reason, ruleId: `guard-${guard.id}` };
|
|
550
602
|
}
|
|
603
|
+
if (actionMode === "penalize") {
|
|
604
|
+
const consequence = guard.consequence ? { ...guard.consequence } : { type: "freeze", rounds: 1, description: `Penalized for violating: ${guard.label}` };
|
|
605
|
+
return { status: "PENALIZE", reason, ruleId: `guard-${guard.id}`, consequence };
|
|
606
|
+
}
|
|
607
|
+
if (actionMode === "reward") {
|
|
608
|
+
const reward = guard.reward ? { ...guard.reward } : { type: "boost_influence", magnitude: 0.1, description: `Rewarded for: ${guard.label}` };
|
|
609
|
+
return { status: "REWARD", reason, ruleId: `guard-${guard.id}`, reward };
|
|
610
|
+
}
|
|
611
|
+
if (actionMode === "modify") {
|
|
612
|
+
const modifiedTo = guard.modify_to ?? guard.redirect ?? "hold";
|
|
613
|
+
return { status: "MODIFY", reason: `${reason} \u2192 Modified to: ${modifiedTo}`, ruleId: `guard-${guard.id}`, modifiedTo };
|
|
614
|
+
}
|
|
615
|
+
if (actionMode === "neutral") {
|
|
616
|
+
return { status: "NEUTRAL", reason, ruleId: `guard-${guard.id}` };
|
|
617
|
+
}
|
|
551
618
|
if (actionMode === "warn" && !warnResult) {
|
|
552
619
|
warnResult = { status: "ALLOW", warning: reason, ruleId: `guard-${guard.id}` };
|
|
553
620
|
}
|
|
@@ -657,9 +724,7 @@ function checkLevelConstraints(event, level, checks) {
|
|
|
657
724
|
return null;
|
|
658
725
|
}
|
|
659
726
|
function matchesKeywords(eventText, ruleText) {
|
|
660
|
-
|
|
661
|
-
if (keywords.length === 0) return false;
|
|
662
|
-
return keywords.every((kw) => eventText.includes(kw));
|
|
727
|
+
return matchesAllKeywords(eventText, ruleText);
|
|
663
728
|
}
|
|
664
729
|
function eventToAllowlistKey(event) {
|
|
665
730
|
return `${(event.tool ?? "*").toLowerCase()}::${event.intent.toLowerCase().trim()}`;
|