@axiom-lattice/gateway 2.1.77 → 2.1.78

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@axiom-lattice/gateway",
3
- "version": "2.1.77",
3
+ "version": "2.1.78",
4
4
  "main": "dist/index.js",
5
5
  "module": "dist/index.mjs",
6
6
  "types": "dist/index.d.ts",
@@ -40,11 +40,11 @@
40
40
  "redis": "^5.0.1",
41
41
  "uuid": "^9.0.1",
42
42
  "zod": "3.25.76",
43
- "@axiom-lattice/agent-eval": "2.1.61",
44
- "@axiom-lattice/core": "2.1.67",
45
- "@axiom-lattice/pg-stores": "1.0.57",
46
- "@axiom-lattice/protocols": "2.1.34",
47
- "@axiom-lattice/queue-redis": "1.0.33"
43
+ "@axiom-lattice/agent-eval": "2.1.62",
44
+ "@axiom-lattice/core": "2.1.68",
45
+ "@axiom-lattice/pg-stores": "1.0.58",
46
+ "@axiom-lattice/protocols": "2.1.35",
47
+ "@axiom-lattice/queue-redis": "1.0.34"
48
48
  },
49
49
  "devDependencies": {
50
50
  "@types/jest": "^29.5.14",
@@ -1,5 +1,5 @@
1
1
  import { FastifyRequest, FastifyReply } from "fastify";
2
- import { getStoreLattice, agentInstanceManager } from "@axiom-lattice/core";
2
+ import { getStoreLattice, agentInstanceManager, ThreadStatus } from "@axiom-lattice/core";
3
3
  import type { WorkflowTrackingStore, WorkflowRun, RunStep } from "@axiom-lattice/protocols";
4
4
  import { MessageChunkTypes } from "@axiom-lattice/protocols";
5
5
 
@@ -331,6 +331,51 @@ export async function getWorkflowRun(
331
331
  }
332
332
  }
333
333
 
334
+ export async function deleteWorkflowRun(
335
+ request: FastifyRequest<{ Params: { runId: string } }>,
336
+ reply: FastifyReply
337
+ ): Promise<ApiResponse> {
338
+ const { runId } = request.params;
339
+ const tenantId = getTenantId(request);
340
+
341
+ try {
342
+ const store = getTrackingStore();
343
+ if (!store) {
344
+ return reply.status(404).send({ success: false, message: "No workflow tracking store configured" });
345
+ }
346
+
347
+ const run = await store.getWorkflowRun(runId);
348
+ if (!run) {
349
+ return reply.status(404).send({ success: false, message: "Workflow run not found" });
350
+ }
351
+
352
+ // If run is still running, abort the agent first
353
+ if (run.status === "running") {
354
+ try {
355
+ const workspace_id = request.headers["x-workspace-id"] as string;
356
+ const project_id = request.headers["x-project-id"] as string;
357
+ const agent = agentInstanceManager.getAgent({
358
+ assistant_id: run.assistantId,
359
+ thread_id: run.threadId,
360
+ tenant_id: tenantId,
361
+ workspace_id,
362
+ project_id,
363
+ });
364
+ await agent.abort();
365
+ } catch (err) {
366
+ request.log.warn({ runId, error: (err as Error).message }, "Failed to abort agent, deleting tracking records anyway");
367
+ }
368
+ }
369
+
370
+ await store.deleteWorkflowRun(runId);
371
+
372
+ return { success: true, message: "Workflow run deleted" };
373
+ } catch (error) {
374
+ request.log.error(error, "Failed to delete workflow run");
375
+ return reply.status(500).send({ success: false, message: "Failed to delete workflow run" });
376
+ }
377
+ }
378
+
334
379
  export async function getRunSteps(
335
380
  request: FastifyRequest<{ Params: { runId: string }; Querystring: { step_type?: string; status?: string } }>,
336
381
  reply: FastifyReply
@@ -435,7 +480,17 @@ export async function replyInboxTask(
435
480
  project_id,
436
481
  });
437
482
 
438
- // 3. 直接在后台触发 resume 执行(不等待,不阻塞 HTTP 响应)
483
+ // 3. 检查 graph 是否处于中断状态
484
+ const runStatus = await agent.getRunStatus();
485
+ if (runStatus !== ThreadStatus.INTERRUPTED) {
486
+ return reply.status(409).send({
487
+ success: false,
488
+ message: `Cannot resume: graph is not interrupted (current status: ${runStatus})`,
489
+ data: { runId: run.id, assistantId: run.assistantId, threadId: run.threadId, status: runStatus },
490
+ });
491
+ }
492
+
493
+ // 4. 直接在后台触发 resume 执行(不等待,不阻塞 HTTP 响应)
439
494
  agent.addMessage({
440
495
  input: { message: "Clarification answers submitted" },
441
496
  command: {
@@ -462,7 +517,7 @@ export async function replyInboxTask(
462
517
  request.log.error(error, "Background resume failed");
463
518
  });
464
519
 
465
- // 4. 立即返回成功(不等待 agent 执行完成)
520
+ // 5. 立即返回成功(不等待 agent 执行完成)
466
521
  return reply.status(200).send({
467
522
  success: true,
468
523
  message: "Resume request submitted successfully",
@@ -51,11 +51,21 @@ export class MessageRouter {
51
51
 
52
52
  try {
53
53
  await this.runMiddlewares(ctx, async () => {
54
+ // Resolve tenantId from installation if not provided
55
+ const tenantId = message.tenantId
56
+ || (await this.installationStore.getInstallationById(message.channelInstallationId))?.tenantId;
57
+
58
+ if (!tenantId) {
59
+ throw new Error(
60
+ "tenantId is required: provide it in the message or ensure the channelInstallation has a tenantId"
61
+ );
62
+ }
63
+
54
64
  let binding = await this.bindingRegistry.resolve({
55
65
  channel: message.channel,
56
66
  senderId: message.sender.id,
57
67
  channelInstallationId: message.channelInstallationId,
58
- tenantId: message.tenantId,
68
+ tenantId,
59
69
  });
60
70
 
61
71
  if (!binding) {
@@ -74,11 +84,11 @@ export class MessageRouter {
74
84
  id: "fallback",
75
85
  channel: message.channel,
76
86
  channelInstallationId: message.channelInstallationId,
77
- tenantId: message.tenantId,
87
+ tenantId,
78
88
  senderId: message.sender.id,
79
89
  agentId: installation.fallbackAgentId,
80
90
  threadId: undefined,
81
- threadMode: "fixed",
91
+ threadMode: "fixed" as const,
82
92
  enabled: true,
83
93
  createdAt: new Date(),
84
94
  updatedAt: new Date(),
@@ -103,7 +113,7 @@ export class MessageRouter {
103
113
  const threadStore = getStoreLattice("default", "thread").store;
104
114
  const newThreadId = randomUUID();
105
115
  const newThread = await threadStore.createThread(
106
- message.tenantId,
116
+ tenantId,
107
117
  ctx.binding.agentId,
108
118
  newThreadId,
109
119
  {
@@ -125,7 +135,7 @@ export class MessageRouter {
125
135
  }
126
136
 
127
137
  const agent = agentInstanceManager.getAgent({
128
- tenant_id: message.tenantId,
138
+ tenant_id: tenantId,
129
139
  assistant_id: ctx.binding.agentId,
130
140
  thread_id: threadId,
131
141
  workspace_id: ctx.binding.workspaceId || "",
@@ -378,7 +378,7 @@ export const registerLatticeRoutes = (app: FastifyInstance, channelDeps?: { rout
378
378
  const inboundMessage = {
379
379
  channel: msg.channel as string,
380
380
  channelInstallationId: (msg.channelInstallationId || "") as string,
381
- tenantId: (msg.tenantId || "default") as string,
381
+ tenantId: msg.tenantId as string | undefined,
382
382
  sender: {
383
383
  id: (msg.sender as Record<string, unknown>).id as string,
384
384
  displayName: (msg.sender as Record<string, unknown>).displayName as string | undefined,
@@ -437,6 +437,10 @@ export const registerLatticeRoutes = (app: FastifyInstance, channelDeps?: { rout
437
437
  Params: { runId: string };
438
438
  }>("/api/workflows/runs/:runId", workflowTrackingController.getWorkflowRun);
439
439
 
440
+ app.delete<{
441
+ Params: { runId: string };
442
+ }>("/api/workflows/runs/:runId", workflowTrackingController.deleteWorkflowRun);
443
+
440
444
  app.get<{
441
445
  Params: { runId: string };
442
446
  Querystring: { step_type?: string; status?: string };