@neuroverseos/governance 0.6.1 → 0.7.0
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 +0 -3
- package/dist/{chunk-AEVT7DSZ.js → chunk-T6EQ7ZBG.js} +366 -3
- package/dist/cli/neuroverse.cjs +770 -129
- package/dist/cli/radiant.cjs +2078 -139
- package/dist/cli/radiant.js +8 -1
- package/dist/radiant/index.cjs +1554 -5
- package/dist/radiant/index.d.cts +146 -8
- package/dist/radiant/index.d.ts +146 -8
- package/dist/radiant/index.js +18 -3
- package/dist/server-BXMC5NOE.js +271 -0
- package/package.json +1 -1
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createAnthropicAI,
|
|
3
|
+
emergent,
|
|
4
|
+
parseRepoScope,
|
|
5
|
+
think
|
|
6
|
+
} from "./chunk-T6EQ7ZBG.js";
|
|
7
|
+
import "./chunk-VGFDMPVB.js";
|
|
8
|
+
import "./chunk-I4RTIMLX.js";
|
|
9
|
+
import "./chunk-ZAF6JH23.js";
|
|
10
|
+
import "./chunk-QLPTHTVB.js";
|
|
11
|
+
import "./chunk-QWGCMQQD.js";
|
|
12
|
+
|
|
13
|
+
// src/radiant/mcp/server.ts
|
|
14
|
+
import { readFileSync, readdirSync, statSync, existsSync } from "fs";
|
|
15
|
+
import { resolve, join, extname } from "path";
|
|
16
|
+
var TOOLS = [
|
|
17
|
+
{
|
|
18
|
+
name: "radiant_think",
|
|
19
|
+
description: "Send a query through the loaded worldmodel + rendering lens and get an Auki-framed response. Use this for strategic questions, decision evaluation, or any question that should be interpreted through the organization's behavioral model.",
|
|
20
|
+
inputSchema: {
|
|
21
|
+
type: "object",
|
|
22
|
+
properties: {
|
|
23
|
+
query: {
|
|
24
|
+
type: "string",
|
|
25
|
+
description: "The question or prompt to interpret through the worldmodel + lens."
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
required: ["query"]
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
name: "radiant_emergent",
|
|
33
|
+
description: "Run a behavioral read on a GitHub repository. Fetches recent activity, classifies events, extracts signals, identifies patterns, computes alignment scores, and produces the EMERGENT / MEANING / MOVE / ALIGNMENT output. Use this when asked about team activity, coordination patterns, or alignment with the worldmodel.",
|
|
34
|
+
inputSchema: {
|
|
35
|
+
type: "object",
|
|
36
|
+
properties: {
|
|
37
|
+
scope: {
|
|
38
|
+
type: "string",
|
|
39
|
+
description: 'GitHub repository in "owner/repo" format (e.g. "aukiverse/posemesh").'
|
|
40
|
+
},
|
|
41
|
+
exocortex_dir: {
|
|
42
|
+
type: "string",
|
|
43
|
+
description: "Optional path to an exocortex directory for stated-intent-vs-observed-behavior comparison."
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
required: ["scope"]
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
];
|
|
50
|
+
var RadiantMcpServer = class {
|
|
51
|
+
config;
|
|
52
|
+
worldmodelContent;
|
|
53
|
+
buffer = "";
|
|
54
|
+
constructor(config) {
|
|
55
|
+
this.config = config;
|
|
56
|
+
this.worldmodelContent = loadWorldmodelContent(config.worldsPath);
|
|
57
|
+
}
|
|
58
|
+
async start() {
|
|
59
|
+
process.stderr.write(
|
|
60
|
+
`Radiant MCP server starting
|
|
61
|
+
Worlds: ${this.config.worldsPath}
|
|
62
|
+
Lens: ${this.config.lensId}
|
|
63
|
+
Tools: radiant_think, radiant_emergent
|
|
64
|
+
`
|
|
65
|
+
);
|
|
66
|
+
process.stdin.setEncoding("utf-8");
|
|
67
|
+
process.stdin.on("data", (chunk) => {
|
|
68
|
+
this.buffer += chunk;
|
|
69
|
+
this.processBuffer();
|
|
70
|
+
});
|
|
71
|
+
process.stdin.on("end", () => {
|
|
72
|
+
process.exit(0);
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
processBuffer() {
|
|
76
|
+
const lines = this.buffer.split("\n");
|
|
77
|
+
this.buffer = lines.pop() ?? "";
|
|
78
|
+
for (const line of lines) {
|
|
79
|
+
const trimmed = line.trim();
|
|
80
|
+
if (!trimmed) continue;
|
|
81
|
+
try {
|
|
82
|
+
const request = JSON.parse(trimmed);
|
|
83
|
+
this.handleRequest(request).catch((err) => {
|
|
84
|
+
this.sendError(request.id, -32603, String(err));
|
|
85
|
+
});
|
|
86
|
+
} catch {
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
async handleRequest(req) {
|
|
91
|
+
switch (req.method) {
|
|
92
|
+
case "initialize":
|
|
93
|
+
this.sendResult(req.id, {
|
|
94
|
+
protocolVersion: "2024-11-05",
|
|
95
|
+
capabilities: { tools: {} },
|
|
96
|
+
serverInfo: {
|
|
97
|
+
name: "radiant",
|
|
98
|
+
version: "0.6.1"
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
break;
|
|
102
|
+
case "notifications/initialized":
|
|
103
|
+
break;
|
|
104
|
+
case "tools/list":
|
|
105
|
+
this.sendResult(req.id, { tools: TOOLS });
|
|
106
|
+
break;
|
|
107
|
+
case "tools/call":
|
|
108
|
+
await this.handleToolCall(req);
|
|
109
|
+
break;
|
|
110
|
+
default:
|
|
111
|
+
this.sendError(req.id, -32601, `Unknown method: ${req.method}`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
async handleToolCall(req) {
|
|
115
|
+
const params = req.params;
|
|
116
|
+
if (!params?.name) {
|
|
117
|
+
this.sendError(req.id, -32602, "Missing tool name");
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
const args = params.arguments ?? {};
|
|
121
|
+
try {
|
|
122
|
+
switch (params.name) {
|
|
123
|
+
case "radiant_think":
|
|
124
|
+
await this.handleThink(req.id, args);
|
|
125
|
+
break;
|
|
126
|
+
case "radiant_emergent":
|
|
127
|
+
await this.handleEmergent(req.id, args);
|
|
128
|
+
break;
|
|
129
|
+
default:
|
|
130
|
+
this.sendError(req.id, -32602, `Unknown tool: ${params.name}`);
|
|
131
|
+
}
|
|
132
|
+
} catch (err) {
|
|
133
|
+
this.sendResult(req.id, {
|
|
134
|
+
content: [{ type: "text", text: `Error: ${err}` }],
|
|
135
|
+
isError: true
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
async handleThink(id, args) {
|
|
140
|
+
const query = String(args.query ?? "");
|
|
141
|
+
if (!query) {
|
|
142
|
+
this.sendResult(id, {
|
|
143
|
+
content: [{ type: "text", text: "Error: query is required" }],
|
|
144
|
+
isError: true
|
|
145
|
+
});
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
const apiKey = process.env.ANTHROPIC_API_KEY;
|
|
149
|
+
if (!apiKey) {
|
|
150
|
+
this.sendResult(id, {
|
|
151
|
+
content: [{ type: "text", text: "Error: ANTHROPIC_API_KEY not set" }],
|
|
152
|
+
isError: true
|
|
153
|
+
});
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
const ai = createAnthropicAI(apiKey, this.config.model || void 0);
|
|
157
|
+
const result = await think({
|
|
158
|
+
worldmodelContent: this.worldmodelContent,
|
|
159
|
+
lensId: this.config.lensId,
|
|
160
|
+
query,
|
|
161
|
+
ai
|
|
162
|
+
});
|
|
163
|
+
let text = result.response;
|
|
164
|
+
if (!result.voiceClean) {
|
|
165
|
+
text += `
|
|
166
|
+
|
|
167
|
+
\u26A0 Voice violations detected: ${result.voiceViolations.map((v) => v.phrase).join(", ")}`;
|
|
168
|
+
}
|
|
169
|
+
this.sendResult(id, {
|
|
170
|
+
content: [{ type: "text", text }]
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
async handleEmergent(id, args) {
|
|
174
|
+
const scopeStr = String(args.scope ?? "");
|
|
175
|
+
if (!scopeStr) {
|
|
176
|
+
this.sendResult(id, {
|
|
177
|
+
content: [{ type: "text", text: 'Error: scope is required (e.g. "aukiverse/posemesh")' }],
|
|
178
|
+
isError: true
|
|
179
|
+
});
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
const apiKey = process.env.ANTHROPIC_API_KEY;
|
|
183
|
+
const githubToken = process.env.GITHUB_TOKEN;
|
|
184
|
+
if (!apiKey) {
|
|
185
|
+
this.sendResult(id, {
|
|
186
|
+
content: [{ type: "text", text: "Error: ANTHROPIC_API_KEY not set" }],
|
|
187
|
+
isError: true
|
|
188
|
+
});
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
if (!githubToken) {
|
|
192
|
+
this.sendResult(id, {
|
|
193
|
+
content: [{ type: "text", text: "Error: GITHUB_TOKEN not set" }],
|
|
194
|
+
isError: true
|
|
195
|
+
});
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
const scope = parseRepoScope(scopeStr);
|
|
199
|
+
const ai = createAnthropicAI(apiKey, this.config.model || void 0);
|
|
200
|
+
const exocortexPath = args.exocortex_dir ? String(args.exocortex_dir) : void 0;
|
|
201
|
+
const result = await emergent({
|
|
202
|
+
scope,
|
|
203
|
+
githubToken,
|
|
204
|
+
worldmodelContent: this.worldmodelContent,
|
|
205
|
+
lensId: this.config.lensId,
|
|
206
|
+
ai,
|
|
207
|
+
windowDays: 14,
|
|
208
|
+
exocortexPath
|
|
209
|
+
});
|
|
210
|
+
let text = result.text;
|
|
211
|
+
if (!result.voiceClean) {
|
|
212
|
+
text += `
|
|
213
|
+
|
|
214
|
+
\u26A0 Voice violations: ${result.voiceViolations.map((v) => v.phrase).join(", ")}`;
|
|
215
|
+
}
|
|
216
|
+
this.sendResult(id, {
|
|
217
|
+
content: [{ type: "text", text }]
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
sendResult(id, result) {
|
|
221
|
+
const response = { jsonrpc: "2.0", id, result };
|
|
222
|
+
process.stdout.write(JSON.stringify(response) + "\n");
|
|
223
|
+
}
|
|
224
|
+
sendError(id, code, message) {
|
|
225
|
+
const response = {
|
|
226
|
+
jsonrpc: "2.0",
|
|
227
|
+
id: id ?? null,
|
|
228
|
+
error: { code, message }
|
|
229
|
+
};
|
|
230
|
+
process.stdout.write(JSON.stringify(response) + "\n");
|
|
231
|
+
}
|
|
232
|
+
};
|
|
233
|
+
function loadWorldmodelContent(worldsPath) {
|
|
234
|
+
const resolved = resolve(worldsPath);
|
|
235
|
+
if (!existsSync(resolved)) {
|
|
236
|
+
throw new Error(`Worlds path not found: ${resolved}`);
|
|
237
|
+
}
|
|
238
|
+
const stat = statSync(resolved);
|
|
239
|
+
if (stat.isFile()) {
|
|
240
|
+
return readFileSync(resolved, "utf-8");
|
|
241
|
+
}
|
|
242
|
+
if (stat.isDirectory()) {
|
|
243
|
+
const files = readdirSync(resolved).filter(
|
|
244
|
+
(f) => extname(f) === ".md" && (f.endsWith(".worldmodel.md") || f.endsWith(".nv-world.md"))
|
|
245
|
+
).sort();
|
|
246
|
+
if (files.length === 0) {
|
|
247
|
+
throw new Error(`No worldmodel files found in ${resolved}`);
|
|
248
|
+
}
|
|
249
|
+
return files.map((f) => readFileSync(join(resolved, f), "utf-8")).join("\n\n---\n\n");
|
|
250
|
+
}
|
|
251
|
+
throw new Error(`Worlds path is neither a file nor directory: ${resolved}`);
|
|
252
|
+
}
|
|
253
|
+
async function startRadiantMcp(args) {
|
|
254
|
+
function parseArg(flag) {
|
|
255
|
+
const idx = args.indexOf(flag);
|
|
256
|
+
return idx >= 0 && idx + 1 < args.length ? args[idx + 1] : void 0;
|
|
257
|
+
}
|
|
258
|
+
const worldsPath = parseArg("--worlds") ?? process.env.RADIANT_WORLDS;
|
|
259
|
+
const lensId = parseArg("--lens") ?? process.env.RADIANT_LENS ?? "auki-builder";
|
|
260
|
+
const model = parseArg("--model") ?? process.env.RADIANT_MODEL;
|
|
261
|
+
if (!worldsPath) {
|
|
262
|
+
process.stderr.write("Error: --worlds <dir> or RADIANT_WORLDS required.\n");
|
|
263
|
+
process.exit(1);
|
|
264
|
+
}
|
|
265
|
+
const server = new RadiantMcpServer({ worldsPath, lensId, model });
|
|
266
|
+
await server.start();
|
|
267
|
+
}
|
|
268
|
+
export {
|
|
269
|
+
RadiantMcpServer,
|
|
270
|
+
startRadiantMcp
|
|
271
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@neuroverseos/governance",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "Deterministic governance engine for AI agents — enforce worlds (permanent rules) and plans (mission constraints) with full audit trace",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|