@agent-e/server 1.4.1 → 1.4.4
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/dist/AgentEServer-45WN6DK4.mjs +7 -0
- package/dist/{chunk-W7GXJB2K.mjs → chunk-QU3P7LLI.mjs} +131 -114
- package/dist/chunk-QU3P7LLI.mjs.map +1 -0
- package/dist/cli.d.mts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +538 -0
- package/dist/cli.js.map +1 -0
- package/dist/cli.mjs +28 -0
- package/dist/cli.mjs.map +1 -0
- package/dist/index.d.mts +14 -8
- package/dist/index.d.ts +14 -8
- package/dist/index.js +130 -113
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +25 -4
- package/dist/AgentEServer-VDZJAOQ6.mjs +0 -7
- package/dist/chunk-W7GXJB2K.mjs.map +0 -1
- /package/dist/{AgentEServer-VDZJAOQ6.mjs.map → AgentEServer-45WN6DK4.mjs.map} +0 -0
package/dist/index.d.mts
CHANGED
|
@@ -3,12 +3,15 @@ import { AgentEConfig, AgentE, EconomyState, EconomicEvent, Diagnosis, AgentEMod
|
|
|
3
3
|
interface ServerConfig {
|
|
4
4
|
port?: number;
|
|
5
5
|
host?: string;
|
|
6
|
-
|
|
6
|
+
agentE?: Partial<Omit<AgentEConfig, 'adapter'>>;
|
|
7
|
+
validateState?: boolean;
|
|
8
|
+
corsOrigin?: string;
|
|
7
9
|
}
|
|
8
|
-
interface
|
|
9
|
-
|
|
10
|
+
interface EnrichedAdjustment {
|
|
11
|
+
parameter: string;
|
|
10
12
|
value: number;
|
|
11
13
|
currency?: string;
|
|
14
|
+
reasoning: string;
|
|
12
15
|
}
|
|
13
16
|
declare class AgentEServer {
|
|
14
17
|
private readonly agentE;
|
|
@@ -16,10 +19,12 @@ declare class AgentEServer {
|
|
|
16
19
|
private lastState;
|
|
17
20
|
private adjustmentQueue;
|
|
18
21
|
private alerts;
|
|
19
|
-
|
|
22
|
+
readonly port: number;
|
|
20
23
|
private readonly host;
|
|
21
24
|
private readonly startedAt;
|
|
22
25
|
private cleanupWs;
|
|
26
|
+
readonly validateState: boolean;
|
|
27
|
+
readonly corsOrigin: string;
|
|
23
28
|
constructor(config?: ServerConfig);
|
|
24
29
|
start(): Promise<void>;
|
|
25
30
|
stop(): Promise<void>;
|
|
@@ -35,13 +40,14 @@ declare class AgentEServer {
|
|
|
35
40
|
* 2. Set state
|
|
36
41
|
* 3. Ingest events
|
|
37
42
|
* 4. Run agentE.tick(state)
|
|
38
|
-
* 5. Drain adjustment queue
|
|
43
|
+
* 5. Drain adjustment queue, enrich with reasoning from decisions
|
|
39
44
|
* 6. Return response
|
|
40
45
|
*/
|
|
41
46
|
processTick(state: EconomyState, events?: EconomicEvent[]): Promise<{
|
|
42
|
-
adjustments:
|
|
47
|
+
adjustments: EnrichedAdjustment[];
|
|
43
48
|
alerts: Diagnosis[];
|
|
44
49
|
health: number;
|
|
50
|
+
tick: number;
|
|
45
51
|
decisions: ReturnType<AgentE['getDecisions']>;
|
|
46
52
|
}>;
|
|
47
53
|
/**
|
|
@@ -66,10 +72,10 @@ declare class AgentEServer {
|
|
|
66
72
|
* @example
|
|
67
73
|
* ```ts
|
|
68
74
|
* import { startServer } from '@agent-e/server';
|
|
69
|
-
* const server = await startServer({ port:
|
|
75
|
+
* const server = await startServer({ port: 3100 });
|
|
70
76
|
* // POST /tick, GET /health, etc.
|
|
71
77
|
* ```
|
|
72
78
|
*/
|
|
73
79
|
declare function startServer(config?: ServerConfig): Promise<AgentEServer>;
|
|
74
80
|
|
|
75
|
-
export { AgentEServer, type ServerConfig, startServer };
|
|
81
|
+
export { AgentEServer, type EnrichedAdjustment, type ServerConfig, startServer };
|
package/dist/index.d.ts
CHANGED
|
@@ -3,12 +3,15 @@ import { AgentEConfig, AgentE, EconomyState, EconomicEvent, Diagnosis, AgentEMod
|
|
|
3
3
|
interface ServerConfig {
|
|
4
4
|
port?: number;
|
|
5
5
|
host?: string;
|
|
6
|
-
|
|
6
|
+
agentE?: Partial<Omit<AgentEConfig, 'adapter'>>;
|
|
7
|
+
validateState?: boolean;
|
|
8
|
+
corsOrigin?: string;
|
|
7
9
|
}
|
|
8
|
-
interface
|
|
9
|
-
|
|
10
|
+
interface EnrichedAdjustment {
|
|
11
|
+
parameter: string;
|
|
10
12
|
value: number;
|
|
11
13
|
currency?: string;
|
|
14
|
+
reasoning: string;
|
|
12
15
|
}
|
|
13
16
|
declare class AgentEServer {
|
|
14
17
|
private readonly agentE;
|
|
@@ -16,10 +19,12 @@ declare class AgentEServer {
|
|
|
16
19
|
private lastState;
|
|
17
20
|
private adjustmentQueue;
|
|
18
21
|
private alerts;
|
|
19
|
-
|
|
22
|
+
readonly port: number;
|
|
20
23
|
private readonly host;
|
|
21
24
|
private readonly startedAt;
|
|
22
25
|
private cleanupWs;
|
|
26
|
+
readonly validateState: boolean;
|
|
27
|
+
readonly corsOrigin: string;
|
|
23
28
|
constructor(config?: ServerConfig);
|
|
24
29
|
start(): Promise<void>;
|
|
25
30
|
stop(): Promise<void>;
|
|
@@ -35,13 +40,14 @@ declare class AgentEServer {
|
|
|
35
40
|
* 2. Set state
|
|
36
41
|
* 3. Ingest events
|
|
37
42
|
* 4. Run agentE.tick(state)
|
|
38
|
-
* 5. Drain adjustment queue
|
|
43
|
+
* 5. Drain adjustment queue, enrich with reasoning from decisions
|
|
39
44
|
* 6. Return response
|
|
40
45
|
*/
|
|
41
46
|
processTick(state: EconomyState, events?: EconomicEvent[]): Promise<{
|
|
42
|
-
adjustments:
|
|
47
|
+
adjustments: EnrichedAdjustment[];
|
|
43
48
|
alerts: Diagnosis[];
|
|
44
49
|
health: number;
|
|
50
|
+
tick: number;
|
|
45
51
|
decisions: ReturnType<AgentE['getDecisions']>;
|
|
46
52
|
}>;
|
|
47
53
|
/**
|
|
@@ -66,10 +72,10 @@ declare class AgentEServer {
|
|
|
66
72
|
* @example
|
|
67
73
|
* ```ts
|
|
68
74
|
* import { startServer } from '@agent-e/server';
|
|
69
|
-
* const server = await startServer({ port:
|
|
75
|
+
* const server = await startServer({ port: 3100 });
|
|
70
76
|
* // POST /tick, GET /health, etc.
|
|
71
77
|
* ```
|
|
72
78
|
*/
|
|
73
79
|
declare function startServer(config?: ServerConfig): Promise<AgentEServer>;
|
|
74
80
|
|
|
75
|
-
export { AgentEServer, type ServerConfig, startServer };
|
|
81
|
+
export { AgentEServer, type EnrichedAdjustment, type ServerConfig, startServer };
|
package/dist/index.js
CHANGED
|
@@ -31,13 +31,13 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
31
31
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
32
32
|
|
|
33
33
|
// src/routes.ts
|
|
34
|
-
function setCorsHeaders(res) {
|
|
35
|
-
res.setHeader("Access-Control-Allow-Origin",
|
|
34
|
+
function setCorsHeaders(res, origin) {
|
|
35
|
+
res.setHeader("Access-Control-Allow-Origin", origin);
|
|
36
36
|
res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
|
|
37
37
|
res.setHeader("Access-Control-Allow-Headers", "Content-Type");
|
|
38
38
|
}
|
|
39
|
-
function json(res, status, data) {
|
|
40
|
-
setCorsHeaders(res);
|
|
39
|
+
function json(res, status, data, origin) {
|
|
40
|
+
setCorsHeaders(res, origin);
|
|
41
41
|
res.writeHead(status, { "Content-Type": "application/json" });
|
|
42
42
|
res.end(JSON.stringify(data));
|
|
43
43
|
}
|
|
@@ -59,12 +59,13 @@ function readBody(req) {
|
|
|
59
59
|
});
|
|
60
60
|
}
|
|
61
61
|
function createRouteHandler(server) {
|
|
62
|
+
const cors = server.corsOrigin;
|
|
62
63
|
return async (req, res) => {
|
|
63
64
|
const url = new URL(req.url ?? "/", `http://${req.headers.host ?? "localhost"}`);
|
|
64
65
|
const path = url.pathname;
|
|
65
66
|
const method = req.method?.toUpperCase() ?? "GET";
|
|
66
67
|
if (method === "OPTIONS") {
|
|
67
|
-
setCorsHeaders(res);
|
|
68
|
+
setCorsHeaders(res, cors);
|
|
68
69
|
res.writeHead(204);
|
|
69
70
|
res.end();
|
|
70
71
|
return;
|
|
@@ -76,47 +77,44 @@ function createRouteHandler(server) {
|
|
|
76
77
|
try {
|
|
77
78
|
parsed = JSON.parse(body);
|
|
78
79
|
} catch {
|
|
79
|
-
json(res, 400, { error: "Invalid JSON" });
|
|
80
|
+
json(res, 400, { error: "Invalid JSON" }, cors);
|
|
80
81
|
return;
|
|
81
82
|
}
|
|
82
83
|
if (!parsed || typeof parsed !== "object") {
|
|
83
|
-
json(res, 400, { error: "Body must be a JSON object" });
|
|
84
|
+
json(res, 400, { error: "Body must be a JSON object" }, cors);
|
|
84
85
|
return;
|
|
85
86
|
}
|
|
86
87
|
const payload = parsed;
|
|
87
88
|
const state = payload["state"] ?? parsed;
|
|
88
89
|
const events = payload["events"];
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
90
|
+
if (server.validateState) {
|
|
91
|
+
const validation = (0, import_core.validateEconomyState)(state);
|
|
92
|
+
if (!validation.valid) {
|
|
93
|
+
json(res, 400, {
|
|
94
|
+
error: "invalid_state",
|
|
95
|
+
validationErrors: validation.errors
|
|
96
|
+
}, cors);
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
96
99
|
}
|
|
97
100
|
const result = await server.processTick(
|
|
98
101
|
state,
|
|
99
102
|
Array.isArray(events) ? events : void 0
|
|
100
103
|
);
|
|
104
|
+
const warnings = server.validateState ? (0, import_core.validateEconomyState)(state).warnings : [];
|
|
101
105
|
json(res, 200, {
|
|
102
106
|
adjustments: result.adjustments,
|
|
103
107
|
alerts: result.alerts.map((a) => ({
|
|
104
|
-
|
|
105
|
-
|
|
108
|
+
principleId: a.principle.id,
|
|
109
|
+
principleName: a.principle.name,
|
|
106
110
|
severity: a.violation.severity,
|
|
107
111
|
evidence: a.violation.evidence,
|
|
108
|
-
|
|
112
|
+
reasoning: a.violation.suggestedAction.reasoning
|
|
109
113
|
})),
|
|
110
114
|
health: result.health,
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
principle: d.diagnosis.principle.id,
|
|
115
|
-
parameter: d.plan.parameter,
|
|
116
|
-
result: d.result,
|
|
117
|
-
reasoning: d.reasoning
|
|
118
|
-
}))
|
|
119
|
-
});
|
|
115
|
+
tick: result.tick,
|
|
116
|
+
...warnings.length > 0 ? { validationWarnings: warnings } : {}
|
|
117
|
+
}, cors);
|
|
120
118
|
return;
|
|
121
119
|
}
|
|
122
120
|
if (path === "/health" && method === "GET") {
|
|
@@ -127,11 +125,11 @@ function createRouteHandler(server) {
|
|
|
127
125
|
mode: agentE.getMode(),
|
|
128
126
|
activePlans: agentE.getActivePlans().length,
|
|
129
127
|
uptime: server.getUptime()
|
|
130
|
-
});
|
|
128
|
+
}, cors);
|
|
131
129
|
return;
|
|
132
130
|
}
|
|
133
131
|
if (path === "/decisions" && method === "GET") {
|
|
134
|
-
const limit = parseInt(url.searchParams.get("limit") ?? "
|
|
132
|
+
const limit = parseInt(url.searchParams.get("limit") ?? "100", 10);
|
|
135
133
|
const since = url.searchParams.get("since");
|
|
136
134
|
const agentE = server.getAgentE();
|
|
137
135
|
let decisions;
|
|
@@ -140,20 +138,7 @@ function createRouteHandler(server) {
|
|
|
140
138
|
} else {
|
|
141
139
|
decisions = agentE.log.latest(limit);
|
|
142
140
|
}
|
|
143
|
-
json(res, 200, {
|
|
144
|
-
decisions: decisions.map((d) => ({
|
|
145
|
-
id: d.id,
|
|
146
|
-
tick: d.tick,
|
|
147
|
-
timestamp: d.timestamp,
|
|
148
|
-
principle: d.diagnosis.principle.id,
|
|
149
|
-
principeName: d.diagnosis.principle.name,
|
|
150
|
-
parameter: d.plan.parameter,
|
|
151
|
-
currentValue: d.plan.currentValue,
|
|
152
|
-
targetValue: d.plan.targetValue,
|
|
153
|
-
result: d.result,
|
|
154
|
-
reasoning: d.reasoning
|
|
155
|
-
}))
|
|
156
|
-
});
|
|
141
|
+
json(res, 200, { decisions }, cors);
|
|
157
142
|
return;
|
|
158
143
|
}
|
|
159
144
|
if (path === "/config" && method === "POST") {
|
|
@@ -162,27 +147,32 @@ function createRouteHandler(server) {
|
|
|
162
147
|
try {
|
|
163
148
|
parsed = JSON.parse(body);
|
|
164
149
|
} catch {
|
|
165
|
-
json(res, 400, { error: "Invalid JSON" });
|
|
150
|
+
json(res, 400, { error: "Invalid JSON" }, cors);
|
|
166
151
|
return;
|
|
167
152
|
}
|
|
168
153
|
const config = parsed;
|
|
169
|
-
if (config["
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
}
|
|
154
|
+
if (Array.isArray(config["lock"])) {
|
|
155
|
+
for (const param of config["lock"]) {
|
|
156
|
+
if (typeof param === "string") server.lock(param);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
if (Array.isArray(config["unlock"])) {
|
|
160
|
+
for (const param of config["unlock"]) {
|
|
161
|
+
if (typeof param === "string") server.unlock(param);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
if (Array.isArray(config["constrain"])) {
|
|
165
|
+
for (const c of config["constrain"]) {
|
|
166
|
+
if (c && typeof c === "object" && typeof c["param"] === "string" && typeof c["min"] === "number" && typeof c["max"] === "number") {
|
|
167
|
+
const constraint = c;
|
|
168
|
+
server.constrain(constraint.param, { min: constraint.min, max: constraint.max });
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
if (config["mode"] === "autonomous" || config["mode"] === "advisor") {
|
|
179
173
|
server.setMode(config["mode"]);
|
|
180
|
-
json(res, 200, { ok: true, action: "mode", mode: config["mode"] });
|
|
181
|
-
} else {
|
|
182
|
-
json(res, 400, {
|
|
183
|
-
error: "Invalid config action. Use: lock, unlock, constrain, or mode"
|
|
184
|
-
});
|
|
185
174
|
}
|
|
175
|
+
json(res, 200, { ok: true }, cors);
|
|
186
176
|
return;
|
|
187
177
|
}
|
|
188
178
|
if (path === "/principles" && method === "GET") {
|
|
@@ -195,7 +185,7 @@ function createRouteHandler(server) {
|
|
|
195
185
|
category: p.category,
|
|
196
186
|
description: p.description
|
|
197
187
|
}))
|
|
198
|
-
});
|
|
188
|
+
}, cors);
|
|
199
189
|
return;
|
|
200
190
|
}
|
|
201
191
|
if (path === "/diagnose" && method === "POST") {
|
|
@@ -204,33 +194,35 @@ function createRouteHandler(server) {
|
|
|
204
194
|
try {
|
|
205
195
|
parsed = JSON.parse(body);
|
|
206
196
|
} catch {
|
|
207
|
-
json(res, 400, { error: "Invalid JSON" });
|
|
197
|
+
json(res, 400, { error: "Invalid JSON" }, cors);
|
|
208
198
|
return;
|
|
209
199
|
}
|
|
210
200
|
const payload = parsed;
|
|
211
201
|
const state = payload["state"] ?? parsed;
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
202
|
+
if (server.validateState) {
|
|
203
|
+
const validation = (0, import_core.validateEconomyState)(state);
|
|
204
|
+
if (!validation.valid) {
|
|
205
|
+
json(res, 400, { error: "invalid_state", validationErrors: validation.errors }, cors);
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
216
208
|
}
|
|
217
209
|
const result = server.diagnoseOnly(state);
|
|
218
210
|
json(res, 200, {
|
|
219
211
|
health: result.health,
|
|
220
212
|
diagnoses: result.diagnoses.map((d) => ({
|
|
221
|
-
|
|
222
|
-
|
|
213
|
+
principleId: d.principle.id,
|
|
214
|
+
principleName: d.principle.name,
|
|
223
215
|
severity: d.violation.severity,
|
|
224
216
|
evidence: d.violation.evidence,
|
|
225
217
|
suggestedAction: d.violation.suggestedAction
|
|
226
218
|
}))
|
|
227
|
-
});
|
|
219
|
+
}, cors);
|
|
228
220
|
return;
|
|
229
221
|
}
|
|
230
|
-
json(res, 404, { error: "Not found" });
|
|
222
|
+
json(res, 404, { error: "Not found" }, cors);
|
|
231
223
|
} catch (err) {
|
|
232
224
|
console.error("[AgentE Server] Unhandled route error:", err);
|
|
233
|
-
json(res, 500, { error: "Internal server error" });
|
|
225
|
+
json(res, 500, { error: "Internal server error" }, cors);
|
|
234
226
|
}
|
|
235
227
|
};
|
|
236
228
|
}
|
|
@@ -251,40 +243,53 @@ function send(ws, data) {
|
|
|
251
243
|
}
|
|
252
244
|
function createWebSocketHandler(httpServer, server) {
|
|
253
245
|
const wss = new import_ws.WebSocketServer({ server: httpServer });
|
|
246
|
+
const aliveMap = /* @__PURE__ */ new WeakMap();
|
|
254
247
|
const heartbeatInterval = setInterval(() => {
|
|
255
248
|
for (const ws of wss.clients) {
|
|
256
249
|
if (ws.readyState === import_ws.WebSocket.OPEN) {
|
|
250
|
+
if (aliveMap.get(ws) === false) {
|
|
251
|
+
ws.terminate();
|
|
252
|
+
continue;
|
|
253
|
+
}
|
|
254
|
+
aliveMap.set(ws, false);
|
|
257
255
|
ws.ping();
|
|
258
256
|
}
|
|
259
257
|
}
|
|
260
258
|
}, 3e4);
|
|
261
259
|
wss.on("connection", (ws) => {
|
|
260
|
+
console.log("[AgentE Server] Client connected");
|
|
261
|
+
aliveMap.set(ws, true);
|
|
262
|
+
ws.on("pong", () => {
|
|
263
|
+
aliveMap.set(ws, true);
|
|
264
|
+
});
|
|
265
|
+
ws.on("close", () => {
|
|
266
|
+
console.log("[AgentE Server] Client disconnected");
|
|
267
|
+
});
|
|
262
268
|
ws.on("message", async (raw) => {
|
|
263
269
|
let msg;
|
|
264
270
|
try {
|
|
265
271
|
msg = JSON.parse(raw.toString());
|
|
266
272
|
} catch {
|
|
267
|
-
send(ws, { type: "error",
|
|
273
|
+
send(ws, { type: "error", message: "Malformed JSON" });
|
|
268
274
|
return;
|
|
269
275
|
}
|
|
270
276
|
if (!msg.type || typeof msg.type !== "string") {
|
|
271
|
-
send(ws, { type: "error",
|
|
277
|
+
send(ws, { type: "error", message: 'Missing "type" field' });
|
|
272
278
|
return;
|
|
273
279
|
}
|
|
274
280
|
switch (msg.type) {
|
|
275
281
|
case "tick": {
|
|
276
282
|
const state = msg["state"];
|
|
277
283
|
const events = msg["events"];
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
284
|
+
if (server.validateState) {
|
|
285
|
+
const validation = (0, import_core2.validateEconomyState)(state);
|
|
286
|
+
if (!validation.valid) {
|
|
287
|
+
send(ws, { type: "validation_error", validationErrors: validation.errors });
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
if (validation.warnings.length > 0) {
|
|
291
|
+
send(ws, { type: "validation_warning", validationWarnings: validation.warnings });
|
|
283
292
|
}
|
|
284
|
-
return;
|
|
285
|
-
}
|
|
286
|
-
for (const w of validation.warnings) {
|
|
287
|
-
send(ws, { type: "validation_warning", warning: w });
|
|
288
293
|
}
|
|
289
294
|
try {
|
|
290
295
|
const result = await server.processTick(
|
|
@@ -295,22 +300,16 @@ function createWebSocketHandler(httpServer, server) {
|
|
|
295
300
|
type: "tick_result",
|
|
296
301
|
adjustments: result.adjustments,
|
|
297
302
|
alerts: result.alerts.map((a) => ({
|
|
298
|
-
|
|
299
|
-
|
|
303
|
+
principleId: a.principle.id,
|
|
304
|
+
principleName: a.principle.name,
|
|
300
305
|
severity: a.violation.severity,
|
|
301
|
-
|
|
306
|
+
reasoning: a.violation.suggestedAction.reasoning
|
|
302
307
|
})),
|
|
303
308
|
health: result.health,
|
|
304
|
-
|
|
305
|
-
id: d.id,
|
|
306
|
-
tick: d.tick,
|
|
307
|
-
principle: d.diagnosis.principle.id,
|
|
308
|
-
parameter: d.plan.parameter,
|
|
309
|
-
result: d.result
|
|
310
|
-
}))
|
|
309
|
+
tick: result.tick
|
|
311
310
|
});
|
|
312
311
|
} catch (err) {
|
|
313
|
-
send(ws, { type: "error",
|
|
312
|
+
send(ws, { type: "error", message: "Tick processing failed" });
|
|
314
313
|
}
|
|
315
314
|
break;
|
|
316
315
|
}
|
|
@@ -320,7 +319,7 @@ function createWebSocketHandler(httpServer, server) {
|
|
|
320
319
|
server.getAgentE().ingest(event);
|
|
321
320
|
send(ws, { type: "event_ack" });
|
|
322
321
|
} else {
|
|
323
|
-
send(ws, { type: "error",
|
|
322
|
+
send(ws, { type: "error", message: 'Missing "event" field' });
|
|
324
323
|
}
|
|
325
324
|
break;
|
|
326
325
|
}
|
|
@@ -338,18 +337,20 @@ function createWebSocketHandler(httpServer, server) {
|
|
|
338
337
|
}
|
|
339
338
|
case "diagnose": {
|
|
340
339
|
const state = msg["state"];
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
340
|
+
if (server.validateState) {
|
|
341
|
+
const validation = (0, import_core2.validateEconomyState)(state);
|
|
342
|
+
if (!validation.valid) {
|
|
343
|
+
send(ws, { type: "validation_error", validationErrors: validation.errors });
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
345
346
|
}
|
|
346
347
|
const result = server.diagnoseOnly(state);
|
|
347
348
|
send(ws, {
|
|
348
349
|
type: "diagnose_result",
|
|
349
350
|
health: result.health,
|
|
350
351
|
diagnoses: result.diagnoses.map((d) => ({
|
|
351
|
-
|
|
352
|
-
|
|
352
|
+
principleId: d.principle.id,
|
|
353
|
+
principleName: d.principle.name,
|
|
353
354
|
severity: d.violation.severity,
|
|
354
355
|
suggestedAction: d.violation.suggestedAction
|
|
355
356
|
}))
|
|
@@ -357,7 +358,7 @@ function createWebSocketHandler(httpServer, server) {
|
|
|
357
358
|
break;
|
|
358
359
|
}
|
|
359
360
|
default:
|
|
360
|
-
send(ws, { type: "error",
|
|
361
|
+
send(ws, { type: "error", message: `Unknown message type: "${msg.type}"` });
|
|
361
362
|
}
|
|
362
363
|
});
|
|
363
364
|
});
|
|
@@ -395,8 +396,10 @@ var init_AgentEServer = __esm({
|
|
|
395
396
|
this.alerts = [];
|
|
396
397
|
this.startedAt = Date.now();
|
|
397
398
|
this.cleanupWs = null;
|
|
398
|
-
this.port = config.port ??
|
|
399
|
+
this.port = config.port ?? 3100;
|
|
399
400
|
this.host = config.host ?? "0.0.0.0";
|
|
401
|
+
this.validateState = config.validateState ?? true;
|
|
402
|
+
this.corsOrigin = config.corsOrigin ?? "*";
|
|
400
403
|
const adapter = {
|
|
401
404
|
getState: () => {
|
|
402
405
|
if (!this.lastState) {
|
|
@@ -418,16 +421,17 @@ var init_AgentEServer = __esm({
|
|
|
418
421
|
this.adjustmentQueue.push({ key, value });
|
|
419
422
|
}
|
|
420
423
|
};
|
|
424
|
+
const agentECfg = config.agentE ?? {};
|
|
421
425
|
const agentEConfig = {
|
|
422
426
|
adapter,
|
|
423
|
-
mode:
|
|
424
|
-
gracePeriod:
|
|
425
|
-
checkInterval:
|
|
426
|
-
...
|
|
427
|
-
...
|
|
428
|
-
...
|
|
429
|
-
...
|
|
430
|
-
...
|
|
427
|
+
mode: agentECfg.mode ?? "autonomous",
|
|
428
|
+
gracePeriod: agentECfg.gracePeriod ?? 0,
|
|
429
|
+
checkInterval: agentECfg.checkInterval ?? 1,
|
|
430
|
+
...agentECfg.dominantRoles ? { dominantRoles: agentECfg.dominantRoles } : {},
|
|
431
|
+
...agentECfg.idealDistribution ? { idealDistribution: agentECfg.idealDistribution } : {},
|
|
432
|
+
...agentECfg.maxAdjustmentPercent !== void 0 ? { maxAdjustmentPercent: agentECfg.maxAdjustmentPercent } : {},
|
|
433
|
+
...agentECfg.cooldownTicks !== void 0 ? { cooldownTicks: agentECfg.cooldownTicks } : {},
|
|
434
|
+
...agentECfg.thresholds ? { thresholds: agentECfg.thresholds } : {}
|
|
431
435
|
};
|
|
432
436
|
this.agentE = new import_core3.AgentE(agentEConfig);
|
|
433
437
|
this.agentE.on("alert", (diagnosis) => {
|
|
@@ -441,6 +445,8 @@ var init_AgentEServer = __esm({
|
|
|
441
445
|
this.cleanupWs = createWebSocketHandler(this.server, this);
|
|
442
446
|
return new Promise((resolve) => {
|
|
443
447
|
this.server.listen(this.port, this.host, () => {
|
|
448
|
+
const addr = this.getAddress();
|
|
449
|
+
console.log(`[AgentE Server] Listening on http://${addr.host}:${addr.port}`);
|
|
444
450
|
resolve();
|
|
445
451
|
});
|
|
446
452
|
});
|
|
@@ -474,7 +480,7 @@ var init_AgentEServer = __esm({
|
|
|
474
480
|
* 2. Set state
|
|
475
481
|
* 3. Ingest events
|
|
476
482
|
* 4. Run agentE.tick(state)
|
|
477
|
-
* 5. Drain adjustment queue
|
|
483
|
+
* 5. Drain adjustment queue, enrich with reasoning from decisions
|
|
478
484
|
* 6. Return response
|
|
479
485
|
*/
|
|
480
486
|
async processTick(state, events) {
|
|
@@ -487,13 +493,25 @@ var init_AgentEServer = __esm({
|
|
|
487
493
|
}
|
|
488
494
|
}
|
|
489
495
|
await this.agentE.tick(state);
|
|
490
|
-
const
|
|
496
|
+
const rawAdj = [...this.adjustmentQueue];
|
|
491
497
|
this.adjustmentQueue = [];
|
|
492
498
|
const decisions = this.agentE.getDecisions({ since: state.tick, until: state.tick });
|
|
499
|
+
const adjustments = rawAdj.map((adj) => {
|
|
500
|
+
const decision = decisions.find(
|
|
501
|
+
(d) => d.plan.parameter === adj.key && d.result === "applied"
|
|
502
|
+
);
|
|
503
|
+
return {
|
|
504
|
+
parameter: adj.key,
|
|
505
|
+
value: adj.value,
|
|
506
|
+
...adj.currency ? { currency: adj.currency } : {},
|
|
507
|
+
reasoning: decision?.diagnosis.violation.suggestedAction.reasoning ?? ""
|
|
508
|
+
};
|
|
509
|
+
});
|
|
493
510
|
return {
|
|
494
511
|
adjustments,
|
|
495
512
|
alerts: [...this.alerts],
|
|
496
513
|
health: this.agentE.getHealth(),
|
|
514
|
+
tick: state.tick,
|
|
497
515
|
decisions
|
|
498
516
|
};
|
|
499
517
|
}
|
|
@@ -503,9 +521,8 @@ var init_AgentEServer = __esm({
|
|
|
503
521
|
diagnoseOnly(state) {
|
|
504
522
|
const prevState = this.lastState;
|
|
505
523
|
this.lastState = state;
|
|
506
|
-
const
|
|
507
|
-
const
|
|
508
|
-
const health = diagnoser.getHealth();
|
|
524
|
+
const diagnoses = this.agentE.diagnoseNow();
|
|
525
|
+
const health = this.agentE.getHealth();
|
|
509
526
|
this.lastState = prevState;
|
|
510
527
|
return { diagnoses, health };
|
|
511
528
|
}
|