@axiom-lattice/gateway 2.1.77 → 2.1.79
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/.turbo/turbo-build.log +8 -8
- package/CHANGELOG.md +24 -0
- package/dist/index.js +79 -20
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +80 -21
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -6
- package/src/channels/lark/LarkChannelAdapter.ts +1 -1
- package/src/channels/lark/controller.ts +4 -3
- package/src/controllers/sandbox.ts +21 -21
- package/src/controllers/workflow-tracking.ts +59 -3
- package/src/router/MessageRouter.ts +15 -5
- package/src/routes/index.ts +5 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@axiom-lattice/gateway",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.79",
|
|
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.
|
|
44
|
-
"@axiom-lattice/core": "2.1.
|
|
45
|
-
"@axiom-lattice/pg-stores": "1.0.
|
|
46
|
-
"@axiom-lattice/protocols": "2.1.
|
|
47
|
-
"@axiom-lattice/queue-redis": "1.0.
|
|
43
|
+
"@axiom-lattice/agent-eval": "2.1.63",
|
|
44
|
+
"@axiom-lattice/core": "2.1.69",
|
|
45
|
+
"@axiom-lattice/pg-stores": "1.0.59",
|
|
46
|
+
"@axiom-lattice/protocols": "2.1.36",
|
|
47
|
+
"@axiom-lattice/queue-redis": "1.0.35"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
50
|
"@types/jest": "^29.5.14",
|
|
@@ -66,7 +66,7 @@ export const larkChannelAdapter: ChannelAdapter<LarkChannelInstallationConfig> =
|
|
|
66
66
|
installation: ChannelInstallation<LarkChannelInstallationConfig>,
|
|
67
67
|
): Promise<void> {
|
|
68
68
|
const { createLarkSender } = await import("./sender");
|
|
69
|
-
const sender = createLarkSender(installation.config);
|
|
69
|
+
const sender = await createLarkSender(installation.config);
|
|
70
70
|
await sender.sendTextReply({
|
|
71
71
|
chatId: replyTarget.rawTarget.chatId as string,
|
|
72
72
|
text: message.text,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { FastifyReply, FastifyRequest } from "fastify";
|
|
2
|
-
import type { ChannelInstallationStore, LarkChannelInstallationConfig } from "@axiom-lattice/protocols";
|
|
2
|
+
import type { ChannelInstallation, ChannelInstallationStore, LarkChannelInstallationConfig } from "@axiom-lattice/protocols";
|
|
3
3
|
import { larkChannelAdapter } from "./LarkChannelAdapter";
|
|
4
4
|
import type { MessageRouter } from "../../router/MessageRouter";
|
|
5
5
|
import { parseLarkRequestBody } from "./verification";
|
|
@@ -23,14 +23,15 @@ export function createLarkEventHandler(deps: {
|
|
|
23
23
|
return;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
const
|
|
26
|
+
const larkInstallation = installation as ChannelInstallation<LarkChannelInstallationConfig>;
|
|
27
|
+
const body = parseLarkRequestBody(request.body, larkInstallation.config.encryptKey);
|
|
27
28
|
|
|
28
29
|
if (body.type === "url_verification" && body.challenge) {
|
|
29
30
|
reply.status(200).send({ challenge: body.challenge });
|
|
30
31
|
return;
|
|
31
32
|
}
|
|
32
33
|
|
|
33
|
-
const inboundMessage = await larkChannelAdapter.receive(request.body,
|
|
34
|
+
const inboundMessage = await larkChannelAdapter.receive(request.body, larkInstallation);
|
|
34
35
|
if (!inboundMessage) {
|
|
35
36
|
reply.status(200).send();
|
|
36
37
|
return;
|
|
@@ -37,14 +37,6 @@ interface SandboxParams {
|
|
|
37
37
|
threadId: string;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
interface ProxyParams extends SandboxParams {
|
|
41
|
-
"*": string;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
interface ResourceParams extends SandboxParams {
|
|
45
|
-
resourcePath: string;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
40
|
export function registerSandboxProxyRoutes(app: FastifyInstance): void {
|
|
49
41
|
// Register uploadfile route FIRST before wildcard routes to ensure it matches
|
|
50
42
|
app.post<{ Params: SandboxParams }>(
|
|
@@ -59,14 +51,18 @@ export function registerSandboxProxyRoutes(app: FastifyInstance): void {
|
|
|
59
51
|
return reply.status(500).send({ error: "Assistant sandbox config not found" });
|
|
60
52
|
}
|
|
61
53
|
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
threadId,
|
|
65
|
-
vmIsolation
|
|
66
|
-
);
|
|
54
|
+
const workspaceId = request.headers["x-workspace-id"] as string;
|
|
55
|
+
const projectId = request.headers["x-project-id"] as string;
|
|
67
56
|
|
|
68
|
-
const sandboxManager = getSandBoxManager()
|
|
69
|
-
const sandbox = await sandboxManager.
|
|
57
|
+
const sandboxManager = getSandBoxManager();
|
|
58
|
+
const sandbox = await sandboxManager.getSandboxFromConfig({
|
|
59
|
+
assistant_id: assistantId,
|
|
60
|
+
thread_id: threadId,
|
|
61
|
+
tenantId,
|
|
62
|
+
workspaceId,
|
|
63
|
+
projectId,
|
|
64
|
+
vmIsolation,
|
|
65
|
+
});
|
|
70
66
|
|
|
71
67
|
try {
|
|
72
68
|
const data = await request.file();
|
|
@@ -122,14 +118,18 @@ export function registerSandboxProxyRoutes(app: FastifyInstance): void {
|
|
|
122
118
|
return reply.status(500).send({ error: "Assistant filesystem vmIsolation not found" });
|
|
123
119
|
}
|
|
124
120
|
|
|
125
|
-
const
|
|
126
|
-
|
|
127
|
-
threadId,
|
|
128
|
-
vmIsolation
|
|
129
|
-
);
|
|
121
|
+
const workspaceId = request.headers["x-workspace-id"] as string;
|
|
122
|
+
const projectId = request.headers["x-project-id"] as string;
|
|
130
123
|
|
|
131
124
|
const sandboxManager = getSandBoxManager();
|
|
132
|
-
const sandbox = await sandboxManager.
|
|
125
|
+
const sandbox = await sandboxManager.getSandboxFromConfig({
|
|
126
|
+
assistant_id: assistantId,
|
|
127
|
+
thread_id: threadId,
|
|
128
|
+
tenantId,
|
|
129
|
+
workspaceId,
|
|
130
|
+
projectId,
|
|
131
|
+
vmIsolation,
|
|
132
|
+
});
|
|
133
133
|
|
|
134
134
|
try {
|
|
135
135
|
// Normalize path to /-prefixed absolute path
|
|
@@ -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
|
|
|
@@ -39,6 +39,7 @@ async function getDefinitionsFromAssistants(tenantId: string): Promise<Array<{
|
|
|
39
39
|
const results: Array<{
|
|
40
40
|
assistantId: string;
|
|
41
41
|
assistantName: string;
|
|
42
|
+
description?: string;
|
|
42
43
|
topologyEdges: { from: string; to: string; purpose: string }[];
|
|
43
44
|
totalEdges: number;
|
|
44
45
|
}> = [];
|
|
@@ -331,6 +332,51 @@ export async function getWorkflowRun(
|
|
|
331
332
|
}
|
|
332
333
|
}
|
|
333
334
|
|
|
335
|
+
export async function deleteWorkflowRun(
|
|
336
|
+
request: FastifyRequest<{ Params: { runId: string } }>,
|
|
337
|
+
reply: FastifyReply
|
|
338
|
+
): Promise<ApiResponse> {
|
|
339
|
+
const { runId } = request.params;
|
|
340
|
+
const tenantId = getTenantId(request);
|
|
341
|
+
|
|
342
|
+
try {
|
|
343
|
+
const store = getTrackingStore();
|
|
344
|
+
if (!store) {
|
|
345
|
+
return reply.status(404).send({ success: false, message: "No workflow tracking store configured" });
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
const run = await store.getWorkflowRun(runId);
|
|
349
|
+
if (!run) {
|
|
350
|
+
return reply.status(404).send({ success: false, message: "Workflow run not found" });
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
// If run is still running, abort the agent first
|
|
354
|
+
if (run.status === "running") {
|
|
355
|
+
try {
|
|
356
|
+
const workspace_id = request.headers["x-workspace-id"] as string;
|
|
357
|
+
const project_id = request.headers["x-project-id"] as string;
|
|
358
|
+
const agent = agentInstanceManager.getAgent({
|
|
359
|
+
assistant_id: run.assistantId,
|
|
360
|
+
thread_id: run.threadId,
|
|
361
|
+
tenant_id: tenantId,
|
|
362
|
+
workspace_id,
|
|
363
|
+
project_id,
|
|
364
|
+
});
|
|
365
|
+
await agent.abort();
|
|
366
|
+
} catch (err) {
|
|
367
|
+
request.log.warn({ runId, error: (err as Error).message }, "Failed to abort agent, deleting tracking records anyway");
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
await store.deleteWorkflowRun(runId);
|
|
372
|
+
|
|
373
|
+
return { success: true, message: "Workflow run deleted" };
|
|
374
|
+
} catch (error) {
|
|
375
|
+
request.log.error(error, "Failed to delete workflow run");
|
|
376
|
+
return reply.status(500).send({ success: false, message: "Failed to delete workflow run" });
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
|
|
334
380
|
export async function getRunSteps(
|
|
335
381
|
request: FastifyRequest<{ Params: { runId: string }; Querystring: { step_type?: string; status?: string } }>,
|
|
336
382
|
reply: FastifyReply
|
|
@@ -435,7 +481,17 @@ export async function replyInboxTask(
|
|
|
435
481
|
project_id,
|
|
436
482
|
});
|
|
437
483
|
|
|
438
|
-
// 3.
|
|
484
|
+
// 3. 检查 graph 是否处于中断状态
|
|
485
|
+
const runStatus = await agent.getRunStatus();
|
|
486
|
+
if (runStatus !== ThreadStatus.INTERRUPTED) {
|
|
487
|
+
return reply.status(409).send({
|
|
488
|
+
success: false,
|
|
489
|
+
message: `Cannot resume: graph is not interrupted (current status: ${runStatus})`,
|
|
490
|
+
data: { runId: run.id, assistantId: run.assistantId, threadId: run.threadId, status: runStatus },
|
|
491
|
+
});
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
// 4. 直接在后台触发 resume 执行(不等待,不阻塞 HTTP 响应)
|
|
439
495
|
agent.addMessage({
|
|
440
496
|
input: { message: "Clarification answers submitted" },
|
|
441
497
|
command: {
|
|
@@ -462,7 +518,7 @@ export async function replyInboxTask(
|
|
|
462
518
|
request.log.error(error, "Background resume failed");
|
|
463
519
|
});
|
|
464
520
|
|
|
465
|
-
//
|
|
521
|
+
// 5. 立即返回成功(不等待 agent 执行完成)
|
|
466
522
|
return reply.status(200).send({
|
|
467
523
|
success: true,
|
|
468
524
|
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
|
|
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
|
|
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
|
-
|
|
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:
|
|
138
|
+
tenant_id: tenantId,
|
|
129
139
|
assistant_id: ctx.binding.agentId,
|
|
130
140
|
thread_id: threadId,
|
|
131
141
|
workspace_id: ctx.binding.workspaceId || "",
|
package/src/routes/index.ts
CHANGED
|
@@ -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:
|
|
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 };
|