@axiom-lattice/gateway 2.1.111 → 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.111 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
+ 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
21
25
  ESM dist/mcp-configs-SHRMQHIL.mjs 685.00 B
22
26
  ESM dist/chunk-K4XELOSO.mjs 12.52 KB
23
27
  ESM dist/sender-PX32VSHB.mjs 873.00 B
24
28
  ESM dist/WechatChannelAdapter-WSDKR4OA.mjs 8.27 KB
25
- ESM dist/a2a-ERG5RMUW.mjs 15.95 KB
26
29
  ESM dist/chunk-6CUQGDJI.mjs 6.42 KB
27
- ESM dist/index.mjs 282.73 KB
30
+ ESM dist/a2a-ERG5RMUW.mjs 15.95 KB
28
31
  ESM dist/resources-VA7LSDKN.mjs 15.81 KB
29
32
  ESM dist/chunk-LHQY46YB.mjs 1.46 KB
30
33
  ESM dist/chunk-K4XELOSO.mjs.map 25.53 KB
31
34
  ESM dist/sender-PX32VSHB.mjs.map 2.07 KB
32
35
  ESM dist/WechatChannelAdapter-WSDKR4OA.mjs.map 16.28 KB
33
- ESM dist/a2a-ERG5RMUW.mjs.map 32.14 KB
34
36
  ESM dist/chunk-6CUQGDJI.mjs.map 14.04 KB
37
+ ESM dist/a2a-ERG5RMUW.mjs.map 32.14 KB
35
38
  ESM dist/resources-VA7LSDKN.mjs.map 29.34 KB
36
39
  ESM dist/chunk-LHQY46YB.mjs.map 2.39 KB
37
- ESM dist/index.mjs.map 598.22 KB
40
+ ESM dist/index.mjs.map 606.92 KB
38
41
  ESM dist/mcp-configs-SHRMQHIL.mjs.map 71.00 B
39
- ESM ⚡️ Build success in 559ms
40
- CJS dist/index.js 353.42 KB
41
- CJS dist/index.js.map 720.44 KB
42
- CJS ⚡️ Build success in 559ms
42
+ ESM ⚡️ Build success in 479ms
43
43
  DTS Build start
44
- DTS ⚡️ Build success in 20544ms
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,16 @@
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
+
3
14
  ## 2.1.111
4
15
 
5
16
  ### Patch Changes
package/dist/index.js CHANGED
@@ -4332,6 +4332,8 @@ async function getAllWorkflowRuns(request, reply) {
4332
4332
  });
4333
4333
  }
4334
4334
  }
4335
+ var INBOX_DEFAULT_PAGE_SIZE = 20;
4336
+ var INBOX_MAX_PAGE_SIZE = 100;
4335
4337
  async function getInboxItems(request, reply) {
4336
4338
  const tenantId = getTenantId7(request);
4337
4339
  try {
@@ -4349,10 +4351,30 @@ async function getInboxItems(request, reply) {
4349
4351
  }
4350
4352
  } catch {
4351
4353
  }
4352
- const runs = await store2.getWorkflowRunsByTenantId(tenantId);
4353
- 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
+ }
4354
4372
  if (pendingRuns.length === 0) {
4355
- 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
+ };
4356
4378
  }
4357
4379
  const checkPromises = pendingRuns.map(async (r) => {
4358
4380
  try {
@@ -4409,13 +4431,10 @@ async function getInboxItems(request, reply) {
4409
4431
  });
4410
4432
  const results = await Promise.all(checkPromises);
4411
4433
  const inboxItems = results.flat();
4412
- inboxItems.sort(
4413
- (a, b) => new Date(b.startedAt).getTime() - new Date(a.startedAt).getTime()
4414
- );
4415
4434
  return {
4416
4435
  success: true,
4417
4436
  message: "Successfully retrieved inbox items",
4418
- data: { records: inboxItems }
4437
+ data: paged ? { records: inboxItems, total, page, pageSize } : { records: inboxItems }
4419
4438
  };
4420
4439
  } catch (error) {
4421
4440
  request.log.error(error, "Failed to get inbox items");
@@ -4648,6 +4667,54 @@ async function replyInboxTask(request, reply) {
4648
4667
  });
4649
4668
  }
4650
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
+ }
4651
4718
 
4652
4719
  // src/controllers/personal-assistant.ts
4653
4720
  var import_core16 = require("@axiom-lattice/core");
@@ -6987,6 +7054,10 @@ var testOrDiscoverBody = import_zod.z.object({
6987
7054
  config: import_zod.z.record(import_zod.z.unknown()).optional()
6988
7055
  });
6989
7056
  function getTenant(request) {
7057
+ const userTenantId = request.user?.tenantId;
7058
+ if (userTenantId) {
7059
+ return userTenantId;
7060
+ }
6990
7061
  return request.headers["x-tenant-id"] || "default";
6991
7062
  }
6992
7063
  function maskSecrets(config) {
@@ -7136,7 +7207,6 @@ var import_uuid5 = require("uuid");
7136
7207
  // src/services/eval-runner.ts
7137
7208
  var import_events = require("events");
7138
7209
  var import_core29 = require("@axiom-lattice/core");
7139
- var import_agent_eval = require("@axiom-lattice/agent-eval");
7140
7210
  var import_uuid4 = require("uuid");
7141
7211
  function mapLogs(logs) {
7142
7212
  return logs.map((l) => ({
@@ -7158,6 +7228,11 @@ var EvalRunner = class {
7158
7228
  const store2 = this.getEvalStore();
7159
7229
  const project = await store2.getProjectById(tenantId, projectId);
7160
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
+ }
7161
7236
  const existingRuns = await store2.getRunsByTenant(tenantId, { projectId, status: "running" });
7162
7237
  if (existingRuns.length > 0) {
7163
7238
  throw new Error("A run is already in progress for this project");
@@ -7174,7 +7249,7 @@ var EvalRunner = class {
7174
7249
  caseId: c.id,
7175
7250
  input: { message: c.inputMessage, files: c.inputFiles },
7176
7251
  steps: c.steps,
7177
- output: { type: c.outputType },
7252
+ output: { type: "message_content" },
7178
7253
  eval: {
7179
7254
  content_assertion: c.contentAssertion,
7180
7255
  eval_rubrics: c.rubrics?.map((r) => ({
@@ -7186,35 +7261,32 @@ var EvalRunner = class {
7186
7261
  }))
7187
7262
  });
7188
7263
  }
7189
- const runId = (0, import_uuid4.v4)();
7190
- const concurrency = project.concurrency || 3;
7191
- await store2.createRun(tenantId, projectId, runId, { totalCases, concurrency });
7192
- const judgeCfg = project.judgeModelConfig;
7193
- const hasModelKey = Boolean(judgeCfg.modelKey);
7194
- const hasApiKey = Boolean(judgeCfg.apiKeyEnvName || judgeCfg.apiKey);
7195
- const hasCredentials = hasApiKey;
7196
- let judgeModelConfig = {};
7197
- if (hasModelKey) {
7198
- judgeModelConfig = { modelKey: judgeCfg.modelKey };
7199
- } else if (!hasCredentials) {
7200
- const firstModel = import_core29.modelLatticeManager.getAllLattices()[0];
7201
- if (firstModel) {
7202
- judgeModelConfig = { modelKey: firstModel.key };
7203
- } else {
7204
- 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`);
7205
7270
  }
7271
+ resolvedJudgeModelKey = judgeModelKey;
7206
7272
  } else {
7207
- 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}"`);
7208
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 });
7209
7283
  const projectConfig = {
7210
7284
  projectName: project.name,
7211
7285
  version: project.version,
7212
7286
  description: project.description,
7213
7287
  suites: evalSuites,
7214
- judge_agent_config: judgeModelConfig,
7288
+ judge_agent_config: { modelKey: resolvedJudgeModelKey },
7215
7289
  lattice_server_config: {
7216
- base_url: project.targetServerConfig.base_url || "",
7217
- api_key: project.targetServerConfig.api_key || "",
7218
7290
  tenant_id: tenantId
7219
7291
  },
7220
7292
  concurrency
@@ -7258,34 +7330,38 @@ var EvalRunner = class {
7258
7330
  };
7259
7331
  const runPromise = (async () => {
7260
7332
  try {
7261
- const evalProject = new import_agent_eval.LatticeEvalProject(projectConfig, onCaseComplete);
7262
- const { report } = await evalProject.runAllSuitesBatch(concurrency);
7263
- const completedCount = stats.passed + stats.failed;
7264
- await store2.updateRunStatus(tenantId, runId, {
7265
- status: "completed",
7266
- completedAt: /* @__PURE__ */ new Date(),
7267
- passedCases: stats.passed,
7268
- failedCases: stats.failed,
7269
- avgScore: completedCount > 0 ? stats.totalScore / completedCount : 0
7270
- });
7271
- this.eventEmitter.emit(`run:${runId}`, {
7272
- type: "completed",
7273
- runId,
7274
- data: { passed: stats.passed, failed: stats.failed, avgScore: completedCount > 0 ? stats.totalScore / completedCount : 0 }
7275
- });
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
+ }
7276
7350
  return { report };
7277
7351
  } catch (err) {
7278
7352
  const errorMsg = err.message;
7279
- await store2.updateRunStatus(tenantId, runId, {
7280
- status: "failed",
7281
- error: errorMsg,
7282
- completedAt: /* @__PURE__ */ new Date()
7283
- });
7284
- this.eventEmitter.emit(`run:${runId}`, {
7285
- type: "error",
7286
- runId,
7287
- data: { message: errorMsg }
7288
- });
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
+ }
7289
7365
  throw err;
7290
7366
  } finally {
7291
7367
  this.runs.delete(runId);
@@ -7330,12 +7406,27 @@ async function createProject(request, reply) {
7330
7406
  const store2 = getEvalStore();
7331
7407
  const id = (0, import_uuid5.v4)();
7332
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
+ }
7333
7418
  const project = await store2.createProject(tenantId, id, {
7334
7419
  name: data.name,
7335
7420
  description: data.description,
7336
7421
  version: data.version,
7337
- judgeModelConfig: data.judgeModelConfig ?? {},
7338
- 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
+ },
7339
7430
  concurrency: data.concurrency ?? 1,
7340
7431
  reportConfig: data.reportConfig
7341
7432
  });
@@ -7359,7 +7450,7 @@ async function listProjects(request, reply) {
7359
7450
  const { modelLatticeManager: modelLatticeManager3 } = await import("@axiom-lattice/core");
7360
7451
  const models = modelLatticeManager3.getAllLattices();
7361
7452
  const first = models[0];
7362
- const judgeModel = first ? { modelKey: first.key } : { provider: "openai", model: "gpt-4" };
7453
+ const judgeModel = first ? { modelKey: first.key } : {};
7363
7454
  const host = request.hostname || "localhost";
7364
7455
  const baseUrl = `http://${host}:${process.env.PORT || 4001}`;
7365
7456
  await store2.createProject(tenantId, (0, import_uuid5.v4)(), {
@@ -7412,7 +7503,30 @@ async function updateProject(request, reply) {
7412
7503
  if (!existing) {
7413
7504
  return reply.status(404).send({ success: false, message: "Project not found" });
7414
7505
  }
7415
- 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);
7416
7530
  return {
7417
7531
  success: true,
7418
7532
  message: "Successfully updated project",
@@ -9466,6 +9580,7 @@ var registerLatticeRoutes = (app2, channelDeps) => {
9466
9580
  app2.delete("/api/workflows/runs/:runId", deleteWorkflowRun);
9467
9581
  app2.get("/api/workflows/runs/:runId/steps", getRunSteps);
9468
9582
  app2.get("/api/workflows/runs/:runId/tasks", getRunTasks);
9583
+ app2.post("/api/workflows/runs/:runId/abort", abortWorkflowRun);
9469
9584
  app2.post("/api/workflows/inbox/reply", replyInboxTask);
9470
9585
  app2.delete(
9471
9586
  "/api/assistants/:assistant_id/threads/:thread_id/pending-messages/:message_id",
@@ -10527,6 +10642,7 @@ var start = async (config) => {
10527
10642
  error: err instanceof Error ? err.message : String(err)
10528
10643
  });
10529
10644
  }
10645
+ (0, import_core40.setEvalRunService)(evalRunner);
10530
10646
  try {
10531
10647
  const menuStore = (0, import_core41.getStoreLattice)("default", "menu").store;
10532
10648
  (0, import_core40.setMenuRegistry)(menuStore);
@@ -10587,11 +10703,13 @@ var start = async (config) => {
10587
10703
  agentTaskConsumer.startPollingQueue();
10588
10704
  }
10589
10705
  }
10590
- import_core41.agentInstanceManager.restore().then((stats) => {
10591
- logger5.info(`Agent recovery complete: ${stats.restored} threads restored, ${stats.errors} errors`);
10592
- }).catch((error) => {
10593
- logger5.error("Agent recovery failed", { error });
10594
- });
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
+ }
10595
10713
  restoreMcpConnections().catch((error) => {
10596
10714
  logger5.error("MCP connection restoration failed", { error });
10597
10715
  });