@axiom-lattice/gateway 2.1.110 → 2.1.112

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.
@@ -1,5 +1,5 @@
1
1
 
2
- > @axiom-lattice/gateway@2.1.110 build /home/runner/work/agentic/agentic/packages/gateway
2
+ > @axiom-lattice/gateway@2.1.112 build /home/runner/work/agentic/agentic/packages/gateway
3
3
  > tsup src/index.ts --format cjs,esm --dts --clean --sourcemap
4
4
 
5
5
  CLI Building entry: src/index.ts
@@ -11,36 +11,36 @@
11
11
  ESM Build start
12
12
  [warn] ▲ [WARNING] "import.meta" is not available with the "cjs" output format and will be empty [empty-import-meta]
13
13
 
14
- src/index.ts:199:33:
15
-  199 │ const __filename = fileURLToPath(import.meta.url);
14
+ src/index.ts:200:33:
15
+  200 │ const __filename = fileURLToPath(import.meta.url);
16
16
  ╵ ~~~~~~~~~~~
17
17
 
18
18
  You need to set the output format to "esm" for "import.meta" to work correctly.
19
19
 
20
20
 
21
- ESM dist/index.mjs 282.73 KB
21
+ CJS dist/index.js 357.58 KB
22
+ CJS dist/index.js.map 729.13 KB
23
+ CJS ⚡️ Build success in 403ms
24
+ ESM dist/index.mjs 286.89 KB
22
25
  ESM dist/mcp-configs-SHRMQHIL.mjs 685.00 B
23
26
  ESM dist/chunk-K4XELOSO.mjs 12.52 KB
24
27
  ESM dist/sender-PX32VSHB.mjs 873.00 B
25
28
  ESM dist/WechatChannelAdapter-WSDKR4OA.mjs 8.27 KB
26
29
  ESM dist/chunk-6CUQGDJI.mjs 6.42 KB
27
30
  ESM dist/a2a-ERG5RMUW.mjs 15.95 KB
28
- ESM dist/resources-5POCLGXV.mjs 15.73 KB
31
+ ESM dist/resources-VA7LSDKN.mjs 15.81 KB
29
32
  ESM dist/chunk-LHQY46YB.mjs 1.46 KB
30
- ESM dist/mcp-configs-SHRMQHIL.mjs.map 71.00 B
31
33
  ESM dist/chunk-K4XELOSO.mjs.map 25.53 KB
32
34
  ESM dist/sender-PX32VSHB.mjs.map 2.07 KB
33
35
  ESM dist/WechatChannelAdapter-WSDKR4OA.mjs.map 16.28 KB
34
36
  ESM dist/chunk-6CUQGDJI.mjs.map 14.04 KB
35
37
  ESM dist/a2a-ERG5RMUW.mjs.map 32.14 KB
36
- ESM dist/index.mjs.map 598.22 KB
38
+ ESM dist/resources-VA7LSDKN.mjs.map 29.34 KB
37
39
  ESM dist/chunk-LHQY46YB.mjs.map 2.39 KB
38
- ESM dist/resources-5POCLGXV.mjs.map 29.34 KB
39
- ESM ⚡️ Build success in 575ms
40
- CJS dist/index.js 353.34 KB
41
- CJS dist/index.js.map 720.44 KB
42
- CJS ⚡️ Build success in 580ms
40
+ ESM dist/index.mjs.map 606.92 KB
41
+ ESM dist/mcp-configs-SHRMQHIL.mjs.map 71.00 B
42
+ ESM ⚡️ Build success in 479ms
43
43
  DTS Build start
44
- DTS ⚡️ Build success in 21069ms
44
+ DTS ⚡️ Build success in 21490ms
45
45
  DTS dist/index.d.ts 7.57 KB
46
46
  DTS dist/index.d.mts 7.57 KB
package/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # @axiom-lattice/gateway
2
2
 
3
+ ## 2.1.112
4
+
5
+ ### Patch Changes
6
+
7
+ - 2d1c9f4: enhance core
8
+ - Updated dependencies [2d1c9f4]
9
+ - @axiom-lattice/core@2.1.99
10
+ - @axiom-lattice/pg-stores@1.0.90
11
+ - @axiom-lattice/protocols@2.1.51
12
+ - @axiom-lattice/queue-redis@1.0.50
13
+
14
+ ## 2.1.111
15
+
16
+ ### Patch Changes
17
+
18
+ - 4e028de: fix issues
19
+ - Updated dependencies [4e028de]
20
+ - @axiom-lattice/core@2.1.98
21
+ - @axiom-lattice/agent-eval@2.1.92
22
+ - @axiom-lattice/pg-stores@1.0.89
23
+
3
24
  ## 2.1.110
4
25
 
5
26
  ### Patch Changes
package/dist/index.js CHANGED
@@ -1977,6 +1977,7 @@ var init_resources = __esm({
1977
1977
  _resolveSafeSubPath(entryFile, subPath) {
1978
1978
  if (!subPath) return entryFile;
1979
1979
  if (subPath.includes("..")) throw new Error("Path traversal denied");
1980
+ if (subPath.startsWith(entryFile + "/") || subPath === entryFile) return subPath;
1980
1981
  const entryDir = this._isFilePath(entryFile) ? entryFile.replace(/[^/]+$/, "") : entryFile + "/";
1981
1982
  return (entryDir + subPath).replace(/\/+/g, "/");
1982
1983
  }
@@ -4331,6 +4332,8 @@ async function getAllWorkflowRuns(request, reply) {
4331
4332
  });
4332
4333
  }
4333
4334
  }
4335
+ var INBOX_DEFAULT_PAGE_SIZE = 20;
4336
+ var INBOX_MAX_PAGE_SIZE = 100;
4334
4337
  async function getInboxItems(request, reply) {
4335
4338
  const tenantId = getTenantId7(request);
4336
4339
  try {
@@ -4348,10 +4351,30 @@ async function getInboxItems(request, reply) {
4348
4351
  }
4349
4352
  } catch {
4350
4353
  }
4351
- const runs = await store2.getWorkflowRunsByTenantId(tenantId);
4352
- const pendingRuns = runs.filter((r) => r.status === "interrupted");
4354
+ const { page: pageParam, pageSize: pageSizeParam } = request.query;
4355
+ const paged = pageParam !== void 0 || pageSizeParam !== void 0;
4356
+ const page = Math.max(1, parseInt(pageParam ?? "", 10) || 1);
4357
+ const pageSize = Math.min(INBOX_MAX_PAGE_SIZE, Math.max(1, parseInt(pageSizeParam ?? "", 10) || INBOX_DEFAULT_PAGE_SIZE));
4358
+ let pendingRuns;
4359
+ let total;
4360
+ if (paged) {
4361
+ const result = await store2.queryWorkflowRuns(tenantId, {
4362
+ status: "interrupted",
4363
+ limit: pageSize,
4364
+ offset: (page - 1) * pageSize
4365
+ });
4366
+ pendingRuns = result.records;
4367
+ total = result.total;
4368
+ } else {
4369
+ const result = await store2.queryWorkflowRuns(tenantId, { status: "interrupted" });
4370
+ pendingRuns = result.records;
4371
+ }
4353
4372
  if (pendingRuns.length === 0) {
4354
- return { success: true, message: "No pending workflows", data: { records: [] } };
4373
+ return {
4374
+ success: true,
4375
+ message: "No pending workflows",
4376
+ data: paged ? { records: [], total, page, pageSize } : { records: [] }
4377
+ };
4355
4378
  }
4356
4379
  const checkPromises = pendingRuns.map(async (r) => {
4357
4380
  try {
@@ -4408,13 +4431,10 @@ async function getInboxItems(request, reply) {
4408
4431
  });
4409
4432
  const results = await Promise.all(checkPromises);
4410
4433
  const inboxItems = results.flat();
4411
- inboxItems.sort(
4412
- (a, b) => new Date(b.startedAt).getTime() - new Date(a.startedAt).getTime()
4413
- );
4414
4434
  return {
4415
4435
  success: true,
4416
4436
  message: "Successfully retrieved inbox items",
4417
- data: { records: inboxItems }
4437
+ data: paged ? { records: inboxItems, total, page, pageSize } : { records: inboxItems }
4418
4438
  };
4419
4439
  } catch (error) {
4420
4440
  request.log.error(error, "Failed to get inbox items");
@@ -4647,6 +4667,54 @@ async function replyInboxTask(request, reply) {
4647
4667
  });
4648
4668
  }
4649
4669
  }
4670
+ async function abortWorkflowRun(request, reply) {
4671
+ try {
4672
+ const { runId } = request.params;
4673
+ const tenantId = getTenantId7(request);
4674
+ const store2 = getTrackingStore();
4675
+ if (!store2) {
4676
+ return reply.status(404).send({
4677
+ success: false,
4678
+ message: "No workflow tracking store configured"
4679
+ });
4680
+ }
4681
+ const run = await store2.getWorkflowRun(runId);
4682
+ if (!run) {
4683
+ return reply.status(404).send({
4684
+ success: false,
4685
+ message: "Workflow run not found"
4686
+ });
4687
+ }
4688
+ await store2.updateWorkflowRun(runId, {
4689
+ status: "cancelled",
4690
+ errorMessage: "Aborted by user",
4691
+ completedAt: /* @__PURE__ */ new Date()
4692
+ }).catch(() => {
4693
+ });
4694
+ const workspace_id = request.headers["x-workspace-id"];
4695
+ const project_id = request.headers["x-project-id"];
4696
+ const agent = import_core15.agentInstanceManager.getAgent({
4697
+ assistant_id: run.assistantId,
4698
+ thread_id: run.threadId,
4699
+ tenant_id: tenantId,
4700
+ workspace_id,
4701
+ project_id
4702
+ });
4703
+ await agent.abort();
4704
+ (0, import_core15.abortWorkflowRun)(runId);
4705
+ return reply.status(200).send({
4706
+ success: true,
4707
+ message: "Workflow aborted",
4708
+ data: { runId, assistantId: run.assistantId, threadId: run.threadId }
4709
+ });
4710
+ } catch (error) {
4711
+ request.log.error(error, "Failed to abort workflow run");
4712
+ return reply.status(500).send({
4713
+ success: false,
4714
+ message: `Abort failed: ${error.message}`
4715
+ });
4716
+ }
4717
+ }
4650
4718
 
4651
4719
  // src/controllers/personal-assistant.ts
4652
4720
  var import_core16 = require("@axiom-lattice/core");
@@ -6986,6 +7054,10 @@ var testOrDiscoverBody = import_zod.z.object({
6986
7054
  config: import_zod.z.record(import_zod.z.unknown()).optional()
6987
7055
  });
6988
7056
  function getTenant(request) {
7057
+ const userTenantId = request.user?.tenantId;
7058
+ if (userTenantId) {
7059
+ return userTenantId;
7060
+ }
6989
7061
  return request.headers["x-tenant-id"] || "default";
6990
7062
  }
6991
7063
  function maskSecrets(config) {
@@ -7135,7 +7207,6 @@ var import_uuid5 = require("uuid");
7135
7207
  // src/services/eval-runner.ts
7136
7208
  var import_events = require("events");
7137
7209
  var import_core29 = require("@axiom-lattice/core");
7138
- var import_agent_eval = require("@axiom-lattice/agent-eval");
7139
7210
  var import_uuid4 = require("uuid");
7140
7211
  function mapLogs(logs) {
7141
7212
  return logs.map((l) => ({
@@ -7157,6 +7228,11 @@ var EvalRunner = class {
7157
7228
  const store2 = this.getEvalStore();
7158
7229
  const project = await store2.getProjectById(tenantId, projectId);
7159
7230
  if (!project) throw new Error("Project not found");
7231
+ for (const ctx of this.runs.values()) {
7232
+ if (ctx.projectId === projectId) {
7233
+ throw new Error("A run is already in progress for this project");
7234
+ }
7235
+ }
7160
7236
  const existingRuns = await store2.getRunsByTenant(tenantId, { projectId, status: "running" });
7161
7237
  if (existingRuns.length > 0) {
7162
7238
  throw new Error("A run is already in progress for this project");
@@ -7173,7 +7249,7 @@ var EvalRunner = class {
7173
7249
  caseId: c.id,
7174
7250
  input: { message: c.inputMessage, files: c.inputFiles },
7175
7251
  steps: c.steps,
7176
- output: { type: c.outputType },
7252
+ output: { type: "message_content" },
7177
7253
  eval: {
7178
7254
  content_assertion: c.contentAssertion,
7179
7255
  eval_rubrics: c.rubrics?.map((r) => ({
@@ -7185,35 +7261,32 @@ var EvalRunner = class {
7185
7261
  }))
7186
7262
  });
7187
7263
  }
7188
- const runId = (0, import_uuid4.v4)();
7189
- const concurrency = project.concurrency || 3;
7190
- await store2.createRun(tenantId, projectId, runId, { totalCases, concurrency });
7191
- const judgeCfg = project.judgeModelConfig;
7192
- const hasModelKey = Boolean(judgeCfg.modelKey);
7193
- const hasApiKey = Boolean(judgeCfg.apiKeyEnvName || judgeCfg.apiKey);
7194
- const hasCredentials = hasApiKey;
7195
- let judgeModelConfig = {};
7196
- if (hasModelKey) {
7197
- judgeModelConfig = { modelKey: judgeCfg.modelKey };
7198
- } else if (!hasCredentials) {
7199
- const firstModel = import_core29.modelLatticeManager.getAllLattices()[0];
7200
- if (firstModel) {
7201
- judgeModelConfig = { modelKey: firstModel.key };
7202
- } else {
7203
- judgeModelConfig = { model: judgeCfg };
7264
+ const judgeCfg = project.judgeModelConfig ?? {};
7265
+ const judgeModelKey = judgeCfg.modelKey || "";
7266
+ let resolvedJudgeModelKey;
7267
+ if (judgeModelKey) {
7268
+ if (!import_core29.modelLatticeManager.hasLattice(judgeModelKey)) {
7269
+ throw new Error(`Judge model "${judgeModelKey}" is not registered`);
7204
7270
  }
7271
+ resolvedJudgeModelKey = judgeModelKey;
7205
7272
  } else {
7206
- judgeModelConfig = { model: judgeCfg };
7273
+ const firstModel = import_core29.modelLatticeManager.getAllLattices()[0];
7274
+ if (!firstModel) {
7275
+ throw new Error("No model registered \u2014 cannot run eval without a judge model");
7276
+ }
7277
+ resolvedJudgeModelKey = firstModel.key;
7278
+ console.warn(`[eval-runner] Project "${project.name}" has no judge modelKey \u2014 falling back to first registered model "${firstModel.key}"`);
7207
7279
  }
7280
+ const runId = (0, import_uuid4.v4)();
7281
+ const concurrency = Math.max(1, Math.floor(project.concurrency) || 3);
7282
+ await store2.createRun(tenantId, projectId, runId, { totalCases, concurrency });
7208
7283
  const projectConfig = {
7209
7284
  projectName: project.name,
7210
7285
  version: project.version,
7211
7286
  description: project.description,
7212
7287
  suites: evalSuites,
7213
- judge_agent_config: judgeModelConfig,
7288
+ judge_agent_config: { modelKey: resolvedJudgeModelKey },
7214
7289
  lattice_server_config: {
7215
- base_url: project.targetServerConfig.base_url || "",
7216
- api_key: project.targetServerConfig.api_key || "",
7217
7290
  tenant_id: tenantId
7218
7291
  },
7219
7292
  concurrency
@@ -7257,34 +7330,38 @@ var EvalRunner = class {
7257
7330
  };
7258
7331
  const runPromise = (async () => {
7259
7332
  try {
7260
- const evalProject = new import_agent_eval.LatticeEvalProject(projectConfig, onCaseComplete);
7261
- const { report } = await evalProject.runAllSuitesBatch(concurrency);
7262
- const completedCount = stats.passed + stats.failed;
7263
- await store2.updateRunStatus(tenantId, runId, {
7264
- status: "completed",
7265
- completedAt: /* @__PURE__ */ new Date(),
7266
- passedCases: stats.passed,
7267
- failedCases: stats.failed,
7268
- avgScore: completedCount > 0 ? stats.totalScore / completedCount : 0
7269
- });
7270
- this.eventEmitter.emit(`run:${runId}`, {
7271
- type: "completed",
7272
- runId,
7273
- data: { passed: stats.passed, failed: stats.failed, avgScore: completedCount > 0 ? stats.totalScore / completedCount : 0 }
7274
- });
7333
+ const evalProject = new import_core29.LatticeEvalProject(projectConfig, onCaseComplete);
7334
+ const { report } = await evalProject.runAllSuitesBatch(concurrency, abortController.signal);
7335
+ if (!abortController.signal.aborted) {
7336
+ const completedCount = stats.passed + stats.failed;
7337
+ await store2.updateRunStatus(tenantId, runId, {
7338
+ status: "completed",
7339
+ completedAt: /* @__PURE__ */ new Date(),
7340
+ passedCases: stats.passed,
7341
+ failedCases: stats.failed,
7342
+ avgScore: completedCount > 0 ? stats.totalScore / completedCount : 0
7343
+ });
7344
+ this.eventEmitter.emit(`run:${runId}`, {
7345
+ type: "completed",
7346
+ runId,
7347
+ data: { passed: stats.passed, failed: stats.failed, avgScore: completedCount > 0 ? stats.totalScore / completedCount : 0 }
7348
+ });
7349
+ }
7275
7350
  return { report };
7276
7351
  } catch (err) {
7277
7352
  const errorMsg = err.message;
7278
- await store2.updateRunStatus(tenantId, runId, {
7279
- status: "failed",
7280
- error: errorMsg,
7281
- completedAt: /* @__PURE__ */ new Date()
7282
- });
7283
- this.eventEmitter.emit(`run:${runId}`, {
7284
- type: "error",
7285
- runId,
7286
- data: { message: errorMsg }
7287
- });
7353
+ if (!abortController.signal.aborted) {
7354
+ await store2.updateRunStatus(tenantId, runId, {
7355
+ status: "failed",
7356
+ error: errorMsg,
7357
+ completedAt: /* @__PURE__ */ new Date()
7358
+ });
7359
+ this.eventEmitter.emit(`run:${runId}`, {
7360
+ type: "error",
7361
+ runId,
7362
+ data: { message: errorMsg }
7363
+ });
7364
+ }
7288
7365
  throw err;
7289
7366
  } finally {
7290
7367
  this.runs.delete(runId);
@@ -7329,12 +7406,27 @@ async function createProject(request, reply) {
7329
7406
  const store2 = getEvalStore();
7330
7407
  const id = (0, import_uuid5.v4)();
7331
7408
  const data = request.body;
7409
+ const serverCfg = data.targetServerConfig || {};
7410
+ const judgeCfg = data.judgeModelConfig || {};
7411
+ const modelKey = judgeCfg.modelKey || "";
7412
+ if (modelKey) {
7413
+ const { modelLatticeManager: modelLatticeManager3 } = await import("@axiom-lattice/core");
7414
+ if (!modelLatticeManager3.hasLattice(modelKey)) {
7415
+ return reply.status(400).send({ success: false, message: `Judge model "${modelKey}" is not registered` });
7416
+ }
7417
+ }
7332
7418
  const project = await store2.createProject(tenantId, id, {
7333
7419
  name: data.name,
7334
7420
  description: data.description,
7335
7421
  version: data.version,
7336
- judgeModelConfig: data.judgeModelConfig ?? {},
7337
- targetServerConfig: data.targetServerConfig ?? {},
7422
+ judgeModelConfig: {
7423
+ modelKey,
7424
+ displayName: judgeCfg.displayName || ""
7425
+ },
7426
+ targetServerConfig: {
7427
+ base_url: serverCfg.base_url || "",
7428
+ api_key: serverCfg.api_key || ""
7429
+ },
7338
7430
  concurrency: data.concurrency ?? 1,
7339
7431
  reportConfig: data.reportConfig
7340
7432
  });
@@ -7358,7 +7450,7 @@ async function listProjects(request, reply) {
7358
7450
  const { modelLatticeManager: modelLatticeManager3 } = await import("@axiom-lattice/core");
7359
7451
  const models = modelLatticeManager3.getAllLattices();
7360
7452
  const first = models[0];
7361
- const judgeModel = first ? { modelKey: first.key } : { provider: "openai", model: "gpt-4" };
7453
+ const judgeModel = first ? { modelKey: first.key } : {};
7362
7454
  const host = request.hostname || "localhost";
7363
7455
  const baseUrl = `http://${host}:${process.env.PORT || 4001}`;
7364
7456
  await store2.createProject(tenantId, (0, import_uuid5.v4)(), {
@@ -7411,7 +7503,30 @@ async function updateProject(request, reply) {
7411
7503
  if (!existing) {
7412
7504
  return reply.status(404).send({ success: false, message: "Project not found" });
7413
7505
  }
7414
- const updated = await store2.updateProject(tenantId, pid, request.body);
7506
+ const body = request.body;
7507
+ const updateData = { ...body };
7508
+ const serverCfg = body.targetServerConfig || {};
7509
+ if (body.targetServerConfig !== void 0) {
7510
+ updateData.targetServerConfig = {
7511
+ base_url: serverCfg.base_url || "",
7512
+ api_key: serverCfg.api_key || ""
7513
+ };
7514
+ }
7515
+ if (body.judgeModelConfig !== void 0) {
7516
+ const judgeCfg = body.judgeModelConfig || {};
7517
+ const modelKey = judgeCfg.modelKey || "";
7518
+ if (modelKey) {
7519
+ const { modelLatticeManager: modelLatticeManager3 } = await import("@axiom-lattice/core");
7520
+ if (!modelLatticeManager3.hasLattice(modelKey)) {
7521
+ return reply.status(400).send({ success: false, message: `Judge model "${modelKey}" is not registered` });
7522
+ }
7523
+ }
7524
+ updateData.judgeModelConfig = {
7525
+ modelKey,
7526
+ displayName: judgeCfg.displayName || ""
7527
+ };
7528
+ }
7529
+ const updated = await store2.updateProject(tenantId, pid, updateData);
7415
7530
  return {
7416
7531
  success: true,
7417
7532
  message: "Successfully updated project",
@@ -9465,6 +9580,7 @@ var registerLatticeRoutes = (app2, channelDeps) => {
9465
9580
  app2.delete("/api/workflows/runs/:runId", deleteWorkflowRun);
9466
9581
  app2.get("/api/workflows/runs/:runId/steps", getRunSteps);
9467
9582
  app2.get("/api/workflows/runs/:runId/tasks", getRunTasks);
9583
+ app2.post("/api/workflows/runs/:runId/abort", abortWorkflowRun);
9468
9584
  app2.post("/api/workflows/inbox/reply", replyInboxTask);
9469
9585
  app2.delete(
9470
9586
  "/api/assistants/:assistant_id/threads/:thread_id/pending-messages/:message_id",
@@ -10526,6 +10642,7 @@ var start = async (config) => {
10526
10642
  error: err instanceof Error ? err.message : String(err)
10527
10643
  });
10528
10644
  }
10645
+ (0, import_core40.setEvalRunService)(evalRunner);
10529
10646
  try {
10530
10647
  const menuStore = (0, import_core41.getStoreLattice)("default", "menu").store;
10531
10648
  (0, import_core40.setMenuRegistry)(menuStore);
@@ -10586,11 +10703,13 @@ var start = async (config) => {
10586
10703
  agentTaskConsumer.startPollingQueue();
10587
10704
  }
10588
10705
  }
10589
- import_core41.agentInstanceManager.restore().then((stats) => {
10590
- logger5.info(`Agent recovery complete: ${stats.restored} threads restored, ${stats.errors} errors`);
10591
- }).catch((error) => {
10592
- logger5.error("Agent recovery failed", { error });
10593
- });
10706
+ if (process.env.AXIOM_RESTORE_PENDING_ON_STARTUP === "true") {
10707
+ import_core41.agentInstanceManager.restore().then((stats) => {
10708
+ logger5.info(`Agent recovery complete: ${stats.restored} threads restored, ${stats.errors} errors`);
10709
+ }).catch((error) => {
10710
+ logger5.error("Agent recovery failed", { error });
10711
+ });
10712
+ }
10594
10713
  restoreMcpConnections().catch((error) => {
10595
10714
  logger5.error("MCP connection restoration failed", { error });
10596
10715
  });