@axiom-lattice/gateway 2.1.91 → 2.1.93
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 +9 -9
- package/CHANGELOG.md +24 -0
- package/dist/index.js +1019 -396
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +923 -299
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -6
- package/scripts/seed-lark-installation.ts +54 -0
- package/src/channels/lark/LarkChannelAdapter.ts +140 -18
- package/src/channels/lark/types.ts +0 -13
- package/src/channels/lark/verification.ts +1 -36
- package/src/controllers/__tests__/run.test.ts +115 -0
- package/src/controllers/__tests__/tasks.test.ts +215 -0
- package/src/controllers/agent_task.ts +7 -0
- package/src/controllers/assistant.ts +15 -2
- package/src/controllers/auth.ts +9 -0
- package/src/controllers/menu-items.ts +114 -0
- package/src/controllers/personal-assistant.ts +191 -0
- package/src/controllers/run.ts +47 -0
- package/src/controllers/tasks.ts +187 -0
- package/src/controllers/workflow-tracking.ts +66 -13
- package/src/index.ts +50 -20
- package/src/router/MessageRouter.ts +107 -41
- package/src/routes/index.ts +23 -0
- package/src/routes/menu-items.ts +10 -0
- package/src/services/agent_task_consumer.ts +2 -8
- package/src/channels/lark/__tests__/aggregator.test.ts +0 -23
- package/src/channels/lark/aggregator.ts +0 -16
- package/src/channels/lark/config.ts +0 -44
- package/src/channels/lark/runner.ts +0 -37
package/dist/index.mjs
CHANGED
|
@@ -19,6 +19,11 @@ function getTenantId(request) {
|
|
|
19
19
|
}
|
|
20
20
|
return request.headers["x-tenant-id"] || "default";
|
|
21
21
|
}
|
|
22
|
+
function getUserId(request) {
|
|
23
|
+
const userId = request.user?.id;
|
|
24
|
+
if (userId) return userId;
|
|
25
|
+
return request.headers["x-user-id"] || void 0;
|
|
26
|
+
}
|
|
22
27
|
function convertAgentConfigToAssistant(config) {
|
|
23
28
|
return {
|
|
24
29
|
id: config.key,
|
|
@@ -51,12 +56,17 @@ async function getAssistantList(request, reply) {
|
|
|
51
56
|
assistantMap.set(assistant.id, assistant);
|
|
52
57
|
});
|
|
53
58
|
const allAssistants = Array.from(assistantMap.values());
|
|
59
|
+
const userId = getUserId(request);
|
|
60
|
+
const filtered = allAssistants.filter((a) => {
|
|
61
|
+
if (!a.ownerUserId) return true;
|
|
62
|
+
return a.ownerUserId === userId;
|
|
63
|
+
});
|
|
54
64
|
return {
|
|
55
65
|
success: true,
|
|
56
66
|
message: "Successfully retrieved assistant list",
|
|
57
67
|
data: {
|
|
58
|
-
records:
|
|
59
|
-
total:
|
|
68
|
+
records: filtered,
|
|
69
|
+
total: filtered.length
|
|
60
70
|
}
|
|
61
71
|
};
|
|
62
72
|
}
|
|
@@ -204,7 +214,7 @@ import {
|
|
|
204
214
|
agentInstanceManager as agentInstanceManager2
|
|
205
215
|
} from "@axiom-lattice/core";
|
|
206
216
|
import { MessageChunkTypes } from "@axiom-lattice/protocols";
|
|
207
|
-
function
|
|
217
|
+
function getUserId2(request) {
|
|
208
218
|
const authUser = request.user;
|
|
209
219
|
if (authUser?.id) return authUser.id;
|
|
210
220
|
return request.headers["x-user-id"] || void 0;
|
|
@@ -226,7 +236,7 @@ var createRun = async (request, reply) => {
|
|
|
226
236
|
const workspace_id = request.headers["x-workspace-id"];
|
|
227
237
|
const project_id = request.headers["x-project-id"];
|
|
228
238
|
const x_request_id = request.headers["x-request-id"] || v4();
|
|
229
|
-
const user_id =
|
|
239
|
+
const user_id = getUserId2(request);
|
|
230
240
|
const mergedConfig = user_id ? { ...custom_run_config, user_id } : custom_run_config;
|
|
231
241
|
if (!assistant_id) {
|
|
232
242
|
reply.status(400).send({
|
|
@@ -380,6 +390,33 @@ var abortRun = async (request, reply) => {
|
|
|
380
390
|
});
|
|
381
391
|
}
|
|
382
392
|
};
|
|
393
|
+
var recoverRun = async (request, reply) => {
|
|
394
|
+
try {
|
|
395
|
+
const { assistantId, threadId } = request.params;
|
|
396
|
+
const tenant_id = request.headers["x-tenant-id"];
|
|
397
|
+
const workspace_id = request.headers["x-workspace-id"] || "default";
|
|
398
|
+
const project_id = request.headers["x-project-id"] || "default";
|
|
399
|
+
const agent = agentInstanceManager2.getAgent({
|
|
400
|
+
assistant_id: assistantId,
|
|
401
|
+
thread_id: threadId,
|
|
402
|
+
tenant_id,
|
|
403
|
+
workspace_id,
|
|
404
|
+
project_id
|
|
405
|
+
});
|
|
406
|
+
await agent.resumeTask();
|
|
407
|
+
const status = await agent.getRunStatus();
|
|
408
|
+
reply.status(200).send({
|
|
409
|
+
success: true,
|
|
410
|
+
threadId,
|
|
411
|
+
status
|
|
412
|
+
});
|
|
413
|
+
} catch (error) {
|
|
414
|
+
reply.status(500).send({
|
|
415
|
+
success: false,
|
|
416
|
+
error: `Recover failed: ${error.message}`
|
|
417
|
+
});
|
|
418
|
+
}
|
|
419
|
+
};
|
|
383
420
|
|
|
384
421
|
// src/controllers/memory.ts
|
|
385
422
|
import { agentInstanceManager as agentInstanceManager3 } from "@axiom-lattice/core";
|
|
@@ -552,6 +589,8 @@ var triggerAgentTask = async (request, reply) => {
|
|
|
552
589
|
try {
|
|
553
590
|
const { assistant_id, thread_id, input, command } = request.body;
|
|
554
591
|
const tenant_id = request.headers["x-tenant-id"];
|
|
592
|
+
const workspace_id = request.headers["x-workspace-id"];
|
|
593
|
+
const project_id = request.headers["x-project-id"];
|
|
555
594
|
if (!assistant_id) {
|
|
556
595
|
reply.status(400).send({
|
|
557
596
|
success: false,
|
|
@@ -572,7 +611,12 @@ var triggerAgentTask = async (request, reply) => {
|
|
|
572
611
|
thread_id,
|
|
573
612
|
input,
|
|
574
613
|
command,
|
|
575
|
-
"x-tenant-id": tenant_id
|
|
614
|
+
"x-tenant-id": tenant_id,
|
|
615
|
+
runConfig: {
|
|
616
|
+
workspaceId: workspace_id,
|
|
617
|
+
projectId: project_id,
|
|
618
|
+
user_id: request.user?.id
|
|
619
|
+
}
|
|
576
620
|
});
|
|
577
621
|
reply.status(200).send({
|
|
578
622
|
success: true
|
|
@@ -1812,6 +1856,16 @@ async function getAllWorkflowRuns(request, reply) {
|
|
|
1812
1856
|
if (!store) {
|
|
1813
1857
|
return reply.status(404).send({ success: false, message: "No workflow tracking store configured" });
|
|
1814
1858
|
}
|
|
1859
|
+
const nameMap = {};
|
|
1860
|
+
try {
|
|
1861
|
+
const asStoreLattice = getStoreLattice4("default", "assistant");
|
|
1862
|
+
const assistantStore = asStoreLattice.store;
|
|
1863
|
+
const assistants = await assistantStore.getAllAssistants(tenantId);
|
|
1864
|
+
for (const a of assistants) {
|
|
1865
|
+
nameMap[a.id] = a.name;
|
|
1866
|
+
}
|
|
1867
|
+
} catch {
|
|
1868
|
+
}
|
|
1815
1869
|
let runs;
|
|
1816
1870
|
if (assistantId) {
|
|
1817
1871
|
runs = await store.getWorkflowRunsByAssistantId(tenantId, assistantId);
|
|
@@ -1821,10 +1875,22 @@ async function getAllWorkflowRuns(request, reply) {
|
|
|
1821
1875
|
if (status) {
|
|
1822
1876
|
runs = runs.filter((r) => r.status === status);
|
|
1823
1877
|
}
|
|
1878
|
+
const enrichedRuns = await Promise.all(
|
|
1879
|
+
runs.map(async (run) => {
|
|
1880
|
+
try {
|
|
1881
|
+
const steps = await store.getRunSteps(run.id);
|
|
1882
|
+
const totalSteps = steps.length;
|
|
1883
|
+
const completedSteps = steps.filter((s) => s.status === "completed").length;
|
|
1884
|
+
return { ...run, totalSteps, completedSteps, assistantName: nameMap[run.assistantId] || run.assistantId };
|
|
1885
|
+
} catch {
|
|
1886
|
+
return { ...run, totalSteps: 0, completedSteps: 0, assistantName: nameMap[run.assistantId] || run.assistantId };
|
|
1887
|
+
}
|
|
1888
|
+
})
|
|
1889
|
+
);
|
|
1824
1890
|
return {
|
|
1825
1891
|
success: true,
|
|
1826
1892
|
message: "Successfully retrieved workflow runs",
|
|
1827
|
-
data: { records:
|
|
1893
|
+
data: { records: enrichedRuns, total: enrichedRuns.length }
|
|
1828
1894
|
};
|
|
1829
1895
|
} catch (error) {
|
|
1830
1896
|
request.log.error(error, "Failed to get workflow runs");
|
|
@@ -1849,17 +1915,40 @@ async function getInboxItems(request, reply) {
|
|
|
1849
1915
|
} catch {
|
|
1850
1916
|
}
|
|
1851
1917
|
const runs = await store.getWorkflowRunsByTenantId(tenantId);
|
|
1852
|
-
const
|
|
1853
|
-
if (
|
|
1854
|
-
return { success: true, message: "No
|
|
1918
|
+
const pendingRuns = runs.filter((r) => r.status === "interrupted");
|
|
1919
|
+
if (pendingRuns.length === 0) {
|
|
1920
|
+
return { success: true, message: "No pending workflows", data: { records: [] } };
|
|
1855
1921
|
}
|
|
1856
|
-
const checkPromises =
|
|
1922
|
+
const checkPromises = pendingRuns.map(async (r) => {
|
|
1857
1923
|
try {
|
|
1858
|
-
const agent =
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1924
|
+
const [steps, agent] = await Promise.all([
|
|
1925
|
+
store.getRunSteps(r.id).catch(() => []),
|
|
1926
|
+
(async () => {
|
|
1927
|
+
try {
|
|
1928
|
+
return agentInstanceManager4.getAgent({
|
|
1929
|
+
assistant_id: r.assistantId,
|
|
1930
|
+
thread_id: r.threadId,
|
|
1931
|
+
tenant_id: r.tenantId
|
|
1932
|
+
});
|
|
1933
|
+
} catch {
|
|
1934
|
+
return null;
|
|
1935
|
+
}
|
|
1936
|
+
})()
|
|
1937
|
+
]);
|
|
1938
|
+
if (!agent) {
|
|
1939
|
+
return [{
|
|
1940
|
+
runId: r.id,
|
|
1941
|
+
assistantId: r.assistantId,
|
|
1942
|
+
assistantName: nameMap[r.assistantId] || r.assistantId,
|
|
1943
|
+
threadId: r.threadId,
|
|
1944
|
+
tenantId: r.tenantId,
|
|
1945
|
+
status: r.status,
|
|
1946
|
+
startedAt: r.startedAt,
|
|
1947
|
+
totalEdges: r.totalEdges,
|
|
1948
|
+
completedEdges: r.completedEdges,
|
|
1949
|
+
steps
|
|
1950
|
+
}];
|
|
1951
|
+
}
|
|
1863
1952
|
const runStatus = await agent.getRunStatus();
|
|
1864
1953
|
if (runStatus !== "interrupted") return [];
|
|
1865
1954
|
const state = await agent.getCurrentState();
|
|
@@ -1872,9 +1961,11 @@ async function getInboxItems(request, reply) {
|
|
|
1872
1961
|
tenantId: r.tenantId,
|
|
1873
1962
|
interruptId: i.id,
|
|
1874
1963
|
interruptValue: i.value,
|
|
1964
|
+
status: r.status,
|
|
1875
1965
|
startedAt: r.startedAt,
|
|
1876
1966
|
totalEdges: r.totalEdges,
|
|
1877
|
-
completedEdges: r.completedEdges
|
|
1967
|
+
completedEdges: r.completedEdges,
|
|
1968
|
+
steps
|
|
1878
1969
|
}));
|
|
1879
1970
|
} catch (err) {
|
|
1880
1971
|
request.log.warn({ runId: r.id, error: err.message }, "Agent check skipped");
|
|
@@ -2120,6 +2211,268 @@ async function replyInboxTask(request, reply) {
|
|
|
2120
2211
|
}
|
|
2121
2212
|
}
|
|
2122
2213
|
|
|
2214
|
+
// src/controllers/personal-assistant.ts
|
|
2215
|
+
import { getStoreLattice as getStoreLattice5, PersonalAssistantConfig } from "@axiom-lattice/core";
|
|
2216
|
+
import { randomUUID as randomUUID3 } from "crypto";
|
|
2217
|
+
function getWorkspaceId2(request) {
|
|
2218
|
+
return request.headers["x-workspace-id"] || "default";
|
|
2219
|
+
}
|
|
2220
|
+
function getTenantId7(request) {
|
|
2221
|
+
const userTenantId = request.user?.tenantId;
|
|
2222
|
+
if (userTenantId) return userTenantId;
|
|
2223
|
+
return request.headers["x-tenant-id"] || "default";
|
|
2224
|
+
}
|
|
2225
|
+
function getUserId3(request) {
|
|
2226
|
+
const userId = request.user?.id || request.headers["x-user-id"];
|
|
2227
|
+
if (!userId) throw new Error("User ID is required");
|
|
2228
|
+
return userId;
|
|
2229
|
+
}
|
|
2230
|
+
function getLinkStore() {
|
|
2231
|
+
return getStoreLattice5("default", "userTenantLink").store;
|
|
2232
|
+
}
|
|
2233
|
+
function getAssistantStore() {
|
|
2234
|
+
return getStoreLattice5("default", "assistant").store;
|
|
2235
|
+
}
|
|
2236
|
+
function getProjectStore() {
|
|
2237
|
+
return getStoreLattice5("default", "project").store;
|
|
2238
|
+
}
|
|
2239
|
+
async function getLinkMeta(userId, tenantId) {
|
|
2240
|
+
const link = await getLinkStore().getLink(userId, tenantId);
|
|
2241
|
+
return link?.metadata || {};
|
|
2242
|
+
}
|
|
2243
|
+
async function updateLinkMeta(userId, tenantId, meta) {
|
|
2244
|
+
await getLinkStore().updateLink(userId, tenantId, { metadata: meta });
|
|
2245
|
+
}
|
|
2246
|
+
async function createPersonalAssistant(request, reply) {
|
|
2247
|
+
const tenantId = getTenantId7(request);
|
|
2248
|
+
const userId = getUserId3(request);
|
|
2249
|
+
const { name, personality } = request.body;
|
|
2250
|
+
if (!name || !personality) {
|
|
2251
|
+
return reply.status(400).send({ success: false, message: "name and personality are required" });
|
|
2252
|
+
}
|
|
2253
|
+
const store = getAssistantStore();
|
|
2254
|
+
const existing = await store.getByOwner(tenantId, userId);
|
|
2255
|
+
if (existing) {
|
|
2256
|
+
return reply.status(409).send({ success: false, message: "You already have a personal assistant" });
|
|
2257
|
+
}
|
|
2258
|
+
const assistantId = randomUUID3();
|
|
2259
|
+
const projectStore = getProjectStore();
|
|
2260
|
+
const projectId = randomUUID3();
|
|
2261
|
+
const wsId = getWorkspaceId2(request);
|
|
2262
|
+
await projectStore.createProject(tenantId, wsId, projectId, {
|
|
2263
|
+
name: `${name}'s Space`,
|
|
2264
|
+
description: "Personal workspace for your assistant"
|
|
2265
|
+
});
|
|
2266
|
+
const config = PersonalAssistantConfig.get();
|
|
2267
|
+
config.key = assistantId;
|
|
2268
|
+
PersonalAssistantConfig.render(config, name, personality);
|
|
2269
|
+
const data = { name, graphDefinition: config, ownerUserId: userId };
|
|
2270
|
+
const assistant = await store.createAssistant(tenantId, assistantId, data);
|
|
2271
|
+
const meta = await getLinkMeta(userId, tenantId);
|
|
2272
|
+
meta.personalAssistantId = assistantId;
|
|
2273
|
+
meta.personalProjectId = projectId;
|
|
2274
|
+
meta.personalWorkspaceId = wsId;
|
|
2275
|
+
await updateLinkMeta(userId, tenantId, meta);
|
|
2276
|
+
return reply.status(201).send({
|
|
2277
|
+
success: true,
|
|
2278
|
+
message: "Personal assistant created",
|
|
2279
|
+
data: { id: assistant.id, name: assistant.name, projectId, workspaceId: wsId, createdAt: assistant.createdAt }
|
|
2280
|
+
});
|
|
2281
|
+
}
|
|
2282
|
+
async function getPersonalAssistant(request, reply) {
|
|
2283
|
+
const tenantId = getTenantId7(request);
|
|
2284
|
+
const userId = getUserId3(request);
|
|
2285
|
+
const store = getAssistantStore();
|
|
2286
|
+
const assistant = await store.getByOwner(tenantId, userId);
|
|
2287
|
+
if (!assistant) {
|
|
2288
|
+
return reply.status(404).send({ success: false, message: "No personal assistant found" });
|
|
2289
|
+
}
|
|
2290
|
+
const meta = await getLinkMeta(userId, tenantId);
|
|
2291
|
+
const projectId = meta.personalProjectId || "default";
|
|
2292
|
+
const workspaceId = meta.personalWorkspaceId || "default";
|
|
2293
|
+
return {
|
|
2294
|
+
success: true,
|
|
2295
|
+
message: "Personal assistant found",
|
|
2296
|
+
data: { id: assistant.id, name: assistant.name, projectId, workspaceId, createdAt: assistant.createdAt }
|
|
2297
|
+
};
|
|
2298
|
+
}
|
|
2299
|
+
async function deletePersonalAssistant(request, reply) {
|
|
2300
|
+
const tenantId = getTenantId7(request);
|
|
2301
|
+
const userId = getUserId3(request);
|
|
2302
|
+
const store = getAssistantStore();
|
|
2303
|
+
const assistant = await store.getByOwner(tenantId, userId);
|
|
2304
|
+
if (!assistant) {
|
|
2305
|
+
return reply.status(404).send({ success: false, message: "No personal assistant found" });
|
|
2306
|
+
}
|
|
2307
|
+
const deleted = await store.deleteAssistant(tenantId, assistant.id);
|
|
2308
|
+
if (!deleted) {
|
|
2309
|
+
return reply.status(500).send({ success: false, message: "Failed to delete personal assistant" });
|
|
2310
|
+
}
|
|
2311
|
+
const threadStore = getStoreLattice5("default", "thread").store;
|
|
2312
|
+
try {
|
|
2313
|
+
const threads = await threadStore.getThreadsByAssistantId(tenantId, assistant.id);
|
|
2314
|
+
for (const t of threads) {
|
|
2315
|
+
await threadStore.deleteThread(tenantId, t.id);
|
|
2316
|
+
}
|
|
2317
|
+
} catch {
|
|
2318
|
+
}
|
|
2319
|
+
const meta = await getLinkMeta(userId, tenantId);
|
|
2320
|
+
const projectId = meta.personalProjectId;
|
|
2321
|
+
const wsId = meta.personalWorkspaceId;
|
|
2322
|
+
if (projectId && wsId) {
|
|
2323
|
+
try {
|
|
2324
|
+
await getProjectStore().deleteProject(tenantId, projectId);
|
|
2325
|
+
} catch {
|
|
2326
|
+
}
|
|
2327
|
+
}
|
|
2328
|
+
delete meta.personalAssistantId;
|
|
2329
|
+
delete meta.personalProjectId;
|
|
2330
|
+
delete meta.personalWorkspaceId;
|
|
2331
|
+
await updateLinkMeta(userId, tenantId, meta);
|
|
2332
|
+
return { success: true, message: "Personal assistant deleted" };
|
|
2333
|
+
}
|
|
2334
|
+
|
|
2335
|
+
// src/controllers/tasks.ts
|
|
2336
|
+
import { getStoreLattice as getStoreLattice6 } from "@axiom-lattice/core";
|
|
2337
|
+
function getTenantId8(request) {
|
|
2338
|
+
const userTenantId = request.user?.tenantId;
|
|
2339
|
+
if (userTenantId) return userTenantId;
|
|
2340
|
+
return request.headers["x-tenant-id"] || "default";
|
|
2341
|
+
}
|
|
2342
|
+
function getUserId4(request) {
|
|
2343
|
+
const userId = request.user?.id || request.headers["x-user-id"];
|
|
2344
|
+
if (!userId) throw new Error("User ID is required");
|
|
2345
|
+
return userId;
|
|
2346
|
+
}
|
|
2347
|
+
function getStore() {
|
|
2348
|
+
return getStoreLattice6("default", "task").store;
|
|
2349
|
+
}
|
|
2350
|
+
async function listTasks(request, reply) {
|
|
2351
|
+
try {
|
|
2352
|
+
const tenantId = getTenantId8(request);
|
|
2353
|
+
const userId = getUserId4(request);
|
|
2354
|
+
const query = request.query;
|
|
2355
|
+
const store = getStore();
|
|
2356
|
+
const tasks = await store.list({
|
|
2357
|
+
tenantId,
|
|
2358
|
+
ownerId: query.ownerId || userId,
|
|
2359
|
+
status: query.status,
|
|
2360
|
+
priority: query.priority,
|
|
2361
|
+
ownerType: query.ownerType,
|
|
2362
|
+
metadata: query.metadata ? JSON.parse(query.metadata) : void 0,
|
|
2363
|
+
limit: query.limit ? parseInt(query.limit) : void 0,
|
|
2364
|
+
offset: query.offset ? parseInt(query.offset) : void 0
|
|
2365
|
+
});
|
|
2366
|
+
return { success: true, data: tasks, count: tasks.length };
|
|
2367
|
+
} catch (error) {
|
|
2368
|
+
return { success: false, error: error.message };
|
|
2369
|
+
}
|
|
2370
|
+
}
|
|
2371
|
+
async function getTask(request, reply) {
|
|
2372
|
+
try {
|
|
2373
|
+
const tenantId = getTenantId8(request);
|
|
2374
|
+
const userId = getUserId4(request);
|
|
2375
|
+
const { id } = request.params;
|
|
2376
|
+
const store = getStore();
|
|
2377
|
+
const task = await store.getById(tenantId, id);
|
|
2378
|
+
if (!task) {
|
|
2379
|
+
return reply.status(404).send({ success: false, error: "Task not found" });
|
|
2380
|
+
}
|
|
2381
|
+
if (task.ownerType === "user" && task.ownerId !== userId) {
|
|
2382
|
+
return reply.status(403).send({ success: false, error: "Access denied" });
|
|
2383
|
+
}
|
|
2384
|
+
return { success: true, data: task };
|
|
2385
|
+
} catch (error) {
|
|
2386
|
+
return { success: false, error: error.message };
|
|
2387
|
+
}
|
|
2388
|
+
}
|
|
2389
|
+
async function createTask(request, reply) {
|
|
2390
|
+
try {
|
|
2391
|
+
const tenantId = getTenantId8(request);
|
|
2392
|
+
const userId = getUserId4(request);
|
|
2393
|
+
const body = request.body;
|
|
2394
|
+
if (!body.title) {
|
|
2395
|
+
return reply.status(400).send({ success: false, error: "title is required" });
|
|
2396
|
+
}
|
|
2397
|
+
const store = getStore();
|
|
2398
|
+
const task = await store.create({
|
|
2399
|
+
...body,
|
|
2400
|
+
tenantId,
|
|
2401
|
+
ownerType: body.ownerType || "user",
|
|
2402
|
+
ownerId: body.ownerId || userId
|
|
2403
|
+
});
|
|
2404
|
+
return reply.status(201).send({ success: true, data: task });
|
|
2405
|
+
} catch (error) {
|
|
2406
|
+
return reply.status(500).send({ success: false, error: error.message });
|
|
2407
|
+
}
|
|
2408
|
+
}
|
|
2409
|
+
async function updateTask(request, reply) {
|
|
2410
|
+
try {
|
|
2411
|
+
const tenantId = getTenantId8(request);
|
|
2412
|
+
const userId = getUserId4(request);
|
|
2413
|
+
const { id } = request.params;
|
|
2414
|
+
const store = getStore();
|
|
2415
|
+
const existing = await store.getById(tenantId, id);
|
|
2416
|
+
if (!existing) {
|
|
2417
|
+
return reply.status(404).send({ success: false, error: "Task not found" });
|
|
2418
|
+
}
|
|
2419
|
+
if (existing.ownerType === "user" && existing.ownerId !== userId) {
|
|
2420
|
+
return reply.status(403).send({ success: false, error: "Access denied" });
|
|
2421
|
+
}
|
|
2422
|
+
const task = await store.update(tenantId, id, request.body);
|
|
2423
|
+
if (!task) {
|
|
2424
|
+
return reply.status(404).send({ success: false, error: "Task not found" });
|
|
2425
|
+
}
|
|
2426
|
+
return { success: true, data: task };
|
|
2427
|
+
} catch (error) {
|
|
2428
|
+
return reply.status(500).send({ success: false, error: error.message });
|
|
2429
|
+
}
|
|
2430
|
+
}
|
|
2431
|
+
async function deleteTask(request, reply) {
|
|
2432
|
+
try {
|
|
2433
|
+
const tenantId = getTenantId8(request);
|
|
2434
|
+
const userId = getUserId4(request);
|
|
2435
|
+
const { id } = request.params;
|
|
2436
|
+
const store = getStore();
|
|
2437
|
+
const existing = await store.getById(tenantId, id);
|
|
2438
|
+
if (!existing) {
|
|
2439
|
+
return reply.status(404).send({ success: false, error: "Task not found" });
|
|
2440
|
+
}
|
|
2441
|
+
if (existing.ownerType === "user" && existing.ownerId !== userId) {
|
|
2442
|
+
return reply.status(403).send({ success: false, error: "Access denied" });
|
|
2443
|
+
}
|
|
2444
|
+
const deleted = await store.delete(tenantId, id);
|
|
2445
|
+
if (!deleted) {
|
|
2446
|
+
return reply.status(404).send({ success: false, error: "Task not found" });
|
|
2447
|
+
}
|
|
2448
|
+
return { success: true, message: "Task deleted" };
|
|
2449
|
+
} catch (error) {
|
|
2450
|
+
return reply.status(500).send({ success: false, error: error.message });
|
|
2451
|
+
}
|
|
2452
|
+
}
|
|
2453
|
+
async function completeTask(request, reply) {
|
|
2454
|
+
try {
|
|
2455
|
+
const tenantId = getTenantId8(request);
|
|
2456
|
+
const userId = getUserId4(request);
|
|
2457
|
+
const { id } = request.params;
|
|
2458
|
+
const store = getStore();
|
|
2459
|
+
const existing = await store.getById(tenantId, id);
|
|
2460
|
+
if (!existing) {
|
|
2461
|
+
return reply.status(404).send({ success: false, error: "Task not found" });
|
|
2462
|
+
}
|
|
2463
|
+
if (existing.ownerType === "user" && existing.ownerId !== userId) {
|
|
2464
|
+
return reply.status(403).send({ success: false, error: "Access denied" });
|
|
2465
|
+
}
|
|
2466
|
+
const task = await store.update(tenantId, id, { status: "completed" });
|
|
2467
|
+
if (!task) {
|
|
2468
|
+
return reply.status(404).send({ success: false, error: "Task not found" });
|
|
2469
|
+
}
|
|
2470
|
+
return { success: true, data: task };
|
|
2471
|
+
} catch (error) {
|
|
2472
|
+
return reply.status(500).send({ success: false, error: error.message });
|
|
2473
|
+
}
|
|
2474
|
+
}
|
|
2475
|
+
|
|
2123
2476
|
// src/schemas/data-query.ts
|
|
2124
2477
|
var dataQuerySchema = {
|
|
2125
2478
|
description: "Execute data query (semantic or SQL)",
|
|
@@ -2684,9 +3037,9 @@ var SandboxService = class {
|
|
|
2684
3037
|
);
|
|
2685
3038
|
return rewritten;
|
|
2686
3039
|
}
|
|
2687
|
-
generateErrorHtml(assistantId, threadId, vmIsolation,
|
|
2688
|
-
const encodedError = encodeURIComponent(
|
|
2689
|
-
return ERROR_HTML.replace("{assistantId}", assistantId).replace("{threadId}", threadId).replace("{vmIsolation}", vmIsolation).replace("{errorMessage}",
|
|
3040
|
+
generateErrorHtml(assistantId, threadId, vmIsolation, errorMessage2) {
|
|
3041
|
+
const encodedError = encodeURIComponent(errorMessage2);
|
|
3042
|
+
return ERROR_HTML.replace("{assistantId}", assistantId).replace("{threadId}", threadId).replace("{vmIsolation}", vmIsolation).replace("{errorMessage}", errorMessage2);
|
|
2690
3043
|
}
|
|
2691
3044
|
};
|
|
2692
3045
|
var sandboxService = new SandboxService();
|
|
@@ -2812,14 +3165,14 @@ function registerSandboxProxyRoutes(app2) {
|
|
|
2812
3165
|
// src/controllers/workspace.ts
|
|
2813
3166
|
import * as fs from "fs/promises";
|
|
2814
3167
|
import * as path from "path";
|
|
2815
|
-
import { getStoreLattice as
|
|
3168
|
+
import { getStoreLattice as getStoreLattice7 } from "@axiom-lattice/core";
|
|
2816
3169
|
import { SandboxFilesystem, FilesystemBackend } from "@axiom-lattice/core";
|
|
2817
3170
|
import { getSandBoxManager as getSandBoxManager3 } from "@axiom-lattice/core";
|
|
2818
3171
|
import { v4 as uuidv4 } from "uuid";
|
|
2819
3172
|
var WorkspaceController = class {
|
|
2820
3173
|
constructor() {
|
|
2821
|
-
this.workspaceStore =
|
|
2822
|
-
this.projectStore =
|
|
3174
|
+
this.workspaceStore = getStoreLattice7("default", "workspace").store;
|
|
3175
|
+
this.projectStore = getStoreLattice7("default", "project").store;
|
|
2823
3176
|
}
|
|
2824
3177
|
getTenantId(request) {
|
|
2825
3178
|
const userTenantId = request.user?.tenantId;
|
|
@@ -3344,11 +3697,11 @@ function registerWorkspaceRoutes(app2) {
|
|
|
3344
3697
|
|
|
3345
3698
|
// src/controllers/database-configs.ts
|
|
3346
3699
|
import {
|
|
3347
|
-
getStoreLattice as
|
|
3700
|
+
getStoreLattice as getStoreLattice8,
|
|
3348
3701
|
sqlDatabaseManager
|
|
3349
3702
|
} from "@axiom-lattice/core";
|
|
3350
|
-
import { randomUUID as
|
|
3351
|
-
function
|
|
3703
|
+
import { randomUUID as randomUUID4 } from "crypto";
|
|
3704
|
+
function getTenantId9(request) {
|
|
3352
3705
|
const userTenantId = request.user?.tenantId;
|
|
3353
3706
|
if (userTenantId) {
|
|
3354
3707
|
return userTenantId;
|
|
@@ -3356,9 +3709,9 @@ function getTenantId7(request) {
|
|
|
3356
3709
|
return request.headers["x-tenant-id"] || "default";
|
|
3357
3710
|
}
|
|
3358
3711
|
async function getDatabaseConfigList(request, reply) {
|
|
3359
|
-
const tenantId =
|
|
3712
|
+
const tenantId = getTenantId9(request);
|
|
3360
3713
|
try {
|
|
3361
|
-
const storeLattice =
|
|
3714
|
+
const storeLattice = getStoreLattice8("default", "database");
|
|
3362
3715
|
const store = storeLattice.store;
|
|
3363
3716
|
const configs = await store.getAllConfigs(tenantId);
|
|
3364
3717
|
console.log("Backend: getAllConfigs returned:", configs);
|
|
@@ -3386,10 +3739,10 @@ async function getDatabaseConfigList(request, reply) {
|
|
|
3386
3739
|
}
|
|
3387
3740
|
}
|
|
3388
3741
|
async function getDatabaseConfig(request, reply) {
|
|
3389
|
-
const tenantId =
|
|
3742
|
+
const tenantId = getTenantId9(request);
|
|
3390
3743
|
const { key } = request.params;
|
|
3391
3744
|
try {
|
|
3392
|
-
const storeLattice =
|
|
3745
|
+
const storeLattice = getStoreLattice8("default", "database");
|
|
3393
3746
|
const store = storeLattice.store;
|
|
3394
3747
|
const config = await store.getConfigByKey(tenantId, key);
|
|
3395
3748
|
if (!config) {
|
|
@@ -3412,10 +3765,10 @@ async function getDatabaseConfig(request, reply) {
|
|
|
3412
3765
|
}
|
|
3413
3766
|
}
|
|
3414
3767
|
async function createDatabaseConfig(request, reply) {
|
|
3415
|
-
const tenantId =
|
|
3768
|
+
const tenantId = getTenantId9(request);
|
|
3416
3769
|
const body = request.body;
|
|
3417
3770
|
try {
|
|
3418
|
-
const storeLattice =
|
|
3771
|
+
const storeLattice = getStoreLattice8("default", "database");
|
|
3419
3772
|
const store = storeLattice.store;
|
|
3420
3773
|
const existing = await store.getConfigByKey(tenantId, body.key);
|
|
3421
3774
|
if (existing) {
|
|
@@ -3425,7 +3778,7 @@ async function createDatabaseConfig(request, reply) {
|
|
|
3425
3778
|
message: "Database configuration with this key already exists"
|
|
3426
3779
|
};
|
|
3427
3780
|
}
|
|
3428
|
-
const id = body.id ||
|
|
3781
|
+
const id = body.id || randomUUID4();
|
|
3429
3782
|
const config = await store.createConfig(tenantId, id, body);
|
|
3430
3783
|
try {
|
|
3431
3784
|
sqlDatabaseManager.registerDatabase(tenantId, config.key, config.config);
|
|
@@ -3447,11 +3800,11 @@ async function createDatabaseConfig(request, reply) {
|
|
|
3447
3800
|
}
|
|
3448
3801
|
}
|
|
3449
3802
|
async function updateDatabaseConfig(request, reply) {
|
|
3450
|
-
const tenantId =
|
|
3803
|
+
const tenantId = getTenantId9(request);
|
|
3451
3804
|
const { key } = request.params;
|
|
3452
3805
|
const updates = request.body;
|
|
3453
3806
|
try {
|
|
3454
|
-
const storeLattice =
|
|
3807
|
+
const storeLattice = getStoreLattice8("default", "database");
|
|
3455
3808
|
const store = storeLattice.store;
|
|
3456
3809
|
const existing = await store.getConfigByKey(tenantId, key);
|
|
3457
3810
|
if (!existing) {
|
|
@@ -3489,10 +3842,10 @@ async function updateDatabaseConfig(request, reply) {
|
|
|
3489
3842
|
}
|
|
3490
3843
|
}
|
|
3491
3844
|
async function deleteDatabaseConfig(request, reply) {
|
|
3492
|
-
const tenantId =
|
|
3845
|
+
const tenantId = getTenantId9(request);
|
|
3493
3846
|
const { keyOrId } = request.params;
|
|
3494
3847
|
try {
|
|
3495
|
-
const storeLattice =
|
|
3848
|
+
const storeLattice = getStoreLattice8("default", "database");
|
|
3496
3849
|
const store = storeLattice.store;
|
|
3497
3850
|
console.log("Delete request - keyOrId:", keyOrId);
|
|
3498
3851
|
let config = await store.getConfigByKey(tenantId, keyOrId);
|
|
@@ -3538,10 +3891,10 @@ async function deleteDatabaseConfig(request, reply) {
|
|
|
3538
3891
|
}
|
|
3539
3892
|
}
|
|
3540
3893
|
async function testDatabaseConnection(request, reply) {
|
|
3541
|
-
const tenantId =
|
|
3894
|
+
const tenantId = getTenantId9(request);
|
|
3542
3895
|
const { key } = request.params;
|
|
3543
3896
|
try {
|
|
3544
|
-
const storeLattice =
|
|
3897
|
+
const storeLattice = getStoreLattice8("default", "database");
|
|
3545
3898
|
const store = storeLattice.store;
|
|
3546
3899
|
const config = await store.getConfigByKey(tenantId, key);
|
|
3547
3900
|
if (!config) {
|
|
@@ -3626,12 +3979,12 @@ function registerDatabaseConfigRoutes(app2) {
|
|
|
3626
3979
|
|
|
3627
3980
|
// src/controllers/metrics-configs.ts
|
|
3628
3981
|
import {
|
|
3629
|
-
getStoreLattice as
|
|
3982
|
+
getStoreLattice as getStoreLattice9,
|
|
3630
3983
|
metricsServerManager as metricsServerManager2,
|
|
3631
3984
|
SemanticMetricsClient as SemanticMetricsClient2
|
|
3632
3985
|
} from "@axiom-lattice/core";
|
|
3633
|
-
import { randomUUID as
|
|
3634
|
-
function
|
|
3986
|
+
import { randomUUID as randomUUID5 } from "crypto";
|
|
3987
|
+
function getTenantId10(request) {
|
|
3635
3988
|
const userTenantId = request.user?.tenantId;
|
|
3636
3989
|
if (userTenantId) {
|
|
3637
3990
|
return userTenantId;
|
|
@@ -3639,9 +3992,9 @@ function getTenantId8(request) {
|
|
|
3639
3992
|
return request.headers["x-tenant-id"] || "default";
|
|
3640
3993
|
}
|
|
3641
3994
|
async function getMetricsServerConfigList(request, reply) {
|
|
3642
|
-
const tenantId =
|
|
3995
|
+
const tenantId = getTenantId10(request);
|
|
3643
3996
|
try {
|
|
3644
|
-
const storeLattice =
|
|
3997
|
+
const storeLattice = getStoreLattice9("default", "metrics");
|
|
3645
3998
|
const store = storeLattice.store;
|
|
3646
3999
|
const configs = await store.getAllConfigs(tenantId);
|
|
3647
4000
|
return {
|
|
@@ -3665,10 +4018,10 @@ async function getMetricsServerConfigList(request, reply) {
|
|
|
3665
4018
|
}
|
|
3666
4019
|
}
|
|
3667
4020
|
async function getMetricsServerConfig(request, reply) {
|
|
3668
|
-
const tenantId =
|
|
4021
|
+
const tenantId = getTenantId10(request);
|
|
3669
4022
|
const { key } = request.params;
|
|
3670
4023
|
try {
|
|
3671
|
-
const storeLattice =
|
|
4024
|
+
const storeLattice = getStoreLattice9("default", "metrics");
|
|
3672
4025
|
const store = storeLattice.store;
|
|
3673
4026
|
const config = await store.getConfigByKey(tenantId, key);
|
|
3674
4027
|
if (!config) {
|
|
@@ -3691,10 +4044,10 @@ async function getMetricsServerConfig(request, reply) {
|
|
|
3691
4044
|
}
|
|
3692
4045
|
}
|
|
3693
4046
|
async function createMetricsServerConfig(request, reply) {
|
|
3694
|
-
const tenantId =
|
|
4047
|
+
const tenantId = getTenantId10(request);
|
|
3695
4048
|
const body = request.body;
|
|
3696
4049
|
try {
|
|
3697
|
-
const storeLattice =
|
|
4050
|
+
const storeLattice = getStoreLattice9("default", "metrics");
|
|
3698
4051
|
const store = storeLattice.store;
|
|
3699
4052
|
const existing = await store.getConfigByKey(tenantId, body.key);
|
|
3700
4053
|
if (existing) {
|
|
@@ -3711,7 +4064,7 @@ async function createMetricsServerConfig(request, reply) {
|
|
|
3711
4064
|
message: "selectedDataSources is required for semantic metrics servers"
|
|
3712
4065
|
};
|
|
3713
4066
|
}
|
|
3714
|
-
const id = body.id ||
|
|
4067
|
+
const id = body.id || randomUUID5();
|
|
3715
4068
|
const configData = {
|
|
3716
4069
|
key: body.key,
|
|
3717
4070
|
name: body.name,
|
|
@@ -3742,11 +4095,11 @@ async function createMetricsServerConfig(request, reply) {
|
|
|
3742
4095
|
}
|
|
3743
4096
|
}
|
|
3744
4097
|
async function updateMetricsServerConfig(request, reply) {
|
|
3745
|
-
const tenantId =
|
|
4098
|
+
const tenantId = getTenantId10(request);
|
|
3746
4099
|
const { key } = request.params;
|
|
3747
4100
|
const updates = request.body;
|
|
3748
4101
|
try {
|
|
3749
|
-
const storeLattice =
|
|
4102
|
+
const storeLattice = getStoreLattice9("default", "metrics");
|
|
3750
4103
|
const store = storeLattice.store;
|
|
3751
4104
|
const existing = await store.getConfigByKey(tenantId, key);
|
|
3752
4105
|
if (!existing) {
|
|
@@ -3793,10 +4146,10 @@ async function updateMetricsServerConfig(request, reply) {
|
|
|
3793
4146
|
}
|
|
3794
4147
|
}
|
|
3795
4148
|
async function deleteMetricsServerConfig(request, reply) {
|
|
3796
|
-
const tenantId =
|
|
4149
|
+
const tenantId = getTenantId10(request);
|
|
3797
4150
|
const { keyOrId } = request.params;
|
|
3798
4151
|
try {
|
|
3799
|
-
const storeLattice =
|
|
4152
|
+
const storeLattice = getStoreLattice9("default", "metrics");
|
|
3800
4153
|
const store = storeLattice.store;
|
|
3801
4154
|
let config = await store.getConfigByKey(tenantId, keyOrId);
|
|
3802
4155
|
let configKey = keyOrId;
|
|
@@ -3840,10 +4193,10 @@ async function deleteMetricsServerConfig(request, reply) {
|
|
|
3840
4193
|
}
|
|
3841
4194
|
}
|
|
3842
4195
|
async function testMetricsServerConnection(request, reply) {
|
|
3843
|
-
const tenantId =
|
|
4196
|
+
const tenantId = getTenantId10(request);
|
|
3844
4197
|
const { key } = request.params;
|
|
3845
4198
|
try {
|
|
3846
|
-
const storeLattice =
|
|
4199
|
+
const storeLattice = getStoreLattice9("default", "metrics");
|
|
3847
4200
|
const store = storeLattice.store;
|
|
3848
4201
|
const config = await store.getConfigByKey(tenantId, key);
|
|
3849
4202
|
if (!config) {
|
|
@@ -3891,10 +4244,10 @@ async function testMetricsServerConnection(request, reply) {
|
|
|
3891
4244
|
}
|
|
3892
4245
|
}
|
|
3893
4246
|
async function listAvailableMetrics(request, reply) {
|
|
3894
|
-
const tenantId =
|
|
4247
|
+
const tenantId = getTenantId10(request);
|
|
3895
4248
|
const { key } = request.params;
|
|
3896
4249
|
try {
|
|
3897
|
-
const storeLattice =
|
|
4250
|
+
const storeLattice = getStoreLattice9("default", "metrics");
|
|
3898
4251
|
const store = storeLattice.store;
|
|
3899
4252
|
const config = await store.getConfigByKey(tenantId, key);
|
|
3900
4253
|
if (!config) {
|
|
@@ -3929,11 +4282,11 @@ async function listAvailableMetrics(request, reply) {
|
|
|
3929
4282
|
}
|
|
3930
4283
|
}
|
|
3931
4284
|
async function queryMetricsData(request, reply) {
|
|
3932
|
-
const tenantId =
|
|
4285
|
+
const tenantId = getTenantId10(request);
|
|
3933
4286
|
const { key } = request.params;
|
|
3934
4287
|
const { metricName, startTime, endTime, step, labels } = request.body;
|
|
3935
4288
|
try {
|
|
3936
|
-
const storeLattice =
|
|
4289
|
+
const storeLattice = getStoreLattice9("default", "metrics");
|
|
3937
4290
|
const store = storeLattice.store;
|
|
3938
4291
|
const config = await store.getConfigByKey(tenantId, key);
|
|
3939
4292
|
if (!config) {
|
|
@@ -3977,10 +4330,10 @@ async function queryMetricsData(request, reply) {
|
|
|
3977
4330
|
}
|
|
3978
4331
|
}
|
|
3979
4332
|
async function getDataSources(request, reply) {
|
|
3980
|
-
const tenantId =
|
|
4333
|
+
const tenantId = getTenantId10(request);
|
|
3981
4334
|
const { key } = request.params;
|
|
3982
4335
|
try {
|
|
3983
|
-
const storeLattice =
|
|
4336
|
+
const storeLattice = getStoreLattice9("default", "metrics");
|
|
3984
4337
|
const store = storeLattice.store;
|
|
3985
4338
|
const config = await store.getConfigByKey(tenantId, key);
|
|
3986
4339
|
if (!config) {
|
|
@@ -4018,10 +4371,10 @@ async function getDataSources(request, reply) {
|
|
|
4018
4371
|
}
|
|
4019
4372
|
}
|
|
4020
4373
|
async function getDatasourceMetrics(request, reply) {
|
|
4021
|
-
const tenantId =
|
|
4374
|
+
const tenantId = getTenantId10(request);
|
|
4022
4375
|
const { key, datasourceId } = request.params;
|
|
4023
4376
|
try {
|
|
4024
|
-
const storeLattice =
|
|
4377
|
+
const storeLattice = getStoreLattice9("default", "metrics");
|
|
4025
4378
|
const store = storeLattice.store;
|
|
4026
4379
|
const config = await store.getConfigByKey(tenantId, key);
|
|
4027
4380
|
if (!config) {
|
|
@@ -4055,11 +4408,11 @@ async function getDatasourceMetrics(request, reply) {
|
|
|
4055
4408
|
}
|
|
4056
4409
|
}
|
|
4057
4410
|
async function querySemanticMetrics(request, reply) {
|
|
4058
|
-
const tenantId =
|
|
4411
|
+
const tenantId = getTenantId10(request);
|
|
4059
4412
|
const { key } = request.params;
|
|
4060
4413
|
const body = request.body;
|
|
4061
4414
|
try {
|
|
4062
|
-
const storeLattice =
|
|
4415
|
+
const storeLattice = getStoreLattice9("default", "metrics");
|
|
4063
4416
|
const store = storeLattice.store;
|
|
4064
4417
|
const config = await store.getConfigByKey(tenantId, key);
|
|
4065
4418
|
if (!config) {
|
|
@@ -4213,12 +4566,12 @@ function registerMetricsServerConfigRoutes(app2) {
|
|
|
4213
4566
|
|
|
4214
4567
|
// src/controllers/mcp-configs.ts
|
|
4215
4568
|
import {
|
|
4216
|
-
getStoreLattice as
|
|
4569
|
+
getStoreLattice as getStoreLattice10,
|
|
4217
4570
|
mcpManager,
|
|
4218
4571
|
toolLatticeManager as toolLatticeManager2
|
|
4219
4572
|
} from "@axiom-lattice/core";
|
|
4220
|
-
import { randomUUID as
|
|
4221
|
-
function
|
|
4573
|
+
import { randomUUID as randomUUID6 } from "crypto";
|
|
4574
|
+
function getTenantId11(request) {
|
|
4222
4575
|
const userTenantId = request.user?.tenantId;
|
|
4223
4576
|
if (userTenantId) {
|
|
4224
4577
|
return userTenantId;
|
|
@@ -4226,9 +4579,9 @@ function getTenantId9(request) {
|
|
|
4226
4579
|
return request.headers["x-tenant-id"] || "default";
|
|
4227
4580
|
}
|
|
4228
4581
|
async function getMcpServerConfigList(request, reply) {
|
|
4229
|
-
const tenantId =
|
|
4582
|
+
const tenantId = getTenantId11(request);
|
|
4230
4583
|
try {
|
|
4231
|
-
const storeLattice =
|
|
4584
|
+
const storeLattice = getStoreLattice10("default", "mcp");
|
|
4232
4585
|
const store = storeLattice.store;
|
|
4233
4586
|
const configs = await store.getAllConfigs(tenantId);
|
|
4234
4587
|
return {
|
|
@@ -4252,10 +4605,10 @@ async function getMcpServerConfigList(request, reply) {
|
|
|
4252
4605
|
}
|
|
4253
4606
|
}
|
|
4254
4607
|
async function getMcpServerConfig(request, reply) {
|
|
4255
|
-
const tenantId =
|
|
4608
|
+
const tenantId = getTenantId11(request);
|
|
4256
4609
|
const { key } = request.params;
|
|
4257
4610
|
try {
|
|
4258
|
-
const storeLattice =
|
|
4611
|
+
const storeLattice = getStoreLattice10("default", "mcp");
|
|
4259
4612
|
const store = storeLattice.store;
|
|
4260
4613
|
const config = await store.getConfigByKey(tenantId, key);
|
|
4261
4614
|
if (!config) {
|
|
@@ -4278,10 +4631,10 @@ async function getMcpServerConfig(request, reply) {
|
|
|
4278
4631
|
}
|
|
4279
4632
|
}
|
|
4280
4633
|
async function createMcpServerConfig(request, reply) {
|
|
4281
|
-
const tenantId =
|
|
4634
|
+
const tenantId = getTenantId11(request);
|
|
4282
4635
|
const body = request.body;
|
|
4283
4636
|
try {
|
|
4284
|
-
const storeLattice =
|
|
4637
|
+
const storeLattice = getStoreLattice10("default", "mcp");
|
|
4285
4638
|
const store = storeLattice.store;
|
|
4286
4639
|
const existing = await store.getConfigByKey(tenantId, body.key);
|
|
4287
4640
|
if (existing) {
|
|
@@ -4291,7 +4644,7 @@ async function createMcpServerConfig(request, reply) {
|
|
|
4291
4644
|
message: "MCP server configuration with this key already exists"
|
|
4292
4645
|
};
|
|
4293
4646
|
}
|
|
4294
|
-
const id = body.id ||
|
|
4647
|
+
const id = body.id || randomUUID6();
|
|
4295
4648
|
const config = await store.createConfig(tenantId, id, body);
|
|
4296
4649
|
try {
|
|
4297
4650
|
await connectAndRegisterTools(config);
|
|
@@ -4317,11 +4670,11 @@ async function createMcpServerConfig(request, reply) {
|
|
|
4317
4670
|
}
|
|
4318
4671
|
}
|
|
4319
4672
|
async function updateMcpServerConfig(request, reply) {
|
|
4320
|
-
const tenantId =
|
|
4673
|
+
const tenantId = getTenantId11(request);
|
|
4321
4674
|
const { key } = request.params;
|
|
4322
4675
|
const updates = request.body;
|
|
4323
4676
|
try {
|
|
4324
|
-
const storeLattice =
|
|
4677
|
+
const storeLattice = getStoreLattice10("default", "mcp");
|
|
4325
4678
|
const store = storeLattice.store;
|
|
4326
4679
|
const existing = await store.getConfigByKey(tenantId, key);
|
|
4327
4680
|
if (!existing) {
|
|
@@ -4367,10 +4720,10 @@ async function updateMcpServerConfig(request, reply) {
|
|
|
4367
4720
|
}
|
|
4368
4721
|
}
|
|
4369
4722
|
async function deleteMcpServerConfig(request, reply) {
|
|
4370
|
-
const tenantId =
|
|
4723
|
+
const tenantId = getTenantId11(request);
|
|
4371
4724
|
const { keyOrId } = request.params;
|
|
4372
4725
|
try {
|
|
4373
|
-
const storeLattice =
|
|
4726
|
+
const storeLattice = getStoreLattice10("default", "mcp");
|
|
4374
4727
|
const store = storeLattice.store;
|
|
4375
4728
|
let config = await store.getConfigByKey(tenantId, keyOrId);
|
|
4376
4729
|
let configKey = keyOrId;
|
|
@@ -4414,10 +4767,10 @@ async function deleteMcpServerConfig(request, reply) {
|
|
|
4414
4767
|
}
|
|
4415
4768
|
}
|
|
4416
4769
|
async function testMcpServerConnection(request, reply) {
|
|
4417
|
-
const tenantId =
|
|
4770
|
+
const tenantId = getTenantId11(request);
|
|
4418
4771
|
const { key } = request.params;
|
|
4419
4772
|
try {
|
|
4420
|
-
const storeLattice =
|
|
4773
|
+
const storeLattice = getStoreLattice10("default", "mcp");
|
|
4421
4774
|
const store = storeLattice.store;
|
|
4422
4775
|
const config = await store.getConfigByKey(tenantId, key);
|
|
4423
4776
|
if (!config) {
|
|
@@ -4467,10 +4820,10 @@ async function testMcpServerConnection(request, reply) {
|
|
|
4467
4820
|
}
|
|
4468
4821
|
}
|
|
4469
4822
|
async function listMcpServerTools(request, reply) {
|
|
4470
|
-
const tenantId =
|
|
4823
|
+
const tenantId = getTenantId11(request);
|
|
4471
4824
|
const { key } = request.params;
|
|
4472
4825
|
try {
|
|
4473
|
-
const storeLattice =
|
|
4826
|
+
const storeLattice = getStoreLattice10("default", "mcp");
|
|
4474
4827
|
const store = storeLattice.store;
|
|
4475
4828
|
const config = await store.getConfigByKey(tenantId, key);
|
|
4476
4829
|
if (!config) {
|
|
@@ -4500,10 +4853,10 @@ async function listMcpServerTools(request, reply) {
|
|
|
4500
4853
|
}
|
|
4501
4854
|
}
|
|
4502
4855
|
async function connectMcpServer(request, reply) {
|
|
4503
|
-
const tenantId =
|
|
4856
|
+
const tenantId = getTenantId11(request);
|
|
4504
4857
|
const { key } = request.params;
|
|
4505
4858
|
try {
|
|
4506
|
-
const storeLattice =
|
|
4859
|
+
const storeLattice = getStoreLattice10("default", "mcp");
|
|
4507
4860
|
const store = storeLattice.store;
|
|
4508
4861
|
const config = await store.getConfigByKey(tenantId, key);
|
|
4509
4862
|
if (!config) {
|
|
@@ -4524,7 +4877,7 @@ async function connectMcpServer(request, reply) {
|
|
|
4524
4877
|
};
|
|
4525
4878
|
} catch (error) {
|
|
4526
4879
|
console.error("Failed to connect MCP server:", error);
|
|
4527
|
-
const storeLattice =
|
|
4880
|
+
const storeLattice = getStoreLattice10("default", "mcp");
|
|
4528
4881
|
const store = storeLattice.store;
|
|
4529
4882
|
const config = await store.getConfigByKey(tenantId, key);
|
|
4530
4883
|
if (config) {
|
|
@@ -4537,10 +4890,10 @@ async function connectMcpServer(request, reply) {
|
|
|
4537
4890
|
}
|
|
4538
4891
|
}
|
|
4539
4892
|
async function disconnectMcpServer(request, reply) {
|
|
4540
|
-
const tenantId =
|
|
4893
|
+
const tenantId = getTenantId11(request);
|
|
4541
4894
|
const { key } = request.params;
|
|
4542
4895
|
try {
|
|
4543
|
-
const storeLattice =
|
|
4896
|
+
const storeLattice = getStoreLattice10("default", "mcp");
|
|
4544
4897
|
const store = storeLattice.store;
|
|
4545
4898
|
const config = await store.getConfigByKey(tenantId, key);
|
|
4546
4899
|
if (!config) {
|
|
@@ -4645,12 +4998,12 @@ function registerMcpServerConfigRoutes(app2) {
|
|
|
4645
4998
|
}
|
|
4646
4999
|
|
|
4647
5000
|
// src/controllers/eval.ts
|
|
4648
|
-
import { getStoreLattice as
|
|
5001
|
+
import { getStoreLattice as getStoreLattice12 } from "@axiom-lattice/core";
|
|
4649
5002
|
import { v4 as uuidv43 } from "uuid";
|
|
4650
5003
|
|
|
4651
5004
|
// src/services/eval-runner.ts
|
|
4652
5005
|
import { EventEmitter } from "events";
|
|
4653
|
-
import { getStoreLattice as
|
|
5006
|
+
import { getStoreLattice as getStoreLattice11, modelLatticeManager as modelLatticeManager2 } from "@axiom-lattice/core";
|
|
4654
5007
|
import { LatticeEvalProject } from "@axiom-lattice/agent-eval";
|
|
4655
5008
|
import { v4 as uuidv42 } from "uuid";
|
|
4656
5009
|
function mapLogs(logs) {
|
|
@@ -4823,13 +5176,13 @@ var EvalRunner = class {
|
|
|
4823
5176
|
return this.runs.has(runId);
|
|
4824
5177
|
}
|
|
4825
5178
|
getEvalStore() {
|
|
4826
|
-
return
|
|
5179
|
+
return getStoreLattice11("default", "eval").store;
|
|
4827
5180
|
}
|
|
4828
5181
|
};
|
|
4829
5182
|
var evalRunner = new EvalRunner();
|
|
4830
5183
|
|
|
4831
5184
|
// src/controllers/eval.ts
|
|
4832
|
-
function
|
|
5185
|
+
function getTenantId12(request) {
|
|
4833
5186
|
const userTenantId = request.user?.tenantId;
|
|
4834
5187
|
if (userTenantId) {
|
|
4835
5188
|
return userTenantId;
|
|
@@ -4837,11 +5190,11 @@ function getTenantId10(request) {
|
|
|
4837
5190
|
return request.headers["x-tenant-id"] || "default";
|
|
4838
5191
|
}
|
|
4839
5192
|
function getEvalStore() {
|
|
4840
|
-
return
|
|
5193
|
+
return getStoreLattice12("default", "eval").store;
|
|
4841
5194
|
}
|
|
4842
5195
|
async function createProject(request, reply) {
|
|
4843
5196
|
try {
|
|
4844
|
-
const tenantId =
|
|
5197
|
+
const tenantId = getTenantId12(request);
|
|
4845
5198
|
const store = getEvalStore();
|
|
4846
5199
|
const id = uuidv43();
|
|
4847
5200
|
const data = request.body;
|
|
@@ -4866,7 +5219,7 @@ async function createProject(request, reply) {
|
|
|
4866
5219
|
}
|
|
4867
5220
|
async function listProjects(request, reply) {
|
|
4868
5221
|
try {
|
|
4869
|
-
const tenantId =
|
|
5222
|
+
const tenantId = getTenantId12(request);
|
|
4870
5223
|
const store = getEvalStore();
|
|
4871
5224
|
let projects = await store.getProjectsByTenant(tenantId);
|
|
4872
5225
|
if (projects.length === 0) {
|
|
@@ -4900,7 +5253,7 @@ async function listProjects(request, reply) {
|
|
|
4900
5253
|
}
|
|
4901
5254
|
async function getProject(request, reply) {
|
|
4902
5255
|
try {
|
|
4903
|
-
const tenantId =
|
|
5256
|
+
const tenantId = getTenantId12(request);
|
|
4904
5257
|
const store = getEvalStore();
|
|
4905
5258
|
const { pid } = request.params;
|
|
4906
5259
|
const project = await store.getProjectById(tenantId, pid);
|
|
@@ -4920,7 +5273,7 @@ async function getProject(request, reply) {
|
|
|
4920
5273
|
}
|
|
4921
5274
|
async function updateProject(request, reply) {
|
|
4922
5275
|
try {
|
|
4923
|
-
const tenantId =
|
|
5276
|
+
const tenantId = getTenantId12(request);
|
|
4924
5277
|
const store = getEvalStore();
|
|
4925
5278
|
const { pid } = request.params;
|
|
4926
5279
|
const existing = await store.getProjectById(tenantId, pid);
|
|
@@ -4940,7 +5293,7 @@ async function updateProject(request, reply) {
|
|
|
4940
5293
|
}
|
|
4941
5294
|
async function deleteProject(request, reply) {
|
|
4942
5295
|
try {
|
|
4943
|
-
const tenantId =
|
|
5296
|
+
const tenantId = getTenantId12(request);
|
|
4944
5297
|
const store = getEvalStore();
|
|
4945
5298
|
const { pid } = request.params;
|
|
4946
5299
|
const existing = await store.getProjectById(tenantId, pid);
|
|
@@ -4959,7 +5312,7 @@ async function deleteProject(request, reply) {
|
|
|
4959
5312
|
}
|
|
4960
5313
|
async function createSuite(request, reply) {
|
|
4961
5314
|
try {
|
|
4962
|
-
const tenantId =
|
|
5315
|
+
const tenantId = getTenantId12(request);
|
|
4963
5316
|
const store = getEvalStore();
|
|
4964
5317
|
const { pid } = request.params;
|
|
4965
5318
|
const project = await store.getProjectById(tenantId, pid);
|
|
@@ -4981,7 +5334,7 @@ async function createSuite(request, reply) {
|
|
|
4981
5334
|
}
|
|
4982
5335
|
async function updateSuite(request, reply) {
|
|
4983
5336
|
try {
|
|
4984
|
-
const tenantId =
|
|
5337
|
+
const tenantId = getTenantId12(request);
|
|
4985
5338
|
const store = getEvalStore();
|
|
4986
5339
|
const { sid } = request.params;
|
|
4987
5340
|
const existing = await store.getSuiteById(tenantId, sid);
|
|
@@ -5001,7 +5354,7 @@ async function updateSuite(request, reply) {
|
|
|
5001
5354
|
}
|
|
5002
5355
|
async function deleteSuite(request, reply) {
|
|
5003
5356
|
try {
|
|
5004
|
-
const tenantId =
|
|
5357
|
+
const tenantId = getTenantId12(request);
|
|
5005
5358
|
const store = getEvalStore();
|
|
5006
5359
|
const { sid } = request.params;
|
|
5007
5360
|
const existing = await store.getSuiteById(tenantId, sid);
|
|
@@ -5020,7 +5373,7 @@ async function deleteSuite(request, reply) {
|
|
|
5020
5373
|
}
|
|
5021
5374
|
async function createCase(request, reply) {
|
|
5022
5375
|
try {
|
|
5023
|
-
const tenantId =
|
|
5376
|
+
const tenantId = getTenantId12(request);
|
|
5024
5377
|
const store = getEvalStore();
|
|
5025
5378
|
const { sid } = request.params;
|
|
5026
5379
|
const suite = await store.getSuiteById(tenantId, sid);
|
|
@@ -5049,7 +5402,7 @@ async function createCase(request, reply) {
|
|
|
5049
5402
|
}
|
|
5050
5403
|
async function listCasesForSuite(request, reply) {
|
|
5051
5404
|
try {
|
|
5052
|
-
const tenantId =
|
|
5405
|
+
const tenantId = getTenantId12(request);
|
|
5053
5406
|
const store = getEvalStore();
|
|
5054
5407
|
const { sid } = request.params;
|
|
5055
5408
|
const cases = await store.getCasesBySuite(tenantId, sid);
|
|
@@ -5065,7 +5418,7 @@ async function listCasesForSuite(request, reply) {
|
|
|
5065
5418
|
}
|
|
5066
5419
|
async function updateCase(request, reply) {
|
|
5067
5420
|
try {
|
|
5068
|
-
const tenantId =
|
|
5421
|
+
const tenantId = getTenantId12(request);
|
|
5069
5422
|
const store = getEvalStore();
|
|
5070
5423
|
const { cid } = request.params;
|
|
5071
5424
|
const existing = await store.getCaseById(tenantId, cid);
|
|
@@ -5085,7 +5438,7 @@ async function updateCase(request, reply) {
|
|
|
5085
5438
|
}
|
|
5086
5439
|
async function deleteCase(request, reply) {
|
|
5087
5440
|
try {
|
|
5088
|
-
const tenantId =
|
|
5441
|
+
const tenantId = getTenantId12(request);
|
|
5089
5442
|
const store = getEvalStore();
|
|
5090
5443
|
const { cid } = request.params;
|
|
5091
5444
|
const existing = await store.getCaseById(tenantId, cid);
|
|
@@ -5117,7 +5470,7 @@ function registerEvalRoutes(app2) {
|
|
|
5117
5470
|
app2.delete("/api/eval/projects/:pid/suites/:sid/cases/:cid", deleteCase);
|
|
5118
5471
|
app2.post("/api/eval/projects/:pid/runs", async (request, reply) => {
|
|
5119
5472
|
try {
|
|
5120
|
-
const tenantId =
|
|
5473
|
+
const tenantId = getTenantId12(request);
|
|
5121
5474
|
const { pid } = request.params;
|
|
5122
5475
|
const runId = await evalRunner.startRun(tenantId, pid);
|
|
5123
5476
|
reply.status(202).send({ success: true, message: "Run started", data: { run_id: runId } });
|
|
@@ -5129,7 +5482,7 @@ function registerEvalRoutes(app2) {
|
|
|
5129
5482
|
});
|
|
5130
5483
|
app2.get("/api/eval/runs", async (request, reply) => {
|
|
5131
5484
|
try {
|
|
5132
|
-
const tenantId =
|
|
5485
|
+
const tenantId = getTenantId12(request);
|
|
5133
5486
|
const query = request.query;
|
|
5134
5487
|
const runs = await getEvalStore().getRunsByTenant(tenantId, { projectId: query.project_id, status: query.status });
|
|
5135
5488
|
reply.send({ success: true, message: "Ok", data: { records: runs, total: runs.length } });
|
|
@@ -5139,7 +5492,7 @@ function registerEvalRoutes(app2) {
|
|
|
5139
5492
|
});
|
|
5140
5493
|
app2.get("/api/eval/runs/:rid", async (request, reply) => {
|
|
5141
5494
|
try {
|
|
5142
|
-
const tenantId =
|
|
5495
|
+
const tenantId = getTenantId12(request);
|
|
5143
5496
|
const { rid } = request.params;
|
|
5144
5497
|
const run = await getEvalStore().getRunById(tenantId, rid);
|
|
5145
5498
|
if (!run) return reply.status(404).send({ success: false, message: "Run not found" });
|
|
@@ -5161,7 +5514,7 @@ function registerEvalRoutes(app2) {
|
|
|
5161
5514
|
const emitter = evalRunner.getEventEmitter();
|
|
5162
5515
|
const eventKey = `run:${rid}`;
|
|
5163
5516
|
if (!evalRunner.isRunning(rid)) {
|
|
5164
|
-
const tenantId =
|
|
5517
|
+
const tenantId = getTenantId12(request);
|
|
5165
5518
|
const run = await getEvalStore().getRunById(tenantId, rid);
|
|
5166
5519
|
if (run) {
|
|
5167
5520
|
const eventType = run.status === "completed" ? "completed" : "error";
|
|
@@ -5200,7 +5553,7 @@ data: ${JSON.stringify(event.data)}
|
|
|
5200
5553
|
});
|
|
5201
5554
|
app2.delete("/api/eval/runs/:rid", async (request, reply) => {
|
|
5202
5555
|
try {
|
|
5203
|
-
const tenantId =
|
|
5556
|
+
const tenantId = getTenantId12(request);
|
|
5204
5557
|
const { rid } = request.params;
|
|
5205
5558
|
const deleted = await getEvalStore().deleteRun(tenantId, rid);
|
|
5206
5559
|
if (!deleted) return reply.status(404).send({ success: false, message: "Run not found" });
|
|
@@ -5211,7 +5564,7 @@ data: ${JSON.stringify(event.data)}
|
|
|
5211
5564
|
});
|
|
5212
5565
|
app2.get("/api/eval/reports/projects/:pid", async (request, reply) => {
|
|
5213
5566
|
try {
|
|
5214
|
-
const tenantId =
|
|
5567
|
+
const tenantId = getTenantId12(request);
|
|
5215
5568
|
const { pid } = request.params;
|
|
5216
5569
|
const report = await getEvalStore().getProjectReport(tenantId, pid);
|
|
5217
5570
|
if (!report) return reply.status(404).send({ success: false, message: "Project not found" });
|
|
@@ -5223,11 +5576,11 @@ data: ${JSON.stringify(event.data)}
|
|
|
5223
5576
|
}
|
|
5224
5577
|
|
|
5225
5578
|
// src/controllers/users.ts
|
|
5226
|
-
import { getStoreLattice as
|
|
5579
|
+
import { getStoreLattice as getStoreLattice13 } from "@axiom-lattice/core";
|
|
5227
5580
|
import { v4 as uuidv44 } from "uuid";
|
|
5228
5581
|
var UsersController = class {
|
|
5229
5582
|
constructor() {
|
|
5230
|
-
this.userStore =
|
|
5583
|
+
this.userStore = getStoreLattice13("default", "user").store;
|
|
5231
5584
|
}
|
|
5232
5585
|
async listUsers(request, reply) {
|
|
5233
5586
|
const { email } = request.query;
|
|
@@ -5305,11 +5658,11 @@ function registerUserRoutes(app2) {
|
|
|
5305
5658
|
}
|
|
5306
5659
|
|
|
5307
5660
|
// src/controllers/tenants.ts
|
|
5308
|
-
import { getStoreLattice as
|
|
5661
|
+
import { getStoreLattice as getStoreLattice14 } from "@axiom-lattice/core";
|
|
5309
5662
|
import { v4 as uuidv45 } from "uuid";
|
|
5310
5663
|
var TenantsController = class {
|
|
5311
5664
|
constructor() {
|
|
5312
|
-
this.tenantStore =
|
|
5665
|
+
this.tenantStore = getStoreLattice14("default", "tenant").store;
|
|
5313
5666
|
}
|
|
5314
5667
|
// ==================== Tenant CRUD ====================
|
|
5315
5668
|
async listTenants(request, reply) {
|
|
@@ -5373,7 +5726,7 @@ function registerTenantRoutes(app2) {
|
|
|
5373
5726
|
}
|
|
5374
5727
|
|
|
5375
5728
|
// src/controllers/auth.ts
|
|
5376
|
-
import { getStoreLattice as
|
|
5729
|
+
import { getStoreLattice as getStoreLattice15 } from "@axiom-lattice/core";
|
|
5377
5730
|
import { v4 as uuidv46 } from "uuid";
|
|
5378
5731
|
var defaultAuthConfig = {
|
|
5379
5732
|
autoApproveUsers: true,
|
|
@@ -5382,9 +5735,9 @@ var defaultAuthConfig = {
|
|
|
5382
5735
|
};
|
|
5383
5736
|
var AuthController = class {
|
|
5384
5737
|
constructor(config = {}) {
|
|
5385
|
-
this.userStore =
|
|
5386
|
-
this.tenantStore =
|
|
5387
|
-
this.userTenantLinkStore =
|
|
5738
|
+
this.userStore = getStoreLattice15("default", "user").store;
|
|
5739
|
+
this.tenantStore = getStoreLattice15("default", "tenant").store;
|
|
5740
|
+
this.userTenantLinkStore = getStoreLattice15("default", "userTenantLink").store;
|
|
5388
5741
|
this.config = { ...defaultAuthConfig, ...config };
|
|
5389
5742
|
}
|
|
5390
5743
|
async register(request, reply) {
|
|
@@ -5538,6 +5891,8 @@ var AuthController = class {
|
|
|
5538
5891
|
});
|
|
5539
5892
|
}
|
|
5540
5893
|
const token = await this.generateToken(userId, tenantId);
|
|
5894
|
+
const link = await this.userTenantLinkStore.getLink(userId, tenantId);
|
|
5895
|
+
const linkMeta = link?.metadata || {};
|
|
5541
5896
|
return {
|
|
5542
5897
|
success: true,
|
|
5543
5898
|
data: {
|
|
@@ -5546,7 +5901,12 @@ var AuthController = class {
|
|
|
5546
5901
|
name: tenant.name,
|
|
5547
5902
|
status: tenant.status
|
|
5548
5903
|
},
|
|
5549
|
-
token
|
|
5904
|
+
token,
|
|
5905
|
+
personalAssistant: linkMeta.personalAssistantId ? {
|
|
5906
|
+
assistantId: linkMeta.personalAssistantId,
|
|
5907
|
+
projectId: linkMeta.personalProjectId || "default",
|
|
5908
|
+
workspaceId: linkMeta.personalWorkspaceId || "default"
|
|
5909
|
+
} : null
|
|
5550
5910
|
}
|
|
5551
5911
|
};
|
|
5552
5912
|
} catch (error) {
|
|
@@ -5792,82 +6152,6 @@ function normalizeChatType(chatType) {
|
|
|
5792
6152
|
return chatType === "p2p" ? "direct" : "group";
|
|
5793
6153
|
}
|
|
5794
6154
|
|
|
5795
|
-
// src/channels/lark/LarkChannelAdapter.ts
|
|
5796
|
-
var larkConfigSchema = z.object({
|
|
5797
|
-
appId: z.string(),
|
|
5798
|
-
appSecret: z.string(),
|
|
5799
|
-
verificationToken: z.string().optional(),
|
|
5800
|
-
encryptKey: z.string().optional()
|
|
5801
|
-
});
|
|
5802
|
-
var larkChannelAdapter = {
|
|
5803
|
-
channel: "lark",
|
|
5804
|
-
configSchema: larkConfigSchema,
|
|
5805
|
-
async receive(rawPayload, installation) {
|
|
5806
|
-
const event = parseLarkMessageEvent(rawPayload);
|
|
5807
|
-
if (!event) return null;
|
|
5808
|
-
return {
|
|
5809
|
-
channel: "lark",
|
|
5810
|
-
channelInstallationId: installation.id,
|
|
5811
|
-
tenantId: installation.tenantId,
|
|
5812
|
-
sender: {
|
|
5813
|
-
id: event.openId,
|
|
5814
|
-
displayName: void 0
|
|
5815
|
-
},
|
|
5816
|
-
content: {
|
|
5817
|
-
text: event.text,
|
|
5818
|
-
metadata: {
|
|
5819
|
-
chatId: event.chatId,
|
|
5820
|
-
chatType: event.chatType,
|
|
5821
|
-
messageId: event.messageId
|
|
5822
|
-
}
|
|
5823
|
-
},
|
|
5824
|
-
conversation: {
|
|
5825
|
-
id: event.chatId,
|
|
5826
|
-
type: event.chatType
|
|
5827
|
-
},
|
|
5828
|
-
replyTarget: {
|
|
5829
|
-
adapterChannel: "lark",
|
|
5830
|
-
channelInstallationId: installation.id,
|
|
5831
|
-
rawTarget: {
|
|
5832
|
-
chatId: event.chatId,
|
|
5833
|
-
messageId: event.messageId,
|
|
5834
|
-
chatType: event.chatType
|
|
5835
|
-
}
|
|
5836
|
-
}
|
|
5837
|
-
};
|
|
5838
|
-
},
|
|
5839
|
-
async sendReply(replyTarget, message, installation) {
|
|
5840
|
-
const { createLarkSender } = await import("./sender-PX32VSHB.mjs");
|
|
5841
|
-
const sender = await createLarkSender(installation.config);
|
|
5842
|
-
await sender.sendTextReply({
|
|
5843
|
-
chatId: replyTarget.rawTarget.chatId,
|
|
5844
|
-
text: message.text
|
|
5845
|
-
});
|
|
5846
|
-
}
|
|
5847
|
-
};
|
|
5848
|
-
|
|
5849
|
-
// src/channels/lark/verification.ts
|
|
5850
|
-
import crypto2 from "crypto";
|
|
5851
|
-
function parseLarkRequestBody(body, encryptKey) {
|
|
5852
|
-
const parsed = body || {};
|
|
5853
|
-
if (encryptKey && typeof parsed.encrypt === "string") {
|
|
5854
|
-
return decryptLarkPayload(encryptKey, parsed.encrypt);
|
|
5855
|
-
}
|
|
5856
|
-
return parsed;
|
|
5857
|
-
}
|
|
5858
|
-
function decryptLarkPayload(encryptKey, encryptedPayload) {
|
|
5859
|
-
const key = crypto2.createHash("sha256").update(encryptKey).digest();
|
|
5860
|
-
const buffer = Buffer.from(encryptedPayload, "base64");
|
|
5861
|
-
const iv = buffer.subarray(0, 16);
|
|
5862
|
-
const ciphertext = buffer.subarray(16);
|
|
5863
|
-
const decipher = crypto2.createDecipheriv("aes-256-cbc", key, iv);
|
|
5864
|
-
const plaintext = Buffer.concat([
|
|
5865
|
-
decipher.update(ciphertext),
|
|
5866
|
-
decipher.final()
|
|
5867
|
-
]).toString("utf8");
|
|
5868
|
-
return JSON.parse(plaintext);
|
|
5869
|
-
}
|
|
5870
|
-
|
|
5871
6155
|
// src/logger/Logger.ts
|
|
5872
6156
|
import pino from "pino";
|
|
5873
6157
|
import "pino-pretty";
|
|
@@ -6006,8 +6290,165 @@ var Logger = class _Logger {
|
|
|
6006
6290
|
}
|
|
6007
6291
|
};
|
|
6008
6292
|
|
|
6009
|
-
// src/channels/lark/
|
|
6293
|
+
// src/channels/lark/LarkChannelAdapter.ts
|
|
6294
|
+
import * as Lark from "@larksuiteoapi/node-sdk";
|
|
6010
6295
|
var logger = new Logger({ serviceName: "lattice/gateway/lark" });
|
|
6296
|
+
var activeConnections = /* @__PURE__ */ new Map();
|
|
6297
|
+
function parseTextContent(content) {
|
|
6298
|
+
if (!content) return null;
|
|
6299
|
+
try {
|
|
6300
|
+
const parsed = JSON.parse(content);
|
|
6301
|
+
return typeof parsed.text === "string" ? parsed.text : null;
|
|
6302
|
+
} catch {
|
|
6303
|
+
return null;
|
|
6304
|
+
}
|
|
6305
|
+
}
|
|
6306
|
+
function normalizeChatType2(chatType) {
|
|
6307
|
+
return chatType === "p2p" ? "direct" : "group";
|
|
6308
|
+
}
|
|
6309
|
+
function wsEventToInbound(event, installationId, tenantId) {
|
|
6310
|
+
const messageId = event.message?.message_id;
|
|
6311
|
+
const chatId = event.message?.chat_id;
|
|
6312
|
+
const openId = event.sender?.sender_id?.open_id;
|
|
6313
|
+
if (!messageId || !chatId || !openId) return null;
|
|
6314
|
+
if (event.message?.message_type !== "text") return null;
|
|
6315
|
+
const text = parseTextContent(event.message.content);
|
|
6316
|
+
if (!text) return null;
|
|
6317
|
+
const chatType = normalizeChatType2(event.message.chat_type);
|
|
6318
|
+
return {
|
|
6319
|
+
channel: "lark",
|
|
6320
|
+
channelInstallationId: installationId,
|
|
6321
|
+
tenantId,
|
|
6322
|
+
sender: { id: openId, displayName: void 0 },
|
|
6323
|
+
content: { text, metadata: { chatId, chatType, messageId } },
|
|
6324
|
+
conversation: { id: chatId, type: chatType },
|
|
6325
|
+
replyTarget: {
|
|
6326
|
+
adapterChannel: "lark",
|
|
6327
|
+
channelInstallationId: installationId,
|
|
6328
|
+
rawTarget: { chatId, messageId, chatType }
|
|
6329
|
+
}
|
|
6330
|
+
};
|
|
6331
|
+
}
|
|
6332
|
+
var larkConfigSchema = z.object({
|
|
6333
|
+
appId: z.string(),
|
|
6334
|
+
appSecret: z.string(),
|
|
6335
|
+
verificationToken: z.string().optional(),
|
|
6336
|
+
encryptKey: z.string().optional()
|
|
6337
|
+
});
|
|
6338
|
+
var larkChannelAdapter = {
|
|
6339
|
+
channel: "lark",
|
|
6340
|
+
configSchema: larkConfigSchema,
|
|
6341
|
+
async receive(rawPayload, installation) {
|
|
6342
|
+
const event = parseLarkMessageEvent(rawPayload);
|
|
6343
|
+
if (!event) return null;
|
|
6344
|
+
return {
|
|
6345
|
+
channel: "lark",
|
|
6346
|
+
channelInstallationId: installation.id,
|
|
6347
|
+
tenantId: installation.tenantId,
|
|
6348
|
+
sender: { id: event.openId, displayName: void 0 },
|
|
6349
|
+
content: {
|
|
6350
|
+
text: event.text,
|
|
6351
|
+
metadata: { chatId: event.chatId, chatType: event.chatType, messageId: event.messageId }
|
|
6352
|
+
},
|
|
6353
|
+
conversation: { id: event.chatId, type: event.chatType },
|
|
6354
|
+
replyTarget: {
|
|
6355
|
+
adapterChannel: "lark",
|
|
6356
|
+
channelInstallationId: installation.id,
|
|
6357
|
+
rawTarget: { chatId: event.chatId, messageId: event.messageId, chatType: event.chatType }
|
|
6358
|
+
}
|
|
6359
|
+
};
|
|
6360
|
+
},
|
|
6361
|
+
async sendReply(replyTarget, message, installation) {
|
|
6362
|
+
const { createLarkSender } = await import("./sender-PX32VSHB.mjs");
|
|
6363
|
+
const sender = await createLarkSender(installation.config);
|
|
6364
|
+
await sender.sendTextReply({
|
|
6365
|
+
chatId: replyTarget.rawTarget.chatId,
|
|
6366
|
+
text: message.text
|
|
6367
|
+
});
|
|
6368
|
+
},
|
|
6369
|
+
resolveThreadId(message, binding) {
|
|
6370
|
+
const date = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
6371
|
+
const chatType = message.conversation?.type === "direct" ? "dm" : "group";
|
|
6372
|
+
const agentId = binding.agentId;
|
|
6373
|
+
if (chatType === "dm") {
|
|
6374
|
+
return `lark:dm:${message.sender.id}:${agentId}:${date}`;
|
|
6375
|
+
}
|
|
6376
|
+
return `lark:group:${message.conversation?.id ?? "unknown"}:${agentId}:${date}`;
|
|
6377
|
+
},
|
|
6378
|
+
async connect(installation, deps) {
|
|
6379
|
+
const { id: installationId, tenantId, config } = installation;
|
|
6380
|
+
if (!config.appId || !config.appSecret) {
|
|
6381
|
+
logger.warn("Lark installation missing credentials, skipping", { installationId });
|
|
6382
|
+
return;
|
|
6383
|
+
}
|
|
6384
|
+
if (activeConnections.has(installationId)) {
|
|
6385
|
+
logger.warn("Lark WS already connected for installation, skipping", { installationId });
|
|
6386
|
+
return;
|
|
6387
|
+
}
|
|
6388
|
+
logger.info("Lark WS client starting", { installationId, tenantId });
|
|
6389
|
+
const router = deps?.router;
|
|
6390
|
+
const eventDispatcher = new Lark.EventDispatcher({}).register({
|
|
6391
|
+
"im.message.receive_v1": async (data) => {
|
|
6392
|
+
try {
|
|
6393
|
+
const inbound = wsEventToInbound(data, installationId, tenantId);
|
|
6394
|
+
if (!inbound) return;
|
|
6395
|
+
logger.info("Lark WS message received", {
|
|
6396
|
+
installationId,
|
|
6397
|
+
senderId: inbound.sender.id,
|
|
6398
|
+
chatId: data.message?.chat_id
|
|
6399
|
+
});
|
|
6400
|
+
if (router) {
|
|
6401
|
+
const result = await router.dispatch(inbound);
|
|
6402
|
+
if (!result.success) {
|
|
6403
|
+
logger.warn("Lark WS dispatch failed", {
|
|
6404
|
+
installationId,
|
|
6405
|
+
error: result.error?.message
|
|
6406
|
+
});
|
|
6407
|
+
}
|
|
6408
|
+
}
|
|
6409
|
+
} catch (err) {
|
|
6410
|
+
logger.error("Lark WS event handler error", {
|
|
6411
|
+
installationId,
|
|
6412
|
+
error: err instanceof Error ? err.message : String(err)
|
|
6413
|
+
});
|
|
6414
|
+
}
|
|
6415
|
+
}
|
|
6416
|
+
});
|
|
6417
|
+
const client = new Lark.WSClient({
|
|
6418
|
+
appId: config.appId,
|
|
6419
|
+
appSecret: config.appSecret,
|
|
6420
|
+
loggerLevel: Lark.LoggerLevel.info
|
|
6421
|
+
});
|
|
6422
|
+
await client.start({ eventDispatcher });
|
|
6423
|
+
activeConnections.set(installationId, client);
|
|
6424
|
+
logger.info("Lark WS client connected", { installationId });
|
|
6425
|
+
}
|
|
6426
|
+
};
|
|
6427
|
+
|
|
6428
|
+
// src/channels/lark/verification.ts
|
|
6429
|
+
import crypto2 from "crypto";
|
|
6430
|
+
function parseLarkRequestBody(body, encryptKey) {
|
|
6431
|
+
const parsed = body || {};
|
|
6432
|
+
if (encryptKey && typeof parsed.encrypt === "string") {
|
|
6433
|
+
return decryptLarkPayload(encryptKey, parsed.encrypt);
|
|
6434
|
+
}
|
|
6435
|
+
return parsed;
|
|
6436
|
+
}
|
|
6437
|
+
function decryptLarkPayload(encryptKey, encryptedPayload) {
|
|
6438
|
+
const key = crypto2.createHash("sha256").update(encryptKey).digest();
|
|
6439
|
+
const buffer = Buffer.from(encryptedPayload, "base64");
|
|
6440
|
+
const iv = buffer.subarray(0, 16);
|
|
6441
|
+
const ciphertext = buffer.subarray(16);
|
|
6442
|
+
const decipher = crypto2.createDecipheriv("aes-256-cbc", key, iv);
|
|
6443
|
+
const plaintext = Buffer.concat([
|
|
6444
|
+
decipher.update(ciphertext),
|
|
6445
|
+
decipher.final()
|
|
6446
|
+
]).toString("utf8");
|
|
6447
|
+
return JSON.parse(plaintext);
|
|
6448
|
+
}
|
|
6449
|
+
|
|
6450
|
+
// src/channels/lark/controller.ts
|
|
6451
|
+
var logger2 = new Logger({ serviceName: "lattice/gateway/lark" });
|
|
6011
6452
|
function createLarkEventHandler(deps) {
|
|
6012
6453
|
return async function handleLarkEvent(request, reply) {
|
|
6013
6454
|
const { installationId } = request.params;
|
|
@@ -6028,7 +6469,7 @@ function createLarkEventHandler(deps) {
|
|
|
6028
6469
|
return;
|
|
6029
6470
|
}
|
|
6030
6471
|
deps.router.dispatch(inboundMessage).catch((error) => {
|
|
6031
|
-
|
|
6472
|
+
logger2.error("Lark message dispatch error", {
|
|
6032
6473
|
error: error instanceof Error ? error.message : String(error)
|
|
6033
6474
|
});
|
|
6034
6475
|
});
|
|
@@ -6060,8 +6501,8 @@ function registerChannelRoutes(app2, dependencies) {
|
|
|
6060
6501
|
}
|
|
6061
6502
|
|
|
6062
6503
|
// src/controllers/channel-installations.ts
|
|
6063
|
-
import { randomUUID as
|
|
6064
|
-
function
|
|
6504
|
+
import { randomUUID as randomUUID7 } from "crypto";
|
|
6505
|
+
function getTenantId13(request) {
|
|
6065
6506
|
const userTenantId = request.user?.tenantId;
|
|
6066
6507
|
if (userTenantId) {
|
|
6067
6508
|
return userTenantId;
|
|
@@ -6069,8 +6510,8 @@ function getTenantId11(request) {
|
|
|
6069
6510
|
return request.headers["x-tenant-id"] || "default";
|
|
6070
6511
|
}
|
|
6071
6512
|
async function getInstallationStore() {
|
|
6072
|
-
const { getStoreLattice:
|
|
6073
|
-
const store =
|
|
6513
|
+
const { getStoreLattice: getStoreLattice18 } = await import("@axiom-lattice/core");
|
|
6514
|
+
const store = getStoreLattice18("default", "channelInstallation").store;
|
|
6074
6515
|
if (store) return store;
|
|
6075
6516
|
const { PostgreSQLChannelInstallationStore } = await import("@axiom-lattice/pg-stores");
|
|
6076
6517
|
const databaseUrl = process.env.DATABASE_URL;
|
|
@@ -6082,7 +6523,7 @@ async function getInstallationStore() {
|
|
|
6082
6523
|
});
|
|
6083
6524
|
}
|
|
6084
6525
|
async function getChannelInstallationList(request, reply) {
|
|
6085
|
-
const tenantId =
|
|
6526
|
+
const tenantId = getTenantId13(request);
|
|
6086
6527
|
const { channel } = request.query;
|
|
6087
6528
|
try {
|
|
6088
6529
|
const store = await getInstallationStore();
|
|
@@ -6108,7 +6549,7 @@ async function getChannelInstallationList(request, reply) {
|
|
|
6108
6549
|
}
|
|
6109
6550
|
}
|
|
6110
6551
|
async function getChannelInstallation(request, reply) {
|
|
6111
|
-
const tenantId =
|
|
6552
|
+
const tenantId = getTenantId13(request);
|
|
6112
6553
|
const { installationId } = request.params;
|
|
6113
6554
|
try {
|
|
6114
6555
|
const store = await getInstallationStore();
|
|
@@ -6141,7 +6582,7 @@ async function getChannelInstallation(request, reply) {
|
|
|
6141
6582
|
}
|
|
6142
6583
|
}
|
|
6143
6584
|
async function createChannelInstallation(request, reply) {
|
|
6144
|
-
const tenantId =
|
|
6585
|
+
const tenantId = getTenantId13(request);
|
|
6145
6586
|
const body = request.body;
|
|
6146
6587
|
try {
|
|
6147
6588
|
if (!body.channel) {
|
|
@@ -6176,7 +6617,7 @@ async function createChannelInstallation(request, reply) {
|
|
|
6176
6617
|
}
|
|
6177
6618
|
}
|
|
6178
6619
|
const store = await getInstallationStore();
|
|
6179
|
-
const installationId = body.id ||
|
|
6620
|
+
const installationId = body.id || randomUUID7();
|
|
6180
6621
|
const installation = await store.createInstallation(
|
|
6181
6622
|
tenantId,
|
|
6182
6623
|
installationId,
|
|
@@ -6204,7 +6645,7 @@ async function createChannelInstallation(request, reply) {
|
|
|
6204
6645
|
}
|
|
6205
6646
|
}
|
|
6206
6647
|
async function updateChannelInstallation(request, reply) {
|
|
6207
|
-
const tenantId =
|
|
6648
|
+
const tenantId = getTenantId13(request);
|
|
6208
6649
|
const { installationId } = request.params;
|
|
6209
6650
|
const body = request.body;
|
|
6210
6651
|
try {
|
|
@@ -6250,7 +6691,7 @@ async function updateChannelInstallation(request, reply) {
|
|
|
6250
6691
|
}
|
|
6251
6692
|
}
|
|
6252
6693
|
async function deleteChannelInstallation(request, reply) {
|
|
6253
|
-
const tenantId =
|
|
6694
|
+
const tenantId = getTenantId13(request);
|
|
6254
6695
|
const { installationId } = request.params;
|
|
6255
6696
|
try {
|
|
6256
6697
|
const store = await getInstallationStore();
|
|
@@ -6301,13 +6742,13 @@ function registerChannelInstallationRoutes(app2) {
|
|
|
6301
6742
|
|
|
6302
6743
|
// src/controllers/channel-bindings.ts
|
|
6303
6744
|
import { getBindingRegistry } from "@axiom-lattice/core";
|
|
6304
|
-
function
|
|
6745
|
+
function getTenantId14(request) {
|
|
6305
6746
|
const userTenantId = request.user?.tenantId;
|
|
6306
6747
|
if (userTenantId) return userTenantId;
|
|
6307
6748
|
return request.headers["x-tenant-id"] || "default";
|
|
6308
6749
|
}
|
|
6309
6750
|
async function getBindingList(request, _reply) {
|
|
6310
|
-
const tenantId =
|
|
6751
|
+
const tenantId = getTenantId14(request);
|
|
6311
6752
|
const { channel, agentId, channelInstallationId, limit, offset } = request.query;
|
|
6312
6753
|
try {
|
|
6313
6754
|
const registry = getBindingRegistry();
|
|
@@ -6319,7 +6760,7 @@ async function getBindingList(request, _reply) {
|
|
|
6319
6760
|
}
|
|
6320
6761
|
}
|
|
6321
6762
|
async function getBinding(request, reply) {
|
|
6322
|
-
const tenantId =
|
|
6763
|
+
const tenantId = getTenantId14(request);
|
|
6323
6764
|
try {
|
|
6324
6765
|
const registry = getBindingRegistry();
|
|
6325
6766
|
const bindings = await registry.list({ tenantId });
|
|
@@ -6335,7 +6776,7 @@ async function getBinding(request, reply) {
|
|
|
6335
6776
|
}
|
|
6336
6777
|
}
|
|
6337
6778
|
async function createBinding(request, reply) {
|
|
6338
|
-
const tenantId =
|
|
6779
|
+
const tenantId = getTenantId14(request);
|
|
6339
6780
|
try {
|
|
6340
6781
|
const registry = getBindingRegistry();
|
|
6341
6782
|
const binding = await registry.create({ ...request.body, tenantId });
|
|
@@ -6349,7 +6790,7 @@ async function createBinding(request, reply) {
|
|
|
6349
6790
|
}
|
|
6350
6791
|
async function updateBinding(request, reply) {
|
|
6351
6792
|
try {
|
|
6352
|
-
const tenantId =
|
|
6793
|
+
const tenantId = getTenantId14(request);
|
|
6353
6794
|
const registry = getBindingRegistry();
|
|
6354
6795
|
const bindings = await registry.list({ tenantId });
|
|
6355
6796
|
const existing = bindings.find((b) => b.id === request.params.id);
|
|
@@ -6367,7 +6808,7 @@ async function updateBinding(request, reply) {
|
|
|
6367
6808
|
}
|
|
6368
6809
|
async function deleteBinding(request, reply) {
|
|
6369
6810
|
try {
|
|
6370
|
-
const tenantId =
|
|
6811
|
+
const tenantId = getTenantId14(request);
|
|
6371
6812
|
const registry = getBindingRegistry();
|
|
6372
6813
|
const bindings = await registry.list({ tenantId });
|
|
6373
6814
|
const existing = bindings.find((b) => b.id === request.params.id);
|
|
@@ -6384,7 +6825,7 @@ async function deleteBinding(request, reply) {
|
|
|
6384
6825
|
}
|
|
6385
6826
|
}
|
|
6386
6827
|
async function resolveBinding(request, _reply) {
|
|
6387
|
-
const tenantId =
|
|
6828
|
+
const tenantId = getTenantId14(request);
|
|
6388
6829
|
const { channel, senderId, channelInstallationId } = request.query;
|
|
6389
6830
|
try {
|
|
6390
6831
|
const registry = getBindingRegistry();
|
|
@@ -6409,6 +6850,105 @@ function registerChannelBindingRoutes(app2) {
|
|
|
6409
6850
|
app2.delete("/api/channel-bindings/:id", deleteBinding);
|
|
6410
6851
|
}
|
|
6411
6852
|
|
|
6853
|
+
// src/controllers/menu-items.ts
|
|
6854
|
+
import { getMenuRegistry } from "@axiom-lattice/core";
|
|
6855
|
+
function getTenantId15(request) {
|
|
6856
|
+
const userTenantId = request.user?.tenantId;
|
|
6857
|
+
if (userTenantId) return userTenantId;
|
|
6858
|
+
return request.headers["x-tenant-id"] || "default";
|
|
6859
|
+
}
|
|
6860
|
+
function errorMessage(err) {
|
|
6861
|
+
return err instanceof Error ? err.message : "Unexpected error";
|
|
6862
|
+
}
|
|
6863
|
+
async function getMenuItemList(request, _reply) {
|
|
6864
|
+
const tenantId = getTenantId15(request);
|
|
6865
|
+
try {
|
|
6866
|
+
const registry = getMenuRegistry();
|
|
6867
|
+
const items = await registry.list({ tenantId, menuTarget: request.query.menuTarget });
|
|
6868
|
+
return { success: true, message: "Menu items retrieved", data: { records: items, total: items.length } };
|
|
6869
|
+
} catch (error) {
|
|
6870
|
+
const msg = errorMessage(error);
|
|
6871
|
+
console.error("Failed to get menu items:", msg);
|
|
6872
|
+
return { success: false, message: msg, data: { records: [], total: 0 } };
|
|
6873
|
+
}
|
|
6874
|
+
}
|
|
6875
|
+
async function getMenuItem(request, reply) {
|
|
6876
|
+
const tenantId = getTenantId15(request);
|
|
6877
|
+
try {
|
|
6878
|
+
const registry = getMenuRegistry();
|
|
6879
|
+
const item = await registry.getById(request.params.id);
|
|
6880
|
+
if (!item || item.tenantId !== tenantId) {
|
|
6881
|
+
reply.status(404);
|
|
6882
|
+
return { success: false, message: "Menu item not found" };
|
|
6883
|
+
}
|
|
6884
|
+
return { success: true, message: "Menu item retrieved", data: item };
|
|
6885
|
+
} catch (error) {
|
|
6886
|
+
const msg = errorMessage(error);
|
|
6887
|
+
console.error("Failed to get menu item:", msg);
|
|
6888
|
+
reply.status(500);
|
|
6889
|
+
return { success: false, message: msg };
|
|
6890
|
+
}
|
|
6891
|
+
}
|
|
6892
|
+
async function createMenuItem(request, reply) {
|
|
6893
|
+
const tenantId = getTenantId15(request);
|
|
6894
|
+
try {
|
|
6895
|
+
const registry = getMenuRegistry();
|
|
6896
|
+
const item = await registry.create({ ...request.body, tenantId });
|
|
6897
|
+
reply.status(201);
|
|
6898
|
+
return { success: true, message: "Menu item created", data: item };
|
|
6899
|
+
} catch (error) {
|
|
6900
|
+
const msg = errorMessage(error);
|
|
6901
|
+
console.error("Failed to create menu item:", msg);
|
|
6902
|
+
reply.status(500);
|
|
6903
|
+
return { success: false, message: msg };
|
|
6904
|
+
}
|
|
6905
|
+
}
|
|
6906
|
+
async function updateMenuItem(request, reply) {
|
|
6907
|
+
try {
|
|
6908
|
+
const tenantId = getTenantId15(request);
|
|
6909
|
+
const registry = getMenuRegistry();
|
|
6910
|
+
const existing = await registry.getById(request.params.id);
|
|
6911
|
+
if (!existing || existing.tenantId !== tenantId) {
|
|
6912
|
+
reply.status(404);
|
|
6913
|
+
return { success: false, message: "Menu item not found" };
|
|
6914
|
+
}
|
|
6915
|
+
const item = await registry.update(request.params.id, request.body);
|
|
6916
|
+
return { success: true, message: "Menu item updated", data: item };
|
|
6917
|
+
} catch (error) {
|
|
6918
|
+
const msg = errorMessage(error);
|
|
6919
|
+
console.error("Failed to update menu item:", msg);
|
|
6920
|
+
reply.status(500);
|
|
6921
|
+
return { success: false, message: msg };
|
|
6922
|
+
}
|
|
6923
|
+
}
|
|
6924
|
+
async function deleteMenuItem(request, reply) {
|
|
6925
|
+
try {
|
|
6926
|
+
const tenantId = getTenantId15(request);
|
|
6927
|
+
const registry = getMenuRegistry();
|
|
6928
|
+
const existing = await registry.getById(request.params.id);
|
|
6929
|
+
if (!existing || existing.tenantId !== tenantId) {
|
|
6930
|
+
reply.status(404);
|
|
6931
|
+
return { success: false, message: "Menu item not found" };
|
|
6932
|
+
}
|
|
6933
|
+
await registry.delete(request.params.id);
|
|
6934
|
+
return { success: true, message: "Menu item deleted" };
|
|
6935
|
+
} catch (error) {
|
|
6936
|
+
const msg = errorMessage(error);
|
|
6937
|
+
console.error("Failed to delete menu item:", msg);
|
|
6938
|
+
reply.status(500);
|
|
6939
|
+
return { success: false, message: msg };
|
|
6940
|
+
}
|
|
6941
|
+
}
|
|
6942
|
+
|
|
6943
|
+
// src/routes/menu-items.ts
|
|
6944
|
+
function registerMenuItemRoutes(app2) {
|
|
6945
|
+
app2.get("/api/menu-items", getMenuItemList);
|
|
6946
|
+
app2.post("/api/menu-items", createMenuItem);
|
|
6947
|
+
app2.get("/api/menu-items/:id", getMenuItem);
|
|
6948
|
+
app2.put("/api/menu-items/:id", updateMenuItem);
|
|
6949
|
+
app2.delete("/api/menu-items/:id", deleteMenuItem);
|
|
6950
|
+
}
|
|
6951
|
+
|
|
6412
6952
|
// src/routes/a2a-bridge.ts
|
|
6413
6953
|
import { v4 as v42 } from "uuid";
|
|
6414
6954
|
var log = {
|
|
@@ -6589,6 +7129,7 @@ var registerLatticeRoutes = (app2, channelDeps) => {
|
|
|
6589
7129
|
app2.post("/api/runs", createRun);
|
|
6590
7130
|
app2.post("/api/resume_stream", resumeStream);
|
|
6591
7131
|
app2.post("/api/assistants/:assistantId/threads/:threadId/abort", abortRun);
|
|
7132
|
+
app2.post("/api/assistants/:assistantId/threads/:threadId/recover", recoverRun);
|
|
6592
7133
|
app2.get(
|
|
6593
7134
|
"/api/assistants/:assistantId/:thread_id/memory",
|
|
6594
7135
|
{ schema: getAllMemoryItemsSchema },
|
|
@@ -6624,6 +7165,15 @@ var registerLatticeRoutes = (app2, channelDeps) => {
|
|
|
6624
7165
|
app2.post("/api/assistants", createAssistant);
|
|
6625
7166
|
app2.put("/api/assistants/:id", updateAssistant);
|
|
6626
7167
|
app2.delete("/api/assistants/:id", deleteAssistant);
|
|
7168
|
+
app2.post("/api/personal-assistant", createPersonalAssistant);
|
|
7169
|
+
app2.get("/api/personal-assistant", getPersonalAssistant);
|
|
7170
|
+
app2.delete("/api/personal-assistant", deletePersonalAssistant);
|
|
7171
|
+
app2.get("/api/tasks", listTasks);
|
|
7172
|
+
app2.get("/api/tasks/:id", getTask);
|
|
7173
|
+
app2.post("/api/tasks", createTask);
|
|
7174
|
+
app2.put("/api/tasks/:id", updateTask);
|
|
7175
|
+
app2.delete("/api/tasks/:id", deleteTask);
|
|
7176
|
+
app2.patch("/api/tasks/:id/complete", completeTask);
|
|
6627
7177
|
app2.get(
|
|
6628
7178
|
"/api/assistants/:assistantId/graph",
|
|
6629
7179
|
{ schema: getAgentGraphSchema },
|
|
@@ -6722,6 +7272,7 @@ var registerLatticeRoutes = (app2, channelDeps) => {
|
|
|
6722
7272
|
});
|
|
6723
7273
|
registerChannelRoutes(app2, channelDeps);
|
|
6724
7274
|
registerChannelInstallationRoutes(app2);
|
|
7275
|
+
registerMenuItemRoutes(app2);
|
|
6725
7276
|
if (channelDeps) {
|
|
6726
7277
|
registerChannelBindingRoutes(app2);
|
|
6727
7278
|
}
|
|
@@ -6800,10 +7351,10 @@ var registerLatticeRoutes = (app2, channelDeps) => {
|
|
|
6800
7351
|
|
|
6801
7352
|
// src/router/MessageRouter.ts
|
|
6802
7353
|
import {
|
|
6803
|
-
getStoreLattice as
|
|
7354
|
+
getStoreLattice as getStoreLattice16,
|
|
6804
7355
|
agentInstanceManager as agentInstanceManager6
|
|
6805
7356
|
} from "@axiom-lattice/core";
|
|
6806
|
-
import { randomUUID as
|
|
7357
|
+
import { randomUUID as randomUUID8 } from "crypto";
|
|
6807
7358
|
var BindingNotFoundError = class extends Error {
|
|
6808
7359
|
constructor(message) {
|
|
6809
7360
|
super(message);
|
|
@@ -6850,6 +7401,9 @@ var MessageRouter = class {
|
|
|
6850
7401
|
inboundMessage: message,
|
|
6851
7402
|
metadata: {}
|
|
6852
7403
|
};
|
|
7404
|
+
let binding = null;
|
|
7405
|
+
let threadId;
|
|
7406
|
+
let agentId;
|
|
6853
7407
|
try {
|
|
6854
7408
|
await this.runMiddlewares(ctx, async () => {
|
|
6855
7409
|
const tenantId = message.tenantId || (await this.installationStore.getInstallationById(message.channelInstallationId))?.tenantId;
|
|
@@ -6866,16 +7420,18 @@ var MessageRouter = class {
|
|
|
6866
7420
|
);
|
|
6867
7421
|
}
|
|
6868
7422
|
console.log({ event: "dispatch:start", channel: message.channel, senderId: message.sender.id, tenantId }, "Message dispatch started");
|
|
6869
|
-
|
|
7423
|
+
const adapter = this.adapterRegistry.get(message.channel);
|
|
7424
|
+
const hasAdapterThreadStrategy = !!adapter?.resolveThreadId;
|
|
7425
|
+
binding = await this.bindingRegistry.resolve({
|
|
6870
7426
|
channel: message.channel,
|
|
6871
7427
|
senderId: message.sender.id,
|
|
6872
7428
|
channelInstallationId: message.channelInstallationId,
|
|
6873
7429
|
tenantId
|
|
6874
7430
|
});
|
|
7431
|
+
const installation = await this.installationStore.getInstallationById(
|
|
7432
|
+
message.channelInstallationId
|
|
7433
|
+
);
|
|
6875
7434
|
if (!binding) {
|
|
6876
|
-
const installation = await this.installationStore.getInstallationById(
|
|
6877
|
-
message.channelInstallationId
|
|
6878
|
-
);
|
|
6879
7435
|
if (installation?.rejectWhenNoBinding) {
|
|
6880
7436
|
console.warn({
|
|
6881
7437
|
event: "dispatch:no_binding",
|
|
@@ -6908,7 +7464,7 @@ var MessageRouter = class {
|
|
|
6908
7464
|
createdAt: /* @__PURE__ */ new Date(),
|
|
6909
7465
|
updatedAt: /* @__PURE__ */ new Date()
|
|
6910
7466
|
};
|
|
6911
|
-
} else {
|
|
7467
|
+
} else if (!hasAdapterThreadStrategy) {
|
|
6912
7468
|
console.error({
|
|
6913
7469
|
event: "dispatch:no_fallback",
|
|
6914
7470
|
channel: message.channel,
|
|
@@ -6920,47 +7476,99 @@ var MessageRouter = class {
|
|
|
6920
7476
|
);
|
|
6921
7477
|
}
|
|
6922
7478
|
}
|
|
6923
|
-
ctx.binding = binding;
|
|
6924
|
-
|
|
6925
|
-
|
|
6926
|
-
|
|
6927
|
-
agentId: binding.agentId,
|
|
6928
|
-
threadId: binding.threadId,
|
|
6929
|
-
threadMode: binding.threadMode,
|
|
6930
|
-
workspaceId: binding.workspaceId,
|
|
6931
|
-
projectId: binding.projectId
|
|
6932
|
-
}, "Binding resolved");
|
|
6933
|
-
if (!binding.enabled) {
|
|
6934
|
-
console.warn({
|
|
6935
|
-
event: "dispatch:binding_disabled",
|
|
7479
|
+
ctx.binding = binding ?? void 0;
|
|
7480
|
+
if (binding) {
|
|
7481
|
+
console.log({
|
|
7482
|
+
event: "dispatch:binding",
|
|
6936
7483
|
bindingId: binding.id,
|
|
6937
7484
|
agentId: binding.agentId,
|
|
6938
|
-
|
|
6939
|
-
|
|
7485
|
+
threadId: binding.threadId,
|
|
7486
|
+
threadMode: binding.threadMode,
|
|
7487
|
+
workspaceId: binding.workspaceId,
|
|
7488
|
+
projectId: binding.projectId
|
|
7489
|
+
}, "Binding resolved");
|
|
7490
|
+
if (!binding.enabled) {
|
|
7491
|
+
console.warn({
|
|
7492
|
+
event: "dispatch:binding_disabled",
|
|
7493
|
+
bindingId: binding.id,
|
|
7494
|
+
agentId: binding.agentId,
|
|
7495
|
+
senderId: message.sender.id
|
|
7496
|
+
}, "Binding is disabled, rejecting message");
|
|
7497
|
+
throw new BindingNotFoundError(
|
|
7498
|
+
`Binding for sender "${message.sender.id}" is disabled`
|
|
7499
|
+
);
|
|
7500
|
+
}
|
|
7501
|
+
}
|
|
7502
|
+
agentId = binding?.agentId ?? installation?.fallbackAgentId;
|
|
7503
|
+
if (!agentId) {
|
|
6940
7504
|
throw new BindingNotFoundError(
|
|
6941
|
-
`
|
|
7505
|
+
`No agent configured for sender "${message.sender.id}"`
|
|
6942
7506
|
);
|
|
6943
7507
|
}
|
|
6944
|
-
|
|
7508
|
+
if (hasAdapterThreadStrategy) {
|
|
7509
|
+
const resolvedThreadId = await adapter.resolveThreadId(message, binding);
|
|
7510
|
+
threadId = resolvedThreadId;
|
|
7511
|
+
console.log({
|
|
7512
|
+
event: "dispatch:thread:adapter",
|
|
7513
|
+
threadId,
|
|
7514
|
+
channel: message.channel,
|
|
7515
|
+
adapterChannel: adapter.channel
|
|
7516
|
+
}, "Thread resolved by adapter strategy");
|
|
7517
|
+
const threadStore = getStoreLattice16("default", "thread").store;
|
|
7518
|
+
try {
|
|
7519
|
+
await threadStore.createThread(
|
|
7520
|
+
tenantId,
|
|
7521
|
+
agentId,
|
|
7522
|
+
threadId,
|
|
7523
|
+
{
|
|
7524
|
+
metadata: {
|
|
7525
|
+
channel: message.channel,
|
|
7526
|
+
channelInstallationId: message.channelInstallationId,
|
|
7527
|
+
senderId: message.sender.id,
|
|
7528
|
+
bindingId: binding?.id,
|
|
7529
|
+
...message.conversation ? {
|
|
7530
|
+
conversationId: message.conversation.id,
|
|
7531
|
+
conversationType: message.conversation.type
|
|
7532
|
+
} : {}
|
|
7533
|
+
}
|
|
7534
|
+
}
|
|
7535
|
+
);
|
|
7536
|
+
console.log({
|
|
7537
|
+
event: "dispatch:thread:adapter:created",
|
|
7538
|
+
threadId
|
|
7539
|
+
}, "Thread created by adapter strategy");
|
|
7540
|
+
} catch {
|
|
7541
|
+
console.log({
|
|
7542
|
+
event: "dispatch:thread:adapter:reuse",
|
|
7543
|
+
threadId
|
|
7544
|
+
}, "Thread already exists, reusing");
|
|
7545
|
+
}
|
|
7546
|
+
} else if (binding) {
|
|
7547
|
+
if (binding.threadMode === "per_conversation") {
|
|
7548
|
+
threadId = void 0;
|
|
7549
|
+
} else {
|
|
7550
|
+
threadId = binding.threadId;
|
|
7551
|
+
}
|
|
7552
|
+
}
|
|
6945
7553
|
if (!threadId) {
|
|
6946
|
-
const threadStore =
|
|
6947
|
-
const newThreadId =
|
|
7554
|
+
const threadStore = getStoreLattice16("default", "thread").store;
|
|
7555
|
+
const newThreadId = randomUUID8();
|
|
6948
7556
|
console.log({
|
|
6949
7557
|
event: "dispatch:thread:create",
|
|
6950
|
-
agentId
|
|
7558
|
+
agentId,
|
|
6951
7559
|
newThreadId,
|
|
6952
7560
|
tenantId
|
|
6953
7561
|
}, "Creating new thread for binding");
|
|
6954
7562
|
const newThread = await threadStore.createThread(
|
|
6955
7563
|
tenantId,
|
|
6956
|
-
|
|
7564
|
+
agentId,
|
|
6957
7565
|
newThreadId,
|
|
6958
7566
|
{
|
|
6959
7567
|
metadata: {
|
|
6960
7568
|
channel: message.channel,
|
|
6961
7569
|
channelInstallationId: message.channelInstallationId,
|
|
6962
7570
|
senderId: message.sender.id,
|
|
6963
|
-
bindingId:
|
|
7571
|
+
bindingId: binding?.id,
|
|
6964
7572
|
...message.conversation ? {
|
|
6965
7573
|
conversationId: message.conversation.id,
|
|
6966
7574
|
conversationType: message.conversation.type
|
|
@@ -6969,36 +7577,35 @@ var MessageRouter = class {
|
|
|
6969
7577
|
}
|
|
6970
7578
|
);
|
|
6971
7579
|
threadId = newThread.id;
|
|
6972
|
-
if (
|
|
6973
|
-
await this.bindingRegistry.update(
|
|
6974
|
-
|
|
6975
|
-
} else {
|
|
6976
|
-
|
|
7580
|
+
if (binding && binding.id !== "fallback") {
|
|
7581
|
+
await this.bindingRegistry.update(binding.id, { threadId });
|
|
7582
|
+
binding.threadId = threadId;
|
|
7583
|
+
} else if (binding) {
|
|
7584
|
+
binding.threadId = threadId;
|
|
6977
7585
|
}
|
|
6978
7586
|
}
|
|
6979
7587
|
console.log({
|
|
6980
7588
|
event: "dispatch:agent",
|
|
6981
|
-
agentId
|
|
7589
|
+
agentId,
|
|
6982
7590
|
threadId,
|
|
6983
|
-
threadMode: ctx.binding.threadMode,
|
|
6984
7591
|
senderId: message.sender.id,
|
|
6985
7592
|
contentLength: message.content.text.length
|
|
6986
7593
|
}, "Dispatching to agent");
|
|
6987
7594
|
const agent = agentInstanceManager6.getAgent({
|
|
6988
7595
|
tenant_id: tenantId,
|
|
6989
|
-
assistant_id:
|
|
7596
|
+
assistant_id: agentId,
|
|
6990
7597
|
thread_id: threadId,
|
|
6991
|
-
workspace_id:
|
|
6992
|
-
project_id:
|
|
7598
|
+
workspace_id: binding?.workspaceId || "",
|
|
7599
|
+
project_id: binding?.projectId || ""
|
|
6993
7600
|
});
|
|
6994
7601
|
if (message.replyTarget) {
|
|
6995
7602
|
const replySubKey = `${threadId}:${message.replyTarget.adapterChannel}:reply`;
|
|
6996
|
-
const
|
|
6997
|
-
if (
|
|
6998
|
-
const
|
|
7603
|
+
const adapter2 = this.adapterRegistry.get(message.replyTarget.adapterChannel);
|
|
7604
|
+
if (adapter2) {
|
|
7605
|
+
const installation2 = await this.installationStore.getInstallationById(
|
|
6999
7606
|
message.channelInstallationId
|
|
7000
7607
|
);
|
|
7001
|
-
if (
|
|
7608
|
+
if (installation2) {
|
|
7002
7609
|
const existing = this._replySubs.get(replySubKey);
|
|
7003
7610
|
if (!existing || existing.count === 0) {
|
|
7004
7611
|
const timer = setTimeout(() => {
|
|
@@ -7038,7 +7645,7 @@ var MessageRouter = class {
|
|
|
7038
7645
|
channel: message.replyTarget.adapterChannel,
|
|
7039
7646
|
replyLength: replyText.length
|
|
7040
7647
|
}, "Sending channel reply");
|
|
7041
|
-
|
|
7648
|
+
adapter2.sendReply(message.replyTarget, { text: replyText }, installation2).then(() => {
|
|
7042
7649
|
console.log({
|
|
7043
7650
|
event: "dispatch:reply:sent",
|
|
7044
7651
|
threadId,
|
|
@@ -7076,7 +7683,7 @@ var MessageRouter = class {
|
|
|
7076
7683
|
});
|
|
7077
7684
|
console.log({
|
|
7078
7685
|
event: "dispatch:complete",
|
|
7079
|
-
agentId
|
|
7686
|
+
agentId,
|
|
7080
7687
|
threadId,
|
|
7081
7688
|
messageId: addResult?.messageId,
|
|
7082
7689
|
result: JSON.stringify(addResult)
|
|
@@ -7085,7 +7692,7 @@ var MessageRouter = class {
|
|
|
7085
7692
|
return {
|
|
7086
7693
|
success: true,
|
|
7087
7694
|
bindingId: ctx.binding?.id,
|
|
7088
|
-
threadId
|
|
7695
|
+
threadId,
|
|
7089
7696
|
result: ctx.result
|
|
7090
7697
|
};
|
|
7091
7698
|
} catch (error) {
|
|
@@ -7196,13 +7803,13 @@ function createRateLimitMiddleware(maxRequests = 10, windowMs = 60 * 1e3, maxEnt
|
|
|
7196
7803
|
}
|
|
7197
7804
|
|
|
7198
7805
|
// src/router/middlewares/auditLogger.ts
|
|
7199
|
-
var
|
|
7806
|
+
var logger3 = new Logger({ serviceName: "lattice/gateway/audit" });
|
|
7200
7807
|
function createAuditLoggerMiddleware() {
|
|
7201
7808
|
return async (ctx, next) => {
|
|
7202
7809
|
const start2 = Date.now();
|
|
7203
7810
|
try {
|
|
7204
7811
|
await next();
|
|
7205
|
-
|
|
7812
|
+
logger3.info("message routed", {
|
|
7206
7813
|
event: "message:routed",
|
|
7207
7814
|
channel: ctx.inboundMessage.channel,
|
|
7208
7815
|
senderId: ctx.inboundMessage.sender.id,
|
|
@@ -7212,7 +7819,7 @@ function createAuditLoggerMiddleware() {
|
|
|
7212
7819
|
status: "success"
|
|
7213
7820
|
});
|
|
7214
7821
|
} catch (error) {
|
|
7215
|
-
|
|
7822
|
+
logger3.error(
|
|
7216
7823
|
error instanceof Error ? error.message : String(error),
|
|
7217
7824
|
{
|
|
7218
7825
|
event: "message:error",
|
|
@@ -7228,7 +7835,7 @@ function createAuditLoggerMiddleware() {
|
|
|
7228
7835
|
}
|
|
7229
7836
|
|
|
7230
7837
|
// src/index.ts
|
|
7231
|
-
import { setBindingRegistry } from "@axiom-lattice/core";
|
|
7838
|
+
import { setBindingRegistry, setMenuRegistry } from "@axiom-lattice/core";
|
|
7232
7839
|
|
|
7233
7840
|
// src/swagger.ts
|
|
7234
7841
|
import swagger from "@fastify/swagger";
|
|
@@ -7317,15 +7924,16 @@ var handleAgentTask = async (taskRequest, retryCount = 0) => {
|
|
|
7317
7924
|
agent.subscribeOnce("message:completed", (evt) => {
|
|
7318
7925
|
eventBus2.publish(callback_event, {
|
|
7319
7926
|
success: true,
|
|
7320
|
-
state: evt.state
|
|
7321
|
-
config: { assistant_id, thread_id, tenant_id }
|
|
7927
|
+
state: evt.state
|
|
7322
7928
|
});
|
|
7323
7929
|
if (main_thread_id && main_tenant_id) {
|
|
7324
7930
|
try {
|
|
7325
7931
|
const mainAgent = agentInstanceManager7.getAgent({
|
|
7326
7932
|
assistant_id: main_assistant_id ?? assistant_id,
|
|
7327
7933
|
thread_id: main_thread_id,
|
|
7328
|
-
tenant_id: main_tenant_id
|
|
7934
|
+
tenant_id: main_tenant_id,
|
|
7935
|
+
workspace_id: runConfig?.workspaceId,
|
|
7936
|
+
project_id: runConfig?.projectId
|
|
7329
7937
|
});
|
|
7330
7938
|
if (mainAgent) {
|
|
7331
7939
|
const messages = evt.state?.values?.messages;
|
|
@@ -7352,8 +7960,7 @@ ${summary}`
|
|
|
7352
7960
|
agent.subscribeOnce("message:interrupted", (evt) => {
|
|
7353
7961
|
eventBus2.publish(callback_event, {
|
|
7354
7962
|
success: true,
|
|
7355
|
-
state: evt.state
|
|
7356
|
-
config: { assistant_id, thread_id, tenant_id }
|
|
7963
|
+
state: evt.state
|
|
7357
7964
|
});
|
|
7358
7965
|
});
|
|
7359
7966
|
}
|
|
@@ -7376,8 +7983,7 @@ ${summary}`
|
|
|
7376
7983
|
if (callback_event) {
|
|
7377
7984
|
eventBus2.publish(callback_event, {
|
|
7378
7985
|
success: false,
|
|
7379
|
-
error: error instanceof Error ? error.message : String(error)
|
|
7380
|
-
config: { assistant_id, thread_id, tenant_id }
|
|
7986
|
+
error: error instanceof Error ? error.message : String(error)
|
|
7381
7987
|
});
|
|
7382
7988
|
}
|
|
7383
7989
|
console.error(
|
|
@@ -7533,12 +8139,7 @@ var _AgentTaskConsumer = class _AgentTaskConsumer {
|
|
|
7533
8139
|
if (taskRequest.callback_event) {
|
|
7534
8140
|
eventBus2.publish(taskRequest.callback_event, {
|
|
7535
8141
|
success: false,
|
|
7536
|
-
error: error instanceof Error ? error.message : String(error)
|
|
7537
|
-
config: {
|
|
7538
|
-
assistant_id: taskRequest.assistant_id,
|
|
7539
|
-
thread_id: taskRequest.thread_id,
|
|
7540
|
-
tenant_id: taskRequest["x-tenant-id"]
|
|
7541
|
-
}
|
|
8142
|
+
error: error instanceof Error ? error.message : String(error)
|
|
7542
8143
|
});
|
|
7543
8144
|
}
|
|
7544
8145
|
});
|
|
@@ -7556,6 +8157,7 @@ import {
|
|
|
7556
8157
|
getLoggerLattice,
|
|
7557
8158
|
loggerLatticeManager,
|
|
7558
8159
|
sandboxLatticeManager as sandboxLatticeManager2,
|
|
8160
|
+
getStoreLattice as getStoreLattice17,
|
|
7559
8161
|
agentInstanceManager as agentInstanceManager8,
|
|
7560
8162
|
createSandboxProvider
|
|
7561
8163
|
} from "@axiom-lattice/core";
|
|
@@ -7573,7 +8175,7 @@ var DEFAULT_LOGGER_CONFIG = {
|
|
|
7573
8175
|
loggerName: "lattice/gateway"
|
|
7574
8176
|
};
|
|
7575
8177
|
var loggerLattice = initializeLogger(DEFAULT_LOGGER_CONFIG);
|
|
7576
|
-
var
|
|
8178
|
+
var logger4 = loggerLattice.client;
|
|
7577
8179
|
function initializeLogger(config) {
|
|
7578
8180
|
if (loggerLatticeManager.hasLattice("default")) {
|
|
7579
8181
|
loggerLatticeManager.removeLattice("default");
|
|
@@ -7672,7 +8274,7 @@ app.setErrorHandler((error, request, reply) => {
|
|
|
7672
8274
|
"x-request-id": getHeaderValue(request.headers["x-request-id"]),
|
|
7673
8275
|
"x-user-id": getHeaderValue(request.headers["x-user-id"])
|
|
7674
8276
|
};
|
|
7675
|
-
|
|
8277
|
+
logger4.error(
|
|
7676
8278
|
`\u8BF7\u6C42\u9519\u8BEF: ${request.method} ${request.url} error:${error.message}`,
|
|
7677
8279
|
{
|
|
7678
8280
|
...context,
|
|
@@ -7712,17 +8314,19 @@ var start = async (config) => {
|
|
|
7712
8314
|
file: config.loggerConfig.file || DEFAULT_LOGGER_CONFIG.file
|
|
7713
8315
|
};
|
|
7714
8316
|
loggerLattice = initializeLogger(loggerConfig);
|
|
7715
|
-
|
|
8317
|
+
logger4 = loggerLattice.client;
|
|
7716
8318
|
}
|
|
7717
8319
|
app.decorate("loggerLattice", loggerLattice);
|
|
7718
8320
|
let channelDeps;
|
|
8321
|
+
const adapterRegistry = new ChannelAdapterRegistry();
|
|
8322
|
+
adapterRegistry.register(larkChannelAdapter);
|
|
7719
8323
|
try {
|
|
7720
|
-
const { getStoreLattice:
|
|
7721
|
-
|
|
7722
|
-
|
|
8324
|
+
const { getStoreLattice: getStore2 } = await import("@axiom-lattice/core");
|
|
8325
|
+
let bindingStore;
|
|
8326
|
+
let installationStore;
|
|
8327
|
+
bindingStore = getStore2("default", "channelBinding").store;
|
|
8328
|
+
installationStore = getStore2("default", "channelInstallation").store;
|
|
7723
8329
|
setBindingRegistry(bindingStore);
|
|
7724
|
-
const adapterRegistry = new ChannelAdapterRegistry();
|
|
7725
|
-
adapterRegistry.register(larkChannelAdapter);
|
|
7726
8330
|
const router = new MessageRouter({
|
|
7727
8331
|
middlewares: [
|
|
7728
8332
|
createDeduplicationMiddleware(),
|
|
@@ -7735,27 +8339,49 @@ var start = async (config) => {
|
|
|
7735
8339
|
});
|
|
7736
8340
|
channelDeps = { router, installationStore };
|
|
7737
8341
|
try {
|
|
7738
|
-
const a2aKeyStore =
|
|
8342
|
+
const a2aKeyStore = getStore2("default", "a2aApiKey").store;
|
|
7739
8343
|
const a2a = await import("./a2a-ERG5RMUW.mjs");
|
|
7740
8344
|
a2a.setA2AKeyStore(a2aKeyStore);
|
|
7741
8345
|
await a2a.refreshStoreKeyMap();
|
|
7742
|
-
|
|
8346
|
+
logger4.info("A2A key store initialized");
|
|
7743
8347
|
} catch {
|
|
7744
8348
|
}
|
|
8349
|
+
} catch (err) {
|
|
8350
|
+
logger4.warn("Channel infrastructure unavailable", {
|
|
8351
|
+
error: err instanceof Error ? err.message : String(err)
|
|
8352
|
+
});
|
|
8353
|
+
}
|
|
8354
|
+
try {
|
|
8355
|
+
const menuStore = getStoreLattice17("default", "menu").store;
|
|
8356
|
+
setMenuRegistry(menuStore);
|
|
8357
|
+
logger4.info("Menu registry initialized");
|
|
7745
8358
|
} catch {
|
|
7746
8359
|
}
|
|
7747
8360
|
registerLatticeRoutes(app, channelDeps);
|
|
7748
8361
|
if (!sandboxLatticeManager2.hasLattice("default")) {
|
|
7749
8362
|
sandboxLatticeManager2.registerLattice("default", getConfiguredSandboxProvider());
|
|
7750
|
-
|
|
8363
|
+
logger4.info("Registered sandbox manager from env configuration");
|
|
8364
|
+
}
|
|
8365
|
+
if (channelDeps && process.env.CHANNELS_ENABLED !== "false") {
|
|
8366
|
+
const { connectAllChannels } = await import("@axiom-lattice/core");
|
|
8367
|
+
try {
|
|
8368
|
+
await connectAllChannels(
|
|
8369
|
+
(channel) => adapterRegistry.get(channel),
|
|
8370
|
+
{ deps: { router: channelDeps.router } }
|
|
8371
|
+
);
|
|
8372
|
+
} catch (err) {
|
|
8373
|
+
logger4.error("Failed to start channel connections", {
|
|
8374
|
+
error: err instanceof Error ? err.message : String(err)
|
|
8375
|
+
});
|
|
8376
|
+
}
|
|
7751
8377
|
}
|
|
7752
8378
|
const target_port = config?.port || Number(process.env.PORT) || 4001;
|
|
7753
8379
|
await app.listen({ port: target_port, host: "0.0.0.0" });
|
|
7754
|
-
|
|
8380
|
+
logger4.info(`Lattice Gateway is running on port: ${target_port}`);
|
|
7755
8381
|
try {
|
|
7756
|
-
|
|
8382
|
+
logger4.info("AgentLifecycleManager initialized");
|
|
7757
8383
|
} catch (error) {
|
|
7758
|
-
|
|
8384
|
+
logger4.warn("Failed to initialize AgentLifecycleManager", { error });
|
|
7759
8385
|
}
|
|
7760
8386
|
const queueServiceConfig = config?.queueServiceConfig;
|
|
7761
8387
|
if (queueServiceConfig) {
|
|
@@ -7765,15 +8391,13 @@ var start = async (config) => {
|
|
|
7765
8391
|
agentTaskConsumer.startPollingQueue();
|
|
7766
8392
|
}
|
|
7767
8393
|
}
|
|
7768
|
-
|
|
7769
|
-
|
|
7770
|
-
|
|
7771
|
-
|
|
7772
|
-
}
|
|
7773
|
-
logger3.error("Agent recovery failed", { error });
|
|
7774
|
-
}
|
|
8394
|
+
agentInstanceManager8.restore().then((stats) => {
|
|
8395
|
+
logger4.info(`Agent recovery complete: ${stats.restored} threads restored, ${stats.errors} errors`);
|
|
8396
|
+
}).catch((error) => {
|
|
8397
|
+
logger4.error("Agent recovery failed", { error });
|
|
8398
|
+
});
|
|
7775
8399
|
} catch (err) {
|
|
7776
|
-
|
|
8400
|
+
logger4.error("Server start failed", { error: err });
|
|
7777
8401
|
process.exit(1);
|
|
7778
8402
|
}
|
|
7779
8403
|
};
|