@agent-e/server 1.5.13 → 1.6.2
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 +87 -0
- package/dist/AgentEServer-DT6ETPR6.mjs +7 -0
- package/dist/chunk-53EPMEWX.mjs +1598 -0
- package/dist/chunk-53EPMEWX.mjs.map +1 -0
- package/dist/cli.js +1105 -22
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +1 -1
- package/dist/index.d.mts +4 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +1110 -23
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2 -2
- package/package.json +2 -2
- package/dist/AgentEServer-CBG5JMN4.mjs +0 -7
- package/dist/chunk-OXHIY4RU.mjs +0 -515
- package/dist/chunk-OXHIY4RU.mjs.map +0 -1
- /package/dist/{AgentEServer-CBG5JMN4.mjs.map → AgentEServer-DT6ETPR6.mjs.map} +0 -0
package/dist/chunk-OXHIY4RU.mjs
DELETED
|
@@ -1,515 +0,0 @@
|
|
|
1
|
-
// src/AgentEServer.ts
|
|
2
|
-
import * as http from "http";
|
|
3
|
-
import {
|
|
4
|
-
AgentE,
|
|
5
|
-
Observer,
|
|
6
|
-
Diagnoser,
|
|
7
|
-
ALL_PRINCIPLES,
|
|
8
|
-
DEFAULT_THRESHOLDS
|
|
9
|
-
} from "@agent-e/core";
|
|
10
|
-
|
|
11
|
-
// src/routes.ts
|
|
12
|
-
import { validateEconomyState } from "@agent-e/core";
|
|
13
|
-
function setCorsHeaders(res, origin) {
|
|
14
|
-
res.setHeader("Access-Control-Allow-Origin", origin);
|
|
15
|
-
res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
|
|
16
|
-
res.setHeader("Access-Control-Allow-Headers", "Content-Type");
|
|
17
|
-
}
|
|
18
|
-
function json(res, status, data, origin) {
|
|
19
|
-
setCorsHeaders(res, origin);
|
|
20
|
-
res.writeHead(status, { "Content-Type": "application/json" });
|
|
21
|
-
res.end(JSON.stringify(data));
|
|
22
|
-
}
|
|
23
|
-
var MAX_BODY_BYTES = 1048576;
|
|
24
|
-
function readBody(req) {
|
|
25
|
-
return new Promise((resolve, reject) => {
|
|
26
|
-
const chunks = [];
|
|
27
|
-
let totalBytes = 0;
|
|
28
|
-
req.on("data", (chunk) => {
|
|
29
|
-
totalBytes += chunk.length;
|
|
30
|
-
if (totalBytes > MAX_BODY_BYTES) {
|
|
31
|
-
req.destroy();
|
|
32
|
-
reject(new Error("Request body too large"));
|
|
33
|
-
return;
|
|
34
|
-
}
|
|
35
|
-
chunks.push(chunk);
|
|
36
|
-
});
|
|
37
|
-
req.on("end", () => resolve(Buffer.concat(chunks).toString("utf-8")));
|
|
38
|
-
req.on("error", reject);
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
function createRouteHandler(server) {
|
|
42
|
-
const cors = server.corsOrigin;
|
|
43
|
-
return async (req, res) => {
|
|
44
|
-
const url = new URL(req.url ?? "/", `http://${req.headers.host ?? "localhost"}`);
|
|
45
|
-
const path = url.pathname;
|
|
46
|
-
const method = req.method?.toUpperCase() ?? "GET";
|
|
47
|
-
if (method === "OPTIONS") {
|
|
48
|
-
setCorsHeaders(res, cors);
|
|
49
|
-
res.writeHead(204);
|
|
50
|
-
res.end();
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
try {
|
|
54
|
-
if (path === "/tick" && method === "POST") {
|
|
55
|
-
const body = await readBody(req);
|
|
56
|
-
let parsed;
|
|
57
|
-
try {
|
|
58
|
-
parsed = JSON.parse(body);
|
|
59
|
-
} catch {
|
|
60
|
-
json(res, 400, { error: "Invalid JSON" }, cors);
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
if (!parsed || typeof parsed !== "object") {
|
|
64
|
-
json(res, 400, { error: "Body must be a JSON object" }, cors);
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
const payload = parsed;
|
|
68
|
-
const state = payload["state"] ?? parsed;
|
|
69
|
-
const events = payload["events"];
|
|
70
|
-
if (server.validateState) {
|
|
71
|
-
const validation = validateEconomyState(state);
|
|
72
|
-
if (!validation.valid) {
|
|
73
|
-
json(res, 400, {
|
|
74
|
-
error: "invalid_state",
|
|
75
|
-
validationErrors: validation.errors
|
|
76
|
-
}, cors);
|
|
77
|
-
return;
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
const result = await server.processTick(
|
|
81
|
-
state,
|
|
82
|
-
Array.isArray(events) ? events : void 0
|
|
83
|
-
);
|
|
84
|
-
const warnings = server.validateState ? validateEconomyState(state).warnings : [];
|
|
85
|
-
json(res, 200, {
|
|
86
|
-
adjustments: result.adjustments,
|
|
87
|
-
alerts: result.alerts.map((a) => ({
|
|
88
|
-
principleId: a.principle.id,
|
|
89
|
-
principleName: a.principle.name,
|
|
90
|
-
severity: a.violation.severity,
|
|
91
|
-
evidence: a.violation.evidence,
|
|
92
|
-
reasoning: a.violation.suggestedAction.reasoning
|
|
93
|
-
})),
|
|
94
|
-
health: result.health,
|
|
95
|
-
tick: result.tick,
|
|
96
|
-
...warnings.length > 0 ? { validationWarnings: warnings } : {}
|
|
97
|
-
}, cors);
|
|
98
|
-
return;
|
|
99
|
-
}
|
|
100
|
-
if (path === "/health" && method === "GET") {
|
|
101
|
-
const agentE = server.getAgentE();
|
|
102
|
-
json(res, 200, {
|
|
103
|
-
health: agentE.getHealth(),
|
|
104
|
-
tick: agentE.metrics.latest()?.tick ?? 0,
|
|
105
|
-
mode: agentE.getMode(),
|
|
106
|
-
activePlans: agentE.getActivePlans().length,
|
|
107
|
-
uptime: server.getUptime()
|
|
108
|
-
}, cors);
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
111
|
-
if (path === "/decisions" && method === "GET") {
|
|
112
|
-
const limit = parseInt(url.searchParams.get("limit") ?? "100", 10);
|
|
113
|
-
const since = url.searchParams.get("since");
|
|
114
|
-
const agentE = server.getAgentE();
|
|
115
|
-
let decisions;
|
|
116
|
-
if (since) {
|
|
117
|
-
decisions = agentE.getDecisions({ since: parseInt(since, 10) });
|
|
118
|
-
} else {
|
|
119
|
-
decisions = agentE.log.latest(limit);
|
|
120
|
-
}
|
|
121
|
-
json(res, 200, { decisions }, cors);
|
|
122
|
-
return;
|
|
123
|
-
}
|
|
124
|
-
if (path === "/config" && method === "POST") {
|
|
125
|
-
const body = await readBody(req);
|
|
126
|
-
let parsed;
|
|
127
|
-
try {
|
|
128
|
-
parsed = JSON.parse(body);
|
|
129
|
-
} catch {
|
|
130
|
-
json(res, 400, { error: "Invalid JSON" }, cors);
|
|
131
|
-
return;
|
|
132
|
-
}
|
|
133
|
-
const config = parsed;
|
|
134
|
-
if (Array.isArray(config["lock"])) {
|
|
135
|
-
for (const param of config["lock"]) {
|
|
136
|
-
if (typeof param === "string") server.lock(param);
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
if (Array.isArray(config["unlock"])) {
|
|
140
|
-
for (const param of config["unlock"]) {
|
|
141
|
-
if (typeof param === "string") server.unlock(param);
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
if (Array.isArray(config["constrain"])) {
|
|
145
|
-
for (const c of config["constrain"]) {
|
|
146
|
-
if (c && typeof c === "object" && typeof c["param"] === "string" && typeof c["min"] === "number" && typeof c["max"] === "number") {
|
|
147
|
-
const constraint = c;
|
|
148
|
-
server.constrain(constraint.param, { min: constraint.min, max: constraint.max });
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
if (config["mode"] === "autonomous" || config["mode"] === "advisor") {
|
|
153
|
-
server.setMode(config["mode"]);
|
|
154
|
-
}
|
|
155
|
-
json(res, 200, { ok: true }, cors);
|
|
156
|
-
return;
|
|
157
|
-
}
|
|
158
|
-
if (path === "/principles" && method === "GET") {
|
|
159
|
-
const principles = server.getAgentE().getPrinciples();
|
|
160
|
-
json(res, 200, {
|
|
161
|
-
count: principles.length,
|
|
162
|
-
principles: principles.map((p) => ({
|
|
163
|
-
id: p.id,
|
|
164
|
-
name: p.name,
|
|
165
|
-
category: p.category,
|
|
166
|
-
description: p.description
|
|
167
|
-
}))
|
|
168
|
-
}, cors);
|
|
169
|
-
return;
|
|
170
|
-
}
|
|
171
|
-
if (path === "/diagnose" && method === "POST") {
|
|
172
|
-
const body = await readBody(req);
|
|
173
|
-
let parsed;
|
|
174
|
-
try {
|
|
175
|
-
parsed = JSON.parse(body);
|
|
176
|
-
} catch {
|
|
177
|
-
json(res, 400, { error: "Invalid JSON" }, cors);
|
|
178
|
-
return;
|
|
179
|
-
}
|
|
180
|
-
const payload = parsed;
|
|
181
|
-
const state = payload["state"] ?? parsed;
|
|
182
|
-
if (server.validateState) {
|
|
183
|
-
const validation = validateEconomyState(state);
|
|
184
|
-
if (!validation.valid) {
|
|
185
|
-
json(res, 400, { error: "invalid_state", validationErrors: validation.errors }, cors);
|
|
186
|
-
return;
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
const result = server.diagnoseOnly(state);
|
|
190
|
-
json(res, 200, {
|
|
191
|
-
health: result.health,
|
|
192
|
-
diagnoses: result.diagnoses.map((d) => ({
|
|
193
|
-
principleId: d.principle.id,
|
|
194
|
-
principleName: d.principle.name,
|
|
195
|
-
severity: d.violation.severity,
|
|
196
|
-
evidence: d.violation.evidence,
|
|
197
|
-
suggestedAction: d.violation.suggestedAction
|
|
198
|
-
}))
|
|
199
|
-
}, cors);
|
|
200
|
-
return;
|
|
201
|
-
}
|
|
202
|
-
json(res, 404, { error: "Not found" }, cors);
|
|
203
|
-
} catch (err) {
|
|
204
|
-
console.error("[AgentE Server] Unhandled route error:", err);
|
|
205
|
-
json(res, 500, { error: "Internal server error" }, cors);
|
|
206
|
-
}
|
|
207
|
-
};
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
// src/websocket.ts
|
|
211
|
-
import { WebSocketServer, WebSocket } from "ws";
|
|
212
|
-
import { validateEconomyState as validateEconomyState2 } from "@agent-e/core";
|
|
213
|
-
function send(ws, data) {
|
|
214
|
-
if (ws.readyState === WebSocket.OPEN) {
|
|
215
|
-
ws.send(JSON.stringify(data));
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
function createWebSocketHandler(httpServer, server) {
|
|
219
|
-
const wss = new WebSocketServer({ server: httpServer });
|
|
220
|
-
const aliveMap = /* @__PURE__ */ new WeakMap();
|
|
221
|
-
const heartbeatInterval = setInterval(() => {
|
|
222
|
-
for (const ws of wss.clients) {
|
|
223
|
-
if (ws.readyState === WebSocket.OPEN) {
|
|
224
|
-
if (aliveMap.get(ws) === false) {
|
|
225
|
-
ws.terminate();
|
|
226
|
-
continue;
|
|
227
|
-
}
|
|
228
|
-
aliveMap.set(ws, false);
|
|
229
|
-
ws.ping();
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
}, 3e4);
|
|
233
|
-
wss.on("connection", (ws) => {
|
|
234
|
-
console.log("[AgentE Server] Client connected");
|
|
235
|
-
aliveMap.set(ws, true);
|
|
236
|
-
ws.on("pong", () => {
|
|
237
|
-
aliveMap.set(ws, true);
|
|
238
|
-
});
|
|
239
|
-
ws.on("close", () => {
|
|
240
|
-
console.log("[AgentE Server] Client disconnected");
|
|
241
|
-
});
|
|
242
|
-
ws.on("message", async (raw) => {
|
|
243
|
-
let msg;
|
|
244
|
-
try {
|
|
245
|
-
msg = JSON.parse(raw.toString());
|
|
246
|
-
} catch {
|
|
247
|
-
send(ws, { type: "error", message: "Malformed JSON" });
|
|
248
|
-
return;
|
|
249
|
-
}
|
|
250
|
-
if (!msg.type || typeof msg.type !== "string") {
|
|
251
|
-
send(ws, { type: "error", message: 'Missing "type" field' });
|
|
252
|
-
return;
|
|
253
|
-
}
|
|
254
|
-
switch (msg.type) {
|
|
255
|
-
case "tick": {
|
|
256
|
-
const state = msg["state"];
|
|
257
|
-
const events = msg["events"];
|
|
258
|
-
if (server.validateState) {
|
|
259
|
-
const validation = validateEconomyState2(state);
|
|
260
|
-
if (!validation.valid) {
|
|
261
|
-
send(ws, { type: "validation_error", validationErrors: validation.errors });
|
|
262
|
-
return;
|
|
263
|
-
}
|
|
264
|
-
if (validation.warnings.length > 0) {
|
|
265
|
-
send(ws, { type: "validation_warning", validationWarnings: validation.warnings });
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
try {
|
|
269
|
-
const result = await server.processTick(
|
|
270
|
-
state,
|
|
271
|
-
Array.isArray(events) ? events : void 0
|
|
272
|
-
);
|
|
273
|
-
send(ws, {
|
|
274
|
-
type: "tick_result",
|
|
275
|
-
adjustments: result.adjustments,
|
|
276
|
-
alerts: result.alerts.map((a) => ({
|
|
277
|
-
principleId: a.principle.id,
|
|
278
|
-
principleName: a.principle.name,
|
|
279
|
-
severity: a.violation.severity,
|
|
280
|
-
reasoning: a.violation.suggestedAction.reasoning
|
|
281
|
-
})),
|
|
282
|
-
health: result.health,
|
|
283
|
-
tick: result.tick
|
|
284
|
-
});
|
|
285
|
-
} catch (err) {
|
|
286
|
-
send(ws, { type: "error", message: "Tick processing failed" });
|
|
287
|
-
}
|
|
288
|
-
break;
|
|
289
|
-
}
|
|
290
|
-
case "event": {
|
|
291
|
-
const event = msg["event"];
|
|
292
|
-
if (event) {
|
|
293
|
-
server.getAgentE().ingest(event);
|
|
294
|
-
send(ws, { type: "event_ack" });
|
|
295
|
-
} else {
|
|
296
|
-
send(ws, { type: "error", message: 'Missing "event" field' });
|
|
297
|
-
}
|
|
298
|
-
break;
|
|
299
|
-
}
|
|
300
|
-
case "health": {
|
|
301
|
-
const agentE = server.getAgentE();
|
|
302
|
-
send(ws, {
|
|
303
|
-
type: "health_result",
|
|
304
|
-
health: agentE.getHealth(),
|
|
305
|
-
tick: agentE.metrics.latest()?.tick ?? 0,
|
|
306
|
-
mode: agentE.getMode(),
|
|
307
|
-
activePlans: agentE.getActivePlans().length,
|
|
308
|
-
uptime: server.getUptime()
|
|
309
|
-
});
|
|
310
|
-
break;
|
|
311
|
-
}
|
|
312
|
-
case "diagnose": {
|
|
313
|
-
const state = msg["state"];
|
|
314
|
-
if (server.validateState) {
|
|
315
|
-
const validation = validateEconomyState2(state);
|
|
316
|
-
if (!validation.valid) {
|
|
317
|
-
send(ws, { type: "validation_error", validationErrors: validation.errors });
|
|
318
|
-
return;
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
const result = server.diagnoseOnly(state);
|
|
322
|
-
send(ws, {
|
|
323
|
-
type: "diagnose_result",
|
|
324
|
-
health: result.health,
|
|
325
|
-
diagnoses: result.diagnoses.map((d) => ({
|
|
326
|
-
principleId: d.principle.id,
|
|
327
|
-
principleName: d.principle.name,
|
|
328
|
-
severity: d.violation.severity,
|
|
329
|
-
suggestedAction: d.violation.suggestedAction
|
|
330
|
-
}))
|
|
331
|
-
});
|
|
332
|
-
break;
|
|
333
|
-
}
|
|
334
|
-
default:
|
|
335
|
-
send(ws, { type: "error", message: `Unknown message type: "${msg.type}"` });
|
|
336
|
-
}
|
|
337
|
-
});
|
|
338
|
-
});
|
|
339
|
-
return () => {
|
|
340
|
-
clearInterval(heartbeatInterval);
|
|
341
|
-
wss.close();
|
|
342
|
-
};
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
// src/AgentEServer.ts
|
|
346
|
-
var AgentEServer = class {
|
|
347
|
-
constructor(config = {}) {
|
|
348
|
-
this.lastState = null;
|
|
349
|
-
this.adjustmentQueue = [];
|
|
350
|
-
this.alerts = [];
|
|
351
|
-
this.startedAt = Date.now();
|
|
352
|
-
this.cleanupWs = null;
|
|
353
|
-
this.port = config.port ?? 3100;
|
|
354
|
-
this.host = config.host ?? "0.0.0.0";
|
|
355
|
-
this.validateState = config.validateState ?? true;
|
|
356
|
-
this.corsOrigin = config.corsOrigin ?? "*";
|
|
357
|
-
const adapter = {
|
|
358
|
-
getState: () => {
|
|
359
|
-
if (!this.lastState) {
|
|
360
|
-
return {
|
|
361
|
-
tick: 0,
|
|
362
|
-
roles: [],
|
|
363
|
-
resources: [],
|
|
364
|
-
currencies: ["default"],
|
|
365
|
-
agentBalances: {},
|
|
366
|
-
agentRoles: {},
|
|
367
|
-
agentInventories: {},
|
|
368
|
-
marketPrices: {},
|
|
369
|
-
recentTransactions: []
|
|
370
|
-
};
|
|
371
|
-
}
|
|
372
|
-
return this.lastState;
|
|
373
|
-
},
|
|
374
|
-
setParam: (key, value, scope) => {
|
|
375
|
-
this.adjustmentQueue.push({ key, value, scope });
|
|
376
|
-
}
|
|
377
|
-
};
|
|
378
|
-
const agentECfg = config.agentE ?? {};
|
|
379
|
-
const agentEConfig = {
|
|
380
|
-
adapter,
|
|
381
|
-
mode: agentECfg.mode ?? "autonomous",
|
|
382
|
-
gracePeriod: agentECfg.gracePeriod ?? 0,
|
|
383
|
-
checkInterval: agentECfg.checkInterval ?? 1,
|
|
384
|
-
...agentECfg.dominantRoles ? { dominantRoles: agentECfg.dominantRoles } : {},
|
|
385
|
-
...agentECfg.idealDistribution ? { idealDistribution: agentECfg.idealDistribution } : {},
|
|
386
|
-
...agentECfg.maxAdjustmentPercent !== void 0 ? { maxAdjustmentPercent: agentECfg.maxAdjustmentPercent } : {},
|
|
387
|
-
...agentECfg.cooldownTicks !== void 0 ? { cooldownTicks: agentECfg.cooldownTicks } : {},
|
|
388
|
-
...agentECfg.thresholds ? { thresholds: agentECfg.thresholds } : {}
|
|
389
|
-
};
|
|
390
|
-
this.thresholds = {
|
|
391
|
-
...DEFAULT_THRESHOLDS,
|
|
392
|
-
...agentECfg.thresholds ?? {},
|
|
393
|
-
...agentECfg.maxAdjustmentPercent !== void 0 ? { maxAdjustmentPercent: agentECfg.maxAdjustmentPercent } : {},
|
|
394
|
-
...agentECfg.cooldownTicks !== void 0 ? { cooldownTicks: agentECfg.cooldownTicks } : {}
|
|
395
|
-
};
|
|
396
|
-
this.agentE = new AgentE(agentEConfig);
|
|
397
|
-
this.agentE.on("alert", (diagnosis) => {
|
|
398
|
-
this.alerts.push(diagnosis);
|
|
399
|
-
});
|
|
400
|
-
this.agentE.connect(adapter).start();
|
|
401
|
-
const routeHandler = createRouteHandler(this);
|
|
402
|
-
this.server = http.createServer(routeHandler);
|
|
403
|
-
}
|
|
404
|
-
async start() {
|
|
405
|
-
this.cleanupWs = createWebSocketHandler(this.server, this);
|
|
406
|
-
return new Promise((resolve) => {
|
|
407
|
-
this.server.listen(this.port, this.host, () => {
|
|
408
|
-
const addr = this.getAddress();
|
|
409
|
-
console.log(`[AgentE Server] Listening on http://${addr.host}:${addr.port}`);
|
|
410
|
-
resolve();
|
|
411
|
-
});
|
|
412
|
-
});
|
|
413
|
-
}
|
|
414
|
-
async stop() {
|
|
415
|
-
this.agentE.stop();
|
|
416
|
-
if (this.cleanupWs) this.cleanupWs();
|
|
417
|
-
return new Promise((resolve, reject) => {
|
|
418
|
-
this.server.close((err) => {
|
|
419
|
-
if (err) reject(err);
|
|
420
|
-
else resolve();
|
|
421
|
-
});
|
|
422
|
-
});
|
|
423
|
-
}
|
|
424
|
-
getAgentE() {
|
|
425
|
-
return this.agentE;
|
|
426
|
-
}
|
|
427
|
-
getAddress() {
|
|
428
|
-
const addr = this.server.address();
|
|
429
|
-
if (addr && typeof addr === "object") {
|
|
430
|
-
return { port: addr.port, host: addr.address };
|
|
431
|
-
}
|
|
432
|
-
return { port: this.port, host: this.host };
|
|
433
|
-
}
|
|
434
|
-
getUptime() {
|
|
435
|
-
return Date.now() - this.startedAt;
|
|
436
|
-
}
|
|
437
|
-
/**
|
|
438
|
-
* Process a tick with the given state.
|
|
439
|
-
* 1. Clear adjustment queue
|
|
440
|
-
* 2. Set state
|
|
441
|
-
* 3. Ingest events
|
|
442
|
-
* 4. Run agentE.tick(state)
|
|
443
|
-
* 5. Drain adjustment queue, enrich with reasoning from decisions
|
|
444
|
-
* 6. Return response
|
|
445
|
-
*/
|
|
446
|
-
async processTick(state, events) {
|
|
447
|
-
this.adjustmentQueue = [];
|
|
448
|
-
this.alerts = [];
|
|
449
|
-
this.lastState = state;
|
|
450
|
-
if (events) {
|
|
451
|
-
for (const event of events) {
|
|
452
|
-
this.agentE.ingest(event);
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
await this.agentE.tick(state);
|
|
456
|
-
const rawAdj = [...this.adjustmentQueue];
|
|
457
|
-
this.adjustmentQueue = [];
|
|
458
|
-
const decisions = this.agentE.getDecisions({ since: state.tick, until: state.tick });
|
|
459
|
-
const adjustments = rawAdj.map((adj) => {
|
|
460
|
-
const decision = decisions.find(
|
|
461
|
-
(d) => d.plan.parameter === adj.key && d.result === "applied"
|
|
462
|
-
);
|
|
463
|
-
return {
|
|
464
|
-
parameter: adj.key,
|
|
465
|
-
value: adj.value,
|
|
466
|
-
...adj.scope ? { scope: adj.scope } : {},
|
|
467
|
-
reasoning: decision?.diagnosis.violation.suggestedAction.reasoning ?? ""
|
|
468
|
-
};
|
|
469
|
-
});
|
|
470
|
-
return {
|
|
471
|
-
adjustments,
|
|
472
|
-
alerts: [...this.alerts],
|
|
473
|
-
health: this.agentE.getHealth(),
|
|
474
|
-
tick: state.tick,
|
|
475
|
-
decisions
|
|
476
|
-
};
|
|
477
|
-
}
|
|
478
|
-
/**
|
|
479
|
-
* Run Observer + Diagnoser on the given state without side effects (no execution).
|
|
480
|
-
* Computes fresh metrics from the state rather than reading stored metrics.
|
|
481
|
-
*/
|
|
482
|
-
diagnoseOnly(state) {
|
|
483
|
-
const observer = new Observer();
|
|
484
|
-
const diagnoser = new Diagnoser(ALL_PRINCIPLES);
|
|
485
|
-
const metrics = observer.compute(state, []);
|
|
486
|
-
const diagnoses = diagnoser.diagnose(metrics, this.thresholds);
|
|
487
|
-
let health = 100;
|
|
488
|
-
if (metrics.avgSatisfaction < 65) health -= 15;
|
|
489
|
-
if (metrics.avgSatisfaction < 50) health -= 10;
|
|
490
|
-
if (metrics.giniCoefficient > 0.45) health -= 15;
|
|
491
|
-
if (metrics.giniCoefficient > 0.6) health -= 10;
|
|
492
|
-
if (Math.abs(metrics.netFlow) > 10) health -= 15;
|
|
493
|
-
if (Math.abs(metrics.netFlow) > 20) health -= 10;
|
|
494
|
-
if (metrics.churnRate > 0.05) health -= 15;
|
|
495
|
-
health = Math.max(0, Math.min(100, health));
|
|
496
|
-
return { diagnoses, health };
|
|
497
|
-
}
|
|
498
|
-
setMode(mode) {
|
|
499
|
-
this.agentE.setMode(mode);
|
|
500
|
-
}
|
|
501
|
-
lock(param) {
|
|
502
|
-
this.agentE.lock(param);
|
|
503
|
-
}
|
|
504
|
-
unlock(param) {
|
|
505
|
-
this.agentE.unlock(param);
|
|
506
|
-
}
|
|
507
|
-
constrain(param, bounds) {
|
|
508
|
-
this.agentE.constrain(param, bounds);
|
|
509
|
-
}
|
|
510
|
-
};
|
|
511
|
-
|
|
512
|
-
export {
|
|
513
|
-
AgentEServer
|
|
514
|
-
};
|
|
515
|
-
//# sourceMappingURL=chunk-OXHIY4RU.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/AgentEServer.ts","../src/routes.ts","../src/websocket.ts"],"sourcesContent":["// AgentEServer — HTTP + WebSocket transport for AgentE\n\nimport * as http from 'node:http';\nimport {\n AgentE,\n Observer,\n Diagnoser,\n ALL_PRINCIPLES,\n DEFAULT_THRESHOLDS,\n validateEconomyState,\n type AgentEConfig,\n type EconomyAdapter,\n type EconomyState,\n type EconomicEvent,\n type Diagnosis,\n type AgentEMode,\n type Thresholds,\n} from '@agent-e/core';\nimport { createRouteHandler } from './routes.js';\nimport { createWebSocketHandler } from './websocket.js';\n\nexport interface ServerConfig {\n port?: number;\n host?: string;\n agentE?: Partial<Omit<AgentEConfig, 'adapter'>>;\n validateState?: boolean;\n corsOrigin?: string;\n}\n\nexport interface EnrichedAdjustment {\n parameter: string;\n value: number;\n scope?: import('@agent-e/core').ParameterScope;\n reasoning: string;\n}\n\ninterface QueuedAdjustment {\n key: string;\n value: number;\n scope: import('@agent-e/core').ParameterScope | undefined;\n}\n\nexport class AgentEServer {\n private readonly agentE: AgentE;\n private readonly server: http.Server;\n private lastState: EconomyState | null = null;\n private adjustmentQueue: QueuedAdjustment[] = [];\n private alerts: Diagnosis[] = [];\n readonly port: number;\n private readonly host: string;\n private readonly thresholds: Thresholds;\n private readonly startedAt = Date.now();\n private cleanupWs: (() => void) | null = null;\n readonly validateState: boolean;\n readonly corsOrigin: string;\n\n constructor(config: ServerConfig = {}) {\n this.port = config.port ?? 3100;\n this.host = config.host ?? '0.0.0.0';\n this.validateState = config.validateState ?? true;\n this.corsOrigin = config.corsOrigin ?? '*';\n\n // Build a \"remote\" adapter — state comes from HTTP/WS, not polled\n const adapter: EconomyAdapter = {\n getState: () => {\n if (!this.lastState) {\n return {\n tick: 0,\n roles: [],\n resources: [],\n currencies: ['default'],\n agentBalances: {},\n agentRoles: {},\n agentInventories: {},\n marketPrices: {},\n recentTransactions: [],\n };\n }\n return this.lastState;\n },\n setParam: (key: string, value: number, scope?: import('@agent-e/core').ParameterScope) => {\n this.adjustmentQueue.push({ key, value, scope });\n },\n };\n\n const agentECfg = config.agentE ?? {};\n const agentEConfig: AgentEConfig = {\n adapter,\n mode: agentECfg.mode ?? 'autonomous',\n gracePeriod: agentECfg.gracePeriod ?? 0,\n checkInterval: agentECfg.checkInterval ?? 1,\n ...(agentECfg.dominantRoles ? { dominantRoles: agentECfg.dominantRoles } : {}),\n ...(agentECfg.idealDistribution ? { idealDistribution: agentECfg.idealDistribution } : {}),\n ...(agentECfg.maxAdjustmentPercent !== undefined ? { maxAdjustmentPercent: agentECfg.maxAdjustmentPercent } : {}),\n ...(agentECfg.cooldownTicks !== undefined ? { cooldownTicks: agentECfg.cooldownTicks } : {}),\n ...(agentECfg.thresholds ? { thresholds: agentECfg.thresholds } : {}),\n };\n\n this.thresholds = {\n ...DEFAULT_THRESHOLDS,\n ...(agentECfg.thresholds ?? {}),\n ...(agentECfg.maxAdjustmentPercent !== undefined ? { maxAdjustmentPercent: agentECfg.maxAdjustmentPercent } : {}),\n ...(agentECfg.cooldownTicks !== undefined ? { cooldownTicks: agentECfg.cooldownTicks } : {}),\n };\n this.agentE = new AgentE(agentEConfig);\n\n // Capture alerts during tick\n this.agentE.on('alert', (diagnosis: unknown) => {\n this.alerts.push(diagnosis as Diagnosis);\n });\n\n this.agentE.connect(adapter).start();\n\n // Create HTTP server\n const routeHandler = createRouteHandler(this);\n this.server = http.createServer(routeHandler);\n }\n\n async start(): Promise<void> {\n // Wire up WebSocket upgrade\n this.cleanupWs = createWebSocketHandler(this.server, this);\n\n return new Promise((resolve) => {\n this.server.listen(this.port, this.host, () => {\n const addr = this.getAddress();\n console.log(`[AgentE Server] Listening on http://${addr.host}:${addr.port}`);\n resolve();\n });\n });\n }\n\n async stop(): Promise<void> {\n this.agentE.stop();\n if (this.cleanupWs) this.cleanupWs();\n return new Promise((resolve, reject) => {\n this.server.close((err) => {\n if (err) reject(err);\n else resolve();\n });\n });\n }\n\n getAgentE(): AgentE {\n return this.agentE;\n }\n\n getAddress(): { port: number; host: string } {\n const addr = this.server.address();\n if (addr && typeof addr === 'object') {\n return { port: addr.port, host: addr.address };\n }\n return { port: this.port, host: this.host };\n }\n\n getUptime(): number {\n return Date.now() - this.startedAt;\n }\n\n /**\n * Process a tick with the given state.\n * 1. Clear adjustment queue\n * 2. Set state\n * 3. Ingest events\n * 4. Run agentE.tick(state)\n * 5. Drain adjustment queue, enrich with reasoning from decisions\n * 6. Return response\n */\n async processTick(\n state: EconomyState,\n events?: EconomicEvent[],\n ): Promise<{\n adjustments: EnrichedAdjustment[];\n alerts: Diagnosis[];\n health: number;\n tick: number;\n decisions: ReturnType<AgentE['getDecisions']>;\n }> {\n // Clear queues\n this.adjustmentQueue = [];\n this.alerts = [];\n\n // Set state\n this.lastState = state;\n\n // Ingest events\n if (events) {\n for (const event of events) {\n this.agentE.ingest(event);\n }\n }\n\n // Run tick\n await this.agentE.tick(state);\n\n // Drain adjustments\n const rawAdj = [...this.adjustmentQueue];\n this.adjustmentQueue = [];\n\n // Cross-reference with decision log to attach reasoning\n const decisions = this.agentE.getDecisions({ since: state.tick, until: state.tick });\n\n const adjustments: EnrichedAdjustment[] = rawAdj.map(adj => {\n const decision = decisions.find(d =>\n d.plan.parameter === adj.key && d.result === 'applied',\n );\n return {\n parameter: adj.key,\n value: adj.value,\n ...(adj.scope ? { scope: adj.scope } : {}),\n reasoning: decision?.diagnosis.violation.suggestedAction.reasoning ?? '',\n };\n });\n\n return {\n adjustments,\n alerts: [...this.alerts],\n health: this.agentE.getHealth(),\n tick: state.tick,\n decisions,\n };\n }\n\n /**\n * Run Observer + Diagnoser on the given state without side effects (no execution).\n * Computes fresh metrics from the state rather than reading stored metrics.\n */\n diagnoseOnly(state: EconomyState): {\n diagnoses: ReturnType<AgentE['diagnoseNow']>;\n health: number;\n } {\n const observer = new Observer();\n const diagnoser = new Diagnoser(ALL_PRINCIPLES);\n const metrics = observer.compute(state, []);\n const diagnoses = diagnoser.diagnose(metrics, this.thresholds);\n\n // Mirrors AgentE.getHealth() — keep in sync if that logic changes\n let health = 100;\n if (metrics.avgSatisfaction < 65) health -= 15;\n if (metrics.avgSatisfaction < 50) health -= 10;\n if (metrics.giniCoefficient > 0.45) health -= 15;\n if (metrics.giniCoefficient > 0.60) health -= 10;\n if (Math.abs(metrics.netFlow) > 10) health -= 15;\n if (Math.abs(metrics.netFlow) > 20) health -= 10;\n if (metrics.churnRate > 0.05) health -= 15;\n health = Math.max(0, Math.min(100, health));\n\n return { diagnoses, health };\n }\n\n setMode(mode: AgentEMode): void {\n this.agentE.setMode(mode);\n }\n\n lock(param: string): void {\n this.agentE.lock(param);\n }\n\n unlock(param: string): void {\n this.agentE.unlock(param);\n }\n\n constrain(param: string, bounds: { min: number; max: number }): void {\n this.agentE.constrain(param, bounds);\n }\n}\n","// HTTP routes for AgentE Server\n// Node http module with manual body parsing. CORS on all responses.\n\nimport type * as http from 'node:http';\nimport { validateEconomyState } from '@agent-e/core';\nimport type { AgentEServer } from './AgentEServer.js';\n\nfunction setCorsHeaders(res: http.ServerResponse, origin: string): void {\n res.setHeader('Access-Control-Allow-Origin', origin);\n res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');\n res.setHeader('Access-Control-Allow-Headers', 'Content-Type');\n}\n\nfunction json(res: http.ServerResponse, status: number, data: unknown, origin: string): void {\n setCorsHeaders(res, origin);\n res.writeHead(status, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify(data));\n}\n\nconst MAX_BODY_BYTES = 1_048_576; // 1 MB\n\nfunction readBody(req: http.IncomingMessage): Promise<string> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n let totalBytes = 0;\n req.on('data', (chunk: Buffer) => {\n totalBytes += chunk.length;\n if (totalBytes > MAX_BODY_BYTES) {\n req.destroy();\n reject(new Error('Request body too large'));\n return;\n }\n chunks.push(chunk);\n });\n req.on('end', () => resolve(Buffer.concat(chunks).toString('utf-8')));\n req.on('error', reject);\n });\n}\n\nexport function createRouteHandler(\n server: AgentEServer,\n): (req: http.IncomingMessage, res: http.ServerResponse) => void {\n const cors = server.corsOrigin;\n\n return async (req, res) => {\n const url = new URL(req.url ?? '/', `http://${req.headers.host ?? 'localhost'}`);\n const path = url.pathname;\n const method = req.method?.toUpperCase() ?? 'GET';\n\n // CORS preflight\n if (method === 'OPTIONS') {\n setCorsHeaders(res, cors);\n res.writeHead(204);\n res.end();\n return;\n }\n\n try {\n // POST /tick — validate state, run tick, return adjustments/alerts/health\n if (path === '/tick' && method === 'POST') {\n const body = await readBody(req);\n let parsed: unknown;\n try {\n parsed = JSON.parse(body);\n } catch {\n json(res, 400, { error: 'Invalid JSON' }, cors);\n return;\n }\n\n if (!parsed || typeof parsed !== 'object') {\n json(res, 400, { error: 'Body must be a JSON object' }, cors);\n return;\n }\n\n const payload = parsed as Record<string, unknown>;\n const state = payload['state'] ?? parsed;\n const events = payload['events'];\n\n // Validate state (if enabled)\n if (server.validateState) {\n const validation = validateEconomyState(state);\n if (!validation.valid) {\n json(res, 400, {\n error: 'invalid_state',\n validationErrors: validation.errors,\n }, cors);\n return;\n }\n }\n\n const result = await server.processTick(\n state as import('@agent-e/core').EconomyState,\n Array.isArray(events) ? events as import('@agent-e/core').EconomicEvent[] : undefined,\n );\n\n // Include validation warnings if any\n const warnings = server.validateState\n ? validateEconomyState(state).warnings\n : [];\n\n json(res, 200, {\n adjustments: result.adjustments,\n alerts: result.alerts.map(a => ({\n principleId: a.principle.id,\n principleName: a.principle.name,\n severity: a.violation.severity,\n evidence: a.violation.evidence,\n reasoning: a.violation.suggestedAction.reasoning,\n })),\n health: result.health,\n tick: result.tick,\n ...(warnings.length > 0 ? { validationWarnings: warnings } : {}),\n }, cors);\n return;\n }\n\n // GET /health — health, tick, mode, activePlans, uptime\n if (path === '/health' && method === 'GET') {\n const agentE = server.getAgentE();\n json(res, 200, {\n health: agentE.getHealth(),\n tick: agentE.metrics.latest()?.tick ?? 0,\n mode: agentE.getMode(),\n activePlans: agentE.getActivePlans().length,\n uptime: server.getUptime(),\n }, cors);\n return;\n }\n\n // GET /decisions — decision log with optional ?limit and ?since\n if (path === '/decisions' && method === 'GET') {\n const limit = parseInt(url.searchParams.get('limit') ?? '100', 10);\n const since = url.searchParams.get('since');\n const agentE = server.getAgentE();\n\n let decisions;\n if (since) {\n decisions = agentE.getDecisions({ since: parseInt(since, 10) });\n } else {\n decisions = agentE.log.latest(limit);\n }\n\n json(res, 200, { decisions }, cors);\n return;\n }\n\n // POST /config — batch lock/unlock/constrain/mode\n if (path === '/config' && method === 'POST') {\n const body = await readBody(req);\n let parsed: unknown;\n try {\n parsed = JSON.parse(body);\n } catch {\n json(res, 400, { error: 'Invalid JSON' }, cors);\n return;\n }\n\n const config = parsed as Record<string, unknown>;\n\n // Lock parameters\n if (Array.isArray(config['lock'])) {\n for (const param of config['lock']) {\n if (typeof param === 'string') server.lock(param);\n }\n }\n\n // Unlock parameters\n if (Array.isArray(config['unlock'])) {\n for (const param of config['unlock']) {\n if (typeof param === 'string') server.unlock(param);\n }\n }\n\n // Constrain parameters\n if (Array.isArray(config['constrain'])) {\n for (const c of config['constrain'] as unknown[]) {\n if (\n c && typeof c === 'object' &&\n typeof (c as Record<string, unknown>)['param'] === 'string' &&\n typeof (c as Record<string, unknown>)['min'] === 'number' &&\n typeof (c as Record<string, unknown>)['max'] === 'number'\n ) {\n const constraint = c as { param: string; min: number; max: number };\n server.constrain(constraint.param, { min: constraint.min, max: constraint.max });\n }\n }\n }\n\n // Mode switch\n if (config['mode'] === 'autonomous' || config['mode'] === 'advisor') {\n server.setMode(config['mode']);\n }\n\n json(res, 200, { ok: true }, cors);\n return;\n }\n\n // GET /principles — list all principles\n if (path === '/principles' && method === 'GET') {\n const principles = server.getAgentE().getPrinciples();\n json(res, 200, {\n count: principles.length,\n principles: principles.map(p => ({\n id: p.id,\n name: p.name,\n category: p.category,\n description: p.description,\n })),\n }, cors);\n return;\n }\n\n // POST /diagnose — standalone Observer+Diagnoser (no side effects)\n if (path === '/diagnose' && method === 'POST') {\n const body = await readBody(req);\n let parsed: unknown;\n try {\n parsed = JSON.parse(body);\n } catch {\n json(res, 400, { error: 'Invalid JSON' }, cors);\n return;\n }\n\n const payload = parsed as Record<string, unknown>;\n const state = payload['state'] ?? parsed;\n\n if (server.validateState) {\n const validation = validateEconomyState(state);\n if (!validation.valid) {\n json(res, 400, { error: 'invalid_state', validationErrors: validation.errors }, cors);\n return;\n }\n }\n\n const result = server.diagnoseOnly(state as import('@agent-e/core').EconomyState);\n\n json(res, 200, {\n health: result.health,\n diagnoses: result.diagnoses.map(d => ({\n principleId: d.principle.id,\n principleName: d.principle.name,\n severity: d.violation.severity,\n evidence: d.violation.evidence,\n suggestedAction: d.violation.suggestedAction,\n })),\n }, cors);\n return;\n }\n\n // 404\n json(res, 404, { error: 'Not found' }, cors);\n } catch (err) {\n console.error('[AgentE Server] Unhandled route error:', err);\n json(res, 500, { error: 'Internal server error' }, cors);\n }\n };\n}\n","// WebSocket handler for AgentE Server\n// Same port via HTTP upgrade. JSON messages with `type` field.\n\nimport type * as http from 'node:http';\nimport { WebSocketServer, WebSocket } from 'ws';\nimport { validateEconomyState, type EconomyState, type EconomicEvent } from '@agent-e/core';\nimport type { AgentEServer } from './AgentEServer.js';\n\ninterface IncomingMessage {\n type: string;\n [key: string]: unknown;\n}\n\nfunction send(ws: WebSocket, data: Record<string, unknown>): void {\n if (ws.readyState === WebSocket.OPEN) {\n ws.send(JSON.stringify(data));\n }\n}\n\nexport function createWebSocketHandler(\n httpServer: http.Server,\n server: AgentEServer,\n): () => void {\n const wss = new WebSocketServer({ server: httpServer });\n\n // Heartbeat: ping every 30s, disconnect if no pong within 10s\n const aliveMap = new WeakMap<WebSocket, boolean>();\n\n const heartbeatInterval = setInterval(() => {\n for (const ws of wss.clients) {\n if (ws.readyState === WebSocket.OPEN) {\n if (aliveMap.get(ws) === false) {\n // No pong received since last ping — terminate\n ws.terminate();\n continue;\n }\n aliveMap.set(ws, false);\n ws.ping();\n }\n }\n }, 30_000);\n\n wss.on('connection', (ws) => {\n console.log('[AgentE Server] Client connected');\n aliveMap.set(ws, true);\n\n ws.on('pong', () => {\n aliveMap.set(ws, true);\n });\n\n ws.on('close', () => {\n console.log('[AgentE Server] Client disconnected');\n });\n\n ws.on('message', async (raw) => {\n let msg: IncomingMessage;\n try {\n msg = JSON.parse(raw.toString()) as IncomingMessage;\n } catch {\n send(ws, { type: 'error', message: 'Malformed JSON' });\n return;\n }\n\n if (!msg.type || typeof msg.type !== 'string') {\n send(ws, { type: 'error', message: 'Missing \"type\" field' });\n return;\n }\n\n switch (msg.type) {\n case 'tick': {\n const state = msg['state'];\n const events = msg['events'];\n\n if (server.validateState) {\n const validation = validateEconomyState(state);\n if (!validation.valid) {\n send(ws, { type: 'validation_error', validationErrors: validation.errors });\n return;\n }\n\n // Forward warnings even if valid\n if (validation.warnings.length > 0) {\n send(ws, { type: 'validation_warning', validationWarnings: validation.warnings });\n }\n }\n\n try {\n const result = await server.processTick(\n state as EconomyState,\n Array.isArray(events) ? events as EconomicEvent[] : undefined,\n );\n\n send(ws, {\n type: 'tick_result',\n adjustments: result.adjustments,\n alerts: result.alerts.map(a => ({\n principleId: a.principle.id,\n principleName: a.principle.name,\n severity: a.violation.severity,\n reasoning: a.violation.suggestedAction.reasoning,\n })),\n health: result.health,\n tick: result.tick,\n });\n } catch (err) {\n send(ws, { type: 'error', message: 'Tick processing failed' });\n }\n break;\n }\n\n case 'event': {\n const event = msg['event'] as EconomicEvent | undefined;\n if (event) {\n server.getAgentE().ingest(event);\n send(ws, { type: 'event_ack' });\n } else {\n send(ws, { type: 'error', message: 'Missing \"event\" field' });\n }\n break;\n }\n\n case 'health': {\n const agentE = server.getAgentE();\n send(ws, {\n type: 'health_result',\n health: agentE.getHealth(),\n tick: agentE.metrics.latest()?.tick ?? 0,\n mode: agentE.getMode(),\n activePlans: agentE.getActivePlans().length,\n uptime: server.getUptime(),\n });\n break;\n }\n\n case 'diagnose': {\n const state = msg['state'];\n\n if (server.validateState) {\n const validation = validateEconomyState(state);\n if (!validation.valid) {\n send(ws, { type: 'validation_error', validationErrors: validation.errors });\n return;\n }\n }\n\n const result = server.diagnoseOnly(state as EconomyState);\n send(ws, {\n type: 'diagnose_result',\n health: result.health,\n diagnoses: result.diagnoses.map(d => ({\n principleId: d.principle.id,\n principleName: d.principle.name,\n severity: d.violation.severity,\n suggestedAction: d.violation.suggestedAction,\n })),\n });\n break;\n }\n\n default:\n send(ws, { type: 'error', message: `Unknown message type: \"${msg.type}\"` });\n }\n });\n });\n\n // Return cleanup function\n return () => {\n clearInterval(heartbeatInterval);\n wss.close();\n };\n}\n"],"mappings":"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","names":["validateEconomyState"]}
|
|
File without changes
|