@axiom-lattice/gateway 2.1.92 → 2.1.94

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/dist/index.js CHANGED
@@ -56,8 +56,8 @@ async function createLarkSender(config, client) {
56
56
  };
57
57
  }
58
58
  async function createDefaultLarkClient(config) {
59
- const Lark = await import("@larksuiteoapi/node-sdk");
60
- return new Lark.Client({
59
+ const Lark2 = await import("@larksuiteoapi/node-sdk");
60
+ return new Lark2.Client({
61
61
  appId: config.appId,
62
62
  appSecret: config.appSecret
63
63
  });
@@ -303,7 +303,7 @@ async function handleTasksSend(request, reply) {
303
303
  taskStore.set(taskId, record);
304
304
  let agent;
305
305
  try {
306
- agent = import_core31.agentInstanceManager.getAgent({
306
+ agent = import_core34.agentInstanceManager.getAgent({
307
307
  assistant_id: assistantId,
308
308
  thread_id: threadId,
309
309
  tenant_id: tenantId,
@@ -395,7 +395,7 @@ async function handleTasksCancel(request, reply) {
395
395
  return;
396
396
  }
397
397
  try {
398
- const agent = import_core31.agentInstanceManager.getAgent({
398
+ const agent = import_core34.agentInstanceManager.getAgent({
399
399
  assistant_id: record.assistantId,
400
400
  thread_id: record.threadId,
401
401
  tenant_id: record.tenantId,
@@ -432,7 +432,7 @@ async function handleTasksStream(request, reply) {
432
432
  }
433
433
  let agent;
434
434
  try {
435
- agent = import_core31.agentInstanceManager.getAgent({
435
+ agent = import_core34.agentInstanceManager.getAgent({
436
436
  assistant_id: record.assistantId,
437
437
  thread_id: record.threadId,
438
438
  tenant_id: record.tenantId,
@@ -627,12 +627,12 @@ function registerA2ARoutes(app2) {
627
627
  handleApiKeyRotate
628
628
  );
629
629
  }
630
- var import_uuid9, import_core31, import_protocols4, taskStore, _a2aKeyStore, _storeKeyMap;
630
+ var import_uuid9, import_core34, import_protocols4, taskStore, _a2aKeyStore, _storeKeyMap;
631
631
  var init_a2a = __esm({
632
632
  "src/routes/a2a.ts"() {
633
633
  "use strict";
634
634
  import_uuid9 = require("uuid");
635
- import_core31 = require("@axiom-lattice/core");
635
+ import_core34 = require("@axiom-lattice/core");
636
636
  import_protocols4 = require("@axiom-lattice/protocols");
637
637
  taskStore = /* @__PURE__ */ new Map();
638
638
  _a2aKeyStore = null;
@@ -666,6 +666,11 @@ function getTenantId(request) {
666
666
  }
667
667
  return request.headers["x-tenant-id"] || "default";
668
668
  }
669
+ function getUserId(request) {
670
+ const userId = request.user?.id;
671
+ if (userId) return userId;
672
+ return request.headers["x-user-id"] || void 0;
673
+ }
669
674
  function convertAgentConfigToAssistant(config) {
670
675
  return {
671
676
  id: config.key,
@@ -698,12 +703,17 @@ async function getAssistantList(request, reply) {
698
703
  assistantMap.set(assistant.id, assistant);
699
704
  });
700
705
  const allAssistants = Array.from(assistantMap.values());
706
+ const userId = getUserId(request);
707
+ const filtered = allAssistants.filter((a) => {
708
+ if (!a.ownerUserId) return true;
709
+ return a.ownerUserId === userId;
710
+ });
701
711
  return {
702
712
  success: true,
703
713
  message: "Successfully retrieved assistant list",
704
714
  data: {
705
- records: allAssistants,
706
- total: allAssistants.length
715
+ records: filtered,
716
+ total: filtered.length
707
717
  }
708
718
  };
709
719
  }
@@ -849,7 +859,7 @@ var getAgentGraph = async (request, reply) => {
849
859
  var import_uuid = require("uuid");
850
860
  var import_core3 = require("@axiom-lattice/core");
851
861
  var import_protocols = require("@axiom-lattice/protocols");
852
- function getUserId(request) {
862
+ function getUserId2(request) {
853
863
  const authUser = request.user;
854
864
  if (authUser?.id) return authUser.id;
855
865
  return request.headers["x-user-id"] || void 0;
@@ -871,7 +881,7 @@ var createRun = async (request, reply) => {
871
881
  const workspace_id = request.headers["x-workspace-id"];
872
882
  const project_id = request.headers["x-project-id"];
873
883
  const x_request_id = request.headers["x-request-id"] || (0, import_uuid.v4)();
874
- const user_id = getUserId(request);
884
+ const user_id = getUserId2(request);
875
885
  const mergedConfig = user_id ? { ...custom_run_config, user_id } : custom_run_config;
876
886
  if (!assistant_id) {
877
887
  reply.status(400).send({
@@ -1025,6 +1035,33 @@ var abortRun = async (request, reply) => {
1025
1035
  });
1026
1036
  }
1027
1037
  };
1038
+ var recoverRun = async (request, reply) => {
1039
+ try {
1040
+ const { assistantId, threadId } = request.params;
1041
+ const tenant_id = request.headers["x-tenant-id"];
1042
+ const workspace_id = request.headers["x-workspace-id"] || "default";
1043
+ const project_id = request.headers["x-project-id"] || "default";
1044
+ const agent = import_core3.agentInstanceManager.getAgent({
1045
+ assistant_id: assistantId,
1046
+ thread_id: threadId,
1047
+ tenant_id,
1048
+ workspace_id,
1049
+ project_id
1050
+ });
1051
+ await agent.resumeTask();
1052
+ const status = await agent.getRunStatus();
1053
+ reply.status(200).send({
1054
+ success: true,
1055
+ threadId,
1056
+ status
1057
+ });
1058
+ } catch (error) {
1059
+ reply.status(500).send({
1060
+ success: false,
1061
+ error: `Recover failed: ${error.message}`
1062
+ });
1063
+ }
1064
+ };
1028
1065
 
1029
1066
  // src/controllers/memory.ts
1030
1067
  var import_core4 = require("@axiom-lattice/core");
@@ -1197,6 +1234,8 @@ var triggerAgentTask = async (request, reply) => {
1197
1234
  try {
1198
1235
  const { assistant_id, thread_id, input, command } = request.body;
1199
1236
  const tenant_id = request.headers["x-tenant-id"];
1237
+ const workspace_id = request.headers["x-workspace-id"];
1238
+ const project_id = request.headers["x-project-id"];
1200
1239
  if (!assistant_id) {
1201
1240
  reply.status(400).send({
1202
1241
  success: false,
@@ -1217,7 +1256,12 @@ var triggerAgentTask = async (request, reply) => {
1217
1256
  thread_id,
1218
1257
  input,
1219
1258
  command,
1220
- "x-tenant-id": tenant_id
1259
+ "x-tenant-id": tenant_id,
1260
+ runConfig: {
1261
+ workspaceId: workspace_id,
1262
+ projectId: project_id,
1263
+ user_id: request.user?.id
1264
+ }
1221
1265
  });
1222
1266
  reply.status(200).send({
1223
1267
  success: true
@@ -2805,6 +2849,268 @@ async function replyInboxTask(request, reply) {
2805
2849
  }
2806
2850
  }
2807
2851
 
2852
+ // src/controllers/personal-assistant.ts
2853
+ var import_core14 = require("@axiom-lattice/core");
2854
+ var import_crypto3 = require("crypto");
2855
+ function getWorkspaceId2(request) {
2856
+ return request.headers["x-workspace-id"] || "default";
2857
+ }
2858
+ function getTenantId7(request) {
2859
+ const userTenantId = request.user?.tenantId;
2860
+ if (userTenantId) return userTenantId;
2861
+ return request.headers["x-tenant-id"] || "default";
2862
+ }
2863
+ function getUserId3(request) {
2864
+ const userId = request.user?.id || request.headers["x-user-id"];
2865
+ if (!userId) throw new Error("User ID is required");
2866
+ return userId;
2867
+ }
2868
+ function getLinkStore() {
2869
+ return (0, import_core14.getStoreLattice)("default", "userTenantLink").store;
2870
+ }
2871
+ function getAssistantStore() {
2872
+ return (0, import_core14.getStoreLattice)("default", "assistant").store;
2873
+ }
2874
+ function getProjectStore() {
2875
+ return (0, import_core14.getStoreLattice)("default", "project").store;
2876
+ }
2877
+ async function getLinkMeta(userId, tenantId) {
2878
+ const link = await getLinkStore().getLink(userId, tenantId);
2879
+ return link?.metadata || {};
2880
+ }
2881
+ async function updateLinkMeta(userId, tenantId, meta) {
2882
+ await getLinkStore().updateLink(userId, tenantId, { metadata: meta });
2883
+ }
2884
+ async function createPersonalAssistant(request, reply) {
2885
+ const tenantId = getTenantId7(request);
2886
+ const userId = getUserId3(request);
2887
+ const { name, personality } = request.body;
2888
+ if (!name || !personality) {
2889
+ return reply.status(400).send({ success: false, message: "name and personality are required" });
2890
+ }
2891
+ const store = getAssistantStore();
2892
+ const existing = await store.getByOwner(tenantId, userId);
2893
+ if (existing) {
2894
+ return reply.status(409).send({ success: false, message: "You already have a personal assistant" });
2895
+ }
2896
+ const assistantId = (0, import_crypto3.randomUUID)();
2897
+ const projectStore = getProjectStore();
2898
+ const projectId = (0, import_crypto3.randomUUID)();
2899
+ const wsId = getWorkspaceId2(request);
2900
+ await projectStore.createProject(tenantId, wsId, projectId, {
2901
+ name: `${name}'s Space`,
2902
+ description: "Personal workspace for your assistant"
2903
+ });
2904
+ const config = import_core14.PersonalAssistantConfig.get();
2905
+ config.key = assistantId;
2906
+ import_core14.PersonalAssistantConfig.render(config, name, personality);
2907
+ const data = { name, graphDefinition: config, ownerUserId: userId };
2908
+ const assistant = await store.createAssistant(tenantId, assistantId, data);
2909
+ const meta = await getLinkMeta(userId, tenantId);
2910
+ meta.personalAssistantId = assistantId;
2911
+ meta.personalProjectId = projectId;
2912
+ meta.personalWorkspaceId = wsId;
2913
+ await updateLinkMeta(userId, tenantId, meta);
2914
+ return reply.status(201).send({
2915
+ success: true,
2916
+ message: "Personal assistant created",
2917
+ data: { id: assistant.id, name: assistant.name, projectId, workspaceId: wsId, createdAt: assistant.createdAt }
2918
+ });
2919
+ }
2920
+ async function getPersonalAssistant(request, reply) {
2921
+ const tenantId = getTenantId7(request);
2922
+ const userId = getUserId3(request);
2923
+ const store = getAssistantStore();
2924
+ const assistant = await store.getByOwner(tenantId, userId);
2925
+ if (!assistant) {
2926
+ return reply.status(404).send({ success: false, message: "No personal assistant found" });
2927
+ }
2928
+ const meta = await getLinkMeta(userId, tenantId);
2929
+ const projectId = meta.personalProjectId || "default";
2930
+ const workspaceId = meta.personalWorkspaceId || "default";
2931
+ return {
2932
+ success: true,
2933
+ message: "Personal assistant found",
2934
+ data: { id: assistant.id, name: assistant.name, projectId, workspaceId, createdAt: assistant.createdAt }
2935
+ };
2936
+ }
2937
+ async function deletePersonalAssistant(request, reply) {
2938
+ const tenantId = getTenantId7(request);
2939
+ const userId = getUserId3(request);
2940
+ const store = getAssistantStore();
2941
+ const assistant = await store.getByOwner(tenantId, userId);
2942
+ if (!assistant) {
2943
+ return reply.status(404).send({ success: false, message: "No personal assistant found" });
2944
+ }
2945
+ const deleted = await store.deleteAssistant(tenantId, assistant.id);
2946
+ if (!deleted) {
2947
+ return reply.status(500).send({ success: false, message: "Failed to delete personal assistant" });
2948
+ }
2949
+ const threadStore = (0, import_core14.getStoreLattice)("default", "thread").store;
2950
+ try {
2951
+ const threads = await threadStore.getThreadsByAssistantId(tenantId, assistant.id);
2952
+ for (const t of threads) {
2953
+ await threadStore.deleteThread(tenantId, t.id);
2954
+ }
2955
+ } catch {
2956
+ }
2957
+ const meta = await getLinkMeta(userId, tenantId);
2958
+ const projectId = meta.personalProjectId;
2959
+ const wsId = meta.personalWorkspaceId;
2960
+ if (projectId && wsId) {
2961
+ try {
2962
+ await getProjectStore().deleteProject(tenantId, projectId);
2963
+ } catch {
2964
+ }
2965
+ }
2966
+ delete meta.personalAssistantId;
2967
+ delete meta.personalProjectId;
2968
+ delete meta.personalWorkspaceId;
2969
+ await updateLinkMeta(userId, tenantId, meta);
2970
+ return { success: true, message: "Personal assistant deleted" };
2971
+ }
2972
+
2973
+ // src/controllers/tasks.ts
2974
+ var import_core15 = require("@axiom-lattice/core");
2975
+ function getTenantId8(request) {
2976
+ const userTenantId = request.user?.tenantId;
2977
+ if (userTenantId) return userTenantId;
2978
+ return request.headers["x-tenant-id"] || "default";
2979
+ }
2980
+ function getUserId4(request) {
2981
+ const userId = request.user?.id || request.headers["x-user-id"];
2982
+ if (!userId) throw new Error("User ID is required");
2983
+ return userId;
2984
+ }
2985
+ function getStore() {
2986
+ return (0, import_core15.getStoreLattice)("default", "task").store;
2987
+ }
2988
+ async function listTasks(request, reply) {
2989
+ try {
2990
+ const tenantId = getTenantId8(request);
2991
+ const userId = getUserId4(request);
2992
+ const query = request.query;
2993
+ const store = getStore();
2994
+ const tasks = await store.list({
2995
+ tenantId,
2996
+ ownerId: query.ownerId || userId,
2997
+ status: query.status,
2998
+ priority: query.priority,
2999
+ ownerType: query.ownerType,
3000
+ metadata: query.metadata ? JSON.parse(query.metadata) : void 0,
3001
+ limit: query.limit ? parseInt(query.limit) : void 0,
3002
+ offset: query.offset ? parseInt(query.offset) : void 0
3003
+ });
3004
+ return { success: true, data: tasks, count: tasks.length };
3005
+ } catch (error) {
3006
+ return { success: false, error: error.message };
3007
+ }
3008
+ }
3009
+ async function getTask(request, reply) {
3010
+ try {
3011
+ const tenantId = getTenantId8(request);
3012
+ const userId = getUserId4(request);
3013
+ const { id } = request.params;
3014
+ const store = getStore();
3015
+ const task = await store.getById(tenantId, id);
3016
+ if (!task) {
3017
+ return reply.status(404).send({ success: false, error: "Task not found" });
3018
+ }
3019
+ if (task.ownerType === "user" && task.ownerId !== userId) {
3020
+ return reply.status(403).send({ success: false, error: "Access denied" });
3021
+ }
3022
+ return { success: true, data: task };
3023
+ } catch (error) {
3024
+ return { success: false, error: error.message };
3025
+ }
3026
+ }
3027
+ async function createTask(request, reply) {
3028
+ try {
3029
+ const tenantId = getTenantId8(request);
3030
+ const userId = getUserId4(request);
3031
+ const body = request.body;
3032
+ if (!body.title) {
3033
+ return reply.status(400).send({ success: false, error: "title is required" });
3034
+ }
3035
+ const store = getStore();
3036
+ const task = await store.create({
3037
+ ...body,
3038
+ tenantId,
3039
+ ownerType: body.ownerType || "user",
3040
+ ownerId: body.ownerId || userId
3041
+ });
3042
+ return reply.status(201).send({ success: true, data: task });
3043
+ } catch (error) {
3044
+ return reply.status(500).send({ success: false, error: error.message });
3045
+ }
3046
+ }
3047
+ async function updateTask(request, reply) {
3048
+ try {
3049
+ const tenantId = getTenantId8(request);
3050
+ const userId = getUserId4(request);
3051
+ const { id } = request.params;
3052
+ const store = getStore();
3053
+ const existing = await store.getById(tenantId, id);
3054
+ if (!existing) {
3055
+ return reply.status(404).send({ success: false, error: "Task not found" });
3056
+ }
3057
+ if (existing.ownerType === "user" && existing.ownerId !== userId) {
3058
+ return reply.status(403).send({ success: false, error: "Access denied" });
3059
+ }
3060
+ const task = await store.update(tenantId, id, request.body);
3061
+ if (!task) {
3062
+ return reply.status(404).send({ success: false, error: "Task not found" });
3063
+ }
3064
+ return { success: true, data: task };
3065
+ } catch (error) {
3066
+ return reply.status(500).send({ success: false, error: error.message });
3067
+ }
3068
+ }
3069
+ async function deleteTask(request, reply) {
3070
+ try {
3071
+ const tenantId = getTenantId8(request);
3072
+ const userId = getUserId4(request);
3073
+ const { id } = request.params;
3074
+ const store = getStore();
3075
+ const existing = await store.getById(tenantId, id);
3076
+ if (!existing) {
3077
+ return reply.status(404).send({ success: false, error: "Task not found" });
3078
+ }
3079
+ if (existing.ownerType === "user" && existing.ownerId !== userId) {
3080
+ return reply.status(403).send({ success: false, error: "Access denied" });
3081
+ }
3082
+ const deleted = await store.delete(tenantId, id);
3083
+ if (!deleted) {
3084
+ return reply.status(404).send({ success: false, error: "Task not found" });
3085
+ }
3086
+ return { success: true, message: "Task deleted" };
3087
+ } catch (error) {
3088
+ return reply.status(500).send({ success: false, error: error.message });
3089
+ }
3090
+ }
3091
+ async function completeTask(request, reply) {
3092
+ try {
3093
+ const tenantId = getTenantId8(request);
3094
+ const userId = getUserId4(request);
3095
+ const { id } = request.params;
3096
+ const store = getStore();
3097
+ const existing = await store.getById(tenantId, id);
3098
+ if (!existing) {
3099
+ return reply.status(404).send({ success: false, error: "Task not found" });
3100
+ }
3101
+ if (existing.ownerType === "user" && existing.ownerId !== userId) {
3102
+ return reply.status(403).send({ success: false, error: "Access denied" });
3103
+ }
3104
+ const task = await store.update(tenantId, id, { status: "completed" });
3105
+ if (!task) {
3106
+ return reply.status(404).send({ success: false, error: "Task not found" });
3107
+ }
3108
+ return { success: true, data: task };
3109
+ } catch (error) {
3110
+ return reply.status(500).send({ success: false, error: error.message });
3111
+ }
3112
+ }
3113
+
2808
3114
  // src/schemas/data-query.ts
2809
3115
  var dataQuerySchema = {
2810
3116
  description: "Execute data query (semantic or SQL)",
@@ -3146,7 +3452,7 @@ var getHealthSchema = {
3146
3452
  };
3147
3453
 
3148
3454
  // src/controllers/thread_status.ts
3149
- var import_core14 = require("@axiom-lattice/core");
3455
+ var import_core16 = require("@axiom-lattice/core");
3150
3456
  async function removePendingMessageHandler(request, reply) {
3151
3457
  try {
3152
3458
  const { assistant_id, thread_id, message_id } = request.params;
@@ -3159,7 +3465,7 @@ async function removePendingMessageHandler(request, reply) {
3159
3465
  if (!assistant_id) {
3160
3466
  return reply.code(400).send({ error: "Missing assistant_id parameter" });
3161
3467
  }
3162
- const agent = import_core14.agentInstanceManager.getAgent({
3468
+ const agent = import_core16.agentInstanceManager.getAgent({
3163
3469
  assistant_id,
3164
3470
  thread_id,
3165
3471
  tenant_id,
@@ -3193,7 +3499,7 @@ async function removePendingMessageHandler(request, reply) {
3193
3499
  }
3194
3500
 
3195
3501
  // src/services/sandbox_service.ts
3196
- var import_core15 = require("@axiom-lattice/core");
3502
+ var import_core17 = require("@axiom-lattice/core");
3197
3503
  var ERROR_HTML = `<!DOCTYPE html>
3198
3504
  <html lang="zh-CN">
3199
3505
  <head>
@@ -3305,7 +3611,7 @@ var ERROR_HTML = `<!DOCTYPE html>
3305
3611
  </html>`;
3306
3612
  var SandboxService = class {
3307
3613
  getFilesystemVmIsolation(tenantId, assistantId) {
3308
- const agentLattice = import_core15.agentLatticeManager.getAgentLatticeWithTenant(tenantId, assistantId);
3614
+ const agentLattice = import_core17.agentLatticeManager.getAgentLatticeWithTenant(tenantId, assistantId);
3309
3615
  if (!agentLattice) {
3310
3616
  return null;
3311
3617
  }
@@ -3319,9 +3625,9 @@ var SandboxService = class {
3319
3625
  computeSandboxName(assistantId, threadId, vmIsolation, tenantId, workspaceId, projectId) {
3320
3626
  switch (vmIsolation) {
3321
3627
  case "agent":
3322
- return (0, import_core15.normalizeSandboxName)(`${tenantId ?? "default"}-${assistantId}`);
3628
+ return (0, import_core17.normalizeSandboxName)(`${tenantId ?? "default"}-${assistantId}`);
3323
3629
  case "project":
3324
- return (0, import_core15.normalizeSandboxName)(
3630
+ return (0, import_core17.normalizeSandboxName)(
3325
3631
  `${tenantId ?? "default"}-${workspaceId ?? "default"}-${projectId ?? "default"}`
3326
3632
  );
3327
3633
  case "global":
@@ -3369,15 +3675,15 @@ var SandboxService = class {
3369
3675
  );
3370
3676
  return rewritten;
3371
3677
  }
3372
- generateErrorHtml(assistantId, threadId, vmIsolation, errorMessage) {
3373
- const encodedError = encodeURIComponent(errorMessage);
3374
- return ERROR_HTML.replace("{assistantId}", assistantId).replace("{threadId}", threadId).replace("{vmIsolation}", vmIsolation).replace("{errorMessage}", errorMessage);
3678
+ generateErrorHtml(assistantId, threadId, vmIsolation, errorMessage2) {
3679
+ const encodedError = encodeURIComponent(errorMessage2);
3680
+ return ERROR_HTML.replace("{assistantId}", assistantId).replace("{threadId}", threadId).replace("{vmIsolation}", vmIsolation).replace("{errorMessage}", errorMessage2);
3375
3681
  }
3376
3682
  };
3377
3683
  var sandboxService = new SandboxService();
3378
3684
 
3379
3685
  // src/controllers/sandbox.ts
3380
- var import_core16 = require("@axiom-lattice/core");
3686
+ var import_core18 = require("@axiom-lattice/core");
3381
3687
  function getFilenameFromPath(path3) {
3382
3688
  const segments = path3.replace(/\/+$/, "").split("/");
3383
3689
  return segments[segments.length - 1] || "download";
@@ -3416,7 +3722,7 @@ function registerSandboxProxyRoutes(app2) {
3416
3722
  }
3417
3723
  const workspaceId = request.headers["x-workspace-id"];
3418
3724
  const projectId = request.headers["x-project-id"];
3419
- const sandboxManager = (0, import_core16.getSandBoxManager)();
3725
+ const sandboxManager = (0, import_core18.getSandBoxManager)();
3420
3726
  const sandbox = await sandboxManager.getSandboxFromConfig({
3421
3727
  assistant_id: assistantId,
3422
3728
  thread_id: threadId,
@@ -3464,7 +3770,7 @@ function registerSandboxProxyRoutes(app2) {
3464
3770
  }
3465
3771
  const workspaceId = request.headers["x-workspace-id"];
3466
3772
  const projectId = request.headers["x-project-id"];
3467
- const sandboxManager = (0, import_core16.getSandBoxManager)();
3773
+ const sandboxManager = (0, import_core18.getSandBoxManager)();
3468
3774
  const sandbox = await sandboxManager.getSandboxFromConfig({
3469
3775
  assistant_id: assistantId,
3470
3776
  thread_id: threadId,
@@ -3497,14 +3803,14 @@ function registerSandboxProxyRoutes(app2) {
3497
3803
  // src/controllers/workspace.ts
3498
3804
  var fs = __toESM(require("fs/promises"));
3499
3805
  var path = __toESM(require("path"));
3500
- var import_core17 = require("@axiom-lattice/core");
3501
- var import_core18 = require("@axiom-lattice/core");
3502
3806
  var import_core19 = require("@axiom-lattice/core");
3807
+ var import_core20 = require("@axiom-lattice/core");
3808
+ var import_core21 = require("@axiom-lattice/core");
3503
3809
  var import_uuid2 = require("uuid");
3504
3810
  var WorkspaceController = class {
3505
3811
  constructor() {
3506
- this.workspaceStore = (0, import_core17.getStoreLattice)("default", "workspace").store;
3507
- this.projectStore = (0, import_core17.getStoreLattice)("default", "project").store;
3812
+ this.workspaceStore = (0, import_core19.getStoreLattice)("default", "workspace").store;
3813
+ this.projectStore = (0, import_core19.getStoreLattice)("default", "project").store;
3508
3814
  }
3509
3815
  getTenantId(request) {
3510
3816
  const userTenantId = request.user?.tenantId;
@@ -3636,8 +3942,9 @@ var WorkspaceController = class {
3636
3942
  if (!workspace) {
3637
3943
  throw new Error("Workspace not found");
3638
3944
  }
3945
+ console.log(`[getBackend] storageType=${workspace.storageType} filePath=${filePath}`);
3639
3946
  if (workspace.storageType === "sandbox") {
3640
- const sandboxManager = (0, import_core19.getSandBoxManager)();
3947
+ const sandboxManager = (0, import_core21.getSandBoxManager)();
3641
3948
  const volumeConfig = {
3642
3949
  assistant_id: assistantId || "",
3643
3950
  thread_id: "",
@@ -3645,20 +3952,25 @@ var WorkspaceController = class {
3645
3952
  workspaceId,
3646
3953
  projectId
3647
3954
  };
3955
+ console.log(`[getBackend] trying volume backend for path=${filePath} assistant_id=${assistantId}`);
3648
3956
  const volumeBackend = await sandboxManager.getVolumeBackendForPath(volumeConfig, filePath || "/project");
3649
3957
  if (volumeBackend) {
3958
+ console.log(`[getBackend] using VolumeFilesystem`);
3650
3959
  return { backend: volumeBackend, workspace };
3651
3960
  }
3961
+ console.log(`[getBackend] volume not found, falling back to SandboxFilesystem`);
3652
3962
  const sandbox = await sandboxManager.getSandboxFromConfig(volumeConfig);
3963
+ console.log(`[getBackend] sandbox acquired, name=${sandbox.name || "unknown"}`);
3653
3964
  return {
3654
- backend: new import_core18.SandboxFilesystem({
3965
+ backend: new import_core20.SandboxFilesystem({
3655
3966
  sandboxInstance: sandbox
3656
3967
  }),
3657
3968
  workspace
3658
3969
  };
3659
3970
  } else {
3971
+ console.log(`[getBackend] using FilesystemBackend rootDir=/lattice_store/tenants/${tenantId}/workspaces/${workspaceId}/${projectId}`);
3660
3972
  return {
3661
- backend: new import_core18.FilesystemBackend({
3973
+ backend: new import_core20.FilesystemBackend({
3662
3974
  rootDir: `/lattice_store/tenants/${tenantId}/workspaces/${workspaceId}/${projectId}`,
3663
3975
  virtualMode: true
3664
3976
  }),
@@ -3736,7 +4048,7 @@ var WorkspaceController = class {
3736
4048
  const { workspace } = await this.getBackend(tenantId, workspaceId, projectId, assistantId);
3737
4049
  const resolvedPath = filePath;
3738
4050
  if (workspace.storageType === "sandbox") {
3739
- const sandboxManager = (0, import_core19.getSandBoxManager)();
4051
+ const sandboxManager = (0, import_core21.getSandBoxManager)();
3740
4052
  const volumeConfig = {
3741
4053
  assistant_id: assistantId || "",
3742
4054
  thread_id: "",
@@ -3786,7 +4098,7 @@ var WorkspaceController = class {
3786
4098
  const { workspace } = await this.getBackend(tenantId, workspaceId, projectId, assistantId);
3787
4099
  const resolvedPath = filePath;
3788
4100
  if (workspace.storageType === "sandbox") {
3789
- const sandboxManager = (0, import_core19.getSandBoxManager)();
4101
+ const sandboxManager = (0, import_core21.getSandBoxManager)();
3790
4102
  const volumeConfig = {
3791
4103
  assistant_id: assistantId || "",
3792
4104
  thread_id: "",
@@ -3873,8 +4185,11 @@ var WorkspaceController = class {
3873
4185
  const { workspaceId, projectId } = request.params;
3874
4186
  const path3 = request.query.path || "/";
3875
4187
  const assistantId = request.query.assistantId;
4188
+ console.log(`[listPath] tenantId=${tenantId} workspaceId=${workspaceId} projectId=${projectId} path=${path3} assistantId=${assistantId}`);
3876
4189
  const { backend } = await this.getBackend(tenantId, workspaceId, projectId, assistantId, path3);
4190
+ console.log(`[listPath] backend type=${backend.constructor.name} calling lsInfo(${path3})`);
3877
4191
  const files = await backend.lsInfo(path3);
4192
+ console.log(`[listPath] result count=${files.length}`);
3878
4193
  return { success: true, data: files };
3879
4194
  }
3880
4195
  async readFile(request) {
@@ -3920,7 +4235,7 @@ var WorkspaceController = class {
3920
4235
  return reply.status(400).send({ success: false, error: "Invalid path parameter" });
3921
4236
  }
3922
4237
  if (workspace.storageType === "sandbox") {
3923
- const sandboxManager = (0, import_core19.getSandBoxManager)();
4238
+ const sandboxManager = (0, import_core21.getSandBoxManager)();
3924
4239
  const volumeConfig = {
3925
4240
  assistant_id: assistantId || "",
3926
4241
  thread_id: "",
@@ -4028,9 +4343,9 @@ function registerWorkspaceRoutes(app2) {
4028
4343
  }
4029
4344
 
4030
4345
  // src/controllers/database-configs.ts
4031
- var import_core20 = require("@axiom-lattice/core");
4032
- var import_crypto3 = require("crypto");
4033
- function getTenantId7(request) {
4346
+ var import_core22 = require("@axiom-lattice/core");
4347
+ var import_crypto4 = require("crypto");
4348
+ function getTenantId9(request) {
4034
4349
  const userTenantId = request.user?.tenantId;
4035
4350
  if (userTenantId) {
4036
4351
  return userTenantId;
@@ -4038,9 +4353,9 @@ function getTenantId7(request) {
4038
4353
  return request.headers["x-tenant-id"] || "default";
4039
4354
  }
4040
4355
  async function getDatabaseConfigList(request, reply) {
4041
- const tenantId = getTenantId7(request);
4356
+ const tenantId = getTenantId9(request);
4042
4357
  try {
4043
- const storeLattice = (0, import_core20.getStoreLattice)("default", "database");
4358
+ const storeLattice = (0, import_core22.getStoreLattice)("default", "database");
4044
4359
  const store = storeLattice.store;
4045
4360
  const configs = await store.getAllConfigs(tenantId);
4046
4361
  console.log("Backend: getAllConfigs returned:", configs);
@@ -4068,10 +4383,10 @@ async function getDatabaseConfigList(request, reply) {
4068
4383
  }
4069
4384
  }
4070
4385
  async function getDatabaseConfig(request, reply) {
4071
- const tenantId = getTenantId7(request);
4386
+ const tenantId = getTenantId9(request);
4072
4387
  const { key } = request.params;
4073
4388
  try {
4074
- const storeLattice = (0, import_core20.getStoreLattice)("default", "database");
4389
+ const storeLattice = (0, import_core22.getStoreLattice)("default", "database");
4075
4390
  const store = storeLattice.store;
4076
4391
  const config = await store.getConfigByKey(tenantId, key);
4077
4392
  if (!config) {
@@ -4094,10 +4409,10 @@ async function getDatabaseConfig(request, reply) {
4094
4409
  }
4095
4410
  }
4096
4411
  async function createDatabaseConfig(request, reply) {
4097
- const tenantId = getTenantId7(request);
4412
+ const tenantId = getTenantId9(request);
4098
4413
  const body = request.body;
4099
4414
  try {
4100
- const storeLattice = (0, import_core20.getStoreLattice)("default", "database");
4415
+ const storeLattice = (0, import_core22.getStoreLattice)("default", "database");
4101
4416
  const store = storeLattice.store;
4102
4417
  const existing = await store.getConfigByKey(tenantId, body.key);
4103
4418
  if (existing) {
@@ -4107,10 +4422,10 @@ async function createDatabaseConfig(request, reply) {
4107
4422
  message: "Database configuration with this key already exists"
4108
4423
  };
4109
4424
  }
4110
- const id = body.id || (0, import_crypto3.randomUUID)();
4425
+ const id = body.id || (0, import_crypto4.randomUUID)();
4111
4426
  const config = await store.createConfig(tenantId, id, body);
4112
4427
  try {
4113
- import_core20.sqlDatabaseManager.registerDatabase(tenantId, config.key, config.config);
4428
+ import_core22.sqlDatabaseManager.registerDatabase(tenantId, config.key, config.config);
4114
4429
  } catch (error) {
4115
4430
  console.warn("Failed to auto-register database:", error);
4116
4431
  }
@@ -4129,11 +4444,11 @@ async function createDatabaseConfig(request, reply) {
4129
4444
  }
4130
4445
  }
4131
4446
  async function updateDatabaseConfig(request, reply) {
4132
- const tenantId = getTenantId7(request);
4447
+ const tenantId = getTenantId9(request);
4133
4448
  const { key } = request.params;
4134
4449
  const updates = request.body;
4135
4450
  try {
4136
- const storeLattice = (0, import_core20.getStoreLattice)("default", "database");
4451
+ const storeLattice = (0, import_core22.getStoreLattice)("default", "database");
4137
4452
  const store = storeLattice.store;
4138
4453
  const existing = await store.getConfigByKey(tenantId, key);
4139
4454
  if (!existing) {
@@ -4152,7 +4467,7 @@ async function updateDatabaseConfig(request, reply) {
4152
4467
  }
4153
4468
  if (updates.config) {
4154
4469
  try {
4155
- import_core20.sqlDatabaseManager.registerDatabase(tenantId, updated.key, updated.config);
4470
+ import_core22.sqlDatabaseManager.registerDatabase(tenantId, updated.key, updated.config);
4156
4471
  } catch (error) {
4157
4472
  console.warn("Failed to re-register database:", error);
4158
4473
  }
@@ -4171,10 +4486,10 @@ async function updateDatabaseConfig(request, reply) {
4171
4486
  }
4172
4487
  }
4173
4488
  async function deleteDatabaseConfig(request, reply) {
4174
- const tenantId = getTenantId7(request);
4489
+ const tenantId = getTenantId9(request);
4175
4490
  const { keyOrId } = request.params;
4176
4491
  try {
4177
- const storeLattice = (0, import_core20.getStoreLattice)("default", "database");
4492
+ const storeLattice = (0, import_core22.getStoreLattice)("default", "database");
4178
4493
  const store = storeLattice.store;
4179
4494
  console.log("Delete request - keyOrId:", keyOrId);
4180
4495
  let config = await store.getConfigByKey(tenantId, keyOrId);
@@ -4201,8 +4516,8 @@ async function deleteDatabaseConfig(request, reply) {
4201
4516
  };
4202
4517
  }
4203
4518
  try {
4204
- if (import_core20.sqlDatabaseManager.hasDatabase(tenantId, configKey)) {
4205
- await import_core20.sqlDatabaseManager.removeDatabase(tenantId, configKey);
4519
+ if (import_core22.sqlDatabaseManager.hasDatabase(tenantId, configKey)) {
4520
+ await import_core22.sqlDatabaseManager.removeDatabase(tenantId, configKey);
4206
4521
  }
4207
4522
  } catch (error) {
4208
4523
  console.warn("Failed to remove from SqlDatabaseManager:", error);
@@ -4220,10 +4535,10 @@ async function deleteDatabaseConfig(request, reply) {
4220
4535
  }
4221
4536
  }
4222
4537
  async function testDatabaseConnection(request, reply) {
4223
- const tenantId = getTenantId7(request);
4538
+ const tenantId = getTenantId9(request);
4224
4539
  const { key } = request.params;
4225
4540
  try {
4226
- const storeLattice = (0, import_core20.getStoreLattice)("default", "database");
4541
+ const storeLattice = (0, import_core22.getStoreLattice)("default", "database");
4227
4542
  const store = storeLattice.store;
4228
4543
  const config = await store.getConfigByKey(tenantId, key);
4229
4544
  if (!config) {
@@ -4234,16 +4549,16 @@ async function testDatabaseConnection(request, reply) {
4234
4549
  };
4235
4550
  }
4236
4551
  const testKey = `__test_${key}_${Date.now()}`;
4237
- import_core20.sqlDatabaseManager.registerDatabase(tenantId, testKey, config.config);
4552
+ import_core22.sqlDatabaseManager.registerDatabase(tenantId, testKey, config.config);
4238
4553
  const startTime = Date.now();
4239
- const db = await import_core20.sqlDatabaseManager.getDatabase(tenantId, testKey);
4554
+ const db = await import_core22.sqlDatabaseManager.getDatabase(tenantId, testKey);
4240
4555
  try {
4241
4556
  await db.connect();
4242
4557
  await db.listTables();
4243
4558
  const latency = Date.now() - startTime;
4244
4559
  await new Promise((resolve) => setTimeout(resolve, 100));
4245
4560
  await db.disconnect();
4246
- await import_core20.sqlDatabaseManager.removeDatabase(tenantId, testKey);
4561
+ await import_core22.sqlDatabaseManager.removeDatabase(tenantId, testKey);
4247
4562
  return {
4248
4563
  success: true,
4249
4564
  message: "Connection test successful",
@@ -4255,7 +4570,7 @@ async function testDatabaseConnection(request, reply) {
4255
4570
  } catch (error) {
4256
4571
  try {
4257
4572
  await db.disconnect();
4258
- await import_core20.sqlDatabaseManager.removeDatabase(tenantId, testKey);
4573
+ await import_core22.sqlDatabaseManager.removeDatabase(tenantId, testKey);
4259
4574
  } catch {
4260
4575
  }
4261
4576
  return {
@@ -4307,9 +4622,9 @@ function registerDatabaseConfigRoutes(app2) {
4307
4622
  }
4308
4623
 
4309
4624
  // src/controllers/metrics-configs.ts
4310
- var import_core21 = require("@axiom-lattice/core");
4311
- var import_crypto4 = require("crypto");
4312
- function getTenantId8(request) {
4625
+ var import_core23 = require("@axiom-lattice/core");
4626
+ var import_crypto5 = require("crypto");
4627
+ function getTenantId10(request) {
4313
4628
  const userTenantId = request.user?.tenantId;
4314
4629
  if (userTenantId) {
4315
4630
  return userTenantId;
@@ -4317,9 +4632,9 @@ function getTenantId8(request) {
4317
4632
  return request.headers["x-tenant-id"] || "default";
4318
4633
  }
4319
4634
  async function getMetricsServerConfigList(request, reply) {
4320
- const tenantId = getTenantId8(request);
4635
+ const tenantId = getTenantId10(request);
4321
4636
  try {
4322
- const storeLattice = (0, import_core21.getStoreLattice)("default", "metrics");
4637
+ const storeLattice = (0, import_core23.getStoreLattice)("default", "metrics");
4323
4638
  const store = storeLattice.store;
4324
4639
  const configs = await store.getAllConfigs(tenantId);
4325
4640
  return {
@@ -4343,10 +4658,10 @@ async function getMetricsServerConfigList(request, reply) {
4343
4658
  }
4344
4659
  }
4345
4660
  async function getMetricsServerConfig(request, reply) {
4346
- const tenantId = getTenantId8(request);
4661
+ const tenantId = getTenantId10(request);
4347
4662
  const { key } = request.params;
4348
4663
  try {
4349
- const storeLattice = (0, import_core21.getStoreLattice)("default", "metrics");
4664
+ const storeLattice = (0, import_core23.getStoreLattice)("default", "metrics");
4350
4665
  const store = storeLattice.store;
4351
4666
  const config = await store.getConfigByKey(tenantId, key);
4352
4667
  if (!config) {
@@ -4369,10 +4684,10 @@ async function getMetricsServerConfig(request, reply) {
4369
4684
  }
4370
4685
  }
4371
4686
  async function createMetricsServerConfig(request, reply) {
4372
- const tenantId = getTenantId8(request);
4687
+ const tenantId = getTenantId10(request);
4373
4688
  const body = request.body;
4374
4689
  try {
4375
- const storeLattice = (0, import_core21.getStoreLattice)("default", "metrics");
4690
+ const storeLattice = (0, import_core23.getStoreLattice)("default", "metrics");
4376
4691
  const store = storeLattice.store;
4377
4692
  const existing = await store.getConfigByKey(tenantId, body.key);
4378
4693
  if (existing) {
@@ -4389,7 +4704,7 @@ async function createMetricsServerConfig(request, reply) {
4389
4704
  message: "selectedDataSources is required for semantic metrics servers"
4390
4705
  };
4391
4706
  }
4392
- const id = body.id || (0, import_crypto4.randomUUID)();
4707
+ const id = body.id || (0, import_crypto5.randomUUID)();
4393
4708
  const configData = {
4394
4709
  key: body.key,
4395
4710
  name: body.name,
@@ -4401,7 +4716,7 @@ async function createMetricsServerConfig(request, reply) {
4401
4716
  };
4402
4717
  const config = await store.createConfig(tenantId, id, configData);
4403
4718
  try {
4404
- import_core21.metricsServerManager.registerServer(tenantId, config.key, config.config);
4719
+ import_core23.metricsServerManager.registerServer(tenantId, config.key, config.config);
4405
4720
  } catch (error) {
4406
4721
  console.warn("Failed to auto-register metrics server:", error);
4407
4722
  }
@@ -4420,11 +4735,11 @@ async function createMetricsServerConfig(request, reply) {
4420
4735
  }
4421
4736
  }
4422
4737
  async function updateMetricsServerConfig(request, reply) {
4423
- const tenantId = getTenantId8(request);
4738
+ const tenantId = getTenantId10(request);
4424
4739
  const { key } = request.params;
4425
4740
  const updates = request.body;
4426
4741
  try {
4427
- const storeLattice = (0, import_core21.getStoreLattice)("default", "metrics");
4742
+ const storeLattice = (0, import_core23.getStoreLattice)("default", "metrics");
4428
4743
  const store = storeLattice.store;
4429
4744
  const existing = await store.getConfigByKey(tenantId, key);
4430
4745
  if (!existing) {
@@ -4452,7 +4767,7 @@ async function updateMetricsServerConfig(request, reply) {
4452
4767
  }
4453
4768
  if (updates.config) {
4454
4769
  try {
4455
- import_core21.metricsServerManager.registerServer(tenantId, updated.key, updated.config);
4770
+ import_core23.metricsServerManager.registerServer(tenantId, updated.key, updated.config);
4456
4771
  } catch (error) {
4457
4772
  console.warn("Failed to re-register metrics server:", error);
4458
4773
  }
@@ -4471,10 +4786,10 @@ async function updateMetricsServerConfig(request, reply) {
4471
4786
  }
4472
4787
  }
4473
4788
  async function deleteMetricsServerConfig(request, reply) {
4474
- const tenantId = getTenantId8(request);
4789
+ const tenantId = getTenantId10(request);
4475
4790
  const { keyOrId } = request.params;
4476
4791
  try {
4477
- const storeLattice = (0, import_core21.getStoreLattice)("default", "metrics");
4792
+ const storeLattice = (0, import_core23.getStoreLattice)("default", "metrics");
4478
4793
  const store = storeLattice.store;
4479
4794
  let config = await store.getConfigByKey(tenantId, keyOrId);
4480
4795
  let configKey = keyOrId;
@@ -4499,8 +4814,8 @@ async function deleteMetricsServerConfig(request, reply) {
4499
4814
  };
4500
4815
  }
4501
4816
  try {
4502
- if (import_core21.metricsServerManager.hasServer(tenantId, configKey)) {
4503
- import_core21.metricsServerManager.removeServer(tenantId, configKey);
4817
+ if (import_core23.metricsServerManager.hasServer(tenantId, configKey)) {
4818
+ import_core23.metricsServerManager.removeServer(tenantId, configKey);
4504
4819
  }
4505
4820
  } catch (error) {
4506
4821
  console.warn("Failed to remove from MetricsServerManager:", error);
@@ -4518,10 +4833,10 @@ async function deleteMetricsServerConfig(request, reply) {
4518
4833
  }
4519
4834
  }
4520
4835
  async function testMetricsServerConnection(request, reply) {
4521
- const tenantId = getTenantId8(request);
4836
+ const tenantId = getTenantId10(request);
4522
4837
  const { key } = request.params;
4523
4838
  try {
4524
- const storeLattice = (0, import_core21.getStoreLattice)("default", "metrics");
4839
+ const storeLattice = (0, import_core23.getStoreLattice)("default", "metrics");
4525
4840
  const store = storeLattice.store;
4526
4841
  const config = await store.getConfigByKey(tenantId, key);
4527
4842
  if (!config) {
@@ -4532,11 +4847,11 @@ async function testMetricsServerConnection(request, reply) {
4532
4847
  };
4533
4848
  }
4534
4849
  const testKey = `__test_${key}_${Date.now()}`;
4535
- import_core21.metricsServerManager.registerServer(tenantId, testKey, config.config);
4850
+ import_core23.metricsServerManager.registerServer(tenantId, testKey, config.config);
4536
4851
  try {
4537
- const client = await import_core21.metricsServerManager.getClient(tenantId, testKey);
4852
+ const client = await import_core23.metricsServerManager.getClient(tenantId, testKey);
4538
4853
  const result = await client.testConnection();
4539
- import_core21.metricsServerManager.removeServer(tenantId, testKey);
4854
+ import_core23.metricsServerManager.removeServer(tenantId, testKey);
4540
4855
  return {
4541
4856
  success: true,
4542
4857
  message: result.connected ? "Connection test successful" : "Connection test failed",
@@ -4544,7 +4859,7 @@ async function testMetricsServerConnection(request, reply) {
4544
4859
  };
4545
4860
  } catch (error) {
4546
4861
  try {
4547
- import_core21.metricsServerManager.removeServer(tenantId, testKey);
4862
+ import_core23.metricsServerManager.removeServer(tenantId, testKey);
4548
4863
  } catch {
4549
4864
  }
4550
4865
  return {
@@ -4569,10 +4884,10 @@ async function testMetricsServerConnection(request, reply) {
4569
4884
  }
4570
4885
  }
4571
4886
  async function listAvailableMetrics(request, reply) {
4572
- const tenantId = getTenantId8(request);
4887
+ const tenantId = getTenantId10(request);
4573
4888
  const { key } = request.params;
4574
4889
  try {
4575
- const storeLattice = (0, import_core21.getStoreLattice)("default", "metrics");
4890
+ const storeLattice = (0, import_core23.getStoreLattice)("default", "metrics");
4576
4891
  const store = storeLattice.store;
4577
4892
  const config = await store.getConfigByKey(tenantId, key);
4578
4893
  if (!config) {
@@ -4582,10 +4897,10 @@ async function listAvailableMetrics(request, reply) {
4582
4897
  message: "Metrics server configuration not found"
4583
4898
  };
4584
4899
  }
4585
- if (!import_core21.metricsServerManager.hasServer(tenantId, key)) {
4586
- import_core21.metricsServerManager.registerServer(tenantId, key, config.config);
4900
+ if (!import_core23.metricsServerManager.hasServer(tenantId, key)) {
4901
+ import_core23.metricsServerManager.registerServer(tenantId, key, config.config);
4587
4902
  }
4588
- const client = await import_core21.metricsServerManager.getClient(tenantId, key);
4903
+ const client = await import_core23.metricsServerManager.getClient(tenantId, key);
4589
4904
  const metrics = await client.listMetrics();
4590
4905
  return {
4591
4906
  success: true,
@@ -4607,11 +4922,11 @@ async function listAvailableMetrics(request, reply) {
4607
4922
  }
4608
4923
  }
4609
4924
  async function queryMetricsData(request, reply) {
4610
- const tenantId = getTenantId8(request);
4925
+ const tenantId = getTenantId10(request);
4611
4926
  const { key } = request.params;
4612
4927
  const { metricName, startTime, endTime, step, labels } = request.body;
4613
4928
  try {
4614
- const storeLattice = (0, import_core21.getStoreLattice)("default", "metrics");
4929
+ const storeLattice = (0, import_core23.getStoreLattice)("default", "metrics");
4615
4930
  const store = storeLattice.store;
4616
4931
  const config = await store.getConfigByKey(tenantId, key);
4617
4932
  if (!config) {
@@ -4628,10 +4943,10 @@ async function queryMetricsData(request, reply) {
4628
4943
  message: "metricName is required"
4629
4944
  };
4630
4945
  }
4631
- if (!import_core21.metricsServerManager.hasServer(tenantId, key)) {
4632
- import_core21.metricsServerManager.registerServer(tenantId, key, config.config);
4946
+ if (!import_core23.metricsServerManager.hasServer(tenantId, key)) {
4947
+ import_core23.metricsServerManager.registerServer(tenantId, key, config.config);
4633
4948
  }
4634
- const client = await import_core21.metricsServerManager.getClient(tenantId, key);
4949
+ const client = await import_core23.metricsServerManager.getClient(tenantId, key);
4635
4950
  const result = await client.queryMetricData(metricName, {
4636
4951
  startTime,
4637
4952
  endTime,
@@ -4655,10 +4970,10 @@ async function queryMetricsData(request, reply) {
4655
4970
  }
4656
4971
  }
4657
4972
  async function getDataSources(request, reply) {
4658
- const tenantId = getTenantId8(request);
4973
+ const tenantId = getTenantId10(request);
4659
4974
  const { key } = request.params;
4660
4975
  try {
4661
- const storeLattice = (0, import_core21.getStoreLattice)("default", "metrics");
4976
+ const storeLattice = (0, import_core23.getStoreLattice)("default", "metrics");
4662
4977
  const store = storeLattice.store;
4663
4978
  const config = await store.getConfigByKey(tenantId, key);
4664
4979
  if (!config) {
@@ -4676,7 +4991,7 @@ async function getDataSources(request, reply) {
4676
4991
  };
4677
4992
  }
4678
4993
  const semanticConfig = config.config;
4679
- const client = new import_core21.SemanticMetricsClient(semanticConfig);
4994
+ const client = new import_core23.SemanticMetricsClient(semanticConfig);
4680
4995
  const allDatasources = await client.getDataSources();
4681
4996
  const selectedIds = semanticConfig.selectedDataSources || [];
4682
4997
  const filteredDatasources = selectedIds.length > 0 ? allDatasources.filter((ds) => selectedIds.includes(String(ds.id))) : allDatasources;
@@ -4696,10 +5011,10 @@ async function getDataSources(request, reply) {
4696
5011
  }
4697
5012
  }
4698
5013
  async function getDatasourceMetrics(request, reply) {
4699
- const tenantId = getTenantId8(request);
5014
+ const tenantId = getTenantId10(request);
4700
5015
  const { key, datasourceId } = request.params;
4701
5016
  try {
4702
- const storeLattice = (0, import_core21.getStoreLattice)("default", "metrics");
5017
+ const storeLattice = (0, import_core23.getStoreLattice)("default", "metrics");
4703
5018
  const store = storeLattice.store;
4704
5019
  const config = await store.getConfigByKey(tenantId, key);
4705
5020
  if (!config) {
@@ -4717,7 +5032,7 @@ async function getDatasourceMetrics(request, reply) {
4717
5032
  };
4718
5033
  }
4719
5034
  const semanticConfig = config.config;
4720
- const client = new import_core21.SemanticMetricsClient(semanticConfig);
5035
+ const client = new import_core23.SemanticMetricsClient(semanticConfig);
4721
5036
  const metrics = await client.getDatasourceMetrics(datasourceId);
4722
5037
  return {
4723
5038
  success: true,
@@ -4733,11 +5048,11 @@ async function getDatasourceMetrics(request, reply) {
4733
5048
  }
4734
5049
  }
4735
5050
  async function querySemanticMetrics(request, reply) {
4736
- const tenantId = getTenantId8(request);
5051
+ const tenantId = getTenantId10(request);
4737
5052
  const { key } = request.params;
4738
5053
  const body = request.body;
4739
5054
  try {
4740
- const storeLattice = (0, import_core21.getStoreLattice)("default", "metrics");
5055
+ const storeLattice = (0, import_core23.getStoreLattice)("default", "metrics");
4741
5056
  const store = storeLattice.store;
4742
5057
  const config = await store.getConfigByKey(tenantId, key);
4743
5058
  if (!config) {
@@ -4762,7 +5077,7 @@ async function querySemanticMetrics(request, reply) {
4762
5077
  };
4763
5078
  }
4764
5079
  const semanticConfig = config.config;
4765
- const client = new import_core21.SemanticMetricsClient(semanticConfig);
5080
+ const client = new import_core23.SemanticMetricsClient(semanticConfig);
4766
5081
  const result = await client.semanticQuery(body);
4767
5082
  const columnNames = result.columns.map((col) => col.name);
4768
5083
  const allDataPoints = [];
@@ -4822,7 +5137,7 @@ async function testSemanticDataSources(request, reply) {
4822
5137
  password: body.password,
4823
5138
  headers: body.headers
4824
5139
  };
4825
- const client = new import_core21.SemanticMetricsClient(testConfig);
5140
+ const client = new import_core23.SemanticMetricsClient(testConfig);
4826
5141
  const datasources = await client.getDataSources();
4827
5142
  return {
4828
5143
  success: true,
@@ -4858,7 +5173,7 @@ async function testDatasourceMetrics(request, reply) {
4858
5173
  password: body.password,
4859
5174
  headers: body.headers
4860
5175
  };
4861
- const client = new import_core21.SemanticMetricsClient(testConfig);
5176
+ const client = new import_core23.SemanticMetricsClient(testConfig);
4862
5177
  const metrics = await client.getDatasourceMetrics(datasourceId);
4863
5178
  return {
4864
5179
  success: true,
@@ -4890,9 +5205,9 @@ function registerMetricsServerConfigRoutes(app2) {
4890
5205
  }
4891
5206
 
4892
5207
  // src/controllers/mcp-configs.ts
4893
- var import_core22 = require("@axiom-lattice/core");
4894
- var import_crypto5 = require("crypto");
4895
- function getTenantId9(request) {
5208
+ var import_core24 = require("@axiom-lattice/core");
5209
+ var import_crypto6 = require("crypto");
5210
+ function getTenantId11(request) {
4896
5211
  const userTenantId = request.user?.tenantId;
4897
5212
  if (userTenantId) {
4898
5213
  return userTenantId;
@@ -4900,9 +5215,9 @@ function getTenantId9(request) {
4900
5215
  return request.headers["x-tenant-id"] || "default";
4901
5216
  }
4902
5217
  async function getMcpServerConfigList(request, reply) {
4903
- const tenantId = getTenantId9(request);
5218
+ const tenantId = getTenantId11(request);
4904
5219
  try {
4905
- const storeLattice = (0, import_core22.getStoreLattice)("default", "mcp");
5220
+ const storeLattice = (0, import_core24.getStoreLattice)("default", "mcp");
4906
5221
  const store = storeLattice.store;
4907
5222
  const configs = await store.getAllConfigs(tenantId);
4908
5223
  return {
@@ -4926,10 +5241,10 @@ async function getMcpServerConfigList(request, reply) {
4926
5241
  }
4927
5242
  }
4928
5243
  async function getMcpServerConfig(request, reply) {
4929
- const tenantId = getTenantId9(request);
5244
+ const tenantId = getTenantId11(request);
4930
5245
  const { key } = request.params;
4931
5246
  try {
4932
- const storeLattice = (0, import_core22.getStoreLattice)("default", "mcp");
5247
+ const storeLattice = (0, import_core24.getStoreLattice)("default", "mcp");
4933
5248
  const store = storeLattice.store;
4934
5249
  const config = await store.getConfigByKey(tenantId, key);
4935
5250
  if (!config) {
@@ -4952,10 +5267,10 @@ async function getMcpServerConfig(request, reply) {
4952
5267
  }
4953
5268
  }
4954
5269
  async function createMcpServerConfig(request, reply) {
4955
- const tenantId = getTenantId9(request);
5270
+ const tenantId = getTenantId11(request);
4956
5271
  const body = request.body;
4957
5272
  try {
4958
- const storeLattice = (0, import_core22.getStoreLattice)("default", "mcp");
5273
+ const storeLattice = (0, import_core24.getStoreLattice)("default", "mcp");
4959
5274
  const store = storeLattice.store;
4960
5275
  const existing = await store.getConfigByKey(tenantId, body.key);
4961
5276
  if (existing) {
@@ -4965,7 +5280,7 @@ async function createMcpServerConfig(request, reply) {
4965
5280
  message: "MCP server configuration with this key already exists"
4966
5281
  };
4967
5282
  }
4968
- const id = body.id || (0, import_crypto5.randomUUID)();
5283
+ const id = body.id || (0, import_crypto6.randomUUID)();
4969
5284
  const config = await store.createConfig(tenantId, id, body);
4970
5285
  try {
4971
5286
  await connectAndRegisterTools(config);
@@ -4991,11 +5306,11 @@ async function createMcpServerConfig(request, reply) {
4991
5306
  }
4992
5307
  }
4993
5308
  async function updateMcpServerConfig(request, reply) {
4994
- const tenantId = getTenantId9(request);
5309
+ const tenantId = getTenantId11(request);
4995
5310
  const { key } = request.params;
4996
5311
  const updates = request.body;
4997
5312
  try {
4998
- const storeLattice = (0, import_core22.getStoreLattice)("default", "mcp");
5313
+ const storeLattice = (0, import_core24.getStoreLattice)("default", "mcp");
4999
5314
  const store = storeLattice.store;
5000
5315
  const existing = await store.getConfigByKey(tenantId, key);
5001
5316
  if (!existing) {
@@ -5015,8 +5330,8 @@ async function updateMcpServerConfig(request, reply) {
5015
5330
  }
5016
5331
  if (shouldReconnect) {
5017
5332
  try {
5018
- if (import_core22.mcpManager.hasServer(key)) {
5019
- await import_core22.mcpManager.removeServer(key);
5333
+ if (import_core24.mcpManager.hasServer(key)) {
5334
+ await import_core24.mcpManager.removeServer(key);
5020
5335
  }
5021
5336
  await connectAndRegisterTools(updated);
5022
5337
  await store.updateConfig(tenantId, existing.id, { status: "connected" });
@@ -5041,10 +5356,10 @@ async function updateMcpServerConfig(request, reply) {
5041
5356
  }
5042
5357
  }
5043
5358
  async function deleteMcpServerConfig(request, reply) {
5044
- const tenantId = getTenantId9(request);
5359
+ const tenantId = getTenantId11(request);
5045
5360
  const { keyOrId } = request.params;
5046
5361
  try {
5047
- const storeLattice = (0, import_core22.getStoreLattice)("default", "mcp");
5362
+ const storeLattice = (0, import_core24.getStoreLattice)("default", "mcp");
5048
5363
  const store = storeLattice.store;
5049
5364
  let config = await store.getConfigByKey(tenantId, keyOrId);
5050
5365
  let configKey = keyOrId;
@@ -5062,8 +5377,8 @@ async function deleteMcpServerConfig(request, reply) {
5062
5377
  };
5063
5378
  }
5064
5379
  try {
5065
- if (import_core22.mcpManager.hasServer(configKey)) {
5066
- await import_core22.mcpManager.removeServer(configKey);
5380
+ if (import_core24.mcpManager.hasServer(configKey)) {
5381
+ await import_core24.mcpManager.removeServer(configKey);
5067
5382
  }
5068
5383
  } catch (error) {
5069
5384
  console.warn("Failed to remove from MCP manager:", error);
@@ -5088,10 +5403,10 @@ async function deleteMcpServerConfig(request, reply) {
5088
5403
  }
5089
5404
  }
5090
5405
  async function testMcpServerConnection(request, reply) {
5091
- const tenantId = getTenantId9(request);
5406
+ const tenantId = getTenantId11(request);
5092
5407
  const { key } = request.params;
5093
5408
  try {
5094
- const storeLattice = (0, import_core22.getStoreLattice)("default", "mcp");
5409
+ const storeLattice = (0, import_core24.getStoreLattice)("default", "mcp");
5095
5410
  const store = storeLattice.store;
5096
5411
  const config = await store.getConfigByKey(tenantId, key);
5097
5412
  if (!config) {
@@ -5105,11 +5420,11 @@ async function testMcpServerConnection(request, reply) {
5105
5420
  try {
5106
5421
  const testKey = `__test_${key}_${Date.now()}`;
5107
5422
  const connection = convertToConnection(config.config);
5108
- import_core22.mcpManager.addServer(testKey, connection);
5109
- await import_core22.mcpManager.connect();
5110
- const tools = await import_core22.mcpManager.getAllTools();
5423
+ import_core24.mcpManager.addServer(testKey, connection);
5424
+ await import_core24.mcpManager.connect();
5425
+ const tools = await import_core24.mcpManager.getAllTools();
5111
5426
  const latency = Date.now() - startTime;
5112
- await import_core22.mcpManager.removeServer(testKey);
5427
+ await import_core24.mcpManager.removeServer(testKey);
5113
5428
  return {
5114
5429
  success: true,
5115
5430
  message: "Connection test successful",
@@ -5141,10 +5456,10 @@ async function testMcpServerConnection(request, reply) {
5141
5456
  }
5142
5457
  }
5143
5458
  async function listMcpServerTools(request, reply) {
5144
- const tenantId = getTenantId9(request);
5459
+ const tenantId = getTenantId11(request);
5145
5460
  const { key } = request.params;
5146
5461
  try {
5147
- const storeLattice = (0, import_core22.getStoreLattice)("default", "mcp");
5462
+ const storeLattice = (0, import_core24.getStoreLattice)("default", "mcp");
5148
5463
  const store = storeLattice.store;
5149
5464
  const config = await store.getConfigByKey(tenantId, key);
5150
5465
  if (!config) {
@@ -5154,10 +5469,10 @@ async function listMcpServerTools(request, reply) {
5154
5469
  message: "MCP server configuration not found"
5155
5470
  };
5156
5471
  }
5157
- if (!import_core22.mcpManager.hasServer(key)) {
5472
+ if (!import_core24.mcpManager.hasServer(key)) {
5158
5473
  await connectAndRegisterTools(config);
5159
5474
  }
5160
- const tools = await import_core22.mcpManager.getAllTools();
5475
+ const tools = await import_core24.mcpManager.getAllTools();
5161
5476
  return {
5162
5477
  success: true,
5163
5478
  message: "Tools retrieved successfully",
@@ -5174,10 +5489,10 @@ async function listMcpServerTools(request, reply) {
5174
5489
  }
5175
5490
  }
5176
5491
  async function connectMcpServer(request, reply) {
5177
- const tenantId = getTenantId9(request);
5492
+ const tenantId = getTenantId11(request);
5178
5493
  const { key } = request.params;
5179
5494
  try {
5180
- const storeLattice = (0, import_core22.getStoreLattice)("default", "mcp");
5495
+ const storeLattice = (0, import_core24.getStoreLattice)("default", "mcp");
5181
5496
  const store = storeLattice.store;
5182
5497
  const config = await store.getConfigByKey(tenantId, key);
5183
5498
  if (!config) {
@@ -5198,7 +5513,7 @@ async function connectMcpServer(request, reply) {
5198
5513
  };
5199
5514
  } catch (error) {
5200
5515
  console.error("Failed to connect MCP server:", error);
5201
- const storeLattice = (0, import_core22.getStoreLattice)("default", "mcp");
5516
+ const storeLattice = (0, import_core24.getStoreLattice)("default", "mcp");
5202
5517
  const store = storeLattice.store;
5203
5518
  const config = await store.getConfigByKey(tenantId, key);
5204
5519
  if (config) {
@@ -5211,10 +5526,10 @@ async function connectMcpServer(request, reply) {
5211
5526
  }
5212
5527
  }
5213
5528
  async function disconnectMcpServer(request, reply) {
5214
- const tenantId = getTenantId9(request);
5529
+ const tenantId = getTenantId11(request);
5215
5530
  const { key } = request.params;
5216
5531
  try {
5217
- const storeLattice = (0, import_core22.getStoreLattice)("default", "mcp");
5532
+ const storeLattice = (0, import_core24.getStoreLattice)("default", "mcp");
5218
5533
  const store = storeLattice.store;
5219
5534
  const config = await store.getConfigByKey(tenantId, key);
5220
5535
  if (!config) {
@@ -5224,8 +5539,8 @@ async function disconnectMcpServer(request, reply) {
5224
5539
  message: "MCP server configuration not found"
5225
5540
  };
5226
5541
  }
5227
- if (import_core22.mcpManager.hasServer(key)) {
5228
- await import_core22.mcpManager.removeServer(key);
5542
+ if (import_core24.mcpManager.hasServer(key)) {
5543
+ await import_core24.mcpManager.removeServer(key);
5229
5544
  }
5230
5545
  const updated = await store.updateConfig(tenantId, config.id, {
5231
5546
  status: "disconnected"
@@ -5255,10 +5570,10 @@ async function testMcpServerTools(request, reply) {
5255
5570
  }
5256
5571
  const testKey = `__test_${Date.now()}`;
5257
5572
  const connection = convertToConnection(body.config);
5258
- import_core22.mcpManager.addServer(testKey, connection);
5259
- await import_core22.mcpManager.connect();
5260
- const tools = await import_core22.mcpManager.getAllTools();
5261
- await import_core22.mcpManager.removeServer(testKey);
5573
+ import_core24.mcpManager.addServer(testKey, connection);
5574
+ await import_core24.mcpManager.connect();
5575
+ const tools = await import_core24.mcpManager.getAllTools();
5576
+ await import_core24.mcpManager.removeServer(testKey);
5262
5577
  return {
5263
5578
  success: true,
5264
5579
  message: "Tools retrieved successfully",
@@ -5295,14 +5610,14 @@ function convertToConnection(config) {
5295
5610
  }
5296
5611
  async function connectAndRegisterTools(config) {
5297
5612
  const connection = convertToConnection(config.config);
5298
- import_core22.mcpManager.addServer(config.key, connection);
5299
- await import_core22.mcpManager.connect();
5300
- const allTools = await import_core22.mcpManager.getAllTools();
5613
+ import_core24.mcpManager.addServer(config.key, connection);
5614
+ await import_core24.mcpManager.connect();
5615
+ const allTools = await import_core24.mcpManager.getAllTools();
5301
5616
  const selectedTools = allTools.filter(
5302
5617
  (tool) => config.selectedTools.includes(tool.name)
5303
5618
  );
5304
5619
  for (const tool of selectedTools) {
5305
- import_core22.toolLatticeManager.registerExistingTool(tool.name, tool);
5620
+ import_core24.toolLatticeManager.registerExistingTool(tool.name, tool);
5306
5621
  }
5307
5622
  }
5308
5623
  function registerMcpServerConfigRoutes(app2) {
@@ -5319,12 +5634,12 @@ function registerMcpServerConfigRoutes(app2) {
5319
5634
  }
5320
5635
 
5321
5636
  // src/controllers/eval.ts
5322
- var import_core24 = require("@axiom-lattice/core");
5637
+ var import_core26 = require("@axiom-lattice/core");
5323
5638
  var import_uuid4 = require("uuid");
5324
5639
 
5325
5640
  // src/services/eval-runner.ts
5326
5641
  var import_events = require("events");
5327
- var import_core23 = require("@axiom-lattice/core");
5642
+ var import_core25 = require("@axiom-lattice/core");
5328
5643
  var import_agent_eval = require("@axiom-lattice/agent-eval");
5329
5644
  var import_uuid3 = require("uuid");
5330
5645
  function mapLogs(logs) {
@@ -5386,7 +5701,7 @@ var EvalRunner = class {
5386
5701
  if (hasModelKey) {
5387
5702
  judgeModelConfig = { modelKey: judgeCfg.modelKey };
5388
5703
  } else if (!hasCredentials) {
5389
- const firstModel = import_core23.modelLatticeManager.getAllLattices()[0];
5704
+ const firstModel = import_core25.modelLatticeManager.getAllLattices()[0];
5390
5705
  if (firstModel) {
5391
5706
  judgeModelConfig = { modelKey: firstModel.key };
5392
5707
  } else {
@@ -5497,13 +5812,13 @@ var EvalRunner = class {
5497
5812
  return this.runs.has(runId);
5498
5813
  }
5499
5814
  getEvalStore() {
5500
- return (0, import_core23.getStoreLattice)("default", "eval").store;
5815
+ return (0, import_core25.getStoreLattice)("default", "eval").store;
5501
5816
  }
5502
5817
  };
5503
5818
  var evalRunner = new EvalRunner();
5504
5819
 
5505
5820
  // src/controllers/eval.ts
5506
- function getTenantId10(request) {
5821
+ function getTenantId12(request) {
5507
5822
  const userTenantId = request.user?.tenantId;
5508
5823
  if (userTenantId) {
5509
5824
  return userTenantId;
@@ -5511,11 +5826,11 @@ function getTenantId10(request) {
5511
5826
  return request.headers["x-tenant-id"] || "default";
5512
5827
  }
5513
5828
  function getEvalStore() {
5514
- return (0, import_core24.getStoreLattice)("default", "eval").store;
5829
+ return (0, import_core26.getStoreLattice)("default", "eval").store;
5515
5830
  }
5516
5831
  async function createProject(request, reply) {
5517
5832
  try {
5518
- const tenantId = getTenantId10(request);
5833
+ const tenantId = getTenantId12(request);
5519
5834
  const store = getEvalStore();
5520
5835
  const id = (0, import_uuid4.v4)();
5521
5836
  const data = request.body;
@@ -5540,7 +5855,7 @@ async function createProject(request, reply) {
5540
5855
  }
5541
5856
  async function listProjects(request, reply) {
5542
5857
  try {
5543
- const tenantId = getTenantId10(request);
5858
+ const tenantId = getTenantId12(request);
5544
5859
  const store = getEvalStore();
5545
5860
  let projects = await store.getProjectsByTenant(tenantId);
5546
5861
  if (projects.length === 0) {
@@ -5574,7 +5889,7 @@ async function listProjects(request, reply) {
5574
5889
  }
5575
5890
  async function getProject(request, reply) {
5576
5891
  try {
5577
- const tenantId = getTenantId10(request);
5892
+ const tenantId = getTenantId12(request);
5578
5893
  const store = getEvalStore();
5579
5894
  const { pid } = request.params;
5580
5895
  const project = await store.getProjectById(tenantId, pid);
@@ -5594,7 +5909,7 @@ async function getProject(request, reply) {
5594
5909
  }
5595
5910
  async function updateProject(request, reply) {
5596
5911
  try {
5597
- const tenantId = getTenantId10(request);
5912
+ const tenantId = getTenantId12(request);
5598
5913
  const store = getEvalStore();
5599
5914
  const { pid } = request.params;
5600
5915
  const existing = await store.getProjectById(tenantId, pid);
@@ -5614,7 +5929,7 @@ async function updateProject(request, reply) {
5614
5929
  }
5615
5930
  async function deleteProject(request, reply) {
5616
5931
  try {
5617
- const tenantId = getTenantId10(request);
5932
+ const tenantId = getTenantId12(request);
5618
5933
  const store = getEvalStore();
5619
5934
  const { pid } = request.params;
5620
5935
  const existing = await store.getProjectById(tenantId, pid);
@@ -5633,7 +5948,7 @@ async function deleteProject(request, reply) {
5633
5948
  }
5634
5949
  async function createSuite(request, reply) {
5635
5950
  try {
5636
- const tenantId = getTenantId10(request);
5951
+ const tenantId = getTenantId12(request);
5637
5952
  const store = getEvalStore();
5638
5953
  const { pid } = request.params;
5639
5954
  const project = await store.getProjectById(tenantId, pid);
@@ -5655,7 +5970,7 @@ async function createSuite(request, reply) {
5655
5970
  }
5656
5971
  async function updateSuite(request, reply) {
5657
5972
  try {
5658
- const tenantId = getTenantId10(request);
5973
+ const tenantId = getTenantId12(request);
5659
5974
  const store = getEvalStore();
5660
5975
  const { sid } = request.params;
5661
5976
  const existing = await store.getSuiteById(tenantId, sid);
@@ -5675,7 +5990,7 @@ async function updateSuite(request, reply) {
5675
5990
  }
5676
5991
  async function deleteSuite(request, reply) {
5677
5992
  try {
5678
- const tenantId = getTenantId10(request);
5993
+ const tenantId = getTenantId12(request);
5679
5994
  const store = getEvalStore();
5680
5995
  const { sid } = request.params;
5681
5996
  const existing = await store.getSuiteById(tenantId, sid);
@@ -5694,7 +6009,7 @@ async function deleteSuite(request, reply) {
5694
6009
  }
5695
6010
  async function createCase(request, reply) {
5696
6011
  try {
5697
- const tenantId = getTenantId10(request);
6012
+ const tenantId = getTenantId12(request);
5698
6013
  const store = getEvalStore();
5699
6014
  const { sid } = request.params;
5700
6015
  const suite = await store.getSuiteById(tenantId, sid);
@@ -5723,7 +6038,7 @@ async function createCase(request, reply) {
5723
6038
  }
5724
6039
  async function listCasesForSuite(request, reply) {
5725
6040
  try {
5726
- const tenantId = getTenantId10(request);
6041
+ const tenantId = getTenantId12(request);
5727
6042
  const store = getEvalStore();
5728
6043
  const { sid } = request.params;
5729
6044
  const cases = await store.getCasesBySuite(tenantId, sid);
@@ -5739,7 +6054,7 @@ async function listCasesForSuite(request, reply) {
5739
6054
  }
5740
6055
  async function updateCase(request, reply) {
5741
6056
  try {
5742
- const tenantId = getTenantId10(request);
6057
+ const tenantId = getTenantId12(request);
5743
6058
  const store = getEvalStore();
5744
6059
  const { cid } = request.params;
5745
6060
  const existing = await store.getCaseById(tenantId, cid);
@@ -5759,7 +6074,7 @@ async function updateCase(request, reply) {
5759
6074
  }
5760
6075
  async function deleteCase(request, reply) {
5761
6076
  try {
5762
- const tenantId = getTenantId10(request);
6077
+ const tenantId = getTenantId12(request);
5763
6078
  const store = getEvalStore();
5764
6079
  const { cid } = request.params;
5765
6080
  const existing = await store.getCaseById(tenantId, cid);
@@ -5791,7 +6106,7 @@ function registerEvalRoutes(app2) {
5791
6106
  app2.delete("/api/eval/projects/:pid/suites/:sid/cases/:cid", deleteCase);
5792
6107
  app2.post("/api/eval/projects/:pid/runs", async (request, reply) => {
5793
6108
  try {
5794
- const tenantId = getTenantId10(request);
6109
+ const tenantId = getTenantId12(request);
5795
6110
  const { pid } = request.params;
5796
6111
  const runId = await evalRunner.startRun(tenantId, pid);
5797
6112
  reply.status(202).send({ success: true, message: "Run started", data: { run_id: runId } });
@@ -5803,7 +6118,7 @@ function registerEvalRoutes(app2) {
5803
6118
  });
5804
6119
  app2.get("/api/eval/runs", async (request, reply) => {
5805
6120
  try {
5806
- const tenantId = getTenantId10(request);
6121
+ const tenantId = getTenantId12(request);
5807
6122
  const query = request.query;
5808
6123
  const runs = await getEvalStore().getRunsByTenant(tenantId, { projectId: query.project_id, status: query.status });
5809
6124
  reply.send({ success: true, message: "Ok", data: { records: runs, total: runs.length } });
@@ -5813,7 +6128,7 @@ function registerEvalRoutes(app2) {
5813
6128
  });
5814
6129
  app2.get("/api/eval/runs/:rid", async (request, reply) => {
5815
6130
  try {
5816
- const tenantId = getTenantId10(request);
6131
+ const tenantId = getTenantId12(request);
5817
6132
  const { rid } = request.params;
5818
6133
  const run = await getEvalStore().getRunById(tenantId, rid);
5819
6134
  if (!run) return reply.status(404).send({ success: false, message: "Run not found" });
@@ -5835,7 +6150,7 @@ function registerEvalRoutes(app2) {
5835
6150
  const emitter = evalRunner.getEventEmitter();
5836
6151
  const eventKey = `run:${rid}`;
5837
6152
  if (!evalRunner.isRunning(rid)) {
5838
- const tenantId = getTenantId10(request);
6153
+ const tenantId = getTenantId12(request);
5839
6154
  const run = await getEvalStore().getRunById(tenantId, rid);
5840
6155
  if (run) {
5841
6156
  const eventType = run.status === "completed" ? "completed" : "error";
@@ -5874,7 +6189,7 @@ data: ${JSON.stringify(event.data)}
5874
6189
  });
5875
6190
  app2.delete("/api/eval/runs/:rid", async (request, reply) => {
5876
6191
  try {
5877
- const tenantId = getTenantId10(request);
6192
+ const tenantId = getTenantId12(request);
5878
6193
  const { rid } = request.params;
5879
6194
  const deleted = await getEvalStore().deleteRun(tenantId, rid);
5880
6195
  if (!deleted) return reply.status(404).send({ success: false, message: "Run not found" });
@@ -5885,7 +6200,7 @@ data: ${JSON.stringify(event.data)}
5885
6200
  });
5886
6201
  app2.get("/api/eval/reports/projects/:pid", async (request, reply) => {
5887
6202
  try {
5888
- const tenantId = getTenantId10(request);
6203
+ const tenantId = getTenantId12(request);
5889
6204
  const { pid } = request.params;
5890
6205
  const report = await getEvalStore().getProjectReport(tenantId, pid);
5891
6206
  if (!report) return reply.status(404).send({ success: false, message: "Project not found" });
@@ -5897,11 +6212,11 @@ data: ${JSON.stringify(event.data)}
5897
6212
  }
5898
6213
 
5899
6214
  // src/controllers/users.ts
5900
- var import_core25 = require("@axiom-lattice/core");
6215
+ var import_core27 = require("@axiom-lattice/core");
5901
6216
  var import_uuid5 = require("uuid");
5902
6217
  var UsersController = class {
5903
6218
  constructor() {
5904
- this.userStore = (0, import_core25.getStoreLattice)("default", "user").store;
6219
+ this.userStore = (0, import_core27.getStoreLattice)("default", "user").store;
5905
6220
  }
5906
6221
  async listUsers(request, reply) {
5907
6222
  const { email } = request.query;
@@ -5979,11 +6294,11 @@ function registerUserRoutes(app2) {
5979
6294
  }
5980
6295
 
5981
6296
  // src/controllers/tenants.ts
5982
- var import_core26 = require("@axiom-lattice/core");
6297
+ var import_core28 = require("@axiom-lattice/core");
5983
6298
  var import_uuid6 = require("uuid");
5984
6299
  var TenantsController = class {
5985
6300
  constructor() {
5986
- this.tenantStore = (0, import_core26.getStoreLattice)("default", "tenant").store;
6301
+ this.tenantStore = (0, import_core28.getStoreLattice)("default", "tenant").store;
5987
6302
  }
5988
6303
  // ==================== Tenant CRUD ====================
5989
6304
  async listTenants(request, reply) {
@@ -6047,7 +6362,7 @@ function registerTenantRoutes(app2) {
6047
6362
  }
6048
6363
 
6049
6364
  // src/controllers/auth.ts
6050
- var import_core27 = require("@axiom-lattice/core");
6365
+ var import_core29 = require("@axiom-lattice/core");
6051
6366
  var import_uuid7 = require("uuid");
6052
6367
  var defaultAuthConfig = {
6053
6368
  autoApproveUsers: true,
@@ -6056,9 +6371,9 @@ var defaultAuthConfig = {
6056
6371
  };
6057
6372
  var AuthController = class {
6058
6373
  constructor(config = {}) {
6059
- this.userStore = (0, import_core27.getStoreLattice)("default", "user").store;
6060
- this.tenantStore = (0, import_core27.getStoreLattice)("default", "tenant").store;
6061
- this.userTenantLinkStore = (0, import_core27.getStoreLattice)("default", "userTenantLink").store;
6374
+ this.userStore = (0, import_core29.getStoreLattice)("default", "user").store;
6375
+ this.tenantStore = (0, import_core29.getStoreLattice)("default", "tenant").store;
6376
+ this.userTenantLinkStore = (0, import_core29.getStoreLattice)("default", "userTenantLink").store;
6062
6377
  this.config = { ...defaultAuthConfig, ...config };
6063
6378
  }
6064
6379
  async register(request, reply) {
@@ -6212,6 +6527,8 @@ var AuthController = class {
6212
6527
  });
6213
6528
  }
6214
6529
  const token = await this.generateToken(userId, tenantId);
6530
+ const link = await this.userTenantLinkStore.getLink(userId, tenantId);
6531
+ const linkMeta = link?.metadata || {};
6215
6532
  return {
6216
6533
  success: true,
6217
6534
  data: {
@@ -6220,7 +6537,12 @@ var AuthController = class {
6220
6537
  name: tenant.name,
6221
6538
  status: tenant.status
6222
6539
  },
6223
- token
6540
+ token,
6541
+ personalAssistant: linkMeta.personalAssistantId ? {
6542
+ assistantId: linkMeta.personalAssistantId,
6543
+ projectId: linkMeta.personalProjectId || "default",
6544
+ workspaceId: linkMeta.personalWorkspaceId || "default"
6545
+ } : null
6224
6546
  }
6225
6547
  };
6226
6548
  } catch (error) {
@@ -6466,82 +6788,6 @@ function normalizeChatType(chatType) {
6466
6788
  return chatType === "p2p" ? "direct" : "group";
6467
6789
  }
6468
6790
 
6469
- // src/channels/lark/LarkChannelAdapter.ts
6470
- var larkConfigSchema = import_zod.z.object({
6471
- appId: import_zod.z.string(),
6472
- appSecret: import_zod.z.string(),
6473
- verificationToken: import_zod.z.string().optional(),
6474
- encryptKey: import_zod.z.string().optional()
6475
- });
6476
- var larkChannelAdapter = {
6477
- channel: "lark",
6478
- configSchema: larkConfigSchema,
6479
- async receive(rawPayload, installation) {
6480
- const event = parseLarkMessageEvent(rawPayload);
6481
- if (!event) return null;
6482
- return {
6483
- channel: "lark",
6484
- channelInstallationId: installation.id,
6485
- tenantId: installation.tenantId,
6486
- sender: {
6487
- id: event.openId,
6488
- displayName: void 0
6489
- },
6490
- content: {
6491
- text: event.text,
6492
- metadata: {
6493
- chatId: event.chatId,
6494
- chatType: event.chatType,
6495
- messageId: event.messageId
6496
- }
6497
- },
6498
- conversation: {
6499
- id: event.chatId,
6500
- type: event.chatType
6501
- },
6502
- replyTarget: {
6503
- adapterChannel: "lark",
6504
- channelInstallationId: installation.id,
6505
- rawTarget: {
6506
- chatId: event.chatId,
6507
- messageId: event.messageId,
6508
- chatType: event.chatType
6509
- }
6510
- }
6511
- };
6512
- },
6513
- async sendReply(replyTarget, message, installation) {
6514
- const { createLarkSender: createLarkSender2 } = await Promise.resolve().then(() => (init_sender(), sender_exports));
6515
- const sender = await createLarkSender2(installation.config);
6516
- await sender.sendTextReply({
6517
- chatId: replyTarget.rawTarget.chatId,
6518
- text: message.text
6519
- });
6520
- }
6521
- };
6522
-
6523
- // src/channels/lark/verification.ts
6524
- var import_crypto6 = __toESM(require("crypto"));
6525
- function parseLarkRequestBody(body, encryptKey) {
6526
- const parsed = body || {};
6527
- if (encryptKey && typeof parsed.encrypt === "string") {
6528
- return decryptLarkPayload(encryptKey, parsed.encrypt);
6529
- }
6530
- return parsed;
6531
- }
6532
- function decryptLarkPayload(encryptKey, encryptedPayload) {
6533
- const key = import_crypto6.default.createHash("sha256").update(encryptKey).digest();
6534
- const buffer = Buffer.from(encryptedPayload, "base64");
6535
- const iv = buffer.subarray(0, 16);
6536
- const ciphertext = buffer.subarray(16);
6537
- const decipher = import_crypto6.default.createDecipheriv("aes-256-cbc", key, iv);
6538
- const plaintext = Buffer.concat([
6539
- decipher.update(ciphertext),
6540
- decipher.final()
6541
- ]).toString("utf8");
6542
- return JSON.parse(plaintext);
6543
- }
6544
-
6545
6791
  // src/logger/Logger.ts
6546
6792
  var import_pino = __toESM(require("pino"));
6547
6793
  var import_pino_pretty = require("pino-pretty");
@@ -6680,8 +6926,165 @@ var Logger = class _Logger {
6680
6926
  }
6681
6927
  };
6682
6928
 
6683
- // src/channels/lark/controller.ts
6929
+ // src/channels/lark/LarkChannelAdapter.ts
6930
+ var Lark = __toESM(require("@larksuiteoapi/node-sdk"));
6684
6931
  var logger = new Logger({ serviceName: "lattice/gateway/lark" });
6932
+ var activeConnections = /* @__PURE__ */ new Map();
6933
+ function parseTextContent(content) {
6934
+ if (!content) return null;
6935
+ try {
6936
+ const parsed = JSON.parse(content);
6937
+ return typeof parsed.text === "string" ? parsed.text : null;
6938
+ } catch {
6939
+ return null;
6940
+ }
6941
+ }
6942
+ function normalizeChatType2(chatType) {
6943
+ return chatType === "p2p" ? "direct" : "group";
6944
+ }
6945
+ function wsEventToInbound(event, installationId, tenantId) {
6946
+ const messageId = event.message?.message_id;
6947
+ const chatId = event.message?.chat_id;
6948
+ const openId = event.sender?.sender_id?.open_id;
6949
+ if (!messageId || !chatId || !openId) return null;
6950
+ if (event.message?.message_type !== "text") return null;
6951
+ const text = parseTextContent(event.message.content);
6952
+ if (!text) return null;
6953
+ const chatType = normalizeChatType2(event.message.chat_type);
6954
+ return {
6955
+ channel: "lark",
6956
+ channelInstallationId: installationId,
6957
+ tenantId,
6958
+ sender: { id: openId, displayName: void 0 },
6959
+ content: { text, metadata: { chatId, chatType, messageId } },
6960
+ conversation: { id: chatId, type: chatType },
6961
+ replyTarget: {
6962
+ adapterChannel: "lark",
6963
+ channelInstallationId: installationId,
6964
+ rawTarget: { chatId, messageId, chatType }
6965
+ }
6966
+ };
6967
+ }
6968
+ var larkConfigSchema = import_zod.z.object({
6969
+ appId: import_zod.z.string(),
6970
+ appSecret: import_zod.z.string(),
6971
+ verificationToken: import_zod.z.string().optional(),
6972
+ encryptKey: import_zod.z.string().optional()
6973
+ });
6974
+ var larkChannelAdapter = {
6975
+ channel: "lark",
6976
+ configSchema: larkConfigSchema,
6977
+ async receive(rawPayload, installation) {
6978
+ const event = parseLarkMessageEvent(rawPayload);
6979
+ if (!event) return null;
6980
+ return {
6981
+ channel: "lark",
6982
+ channelInstallationId: installation.id,
6983
+ tenantId: installation.tenantId,
6984
+ sender: { id: event.openId, displayName: void 0 },
6985
+ content: {
6986
+ text: event.text,
6987
+ metadata: { chatId: event.chatId, chatType: event.chatType, messageId: event.messageId }
6988
+ },
6989
+ conversation: { id: event.chatId, type: event.chatType },
6990
+ replyTarget: {
6991
+ adapterChannel: "lark",
6992
+ channelInstallationId: installation.id,
6993
+ rawTarget: { chatId: event.chatId, messageId: event.messageId, chatType: event.chatType }
6994
+ }
6995
+ };
6996
+ },
6997
+ async sendReply(replyTarget, message, installation) {
6998
+ const { createLarkSender: createLarkSender2 } = await Promise.resolve().then(() => (init_sender(), sender_exports));
6999
+ const sender = await createLarkSender2(installation.config);
7000
+ await sender.sendTextReply({
7001
+ chatId: replyTarget.rawTarget.chatId,
7002
+ text: message.text
7003
+ });
7004
+ },
7005
+ resolveThreadId(message, binding) {
7006
+ const date = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
7007
+ const chatType = message.conversation?.type === "direct" ? "dm" : "group";
7008
+ const agentId = binding.agentId;
7009
+ if (chatType === "dm") {
7010
+ return `lark:dm:${message.sender.id}:${agentId}:${date}`;
7011
+ }
7012
+ return `lark:group:${message.conversation?.id ?? "unknown"}:${agentId}:${date}`;
7013
+ },
7014
+ async connect(installation, deps) {
7015
+ const { id: installationId, tenantId, config } = installation;
7016
+ if (!config.appId || !config.appSecret) {
7017
+ logger.warn("Lark installation missing credentials, skipping", { installationId });
7018
+ return;
7019
+ }
7020
+ if (activeConnections.has(installationId)) {
7021
+ logger.warn("Lark WS already connected for installation, skipping", { installationId });
7022
+ return;
7023
+ }
7024
+ logger.info("Lark WS client starting", { installationId, tenantId });
7025
+ const router = deps?.router;
7026
+ const eventDispatcher = new Lark.EventDispatcher({}).register({
7027
+ "im.message.receive_v1": async (data) => {
7028
+ try {
7029
+ const inbound = wsEventToInbound(data, installationId, tenantId);
7030
+ if (!inbound) return;
7031
+ logger.info("Lark WS message received", {
7032
+ installationId,
7033
+ senderId: inbound.sender.id,
7034
+ chatId: data.message?.chat_id
7035
+ });
7036
+ if (router) {
7037
+ const result = await router.dispatch(inbound);
7038
+ if (!result.success) {
7039
+ logger.warn("Lark WS dispatch failed", {
7040
+ installationId,
7041
+ error: result.error?.message
7042
+ });
7043
+ }
7044
+ }
7045
+ } catch (err) {
7046
+ logger.error("Lark WS event handler error", {
7047
+ installationId,
7048
+ error: err instanceof Error ? err.message : String(err)
7049
+ });
7050
+ }
7051
+ }
7052
+ });
7053
+ const client = new Lark.WSClient({
7054
+ appId: config.appId,
7055
+ appSecret: config.appSecret,
7056
+ loggerLevel: Lark.LoggerLevel.info
7057
+ });
7058
+ await client.start({ eventDispatcher });
7059
+ activeConnections.set(installationId, client);
7060
+ logger.info("Lark WS client connected", { installationId });
7061
+ }
7062
+ };
7063
+
7064
+ // src/channels/lark/verification.ts
7065
+ var import_crypto7 = __toESM(require("crypto"));
7066
+ function parseLarkRequestBody(body, encryptKey) {
7067
+ const parsed = body || {};
7068
+ if (encryptKey && typeof parsed.encrypt === "string") {
7069
+ return decryptLarkPayload(encryptKey, parsed.encrypt);
7070
+ }
7071
+ return parsed;
7072
+ }
7073
+ function decryptLarkPayload(encryptKey, encryptedPayload) {
7074
+ const key = import_crypto7.default.createHash("sha256").update(encryptKey).digest();
7075
+ const buffer = Buffer.from(encryptedPayload, "base64");
7076
+ const iv = buffer.subarray(0, 16);
7077
+ const ciphertext = buffer.subarray(16);
7078
+ const decipher = import_crypto7.default.createDecipheriv("aes-256-cbc", key, iv);
7079
+ const plaintext = Buffer.concat([
7080
+ decipher.update(ciphertext),
7081
+ decipher.final()
7082
+ ]).toString("utf8");
7083
+ return JSON.parse(plaintext);
7084
+ }
7085
+
7086
+ // src/channels/lark/controller.ts
7087
+ var logger2 = new Logger({ serviceName: "lattice/gateway/lark" });
6685
7088
  function createLarkEventHandler(deps) {
6686
7089
  return async function handleLarkEvent(request, reply) {
6687
7090
  const { installationId } = request.params;
@@ -6702,7 +7105,7 @@ function createLarkEventHandler(deps) {
6702
7105
  return;
6703
7106
  }
6704
7107
  deps.router.dispatch(inboundMessage).catch((error) => {
6705
- logger.error("Lark message dispatch error", {
7108
+ logger2.error("Lark message dispatch error", {
6706
7109
  error: error instanceof Error ? error.message : String(error)
6707
7110
  });
6708
7111
  });
@@ -6734,8 +7137,8 @@ function registerChannelRoutes(app2, dependencies) {
6734
7137
  }
6735
7138
 
6736
7139
  // src/controllers/channel-installations.ts
6737
- var import_crypto7 = require("crypto");
6738
- function getTenantId11(request) {
7140
+ var import_crypto8 = require("crypto");
7141
+ function getTenantId13(request) {
6739
7142
  const userTenantId = request.user?.tenantId;
6740
7143
  if (userTenantId) {
6741
7144
  return userTenantId;
@@ -6743,8 +7146,8 @@ function getTenantId11(request) {
6743
7146
  return request.headers["x-tenant-id"] || "default";
6744
7147
  }
6745
7148
  async function getInstallationStore() {
6746
- const { getStoreLattice: getStoreLattice16 } = await import("@axiom-lattice/core");
6747
- const store = getStoreLattice16("default", "channelInstallation").store;
7149
+ const { getStoreLattice: getStoreLattice18 } = await import("@axiom-lattice/core");
7150
+ const store = getStoreLattice18("default", "channelInstallation").store;
6748
7151
  if (store) return store;
6749
7152
  const { PostgreSQLChannelInstallationStore } = await import("@axiom-lattice/pg-stores");
6750
7153
  const databaseUrl = process.env.DATABASE_URL;
@@ -6756,7 +7159,7 @@ async function getInstallationStore() {
6756
7159
  });
6757
7160
  }
6758
7161
  async function getChannelInstallationList(request, reply) {
6759
- const tenantId = getTenantId11(request);
7162
+ const tenantId = getTenantId13(request);
6760
7163
  const { channel } = request.query;
6761
7164
  try {
6762
7165
  const store = await getInstallationStore();
@@ -6782,7 +7185,7 @@ async function getChannelInstallationList(request, reply) {
6782
7185
  }
6783
7186
  }
6784
7187
  async function getChannelInstallation(request, reply) {
6785
- const tenantId = getTenantId11(request);
7188
+ const tenantId = getTenantId13(request);
6786
7189
  const { installationId } = request.params;
6787
7190
  try {
6788
7191
  const store = await getInstallationStore();
@@ -6815,7 +7218,7 @@ async function getChannelInstallation(request, reply) {
6815
7218
  }
6816
7219
  }
6817
7220
  async function createChannelInstallation(request, reply) {
6818
- const tenantId = getTenantId11(request);
7221
+ const tenantId = getTenantId13(request);
6819
7222
  const body = request.body;
6820
7223
  try {
6821
7224
  if (!body.channel) {
@@ -6850,7 +7253,7 @@ async function createChannelInstallation(request, reply) {
6850
7253
  }
6851
7254
  }
6852
7255
  const store = await getInstallationStore();
6853
- const installationId = body.id || (0, import_crypto7.randomUUID)();
7256
+ const installationId = body.id || (0, import_crypto8.randomUUID)();
6854
7257
  const installation = await store.createInstallation(
6855
7258
  tenantId,
6856
7259
  installationId,
@@ -6878,7 +7281,7 @@ async function createChannelInstallation(request, reply) {
6878
7281
  }
6879
7282
  }
6880
7283
  async function updateChannelInstallation(request, reply) {
6881
- const tenantId = getTenantId11(request);
7284
+ const tenantId = getTenantId13(request);
6882
7285
  const { installationId } = request.params;
6883
7286
  const body = request.body;
6884
7287
  try {
@@ -6924,7 +7327,7 @@ async function updateChannelInstallation(request, reply) {
6924
7327
  }
6925
7328
  }
6926
7329
  async function deleteChannelInstallation(request, reply) {
6927
- const tenantId = getTenantId11(request);
7330
+ const tenantId = getTenantId13(request);
6928
7331
  const { installationId } = request.params;
6929
7332
  try {
6930
7333
  const store = await getInstallationStore();
@@ -6974,17 +7377,17 @@ function registerChannelInstallationRoutes(app2) {
6974
7377
  }
6975
7378
 
6976
7379
  // src/controllers/channel-bindings.ts
6977
- var import_core28 = require("@axiom-lattice/core");
6978
- function getTenantId12(request) {
7380
+ var import_core30 = require("@axiom-lattice/core");
7381
+ function getTenantId14(request) {
6979
7382
  const userTenantId = request.user?.tenantId;
6980
7383
  if (userTenantId) return userTenantId;
6981
7384
  return request.headers["x-tenant-id"] || "default";
6982
7385
  }
6983
7386
  async function getBindingList(request, _reply) {
6984
- const tenantId = getTenantId12(request);
7387
+ const tenantId = getTenantId14(request);
6985
7388
  const { channel, agentId, channelInstallationId, limit, offset } = request.query;
6986
7389
  try {
6987
- const registry = (0, import_core28.getBindingRegistry)();
7390
+ const registry = (0, import_core30.getBindingRegistry)();
6988
7391
  const bindings = await registry.list({ channel, agentId, tenantId, channelInstallationId, limit, offset });
6989
7392
  return { success: true, message: "Bindings retrieved", data: { records: bindings, total: bindings.length } };
6990
7393
  } catch (error) {
@@ -6993,9 +7396,9 @@ async function getBindingList(request, _reply) {
6993
7396
  }
6994
7397
  }
6995
7398
  async function getBinding(request, reply) {
6996
- const tenantId = getTenantId12(request);
7399
+ const tenantId = getTenantId14(request);
6997
7400
  try {
6998
- const registry = (0, import_core28.getBindingRegistry)();
7401
+ const registry = (0, import_core30.getBindingRegistry)();
6999
7402
  const bindings = await registry.list({ tenantId });
7000
7403
  const binding = bindings.find((b) => b.id === request.params.id);
7001
7404
  if (!binding || binding.tenantId !== tenantId) {
@@ -7009,9 +7412,9 @@ async function getBinding(request, reply) {
7009
7412
  }
7010
7413
  }
7011
7414
  async function createBinding(request, reply) {
7012
- const tenantId = getTenantId12(request);
7415
+ const tenantId = getTenantId14(request);
7013
7416
  try {
7014
- const registry = (0, import_core28.getBindingRegistry)();
7417
+ const registry = (0, import_core30.getBindingRegistry)();
7015
7418
  const binding = await registry.create({ ...request.body, tenantId });
7016
7419
  reply.status(201);
7017
7420
  return { success: true, message: "Binding created", data: binding };
@@ -7023,8 +7426,8 @@ async function createBinding(request, reply) {
7023
7426
  }
7024
7427
  async function updateBinding(request, reply) {
7025
7428
  try {
7026
- const tenantId = getTenantId12(request);
7027
- const registry = (0, import_core28.getBindingRegistry)();
7429
+ const tenantId = getTenantId14(request);
7430
+ const registry = (0, import_core30.getBindingRegistry)();
7028
7431
  const bindings = await registry.list({ tenantId });
7029
7432
  const existing = bindings.find((b) => b.id === request.params.id);
7030
7433
  if (!existing || existing.tenantId !== tenantId) {
@@ -7041,8 +7444,8 @@ async function updateBinding(request, reply) {
7041
7444
  }
7042
7445
  async function deleteBinding(request, reply) {
7043
7446
  try {
7044
- const tenantId = getTenantId12(request);
7045
- const registry = (0, import_core28.getBindingRegistry)();
7447
+ const tenantId = getTenantId14(request);
7448
+ const registry = (0, import_core30.getBindingRegistry)();
7046
7449
  const bindings = await registry.list({ tenantId });
7047
7450
  const existing = bindings.find((b) => b.id === request.params.id);
7048
7451
  if (!existing || existing.tenantId !== tenantId) {
@@ -7058,10 +7461,10 @@ async function deleteBinding(request, reply) {
7058
7461
  }
7059
7462
  }
7060
7463
  async function resolveBinding(request, _reply) {
7061
- const tenantId = getTenantId12(request);
7464
+ const tenantId = getTenantId14(request);
7062
7465
  const { channel, senderId, channelInstallationId } = request.query;
7063
7466
  try {
7064
- const registry = (0, import_core28.getBindingRegistry)();
7467
+ const registry = (0, import_core30.getBindingRegistry)();
7065
7468
  const binding = await registry.resolve({ channel, senderId, channelInstallationId, tenantId });
7066
7469
  if (!binding) {
7067
7470
  return { success: false, message: "No binding found", data: null };
@@ -7083,6 +7486,105 @@ function registerChannelBindingRoutes(app2) {
7083
7486
  app2.delete("/api/channel-bindings/:id", deleteBinding);
7084
7487
  }
7085
7488
 
7489
+ // src/controllers/menu-items.ts
7490
+ var import_core31 = require("@axiom-lattice/core");
7491
+ function getTenantId15(request) {
7492
+ const userTenantId = request.user?.tenantId;
7493
+ if (userTenantId) return userTenantId;
7494
+ return request.headers["x-tenant-id"] || "default";
7495
+ }
7496
+ function errorMessage(err) {
7497
+ return err instanceof Error ? err.message : "Unexpected error";
7498
+ }
7499
+ async function getMenuItemList(request, _reply) {
7500
+ const tenantId = getTenantId15(request);
7501
+ try {
7502
+ const registry = (0, import_core31.getMenuRegistry)();
7503
+ const items = await registry.list({ tenantId, menuTarget: request.query.menuTarget });
7504
+ return { success: true, message: "Menu items retrieved", data: { records: items, total: items.length } };
7505
+ } catch (error) {
7506
+ const msg = errorMessage(error);
7507
+ console.error("Failed to get menu items:", msg);
7508
+ return { success: false, message: msg, data: { records: [], total: 0 } };
7509
+ }
7510
+ }
7511
+ async function getMenuItem(request, reply) {
7512
+ const tenantId = getTenantId15(request);
7513
+ try {
7514
+ const registry = (0, import_core31.getMenuRegistry)();
7515
+ const item = await registry.getById(request.params.id);
7516
+ if (!item || item.tenantId !== tenantId) {
7517
+ reply.status(404);
7518
+ return { success: false, message: "Menu item not found" };
7519
+ }
7520
+ return { success: true, message: "Menu item retrieved", data: item };
7521
+ } catch (error) {
7522
+ const msg = errorMessage(error);
7523
+ console.error("Failed to get menu item:", msg);
7524
+ reply.status(500);
7525
+ return { success: false, message: msg };
7526
+ }
7527
+ }
7528
+ async function createMenuItem(request, reply) {
7529
+ const tenantId = getTenantId15(request);
7530
+ try {
7531
+ const registry = (0, import_core31.getMenuRegistry)();
7532
+ const item = await registry.create({ ...request.body, tenantId });
7533
+ reply.status(201);
7534
+ return { success: true, message: "Menu item created", data: item };
7535
+ } catch (error) {
7536
+ const msg = errorMessage(error);
7537
+ console.error("Failed to create menu item:", msg);
7538
+ reply.status(500);
7539
+ return { success: false, message: msg };
7540
+ }
7541
+ }
7542
+ async function updateMenuItem(request, reply) {
7543
+ try {
7544
+ const tenantId = getTenantId15(request);
7545
+ const registry = (0, import_core31.getMenuRegistry)();
7546
+ const existing = await registry.getById(request.params.id);
7547
+ if (!existing || existing.tenantId !== tenantId) {
7548
+ reply.status(404);
7549
+ return { success: false, message: "Menu item not found" };
7550
+ }
7551
+ const item = await registry.update(request.params.id, request.body);
7552
+ return { success: true, message: "Menu item updated", data: item };
7553
+ } catch (error) {
7554
+ const msg = errorMessage(error);
7555
+ console.error("Failed to update menu item:", msg);
7556
+ reply.status(500);
7557
+ return { success: false, message: msg };
7558
+ }
7559
+ }
7560
+ async function deleteMenuItem(request, reply) {
7561
+ try {
7562
+ const tenantId = getTenantId15(request);
7563
+ const registry = (0, import_core31.getMenuRegistry)();
7564
+ const existing = await registry.getById(request.params.id);
7565
+ if (!existing || existing.tenantId !== tenantId) {
7566
+ reply.status(404);
7567
+ return { success: false, message: "Menu item not found" };
7568
+ }
7569
+ await registry.delete(request.params.id);
7570
+ return { success: true, message: "Menu item deleted" };
7571
+ } catch (error) {
7572
+ const msg = errorMessage(error);
7573
+ console.error("Failed to delete menu item:", msg);
7574
+ reply.status(500);
7575
+ return { success: false, message: msg };
7576
+ }
7577
+ }
7578
+
7579
+ // src/routes/menu-items.ts
7580
+ function registerMenuItemRoutes(app2) {
7581
+ app2.get("/api/menu-items", getMenuItemList);
7582
+ app2.post("/api/menu-items", createMenuItem);
7583
+ app2.get("/api/menu-items/:id", getMenuItem);
7584
+ app2.put("/api/menu-items/:id", updateMenuItem);
7585
+ app2.delete("/api/menu-items/:id", deleteMenuItem);
7586
+ }
7587
+
7086
7588
  // src/routes/a2a-bridge.ts
7087
7589
  var import_uuid8 = require("uuid");
7088
7590
  var log = {
@@ -7263,6 +7765,7 @@ var registerLatticeRoutes = (app2, channelDeps) => {
7263
7765
  app2.post("/api/runs", createRun);
7264
7766
  app2.post("/api/resume_stream", resumeStream);
7265
7767
  app2.post("/api/assistants/:assistantId/threads/:threadId/abort", abortRun);
7768
+ app2.post("/api/assistants/:assistantId/threads/:threadId/recover", recoverRun);
7266
7769
  app2.get(
7267
7770
  "/api/assistants/:assistantId/:thread_id/memory",
7268
7771
  { schema: getAllMemoryItemsSchema },
@@ -7298,6 +7801,15 @@ var registerLatticeRoutes = (app2, channelDeps) => {
7298
7801
  app2.post("/api/assistants", createAssistant);
7299
7802
  app2.put("/api/assistants/:id", updateAssistant);
7300
7803
  app2.delete("/api/assistants/:id", deleteAssistant);
7804
+ app2.post("/api/personal-assistant", createPersonalAssistant);
7805
+ app2.get("/api/personal-assistant", getPersonalAssistant);
7806
+ app2.delete("/api/personal-assistant", deletePersonalAssistant);
7807
+ app2.get("/api/tasks", listTasks);
7808
+ app2.get("/api/tasks/:id", getTask);
7809
+ app2.post("/api/tasks", createTask);
7810
+ app2.put("/api/tasks/:id", updateTask);
7811
+ app2.delete("/api/tasks/:id", deleteTask);
7812
+ app2.patch("/api/tasks/:id/complete", completeTask);
7301
7813
  app2.get(
7302
7814
  "/api/assistants/:assistantId/graph",
7303
7815
  { schema: getAgentGraphSchema },
@@ -7396,6 +7908,7 @@ var registerLatticeRoutes = (app2, channelDeps) => {
7396
7908
  });
7397
7909
  registerChannelRoutes(app2, channelDeps);
7398
7910
  registerChannelInstallationRoutes(app2);
7911
+ registerMenuItemRoutes(app2);
7399
7912
  if (channelDeps) {
7400
7913
  registerChannelBindingRoutes(app2);
7401
7914
  }
@@ -7473,8 +7986,8 @@ var registerLatticeRoutes = (app2, channelDeps) => {
7473
7986
  };
7474
7987
 
7475
7988
  // src/router/MessageRouter.ts
7476
- var import_core29 = require("@axiom-lattice/core");
7477
- var import_crypto8 = require("crypto");
7989
+ var import_core32 = require("@axiom-lattice/core");
7990
+ var import_crypto9 = require("crypto");
7478
7991
  var BindingNotFoundError = class extends Error {
7479
7992
  constructor(message) {
7480
7993
  super(message);
@@ -7521,6 +8034,9 @@ var MessageRouter = class {
7521
8034
  inboundMessage: message,
7522
8035
  metadata: {}
7523
8036
  };
8037
+ let binding = null;
8038
+ let threadId;
8039
+ let agentId;
7524
8040
  try {
7525
8041
  await this.runMiddlewares(ctx, async () => {
7526
8042
  const tenantId = message.tenantId || (await this.installationStore.getInstallationById(message.channelInstallationId))?.tenantId;
@@ -7537,16 +8053,18 @@ var MessageRouter = class {
7537
8053
  );
7538
8054
  }
7539
8055
  console.log({ event: "dispatch:start", channel: message.channel, senderId: message.sender.id, tenantId }, "Message dispatch started");
7540
- let binding = await this.bindingRegistry.resolve({
8056
+ const adapter = this.adapterRegistry.get(message.channel);
8057
+ const hasAdapterThreadStrategy = !!adapter?.resolveThreadId;
8058
+ binding = await this.bindingRegistry.resolve({
7541
8059
  channel: message.channel,
7542
8060
  senderId: message.sender.id,
7543
8061
  channelInstallationId: message.channelInstallationId,
7544
8062
  tenantId
7545
8063
  });
8064
+ const installation = await this.installationStore.getInstallationById(
8065
+ message.channelInstallationId
8066
+ );
7546
8067
  if (!binding) {
7547
- const installation = await this.installationStore.getInstallationById(
7548
- message.channelInstallationId
7549
- );
7550
8068
  if (installation?.rejectWhenNoBinding) {
7551
8069
  console.warn({
7552
8070
  event: "dispatch:no_binding",
@@ -7579,7 +8097,7 @@ var MessageRouter = class {
7579
8097
  createdAt: /* @__PURE__ */ new Date(),
7580
8098
  updatedAt: /* @__PURE__ */ new Date()
7581
8099
  };
7582
- } else {
8100
+ } else if (!hasAdapterThreadStrategy) {
7583
8101
  console.error({
7584
8102
  event: "dispatch:no_fallback",
7585
8103
  channel: message.channel,
@@ -7591,47 +8109,99 @@ var MessageRouter = class {
7591
8109
  );
7592
8110
  }
7593
8111
  }
7594
- ctx.binding = binding;
7595
- console.log({
7596
- event: "dispatch:binding",
7597
- bindingId: binding.id,
7598
- agentId: binding.agentId,
7599
- threadId: binding.threadId,
7600
- threadMode: binding.threadMode,
7601
- workspaceId: binding.workspaceId,
7602
- projectId: binding.projectId
7603
- }, "Binding resolved");
7604
- if (!binding.enabled) {
7605
- console.warn({
7606
- event: "dispatch:binding_disabled",
8112
+ ctx.binding = binding ?? void 0;
8113
+ if (binding) {
8114
+ console.log({
8115
+ event: "dispatch:binding",
7607
8116
  bindingId: binding.id,
7608
8117
  agentId: binding.agentId,
7609
- senderId: message.sender.id
7610
- }, "Binding is disabled, rejecting message");
8118
+ threadId: binding.threadId,
8119
+ threadMode: binding.threadMode,
8120
+ workspaceId: binding.workspaceId,
8121
+ projectId: binding.projectId
8122
+ }, "Binding resolved");
8123
+ if (!binding.enabled) {
8124
+ console.warn({
8125
+ event: "dispatch:binding_disabled",
8126
+ bindingId: binding.id,
8127
+ agentId: binding.agentId,
8128
+ senderId: message.sender.id
8129
+ }, "Binding is disabled, rejecting message");
8130
+ throw new BindingNotFoundError(
8131
+ `Binding for sender "${message.sender.id}" is disabled`
8132
+ );
8133
+ }
8134
+ }
8135
+ agentId = binding?.agentId ?? installation?.fallbackAgentId;
8136
+ if (!agentId) {
7611
8137
  throw new BindingNotFoundError(
7612
- `Binding for sender "${message.sender.id}" is disabled`
8138
+ `No agent configured for sender "${message.sender.id}"`
7613
8139
  );
7614
8140
  }
7615
- let threadId = ctx.binding.threadMode === "per_conversation" ? void 0 : ctx.binding.threadId;
8141
+ if (hasAdapterThreadStrategy) {
8142
+ const resolvedThreadId = await adapter.resolveThreadId(message, binding);
8143
+ threadId = resolvedThreadId;
8144
+ console.log({
8145
+ event: "dispatch:thread:adapter",
8146
+ threadId,
8147
+ channel: message.channel,
8148
+ adapterChannel: adapter.channel
8149
+ }, "Thread resolved by adapter strategy");
8150
+ const threadStore = (0, import_core32.getStoreLattice)("default", "thread").store;
8151
+ try {
8152
+ await threadStore.createThread(
8153
+ tenantId,
8154
+ agentId,
8155
+ threadId,
8156
+ {
8157
+ metadata: {
8158
+ channel: message.channel,
8159
+ channelInstallationId: message.channelInstallationId,
8160
+ senderId: message.sender.id,
8161
+ bindingId: binding?.id,
8162
+ ...message.conversation ? {
8163
+ conversationId: message.conversation.id,
8164
+ conversationType: message.conversation.type
8165
+ } : {}
8166
+ }
8167
+ }
8168
+ );
8169
+ console.log({
8170
+ event: "dispatch:thread:adapter:created",
8171
+ threadId
8172
+ }, "Thread created by adapter strategy");
8173
+ } catch {
8174
+ console.log({
8175
+ event: "dispatch:thread:adapter:reuse",
8176
+ threadId
8177
+ }, "Thread already exists, reusing");
8178
+ }
8179
+ } else if (binding) {
8180
+ if (binding.threadMode === "per_conversation") {
8181
+ threadId = void 0;
8182
+ } else {
8183
+ threadId = binding.threadId;
8184
+ }
8185
+ }
7616
8186
  if (!threadId) {
7617
- const threadStore = (0, import_core29.getStoreLattice)("default", "thread").store;
7618
- const newThreadId = (0, import_crypto8.randomUUID)();
8187
+ const threadStore = (0, import_core32.getStoreLattice)("default", "thread").store;
8188
+ const newThreadId = (0, import_crypto9.randomUUID)();
7619
8189
  console.log({
7620
8190
  event: "dispatch:thread:create",
7621
- agentId: ctx.binding.agentId,
8191
+ agentId,
7622
8192
  newThreadId,
7623
8193
  tenantId
7624
8194
  }, "Creating new thread for binding");
7625
8195
  const newThread = await threadStore.createThread(
7626
8196
  tenantId,
7627
- ctx.binding.agentId,
8197
+ agentId,
7628
8198
  newThreadId,
7629
8199
  {
7630
8200
  metadata: {
7631
8201
  channel: message.channel,
7632
8202
  channelInstallationId: message.channelInstallationId,
7633
8203
  senderId: message.sender.id,
7634
- bindingId: ctx.binding.id,
8204
+ bindingId: binding?.id,
7635
8205
  ...message.conversation ? {
7636
8206
  conversationId: message.conversation.id,
7637
8207
  conversationType: message.conversation.type
@@ -7640,36 +8210,35 @@ var MessageRouter = class {
7640
8210
  }
7641
8211
  );
7642
8212
  threadId = newThread.id;
7643
- if (ctx.binding.id !== "fallback") {
7644
- await this.bindingRegistry.update(ctx.binding.id, { threadId });
7645
- ctx.binding.threadId = threadId;
7646
- } else {
7647
- ctx.binding.threadId = threadId;
8213
+ if (binding && binding.id !== "fallback") {
8214
+ await this.bindingRegistry.update(binding.id, { threadId });
8215
+ binding.threadId = threadId;
8216
+ } else if (binding) {
8217
+ binding.threadId = threadId;
7648
8218
  }
7649
8219
  }
7650
8220
  console.log({
7651
8221
  event: "dispatch:agent",
7652
- agentId: ctx.binding.agentId,
8222
+ agentId,
7653
8223
  threadId,
7654
- threadMode: ctx.binding.threadMode,
7655
8224
  senderId: message.sender.id,
7656
8225
  contentLength: message.content.text.length
7657
8226
  }, "Dispatching to agent");
7658
- const agent = import_core29.agentInstanceManager.getAgent({
8227
+ const agent = import_core32.agentInstanceManager.getAgent({
7659
8228
  tenant_id: tenantId,
7660
- assistant_id: ctx.binding.agentId,
8229
+ assistant_id: agentId,
7661
8230
  thread_id: threadId,
7662
- workspace_id: ctx.binding.workspaceId || "",
7663
- project_id: ctx.binding.projectId || ""
8231
+ workspace_id: binding?.workspaceId || "",
8232
+ project_id: binding?.projectId || ""
7664
8233
  });
7665
8234
  if (message.replyTarget) {
7666
8235
  const replySubKey = `${threadId}:${message.replyTarget.adapterChannel}:reply`;
7667
- const adapter = this.adapterRegistry.get(message.replyTarget.adapterChannel);
7668
- if (adapter) {
7669
- const installation = await this.installationStore.getInstallationById(
8236
+ const adapter2 = this.adapterRegistry.get(message.replyTarget.adapterChannel);
8237
+ if (adapter2) {
8238
+ const installation2 = await this.installationStore.getInstallationById(
7670
8239
  message.channelInstallationId
7671
8240
  );
7672
- if (installation) {
8241
+ if (installation2) {
7673
8242
  const existing = this._replySubs.get(replySubKey);
7674
8243
  if (!existing || existing.count === 0) {
7675
8244
  const timer = setTimeout(() => {
@@ -7709,7 +8278,7 @@ var MessageRouter = class {
7709
8278
  channel: message.replyTarget.adapterChannel,
7710
8279
  replyLength: replyText.length
7711
8280
  }, "Sending channel reply");
7712
- adapter.sendReply(message.replyTarget, { text: replyText }, installation).then(() => {
8281
+ adapter2.sendReply(message.replyTarget, { text: replyText }, installation2).then(() => {
7713
8282
  console.log({
7714
8283
  event: "dispatch:reply:sent",
7715
8284
  threadId,
@@ -7747,7 +8316,7 @@ var MessageRouter = class {
7747
8316
  });
7748
8317
  console.log({
7749
8318
  event: "dispatch:complete",
7750
- agentId: ctx.binding.agentId,
8319
+ agentId,
7751
8320
  threadId,
7752
8321
  messageId: addResult?.messageId,
7753
8322
  result: JSON.stringify(addResult)
@@ -7756,7 +8325,7 @@ var MessageRouter = class {
7756
8325
  return {
7757
8326
  success: true,
7758
8327
  bindingId: ctx.binding?.id,
7759
- threadId: ctx.binding?.threadId,
8328
+ threadId,
7760
8329
  result: ctx.result
7761
8330
  };
7762
8331
  } catch (error) {
@@ -7867,13 +8436,13 @@ function createRateLimitMiddleware(maxRequests = 10, windowMs = 60 * 1e3, maxEnt
7867
8436
  }
7868
8437
 
7869
8438
  // src/router/middlewares/auditLogger.ts
7870
- var logger2 = new Logger({ serviceName: "lattice/gateway/audit" });
8439
+ var logger3 = new Logger({ serviceName: "lattice/gateway/audit" });
7871
8440
  function createAuditLoggerMiddleware() {
7872
8441
  return async (ctx, next) => {
7873
8442
  const start2 = Date.now();
7874
8443
  try {
7875
8444
  await next();
7876
- logger2.info("message routed", {
8445
+ logger3.info("message routed", {
7877
8446
  event: "message:routed",
7878
8447
  channel: ctx.inboundMessage.channel,
7879
8448
  senderId: ctx.inboundMessage.sender.id,
@@ -7883,7 +8452,7 @@ function createAuditLoggerMiddleware() {
7883
8452
  status: "success"
7884
8453
  });
7885
8454
  } catch (error) {
7886
- logger2.error(
8455
+ logger3.error(
7887
8456
  error instanceof Error ? error.message : String(error),
7888
8457
  {
7889
8458
  event: "message:error",
@@ -7899,7 +8468,7 @@ function createAuditLoggerMiddleware() {
7899
8468
  }
7900
8469
 
7901
8470
  // src/index.ts
7902
- var import_core32 = require("@axiom-lattice/core");
8471
+ var import_core35 = require("@axiom-lattice/core");
7903
8472
 
7904
8473
  // src/swagger.ts
7905
8474
  var import_swagger = __toESM(require("@fastify/swagger"));
@@ -7964,7 +8533,7 @@ var configureSwagger = async (app2, customSwaggerConfig, customSwaggerUiConfig)
7964
8533
  };
7965
8534
 
7966
8535
  // src/services/agent_task_consumer.ts
7967
- var import_core30 = require("@axiom-lattice/core");
8536
+ var import_core33 = require("@axiom-lattice/core");
7968
8537
  var handleAgentTask = async (taskRequest, retryCount = 0) => {
7969
8538
  const {
7970
8539
  assistant_id,
@@ -7982,21 +8551,22 @@ var handleAgentTask = async (taskRequest, retryCount = 0) => {
7982
8551
  console.log(
7983
8552
  `\u5F00\u59CB\u5904\u7406\u4EFB\u52A1 [assistant_id: ${assistant_id}, thread_id: ${thread_id}]`
7984
8553
  );
7985
- const agent = import_core30.agentInstanceManager.getAgent({ assistant_id, thread_id, tenant_id, workspace_id: runConfig?.workspaceId, project_id: runConfig?.projectId, custom_run_config: runConfig });
7986
- await agent.addMessage({ input, command, custom_run_config: runConfig }, import_core30.QueueMode.STEER);
8554
+ const agent = import_core33.agentInstanceManager.getAgent({ assistant_id, thread_id, tenant_id, workspace_id: runConfig?.workspaceId, project_id: runConfig?.projectId, custom_run_config: runConfig });
8555
+ await agent.addMessage({ input, command, custom_run_config: runConfig }, import_core33.QueueMode.STEER);
7987
8556
  if (callback_event) {
7988
8557
  agent.subscribeOnce("message:completed", (evt) => {
7989
- import_core30.eventBus.publish(callback_event, {
8558
+ import_core33.eventBus.publish(callback_event, {
7990
8559
  success: true,
7991
- state: evt.state,
7992
- config: { assistant_id, thread_id, tenant_id }
8560
+ state: evt.state
7993
8561
  });
7994
8562
  if (main_thread_id && main_tenant_id) {
7995
8563
  try {
7996
- const mainAgent = import_core30.agentInstanceManager.getAgent({
8564
+ const mainAgent = import_core33.agentInstanceManager.getAgent({
7997
8565
  assistant_id: main_assistant_id ?? assistant_id,
7998
8566
  thread_id: main_thread_id,
7999
- tenant_id: main_tenant_id
8567
+ tenant_id: main_tenant_id,
8568
+ workspace_id: runConfig?.workspaceId,
8569
+ project_id: runConfig?.projectId
8000
8570
  });
8001
8571
  if (mainAgent) {
8002
8572
  const messages = evt.state?.values?.messages;
@@ -8021,10 +8591,9 @@ ${summary}`
8021
8591
  }
8022
8592
  });
8023
8593
  agent.subscribeOnce("message:interrupted", (evt) => {
8024
- import_core30.eventBus.publish(callback_event, {
8594
+ import_core33.eventBus.publish(callback_event, {
8025
8595
  success: true,
8026
- state: evt.state,
8027
- config: { assistant_id, thread_id, tenant_id }
8596
+ state: evt.state
8028
8597
  });
8029
8598
  });
8030
8599
  }
@@ -8045,10 +8614,9 @@ ${summary}`
8045
8614
  return handleAgentTask(taskRequest, nextRetryCount);
8046
8615
  }
8047
8616
  if (callback_event) {
8048
- import_core30.eventBus.publish(callback_event, {
8617
+ import_core33.eventBus.publish(callback_event, {
8049
8618
  success: false,
8050
- error: error instanceof Error ? error.message : String(error),
8051
- config: { assistant_id, thread_id, tenant_id }
8619
+ error: error instanceof Error ? error.message : String(error)
8052
8620
  });
8053
8621
  }
8054
8622
  console.error(
@@ -8083,7 +8651,7 @@ var _AgentTaskConsumer = class _AgentTaskConsumer {
8083
8651
  * 初始化事件监听和队列轮询
8084
8652
  */
8085
8653
  initialize() {
8086
- import_core30.eventBus.subscribe(import_core30.AGENT_TASK_EVENT, this.trigger_agent_task.bind(this));
8654
+ import_core33.eventBus.subscribe(import_core33.AGENT_TASK_EVENT, this.trigger_agent_task.bind(this));
8087
8655
  this.startPollingQueue();
8088
8656
  console.log("Agent\u4EFB\u52A1\u6D88\u8D39\u8005\u5DF2\u542F\u52A8\u5E76\u76D1\u542C\u4EFB\u52A1\u4E8B\u4EF6\u548C\u961F\u5217");
8089
8657
  }
@@ -8202,14 +8770,9 @@ var _AgentTaskConsumer = class _AgentTaskConsumer {
8202
8770
  handleAgentTask(taskRequest).catch((error) => {
8203
8771
  console.error("\u5904\u7406Agent\u4EFB\u52A1\u65F6\u53D1\u751F\u672A\u6355\u83B7\u7684\u9519\u8BEF:", error);
8204
8772
  if (taskRequest.callback_event) {
8205
- import_core30.eventBus.publish(taskRequest.callback_event, {
8773
+ import_core33.eventBus.publish(taskRequest.callback_event, {
8206
8774
  success: false,
8207
- error: error instanceof Error ? error.message : String(error),
8208
- config: {
8209
- assistant_id: taskRequest.assistant_id,
8210
- thread_id: taskRequest.thread_id,
8211
- tenant_id: taskRequest["x-tenant-id"]
8212
- }
8775
+ error: error instanceof Error ? error.message : String(error)
8213
8776
  });
8214
8777
  }
8215
8778
  });
@@ -8222,7 +8785,7 @@ _AgentTaskConsumer.agent_run_endpoint = "http://localhost:4001/api/runs";
8222
8785
  var AgentTaskConsumer = _AgentTaskConsumer;
8223
8786
 
8224
8787
  // src/index.ts
8225
- var import_core33 = require("@axiom-lattice/core");
8788
+ var import_core36 = require("@axiom-lattice/core");
8226
8789
  var import_protocols5 = require("@axiom-lattice/protocols");
8227
8790
  var import_meta = {};
8228
8791
  process.on("unhandledRejection", (reason, promise) => {
@@ -8236,13 +8799,13 @@ var DEFAULT_LOGGER_CONFIG = {
8236
8799
  loggerName: "lattice/gateway"
8237
8800
  };
8238
8801
  var loggerLattice = initializeLogger(DEFAULT_LOGGER_CONFIG);
8239
- var logger3 = loggerLattice.client;
8802
+ var logger4 = loggerLattice.client;
8240
8803
  function initializeLogger(config) {
8241
- if (import_core33.loggerLatticeManager.hasLattice("default")) {
8242
- import_core33.loggerLatticeManager.removeLattice("default");
8804
+ if (import_core36.loggerLatticeManager.hasLattice("default")) {
8805
+ import_core36.loggerLatticeManager.removeLattice("default");
8243
8806
  }
8244
- (0, import_core33.registerLoggerLattice)("default", config);
8245
- return (0, import_core33.getLoggerLattice)("default");
8807
+ (0, import_core36.registerLoggerLattice)("default", config);
8808
+ return (0, import_core36.getLoggerLattice)("default");
8246
8809
  }
8247
8810
  var app = (0, import_fastify.default)({
8248
8811
  logger: false,
@@ -8279,6 +8842,8 @@ app.addHook("preHandler", async (request, reply) => {
8279
8842
  if (!authRequired) return;
8280
8843
  if (request.method === "OPTIONS") return;
8281
8844
  if (PUBLIC_ROUTES.some((r) => request.url === r)) return;
8845
+ const urlPath = request.url.split("?")[0];
8846
+ if (urlPath.includes("/viewfile") || urlPath.includes("/downloadfile")) return;
8282
8847
  return reply.status(401).send({
8283
8848
  success: false,
8284
8849
  error: "Unauthorized - Missing or invalid token"
@@ -8335,7 +8900,7 @@ app.setErrorHandler((error, request, reply) => {
8335
8900
  "x-request-id": getHeaderValue(request.headers["x-request-id"]),
8336
8901
  "x-user-id": getHeaderValue(request.headers["x-user-id"])
8337
8902
  };
8338
- logger3.error(
8903
+ logger4.error(
8339
8904
  `\u8BF7\u6C42\u9519\u8BEF: ${request.method} ${request.url} error:${error.message}`,
8340
8905
  {
8341
8906
  ...context,
@@ -8351,7 +8916,7 @@ app.setErrorHandler((error, request, reply) => {
8351
8916
  });
8352
8917
  function getConfiguredSandboxProvider() {
8353
8918
  const sandboxProviderType = process.env.SANDBOX_PROVIDER_TYPE || "microsandbox-remote";
8354
- return (0, import_core33.createSandboxProvider)({
8919
+ return (0, import_core36.createSandboxProvider)({
8355
8920
  type: sandboxProviderType,
8356
8921
  remoteBaseURL: process.env.SANDBOX_BASE_URL,
8357
8922
  microsandboxServiceBaseURL: process.env.MICROSANDBOX_SERVICE_BASE_URL,
@@ -8375,17 +8940,19 @@ var start = async (config) => {
8375
8940
  file: config.loggerConfig.file || DEFAULT_LOGGER_CONFIG.file
8376
8941
  };
8377
8942
  loggerLattice = initializeLogger(loggerConfig);
8378
- logger3 = loggerLattice.client;
8943
+ logger4 = loggerLattice.client;
8379
8944
  }
8380
8945
  app.decorate("loggerLattice", loggerLattice);
8381
8946
  let channelDeps;
8947
+ const adapterRegistry = new ChannelAdapterRegistry();
8948
+ adapterRegistry.register(larkChannelAdapter);
8382
8949
  try {
8383
- const { getStoreLattice: getStoreLattice16 } = await import("@axiom-lattice/core");
8384
- const bindingStore = getStoreLattice16("default", "channelBinding").store;
8385
- const installationStore = getStoreLattice16("default", "channelInstallation").store;
8386
- (0, import_core32.setBindingRegistry)(bindingStore);
8387
- const adapterRegistry = new ChannelAdapterRegistry();
8388
- adapterRegistry.register(larkChannelAdapter);
8950
+ const { getStoreLattice: getStore2 } = await import("@axiom-lattice/core");
8951
+ let bindingStore;
8952
+ let installationStore;
8953
+ bindingStore = getStore2("default", "channelBinding").store;
8954
+ installationStore = getStore2("default", "channelInstallation").store;
8955
+ (0, import_core35.setBindingRegistry)(bindingStore);
8389
8956
  const router = new MessageRouter({
8390
8957
  middlewares: [
8391
8958
  createDeduplicationMiddleware(),
@@ -8398,27 +8965,49 @@ var start = async (config) => {
8398
8965
  });
8399
8966
  channelDeps = { router, installationStore };
8400
8967
  try {
8401
- const a2aKeyStore = getStoreLattice16("default", "a2aApiKey").store;
8968
+ const a2aKeyStore = getStore2("default", "a2aApiKey").store;
8402
8969
  const a2a = await Promise.resolve().then(() => (init_a2a(), a2a_exports));
8403
8970
  a2a.setA2AKeyStore(a2aKeyStore);
8404
8971
  await a2a.refreshStoreKeyMap();
8405
- logger3.info("A2A key store initialized");
8972
+ logger4.info("A2A key store initialized");
8406
8973
  } catch {
8407
8974
  }
8975
+ } catch (err) {
8976
+ logger4.warn("Channel infrastructure unavailable", {
8977
+ error: err instanceof Error ? err.message : String(err)
8978
+ });
8979
+ }
8980
+ try {
8981
+ const menuStore = (0, import_core36.getStoreLattice)("default", "menu").store;
8982
+ (0, import_core35.setMenuRegistry)(menuStore);
8983
+ logger4.info("Menu registry initialized");
8408
8984
  } catch {
8409
8985
  }
8410
8986
  registerLatticeRoutes(app, channelDeps);
8411
- if (!import_core33.sandboxLatticeManager.hasLattice("default")) {
8412
- import_core33.sandboxLatticeManager.registerLattice("default", getConfiguredSandboxProvider());
8413
- logger3.info("Registered sandbox manager from env configuration");
8987
+ if (!import_core36.sandboxLatticeManager.hasLattice("default")) {
8988
+ import_core36.sandboxLatticeManager.registerLattice("default", getConfiguredSandboxProvider());
8989
+ logger4.info("Registered sandbox manager from env configuration");
8990
+ }
8991
+ if (channelDeps && process.env.CHANNELS_ENABLED !== "false") {
8992
+ const { connectAllChannels } = await import("@axiom-lattice/core");
8993
+ try {
8994
+ await connectAllChannels(
8995
+ (channel) => adapterRegistry.get(channel),
8996
+ { deps: { router: channelDeps.router } }
8997
+ );
8998
+ } catch (err) {
8999
+ logger4.error("Failed to start channel connections", {
9000
+ error: err instanceof Error ? err.message : String(err)
9001
+ });
9002
+ }
8414
9003
  }
8415
9004
  const target_port = config?.port || Number(process.env.PORT) || 4001;
8416
9005
  await app.listen({ port: target_port, host: "0.0.0.0" });
8417
- logger3.info(`Lattice Gateway is running on port: ${target_port}`);
9006
+ logger4.info(`Lattice Gateway is running on port: ${target_port}`);
8418
9007
  try {
8419
- logger3.info("AgentLifecycleManager initialized");
9008
+ logger4.info("AgentLifecycleManager initialized");
8420
9009
  } catch (error) {
8421
- logger3.warn("Failed to initialize AgentLifecycleManager", { error });
9010
+ logger4.warn("Failed to initialize AgentLifecycleManager", { error });
8422
9011
  }
8423
9012
  const queueServiceConfig = config?.queueServiceConfig;
8424
9013
  if (queueServiceConfig) {
@@ -8428,15 +9017,13 @@ var start = async (config) => {
8428
9017
  agentTaskConsumer.startPollingQueue();
8429
9018
  }
8430
9019
  }
8431
- try {
8432
- logger3.info("Starting agent instance recovery...");
8433
- const restoreStats = await import_core33.agentInstanceManager.restore();
8434
- logger3.info(`Agent recovery complete: ${restoreStats.restored} threads restored, ${restoreStats.errors} errors`);
8435
- } catch (error) {
8436
- logger3.error("Agent recovery failed", { error });
8437
- }
9020
+ import_core36.agentInstanceManager.restore().then((stats) => {
9021
+ logger4.info(`Agent recovery complete: ${stats.restored} threads restored, ${stats.errors} errors`);
9022
+ }).catch((error) => {
9023
+ logger4.error("Agent recovery failed", { error });
9024
+ });
8438
9025
  } catch (err) {
8439
- logger3.error("Server start failed", { error: err });
9026
+ logger4.error("Server start failed", { error: err });
8440
9027
  process.exit(1);
8441
9028
  }
8442
9029
  };