@agent-e/server 1.6.10 → 1.6.11

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/index.js CHANGED
@@ -979,8 +979,17 @@ function setSecurityHeaders(res) {
979
979
  }
980
980
  function setCorsHeaders(res, allowedOrigin, requestOrigin) {
981
981
  setSecurityHeaders(res);
982
- const origin = allowedOrigin === "*" ? "*" : requestOrigin === allowedOrigin ? allowedOrigin : allowedOrigin;
983
- res.setHeader("Access-Control-Allow-Origin", origin);
982
+ let origin;
983
+ if (allowedOrigin === "*") {
984
+ origin = "*";
985
+ } else if (requestOrigin === void 0) {
986
+ origin = allowedOrigin;
987
+ } else {
988
+ origin = requestOrigin === allowedOrigin ? allowedOrigin : "";
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
  }
@@ -1028,8 +1037,10 @@ function createRouteHandler(server) {
1028
1037
  const url = new URL(req.url ?? "/", `http://${req.headers.host ?? "localhost"}`);
1029
1038
  const path = url.pathname;
1030
1039
  const method = req.method?.toUpperCase() ?? "GET";
1040
+ const reqOrigin = req.headers["origin"];
1041
+ const respond = (status, data) => json(res, status, data, cors, reqOrigin);
1031
1042
  if (method === "OPTIONS") {
1032
- setCorsHeaders(res, cors);
1043
+ setCorsHeaders(res, cors, reqOrigin);
1033
1044
  res.writeHead(204);
1034
1045
  res.end();
1035
1046
  return;
@@ -1037,7 +1048,7 @@ function createRouteHandler(server) {
1037
1048
  try {
1038
1049
  if (path === "/tick" && method === "POST") {
1039
1050
  if (!checkAuth(req, apiKey)) {
1040
- json(res, 401, { error: "Unauthorized" }, cors);
1051
+ respond(401, { error: "Unauthorized" });
1041
1052
  return;
1042
1053
  }
1043
1054
  const body = await readBody(req);
@@ -1045,11 +1056,11 @@ function createRouteHandler(server) {
1045
1056
  try {
1046
1057
  parsed = sanitizeJson(JSON.parse(body));
1047
1058
  } catch {
1048
- json(res, 400, { error: "Invalid JSON" }, cors);
1059
+ respond(400, { error: "Invalid JSON" });
1049
1060
  return;
1050
1061
  }
1051
1062
  if (!parsed || typeof parsed !== "object") {
1052
- json(res, 400, { error: "Body must be a JSON object" }, cors);
1063
+ respond(400, { error: "Body must be a JSON object" });
1053
1064
  return;
1054
1065
  }
1055
1066
  const payload = parsed;
@@ -1057,10 +1068,10 @@ function createRouteHandler(server) {
1057
1068
  const events = payload["events"];
1058
1069
  const validation = server.validateState ? (0, import_core.validateEconomyState)(state) : null;
1059
1070
  if (validation && !validation.valid) {
1060
- json(res, 400, {
1071
+ respond(400, {
1061
1072
  error: "invalid_state",
1062
1073
  validationErrors: validation.errors
1063
- }, cors);
1074
+ });
1064
1075
  return;
1065
1076
  }
1066
1077
  const result = await server.processTick(
@@ -1068,7 +1079,7 @@ function createRouteHandler(server) {
1068
1079
  Array.isArray(events) ? events : void 0
1069
1080
  );
1070
1081
  const warnings = validation?.warnings ?? [];
1071
- json(res, 200, {
1082
+ respond(200, {
1072
1083
  adjustments: result.adjustments,
1073
1084
  alerts: result.alerts.map((a) => ({
1074
1085
  principleId: a.principle.id,
@@ -1080,18 +1091,18 @@ function createRouteHandler(server) {
1080
1091
  health: result.health,
1081
1092
  tick: result.tick,
1082
1093
  ...warnings.length > 0 ? { validationWarnings: warnings } : {}
1083
- }, cors);
1094
+ });
1084
1095
  return;
1085
1096
  }
1086
1097
  if (path === "/health" && method === "GET") {
1087
1098
  const agentE = server.getAgentE();
1088
- json(res, 200, {
1099
+ respond(200, {
1089
1100
  health: agentE.getHealth(),
1090
1101
  tick: agentE.metrics.latest()?.tick ?? 0,
1091
1102
  mode: agentE.getMode(),
1092
1103
  activePlans: agentE.getActivePlans().length,
1093
1104
  uptime: server.getUptime()
1094
- }, cors);
1105
+ });
1095
1106
  return;
1096
1107
  }
1097
1108
  if (path === "/decisions" && method === "GET") {
@@ -1103,19 +1114,19 @@ function createRouteHandler(server) {
1103
1114
  if (sinceParam) {
1104
1115
  const since = parseInt(sinceParam, 10);
1105
1116
  if (Number.isNaN(since)) {
1106
- json(res, 400, { error: 'Invalid "since" parameter \u2014 must be a number' }, cors);
1117
+ respond(400, { error: 'Invalid "since" parameter \u2014 must be a number' });
1107
1118
  return;
1108
1119
  }
1109
1120
  decisions = agentE.getDecisions({ since });
1110
1121
  } else {
1111
1122
  decisions = agentE.log.latest(limit);
1112
1123
  }
1113
- json(res, 200, { decisions }, cors);
1124
+ respond(200, { decisions });
1114
1125
  return;
1115
1126
  }
1116
1127
  if (path === "/config" && method === "POST") {
1117
1128
  if (!checkAuth(req, apiKey)) {
1118
- json(res, 401, { error: "Unauthorized" }, cors);
1129
+ respond(401, { error: "Unauthorized" });
1119
1130
  return;
1120
1131
  }
1121
1132
  const body = await readBody(req);
@@ -1123,7 +1134,7 @@ function createRouteHandler(server) {
1123
1134
  try {
1124
1135
  parsed = sanitizeJson(JSON.parse(body));
1125
1136
  } catch {
1126
- json(res, 400, { error: "Invalid JSON" }, cors);
1137
+ respond(400, { error: "Invalid JSON" });
1127
1138
  return;
1128
1139
  }
1129
1140
  const config = parsed;
@@ -1143,11 +1154,11 @@ function createRouteHandler(server) {
1143
1154
  if (c && typeof c === "object" && typeof c["param"] === "string" && typeof c["min"] === "number" && typeof c["max"] === "number") {
1144
1155
  const constraint = c;
1145
1156
  if (!Number.isFinite(constraint.min) || !Number.isFinite(constraint.max)) {
1146
- json(res, 400, { error: "Constraint bounds must be finite numbers" }, cors);
1157
+ respond(400, { error: "Constraint bounds must be finite numbers" });
1147
1158
  return;
1148
1159
  }
1149
1160
  if (constraint.min > constraint.max) {
1150
- json(res, 400, { error: "Constraint min cannot exceed max" }, cors);
1161
+ respond(400, { error: "Constraint min cannot exceed max" });
1151
1162
  return;
1152
1163
  }
1153
1164
  validated.push(constraint);
@@ -1160,12 +1171,12 @@ function createRouteHandler(server) {
1160
1171
  if (config["mode"] === "autonomous" || config["mode"] === "advisor") {
1161
1172
  server.setMode(config["mode"]);
1162
1173
  }
1163
- json(res, 200, { ok: true }, cors);
1174
+ respond(200, { ok: true });
1164
1175
  return;
1165
1176
  }
1166
1177
  if (path === "/principles" && method === "GET") {
1167
1178
  const principles = server.getAgentE().getPrinciples();
1168
- json(res, 200, {
1179
+ respond(200, {
1169
1180
  count: principles.length,
1170
1181
  principles: principles.map((p) => ({
1171
1182
  id: p.id,
@@ -1173,12 +1184,12 @@ function createRouteHandler(server) {
1173
1184
  category: p.category,
1174
1185
  description: p.description
1175
1186
  }))
1176
- }, cors);
1187
+ });
1177
1188
  return;
1178
1189
  }
1179
1190
  if (path === "/diagnose" && method === "POST") {
1180
1191
  if (!checkAuth(req, apiKey)) {
1181
- json(res, 401, { error: "Unauthorized" }, cors);
1192
+ respond(401, { error: "Unauthorized" });
1182
1193
  return;
1183
1194
  }
1184
1195
  const body = await readBody(req);
@@ -1186,7 +1197,7 @@ function createRouteHandler(server) {
1186
1197
  try {
1187
1198
  parsed = sanitizeJson(JSON.parse(body));
1188
1199
  } catch {
1189
- json(res, 400, { error: "Invalid JSON" }, cors);
1200
+ respond(400, { error: "Invalid JSON" });
1190
1201
  return;
1191
1202
  }
1192
1203
  const payload = parsed;
@@ -1194,12 +1205,12 @@ function createRouteHandler(server) {
1194
1205
  if (server.validateState) {
1195
1206
  const validation = (0, import_core.validateEconomyState)(state);
1196
1207
  if (!validation.valid) {
1197
- json(res, 400, { error: "invalid_state", validationErrors: validation.errors }, cors);
1208
+ respond(400, { error: "invalid_state", validationErrors: validation.errors });
1198
1209
  return;
1199
1210
  }
1200
1211
  }
1201
1212
  const result = server.diagnoseOnly(state);
1202
- json(res, 200, {
1213
+ respond(200, {
1203
1214
  health: result.health,
1204
1215
  diagnoses: result.diagnoses.map((d) => ({
1205
1216
  principleId: d.principle.id,
@@ -1208,11 +1219,11 @@ function createRouteHandler(server) {
1208
1219
  evidence: d.violation.evidence,
1209
1220
  suggestedAction: d.violation.suggestedAction
1210
1221
  }))
1211
- }, cors);
1222
+ });
1212
1223
  return;
1213
1224
  }
1214
1225
  if (path === "/" && method === "GET" && server.serveDashboard) {
1215
- setCorsHeaders(res, cors);
1226
+ setCorsHeaders(res, cors, reqOrigin);
1216
1227
  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
1228
  res.setHeader("Cache-Control", "public, max-age=60");
1218
1229
  res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
@@ -1223,7 +1234,7 @@ function createRouteHandler(server) {
1223
1234
  const agentE = server.getAgentE();
1224
1235
  const latest = agentE.store.latest();
1225
1236
  const history = agentE.store.recentHistory(100);
1226
- json(res, 200, { latest, history }, cors);
1237
+ respond(200, { latest, history });
1227
1238
  return;
1228
1239
  }
1229
1240
  if (path === "/metrics/personas" && method === "GET") {
@@ -1231,12 +1242,12 @@ function createRouteHandler(server) {
1231
1242
  const latest = agentE.store.latest();
1232
1243
  const dist = latest.personaDistribution || {};
1233
1244
  const total = Object.values(dist).reduce((s, v) => s + v, 0);
1234
- json(res, 200, { distribution: dist, total }, cors);
1245
+ respond(200, { distribution: dist, total });
1235
1246
  return;
1236
1247
  }
1237
1248
  if (path === "/approve" && method === "POST") {
1238
1249
  if (!checkAuth(req, apiKey)) {
1239
- json(res, 401, { error: "Unauthorized" }, cors);
1250
+ respond(401, { error: "Unauthorized" });
1240
1251
  return;
1241
1252
  }
1242
1253
  const body = await readBody(req);
@@ -1244,42 +1255,42 @@ function createRouteHandler(server) {
1244
1255
  try {
1245
1256
  parsed = sanitizeJson(JSON.parse(body));
1246
1257
  } catch {
1247
- json(res, 400, { error: "Invalid JSON" }, cors);
1258
+ respond(400, { error: "Invalid JSON" });
1248
1259
  return;
1249
1260
  }
1250
1261
  const payload = parsed;
1251
1262
  const decisionId = payload["decisionId"];
1252
1263
  if (!decisionId) {
1253
- json(res, 400, { error: "missing_decision_id" }, cors);
1264
+ respond(400, { error: "missing_decision_id" });
1254
1265
  return;
1255
1266
  }
1256
1267
  const agentE = server.getAgentE();
1257
1268
  if (agentE.getMode() !== "advisor") {
1258
- json(res, 400, { error: "not_in_advisor_mode" }, cors);
1269
+ respond(400, { error: "not_in_advisor_mode" });
1259
1270
  return;
1260
1271
  }
1261
1272
  const entry = agentE.log.getById(decisionId);
1262
1273
  if (!entry) {
1263
- json(res, 404, { error: "decision_not_found" }, cors);
1274
+ respond(404, { error: "decision_not_found" });
1264
1275
  return;
1265
1276
  }
1266
1277
  if (entry.result !== "skipped_override") {
1267
- json(res, 409, { error: "decision_not_pending", currentResult: entry.result }, cors);
1278
+ respond(409, { error: "decision_not_pending", currentResult: entry.result });
1268
1279
  return;
1269
1280
  }
1270
1281
  await agentE.apply(entry.plan);
1271
1282
  agentE.log.updateResult(decisionId, "applied");
1272
1283
  server.broadcast({ type: "advisor_action", action: "approved", decisionId });
1273
- json(res, 200, {
1284
+ respond(200, {
1274
1285
  ok: true,
1275
1286
  parameter: entry.plan.parameter,
1276
1287
  value: entry.plan.targetValue
1277
- }, cors);
1288
+ });
1278
1289
  return;
1279
1290
  }
1280
1291
  if (path === "/reject" && method === "POST") {
1281
1292
  if (!checkAuth(req, apiKey)) {
1282
- json(res, 401, { error: "Unauthorized" }, cors);
1293
+ respond(401, { error: "Unauthorized" });
1283
1294
  return;
1284
1295
  }
1285
1296
  const body = await readBody(req);
@@ -1287,49 +1298,49 @@ function createRouteHandler(server) {
1287
1298
  try {
1288
1299
  parsed = sanitizeJson(JSON.parse(body));
1289
1300
  } catch {
1290
- json(res, 400, { error: "Invalid JSON" }, cors);
1301
+ respond(400, { error: "Invalid JSON" });
1291
1302
  return;
1292
1303
  }
1293
1304
  const payload = parsed;
1294
1305
  const decisionId = payload["decisionId"];
1295
1306
  const reason = payload["reason"] || void 0;
1296
1307
  if (!decisionId) {
1297
- json(res, 400, { error: "missing_decision_id" }, cors);
1308
+ respond(400, { error: "missing_decision_id" });
1298
1309
  return;
1299
1310
  }
1300
1311
  const agentE = server.getAgentE();
1301
1312
  if (agentE.getMode() !== "advisor") {
1302
- json(res, 400, { error: "not_in_advisor_mode" }, cors);
1313
+ respond(400, { error: "not_in_advisor_mode" });
1303
1314
  return;
1304
1315
  }
1305
1316
  const entry = agentE.log.getById(decisionId);
1306
1317
  if (!entry) {
1307
- json(res, 404, { error: "decision_not_found" }, cors);
1318
+ respond(404, { error: "decision_not_found" });
1308
1319
  return;
1309
1320
  }
1310
1321
  if (entry.result !== "skipped_override") {
1311
- json(res, 409, { error: "decision_not_pending", currentResult: entry.result }, cors);
1322
+ respond(409, { error: "decision_not_pending", currentResult: entry.result });
1312
1323
  return;
1313
1324
  }
1314
1325
  agentE.log.updateResult(decisionId, "rejected", reason);
1315
1326
  server.broadcast({ type: "advisor_action", action: "rejected", decisionId, reason });
1316
- json(res, 200, { ok: true, decisionId }, cors);
1327
+ respond(200, { ok: true, decisionId });
1317
1328
  return;
1318
1329
  }
1319
1330
  if (path === "/pending" && method === "GET") {
1320
1331
  const agentE = server.getAgentE();
1321
1332
  const pending = agentE.log.query({ result: "skipped_override" });
1322
- json(res, 200, {
1333
+ respond(200, {
1323
1334
  mode: agentE.getMode(),
1324
1335
  pending,
1325
1336
  count: pending.length
1326
- }, cors);
1337
+ });
1327
1338
  return;
1328
1339
  }
1329
- json(res, 404, { error: "Not found" }, cors);
1340
+ respond(404, { error: "Not found" });
1330
1341
  } catch (err) {
1331
1342
  console.error("[AgentE Server] Unhandled route error:", err);
1332
- json(res, 500, { error: "Internal server error" }, cors);
1343
+ respond(500, { error: "Internal server error" });
1333
1344
  }
1334
1345
  };
1335
1346
  }