@agent-e/server 1.6.10 → 1.6.12
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-PXMTFBHR.mjs +7 -0
- package/dist/{chunk-MH5XTBNY.mjs → chunk-O2UFQVI2.mjs} +72 -50
- package/dist/chunk-O2UFQVI2.mjs.map +1 -0
- package/dist/cli.js +72 -50
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +2 -2
- package/dist/cli.mjs.map +1 -1
- package/dist/index.js +72 -50
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2 -2
- package/package.json +2 -2
- package/dist/AgentEServer-WOYIMZWG.mjs +0 -7
- package/dist/chunk-MH5XTBNY.mjs.map +0 -1
- /package/dist/{AgentEServer-WOYIMZWG.mjs.map → AgentEServer-PXMTFBHR.mjs.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -979,8 +979,17 @@ function setSecurityHeaders(res) {
|
|
|
979
979
|
}
|
|
980
980
|
function setCorsHeaders(res, allowedOrigin, requestOrigin) {
|
|
981
981
|
setSecurityHeaders(res);
|
|
982
|
-
|
|
983
|
-
|
|
982
|
+
let origin;
|
|
983
|
+
if (allowedOrigin === "*") {
|
|
984
|
+
origin = "*";
|
|
985
|
+
} else if (requestOrigin === void 0) {
|
|
986
|
+
origin = allowedOrigin;
|
|
987
|
+
} else {
|
|
988
|
+
origin = requestOrigin.toLowerCase() === allowedOrigin.toLowerCase() ? requestOrigin : "";
|
|
989
|
+
}
|
|
990
|
+
if (origin) {
|
|
991
|
+
res.setHeader("Access-Control-Allow-Origin", origin);
|
|
992
|
+
}
|
|
984
993
|
res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
|
|
985
994
|
res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
|
|
986
995
|
}
|
|
@@ -997,7 +1006,10 @@ function sanitizeJson(obj) {
|
|
|
997
1006
|
function checkAuth(req, apiKey) {
|
|
998
1007
|
if (!apiKey) return true;
|
|
999
1008
|
const header = req.headers["authorization"];
|
|
1000
|
-
|
|
1009
|
+
if (typeof header !== "string") return false;
|
|
1010
|
+
const expected = `Bearer ${apiKey}`;
|
|
1011
|
+
if (header.length !== expected.length) return false;
|
|
1012
|
+
return (0, import_node_crypto.timingSafeEqual)(Buffer.from(header), Buffer.from(expected));
|
|
1001
1013
|
}
|
|
1002
1014
|
function json(res, status, data, origin, reqOrigin) {
|
|
1003
1015
|
setCorsHeaders(res, origin, reqOrigin);
|
|
@@ -1028,8 +1040,10 @@ function createRouteHandler(server) {
|
|
|
1028
1040
|
const url = new URL(req.url ?? "/", `http://${req.headers.host ?? "localhost"}`);
|
|
1029
1041
|
const path = url.pathname;
|
|
1030
1042
|
const method = req.method?.toUpperCase() ?? "GET";
|
|
1043
|
+
const reqOrigin = req.headers["origin"];
|
|
1044
|
+
const respond = (status, data) => json(res, status, data, cors, reqOrigin);
|
|
1031
1045
|
if (method === "OPTIONS") {
|
|
1032
|
-
setCorsHeaders(res, cors);
|
|
1046
|
+
setCorsHeaders(res, cors, reqOrigin);
|
|
1033
1047
|
res.writeHead(204);
|
|
1034
1048
|
res.end();
|
|
1035
1049
|
return;
|
|
@@ -1037,7 +1051,7 @@ function createRouteHandler(server) {
|
|
|
1037
1051
|
try {
|
|
1038
1052
|
if (path === "/tick" && method === "POST") {
|
|
1039
1053
|
if (!checkAuth(req, apiKey)) {
|
|
1040
|
-
|
|
1054
|
+
respond(401, { error: "Unauthorized" });
|
|
1041
1055
|
return;
|
|
1042
1056
|
}
|
|
1043
1057
|
const body = await readBody(req);
|
|
@@ -1045,11 +1059,11 @@ function createRouteHandler(server) {
|
|
|
1045
1059
|
try {
|
|
1046
1060
|
parsed = sanitizeJson(JSON.parse(body));
|
|
1047
1061
|
} catch {
|
|
1048
|
-
|
|
1062
|
+
respond(400, { error: "Invalid JSON" });
|
|
1049
1063
|
return;
|
|
1050
1064
|
}
|
|
1051
1065
|
if (!parsed || typeof parsed !== "object") {
|
|
1052
|
-
|
|
1066
|
+
respond(400, { error: "Body must be a JSON object" });
|
|
1053
1067
|
return;
|
|
1054
1068
|
}
|
|
1055
1069
|
const payload = parsed;
|
|
@@ -1057,10 +1071,10 @@ function createRouteHandler(server) {
|
|
|
1057
1071
|
const events = payload["events"];
|
|
1058
1072
|
const validation = server.validateState ? (0, import_core.validateEconomyState)(state) : null;
|
|
1059
1073
|
if (validation && !validation.valid) {
|
|
1060
|
-
|
|
1074
|
+
respond(400, {
|
|
1061
1075
|
error: "invalid_state",
|
|
1062
1076
|
validationErrors: validation.errors
|
|
1063
|
-
}
|
|
1077
|
+
});
|
|
1064
1078
|
return;
|
|
1065
1079
|
}
|
|
1066
1080
|
const result = await server.processTick(
|
|
@@ -1068,7 +1082,7 @@ function createRouteHandler(server) {
|
|
|
1068
1082
|
Array.isArray(events) ? events : void 0
|
|
1069
1083
|
);
|
|
1070
1084
|
const warnings = validation?.warnings ?? [];
|
|
1071
|
-
|
|
1085
|
+
respond(200, {
|
|
1072
1086
|
adjustments: result.adjustments,
|
|
1073
1087
|
alerts: result.alerts.map((a) => ({
|
|
1074
1088
|
principleId: a.principle.id,
|
|
@@ -1080,18 +1094,18 @@ function createRouteHandler(server) {
|
|
|
1080
1094
|
health: result.health,
|
|
1081
1095
|
tick: result.tick,
|
|
1082
1096
|
...warnings.length > 0 ? { validationWarnings: warnings } : {}
|
|
1083
|
-
}
|
|
1097
|
+
});
|
|
1084
1098
|
return;
|
|
1085
1099
|
}
|
|
1086
1100
|
if (path === "/health" && method === "GET") {
|
|
1087
1101
|
const agentE = server.getAgentE();
|
|
1088
|
-
|
|
1102
|
+
respond(200, {
|
|
1089
1103
|
health: agentE.getHealth(),
|
|
1090
1104
|
tick: agentE.metrics.latest()?.tick ?? 0,
|
|
1091
1105
|
mode: agentE.getMode(),
|
|
1092
1106
|
activePlans: agentE.getActivePlans().length,
|
|
1093
1107
|
uptime: server.getUptime()
|
|
1094
|
-
}
|
|
1108
|
+
});
|
|
1095
1109
|
return;
|
|
1096
1110
|
}
|
|
1097
1111
|
if (path === "/decisions" && method === "GET") {
|
|
@@ -1103,19 +1117,19 @@ function createRouteHandler(server) {
|
|
|
1103
1117
|
if (sinceParam) {
|
|
1104
1118
|
const since = parseInt(sinceParam, 10);
|
|
1105
1119
|
if (Number.isNaN(since)) {
|
|
1106
|
-
|
|
1120
|
+
respond(400, { error: 'Invalid "since" parameter \u2014 must be a number' });
|
|
1107
1121
|
return;
|
|
1108
1122
|
}
|
|
1109
1123
|
decisions = agentE.getDecisions({ since });
|
|
1110
1124
|
} else {
|
|
1111
1125
|
decisions = agentE.log.latest(limit);
|
|
1112
1126
|
}
|
|
1113
|
-
|
|
1127
|
+
respond(200, { decisions });
|
|
1114
1128
|
return;
|
|
1115
1129
|
}
|
|
1116
1130
|
if (path === "/config" && method === "POST") {
|
|
1117
1131
|
if (!checkAuth(req, apiKey)) {
|
|
1118
|
-
|
|
1132
|
+
respond(401, { error: "Unauthorized" });
|
|
1119
1133
|
return;
|
|
1120
1134
|
}
|
|
1121
1135
|
const body = await readBody(req);
|
|
@@ -1123,7 +1137,7 @@ function createRouteHandler(server) {
|
|
|
1123
1137
|
try {
|
|
1124
1138
|
parsed = sanitizeJson(JSON.parse(body));
|
|
1125
1139
|
} catch {
|
|
1126
|
-
|
|
1140
|
+
respond(400, { error: "Invalid JSON" });
|
|
1127
1141
|
return;
|
|
1128
1142
|
}
|
|
1129
1143
|
const config = parsed;
|
|
@@ -1143,11 +1157,11 @@ function createRouteHandler(server) {
|
|
|
1143
1157
|
if (c && typeof c === "object" && typeof c["param"] === "string" && typeof c["min"] === "number" && typeof c["max"] === "number") {
|
|
1144
1158
|
const constraint = c;
|
|
1145
1159
|
if (!Number.isFinite(constraint.min) || !Number.isFinite(constraint.max)) {
|
|
1146
|
-
|
|
1160
|
+
respond(400, { error: "Constraint bounds must be finite numbers" });
|
|
1147
1161
|
return;
|
|
1148
1162
|
}
|
|
1149
1163
|
if (constraint.min > constraint.max) {
|
|
1150
|
-
|
|
1164
|
+
respond(400, { error: "Constraint min cannot exceed max" });
|
|
1151
1165
|
return;
|
|
1152
1166
|
}
|
|
1153
1167
|
validated.push(constraint);
|
|
@@ -1160,12 +1174,12 @@ function createRouteHandler(server) {
|
|
|
1160
1174
|
if (config["mode"] === "autonomous" || config["mode"] === "advisor") {
|
|
1161
1175
|
server.setMode(config["mode"]);
|
|
1162
1176
|
}
|
|
1163
|
-
|
|
1177
|
+
respond(200, { ok: true });
|
|
1164
1178
|
return;
|
|
1165
1179
|
}
|
|
1166
1180
|
if (path === "/principles" && method === "GET") {
|
|
1167
1181
|
const principles = server.getAgentE().getPrinciples();
|
|
1168
|
-
|
|
1182
|
+
respond(200, {
|
|
1169
1183
|
count: principles.length,
|
|
1170
1184
|
principles: principles.map((p) => ({
|
|
1171
1185
|
id: p.id,
|
|
@@ -1173,12 +1187,12 @@ function createRouteHandler(server) {
|
|
|
1173
1187
|
category: p.category,
|
|
1174
1188
|
description: p.description
|
|
1175
1189
|
}))
|
|
1176
|
-
}
|
|
1190
|
+
});
|
|
1177
1191
|
return;
|
|
1178
1192
|
}
|
|
1179
1193
|
if (path === "/diagnose" && method === "POST") {
|
|
1180
1194
|
if (!checkAuth(req, apiKey)) {
|
|
1181
|
-
|
|
1195
|
+
respond(401, { error: "Unauthorized" });
|
|
1182
1196
|
return;
|
|
1183
1197
|
}
|
|
1184
1198
|
const body = await readBody(req);
|
|
@@ -1186,7 +1200,7 @@ function createRouteHandler(server) {
|
|
|
1186
1200
|
try {
|
|
1187
1201
|
parsed = sanitizeJson(JSON.parse(body));
|
|
1188
1202
|
} catch {
|
|
1189
|
-
|
|
1203
|
+
respond(400, { error: "Invalid JSON" });
|
|
1190
1204
|
return;
|
|
1191
1205
|
}
|
|
1192
1206
|
const payload = parsed;
|
|
@@ -1194,12 +1208,12 @@ function createRouteHandler(server) {
|
|
|
1194
1208
|
if (server.validateState) {
|
|
1195
1209
|
const validation = (0, import_core.validateEconomyState)(state);
|
|
1196
1210
|
if (!validation.valid) {
|
|
1197
|
-
|
|
1211
|
+
respond(400, { error: "invalid_state", validationErrors: validation.errors });
|
|
1198
1212
|
return;
|
|
1199
1213
|
}
|
|
1200
1214
|
}
|
|
1201
1215
|
const result = server.diagnoseOnly(state);
|
|
1202
|
-
|
|
1216
|
+
respond(200, {
|
|
1203
1217
|
health: result.health,
|
|
1204
1218
|
diagnoses: result.diagnoses.map((d) => ({
|
|
1205
1219
|
principleId: d.principle.id,
|
|
@@ -1208,11 +1222,11 @@ function createRouteHandler(server) {
|
|
|
1208
1222
|
evidence: d.violation.evidence,
|
|
1209
1223
|
suggestedAction: d.violation.suggestedAction
|
|
1210
1224
|
}))
|
|
1211
|
-
}
|
|
1225
|
+
});
|
|
1212
1226
|
return;
|
|
1213
1227
|
}
|
|
1214
1228
|
if (path === "/" && method === "GET" && server.serveDashboard) {
|
|
1215
|
-
setCorsHeaders(res, cors);
|
|
1229
|
+
setCorsHeaders(res, cors, reqOrigin);
|
|
1216
1230
|
res.setHeader("Content-Security-Policy", "default-src 'self'; script-src 'unsafe-inline' https://cdn.jsdelivr.net; style-src 'unsafe-inline' https://fonts.googleapis.com; font-src https://fonts.gstatic.com; connect-src 'self' ws: wss:; img-src 'self' data:");
|
|
1217
1231
|
res.setHeader("Cache-Control", "public, max-age=60");
|
|
1218
1232
|
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
@@ -1223,7 +1237,7 @@ function createRouteHandler(server) {
|
|
|
1223
1237
|
const agentE = server.getAgentE();
|
|
1224
1238
|
const latest = agentE.store.latest();
|
|
1225
1239
|
const history = agentE.store.recentHistory(100);
|
|
1226
|
-
|
|
1240
|
+
respond(200, { latest, history });
|
|
1227
1241
|
return;
|
|
1228
1242
|
}
|
|
1229
1243
|
if (path === "/metrics/personas" && method === "GET") {
|
|
@@ -1231,12 +1245,12 @@ function createRouteHandler(server) {
|
|
|
1231
1245
|
const latest = agentE.store.latest();
|
|
1232
1246
|
const dist = latest.personaDistribution || {};
|
|
1233
1247
|
const total = Object.values(dist).reduce((s, v) => s + v, 0);
|
|
1234
|
-
|
|
1248
|
+
respond(200, { distribution: dist, total });
|
|
1235
1249
|
return;
|
|
1236
1250
|
}
|
|
1237
1251
|
if (path === "/approve" && method === "POST") {
|
|
1238
1252
|
if (!checkAuth(req, apiKey)) {
|
|
1239
|
-
|
|
1253
|
+
respond(401, { error: "Unauthorized" });
|
|
1240
1254
|
return;
|
|
1241
1255
|
}
|
|
1242
1256
|
const body = await readBody(req);
|
|
@@ -1244,42 +1258,42 @@ function createRouteHandler(server) {
|
|
|
1244
1258
|
try {
|
|
1245
1259
|
parsed = sanitizeJson(JSON.parse(body));
|
|
1246
1260
|
} catch {
|
|
1247
|
-
|
|
1261
|
+
respond(400, { error: "Invalid JSON" });
|
|
1248
1262
|
return;
|
|
1249
1263
|
}
|
|
1250
1264
|
const payload = parsed;
|
|
1251
1265
|
const decisionId = payload["decisionId"];
|
|
1252
1266
|
if (!decisionId) {
|
|
1253
|
-
|
|
1267
|
+
respond(400, { error: "missing_decision_id" });
|
|
1254
1268
|
return;
|
|
1255
1269
|
}
|
|
1256
1270
|
const agentE = server.getAgentE();
|
|
1257
1271
|
if (agentE.getMode() !== "advisor") {
|
|
1258
|
-
|
|
1272
|
+
respond(400, { error: "not_in_advisor_mode" });
|
|
1259
1273
|
return;
|
|
1260
1274
|
}
|
|
1261
1275
|
const entry = agentE.log.getById(decisionId);
|
|
1262
1276
|
if (!entry) {
|
|
1263
|
-
|
|
1277
|
+
respond(404, { error: "decision_not_found" });
|
|
1264
1278
|
return;
|
|
1265
1279
|
}
|
|
1266
1280
|
if (entry.result !== "skipped_override") {
|
|
1267
|
-
|
|
1281
|
+
respond(409, { error: "decision_not_pending", currentResult: entry.result });
|
|
1268
1282
|
return;
|
|
1269
1283
|
}
|
|
1270
1284
|
await agentE.apply(entry.plan);
|
|
1271
1285
|
agentE.log.updateResult(decisionId, "applied");
|
|
1272
1286
|
server.broadcast({ type: "advisor_action", action: "approved", decisionId });
|
|
1273
|
-
|
|
1287
|
+
respond(200, {
|
|
1274
1288
|
ok: true,
|
|
1275
1289
|
parameter: entry.plan.parameter,
|
|
1276
1290
|
value: entry.plan.targetValue
|
|
1277
|
-
}
|
|
1291
|
+
});
|
|
1278
1292
|
return;
|
|
1279
1293
|
}
|
|
1280
1294
|
if (path === "/reject" && method === "POST") {
|
|
1281
1295
|
if (!checkAuth(req, apiKey)) {
|
|
1282
|
-
|
|
1296
|
+
respond(401, { error: "Unauthorized" });
|
|
1283
1297
|
return;
|
|
1284
1298
|
}
|
|
1285
1299
|
const body = await readBody(req);
|
|
@@ -1287,56 +1301,57 @@ function createRouteHandler(server) {
|
|
|
1287
1301
|
try {
|
|
1288
1302
|
parsed = sanitizeJson(JSON.parse(body));
|
|
1289
1303
|
} catch {
|
|
1290
|
-
|
|
1304
|
+
respond(400, { error: "Invalid JSON" });
|
|
1291
1305
|
return;
|
|
1292
1306
|
}
|
|
1293
1307
|
const payload = parsed;
|
|
1294
1308
|
const decisionId = payload["decisionId"];
|
|
1295
1309
|
const reason = payload["reason"] || void 0;
|
|
1296
1310
|
if (!decisionId) {
|
|
1297
|
-
|
|
1311
|
+
respond(400, { error: "missing_decision_id" });
|
|
1298
1312
|
return;
|
|
1299
1313
|
}
|
|
1300
1314
|
const agentE = server.getAgentE();
|
|
1301
1315
|
if (agentE.getMode() !== "advisor") {
|
|
1302
|
-
|
|
1316
|
+
respond(400, { error: "not_in_advisor_mode" });
|
|
1303
1317
|
return;
|
|
1304
1318
|
}
|
|
1305
1319
|
const entry = agentE.log.getById(decisionId);
|
|
1306
1320
|
if (!entry) {
|
|
1307
|
-
|
|
1321
|
+
respond(404, { error: "decision_not_found" });
|
|
1308
1322
|
return;
|
|
1309
1323
|
}
|
|
1310
1324
|
if (entry.result !== "skipped_override") {
|
|
1311
|
-
|
|
1325
|
+
respond(409, { error: "decision_not_pending", currentResult: entry.result });
|
|
1312
1326
|
return;
|
|
1313
1327
|
}
|
|
1314
1328
|
agentE.log.updateResult(decisionId, "rejected", reason);
|
|
1315
1329
|
server.broadcast({ type: "advisor_action", action: "rejected", decisionId, reason });
|
|
1316
|
-
|
|
1330
|
+
respond(200, { ok: true, decisionId });
|
|
1317
1331
|
return;
|
|
1318
1332
|
}
|
|
1319
1333
|
if (path === "/pending" && method === "GET") {
|
|
1320
1334
|
const agentE = server.getAgentE();
|
|
1321
1335
|
const pending = agentE.log.query({ result: "skipped_override" });
|
|
1322
|
-
|
|
1336
|
+
respond(200, {
|
|
1323
1337
|
mode: agentE.getMode(),
|
|
1324
1338
|
pending,
|
|
1325
1339
|
count: pending.length
|
|
1326
|
-
}
|
|
1340
|
+
});
|
|
1327
1341
|
return;
|
|
1328
1342
|
}
|
|
1329
|
-
|
|
1343
|
+
respond(404, { error: "Not found" });
|
|
1330
1344
|
} catch (err) {
|
|
1331
1345
|
console.error("[AgentE Server] Unhandled route error:", err);
|
|
1332
|
-
|
|
1346
|
+
respond(500, { error: "Internal server error" });
|
|
1333
1347
|
}
|
|
1334
1348
|
};
|
|
1335
1349
|
}
|
|
1336
|
-
var import_core, MAX_BODY_BYTES;
|
|
1350
|
+
var import_node_crypto, import_core, MAX_BODY_BYTES;
|
|
1337
1351
|
var init_routes = __esm({
|
|
1338
1352
|
"src/routes.ts"() {
|
|
1339
1353
|
"use strict";
|
|
1354
|
+
import_node_crypto = require("crypto");
|
|
1340
1355
|
import_core = require("@agent-e/core");
|
|
1341
1356
|
init_dashboard();
|
|
1342
1357
|
MAX_BODY_BYTES = 1048576;
|
|
@@ -1379,6 +1394,13 @@ function createWebSocketHandler(httpServer, server) {
|
|
|
1379
1394
|
ws.close(1013, "Server at capacity");
|
|
1380
1395
|
return;
|
|
1381
1396
|
}
|
|
1397
|
+
const wsOrigin = req.headers["origin"];
|
|
1398
|
+
if (wsOrigin && server.corsOrigin !== "*") {
|
|
1399
|
+
if (wsOrigin.toLowerCase() !== server.corsOrigin.toLowerCase()) {
|
|
1400
|
+
ws.close(1008, "Origin not allowed");
|
|
1401
|
+
return;
|
|
1402
|
+
}
|
|
1403
|
+
}
|
|
1382
1404
|
if (server.apiKey) {
|
|
1383
1405
|
const url = new URL(req.url ?? "/", `http://${req.headers.host ?? "localhost"}`);
|
|
1384
1406
|
const token = url.searchParams.get("token") ?? req.headers["authorization"]?.replace("Bearer ", "");
|