@axiom-lattice/gateway 2.1.28 → 2.1.29

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
@@ -5,6 +5,9 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
6
  var __getProtoOf = Object.getPrototypeOf;
7
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __esm = (fn, res) => function __init() {
9
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
10
+ };
8
11
  var __export = (target, all) => {
9
12
  for (var name in all)
10
13
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -27,6 +30,106 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
27
30
  ));
28
31
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
32
 
33
+ // src/config.ts
34
+ var config_exports = {};
35
+ __export(config_exports, {
36
+ config: () => config,
37
+ configService: () => configService
38
+ });
39
+ var ConfigService, configService, config;
40
+ var init_config = __esm({
41
+ "src/config.ts"() {
42
+ "use strict";
43
+ ConfigService = class {
44
+ constructor() {
45
+ this.config = this.loadFromEnv();
46
+ }
47
+ /**
48
+ * Load configuration from environment variables
49
+ */
50
+ loadFromEnv() {
51
+ return {
52
+ port: process.env.PORT ? Number(process.env.PORT) : void 0,
53
+ queueServiceType: process.env.QUEUE_SERVICE_TYPE,
54
+ redisUrl: process.env.REDIS_URL,
55
+ redisPassword: process.env.REDIS_PASSWORD,
56
+ queueName: process.env.QUEUE_NAME
57
+ };
58
+ }
59
+ /**
60
+ * Update configuration from JSON object
61
+ * This will update both the internal config and process.env
62
+ */
63
+ updateConfig(jsonConfig) {
64
+ for (const [key, value] of Object.entries(jsonConfig)) {
65
+ if (value !== null && value !== void 0) {
66
+ if (typeof value === "object" && !Array.isArray(value)) {
67
+ for (const [nestedKey, nestedValue] of Object.entries(value)) {
68
+ const envKey = `${key.toUpperCase()}_${nestedKey.toUpperCase()}`;
69
+ process.env[envKey] = String(nestedValue);
70
+ }
71
+ } else {
72
+ process.env[key.toUpperCase()] = String(value);
73
+ }
74
+ }
75
+ }
76
+ this.config = this.loadFromEnv();
77
+ this.config = this.deepMerge(this.config, jsonConfig);
78
+ }
79
+ /**
80
+ * Deep merge two objects
81
+ */
82
+ deepMerge(target, source) {
83
+ const output = { ...target };
84
+ if (this.isObject(target) && this.isObject(source)) {
85
+ Object.keys(source).forEach((key) => {
86
+ if (this.isObject(source[key])) {
87
+ if (!(key in target)) {
88
+ Object.assign(output, { [key]: source[key] });
89
+ } else {
90
+ output[key] = this.deepMerge(target[key], source[key]);
91
+ }
92
+ } else {
93
+ Object.assign(output, { [key]: source[key] });
94
+ }
95
+ });
96
+ }
97
+ return output;
98
+ }
99
+ /**
100
+ * Check if value is a plain object
101
+ */
102
+ isObject(item) {
103
+ return item && typeof item === "object" && !Array.isArray(item);
104
+ }
105
+ /**
106
+ * Get current configuration
107
+ */
108
+ getConfig() {
109
+ return { ...this.config };
110
+ }
111
+ };
112
+ configService = new ConfigService();
113
+ config = {
114
+ get port() {
115
+ return configService.getConfig().port;
116
+ },
117
+ get queueServiceType() {
118
+ return configService.getConfig().queueServiceType;
119
+ },
120
+ get redisUrl() {
121
+ return configService.getConfig().redisUrl;
122
+ },
123
+ get redisPassword() {
124
+ return configService.getConfig().redisPassword;
125
+ },
126
+ get queueName() {
127
+ return configService.getConfig().queueName;
128
+ }
129
+ };
130
+ }
131
+ });
132
+
30
133
  // src/index.ts
31
134
  var index_exports = {};
32
135
  __export(index_exports, {
@@ -44,6 +147,31 @@ var import_messages = require("@langchain/core/messages");
44
147
  var import_langgraph = require("@langchain/langgraph");
45
148
  var import_uuid = require("uuid");
46
149
  var import_core = require("@axiom-lattice/core");
150
+ async function fetchDatabaseConfigs(baseURL, apiKey, tenantId) {
151
+ try {
152
+ const headers = {};
153
+ if (apiKey) {
154
+ headers["Authorization"] = `Bearer ${apiKey}`;
155
+ }
156
+ if (tenantId) {
157
+ headers["x-tenant-id"] = tenantId;
158
+ }
159
+ const response = await fetch(`${baseURL}/api/database-configs`, { headers });
160
+ if (response.ok) {
161
+ const data = await response.json();
162
+ if (data.success && data.data && Array.isArray(data.data.records)) {
163
+ return data.data.records.map((record) => ({
164
+ key: record.key,
165
+ name: record.name,
166
+ description: record.description
167
+ }));
168
+ }
169
+ }
170
+ } catch (error) {
171
+ console.error("Failed to fetch database configs:", error);
172
+ }
173
+ return [];
174
+ }
47
175
  function getOrCreateChunkBuffer() {
48
176
  if (!(0, import_core.hasChunkBuffer)("default")) {
49
177
  const buffer = new import_core.InMemoryChunkBuffer({
@@ -61,6 +189,8 @@ async function agent_invoke({
61
189
  thread_id,
62
190
  assistant_id,
63
191
  tenant_id,
192
+ workspace_id,
193
+ project_id,
64
194
  command,
65
195
  run_id
66
196
  }) {
@@ -72,10 +202,19 @@ async function agent_invoke({
72
202
  if (!runnable_agent) {
73
203
  throw new Error(`Agent ${assistant_id} not found`);
74
204
  }
205
+ const { configService: configService2 } = await Promise.resolve().then(() => (init_config(), config_exports));
206
+ const gatewayConfig = configService2.getConfig();
207
+ const databaseConfigs = await fetchDatabaseConfigs(
208
+ gatewayConfig.baseURL || "http://localhost:4001",
209
+ void 0,
210
+ tenant_id
211
+ );
212
+ global.__DATABASE_CONFIGS__ = databaseConfigs;
75
213
  const runConfig = {
76
214
  ...agentLattice?.config?.runConfig || {},
77
215
  assistant_id,
78
- sandboxConfig: agentLattice?.config?.connectedSandbox
216
+ workspaceId: workspace_id,
217
+ projectId: project_id
79
218
  };
80
219
  const result = await runnable_agent.invoke(
81
220
  command ? new import_langgraph.Command(command) : { ...rest, messages, "x-tenant-id": tenant_id },
@@ -84,11 +223,12 @@ async function agent_invoke({
84
223
  thread_id,
85
224
  run_id: run_id || (0, import_uuid.v4)(),
86
225
  "x-tenant-id": tenant_id,
226
+ "x-workspace-id": workspace_id,
227
+ "x-project-id": project_id,
87
228
  "x-request-id": run_id,
88
229
  "x-thread-id": thread_id,
89
230
  "x-assistant-id": assistant_id,
90
231
  runConfig
91
- // Inject runConfig for tools to access
92
232
  },
93
233
  recursionLimit: 200
94
234
  }
@@ -107,6 +247,8 @@ async function agent_stream({
107
247
  thread_id,
108
248
  command,
109
249
  tenant_id,
250
+ workspace_id,
251
+ project_id,
110
252
  assistant_id,
111
253
  run_id
112
254
  }) {
@@ -119,10 +261,19 @@ async function agent_stream({
119
261
  messages = [humanMessage];
120
262
  }
121
263
  const chunkBuffer = getOrCreateChunkBuffer();
264
+ const { configService: configService2 } = await Promise.resolve().then(() => (init_config(), config_exports));
265
+ const gatewayConfig = configService2.getConfig();
266
+ const databaseConfigs = await fetchDatabaseConfigs(
267
+ gatewayConfig.baseURL || "http://localhost:4001",
268
+ void 0,
269
+ tenant_id
270
+ );
271
+ global.__DATABASE_CONFIGS__ = databaseConfigs;
122
272
  const runConfig = {
123
273
  ...agentLattice?.config?.runConfig || {},
124
274
  assistant_id,
125
- sandboxConfig: agentLattice?.config?.connectedSandbox
275
+ workspaceId: workspace_id,
276
+ projectId: project_id
126
277
  };
127
278
  try {
128
279
  if (!runnable_agent) {
@@ -139,6 +290,8 @@ async function agent_stream({
139
290
  thread_id,
140
291
  run_id: run_id || (0, import_uuid.v4)(),
141
292
  "x-tenant-id": tenant_id,
293
+ "x-workspace-id": workspace_id,
294
+ "x-project-id": project_id,
142
295
  "x-request-id": run_id,
143
296
  "x-thread-id": thread_id,
144
297
  "x-assistant-id": assistant_id,
@@ -272,12 +425,12 @@ async function resume_stream({
272
425
  var import_core2 = require("@axiom-lattice/core");
273
426
  var import_crypto = require("crypto");
274
427
  var import_core3 = require("@axiom-lattice/core");
275
- function convertAgentConfigToAssistant(config) {
428
+ function convertAgentConfigToAssistant(config2) {
276
429
  return {
277
- id: config.key,
278
- name: config.name,
279
- description: config.description,
280
- graphDefinition: config,
430
+ id: config2.key,
431
+ name: config2.name,
432
+ description: config2.description,
433
+ graphDefinition: config2,
281
434
  // Store the full config as graphDefinition
282
435
  createdAt: /* @__PURE__ */ new Date(0),
283
436
  // Code-configured agents have no creation date
@@ -317,7 +470,7 @@ async function getAssistant(request, reply) {
317
470
  let assistant = await assistantStore.getAssistantById(id);
318
471
  if (!assistant) {
319
472
  const agentConfigs = await (0, import_core3.getAllAgentConfigs)();
320
- const agentConfig = agentConfigs.find((config) => config.key === id);
473
+ const agentConfig = agentConfigs.find((config2) => config2.key === id);
321
474
  if (agentConfig) {
322
475
  assistant = convertAgentConfigToAssistant(agentConfig);
323
476
  }
@@ -392,7 +545,7 @@ async function deleteAssistant(request, reply) {
392
545
  const storeLattice = (0, import_core2.getStoreLattice)("default", "assistant");
393
546
  const assistantStore = storeLattice.store;
394
547
  const agentConfigs = await (0, import_core3.getAllAgentConfigs)();
395
- const isCodeConfigured = agentConfigs.some((config) => config.key === id);
548
+ const isCodeConfigured = agentConfigs.some((config2) => config2.key === id);
396
549
  if (isCodeConfigured) {
397
550
  const exists2 = await assistantStore.hasAssistant(id);
398
551
  if (!exists2) {
@@ -456,6 +609,8 @@ var createRun = async (request, reply) => {
456
609
  ...input
457
610
  } = request.body;
458
611
  const tenant_id = request.headers["x-tenant-id"];
612
+ const workspace_id = request.headers["x-workspace-id"];
613
+ const project_id = request.headers["x-project-id"];
459
614
  const x_request_id = request.headers["x-request-id"] || (0, import_uuid2.v4)();
460
615
  if (!assistant_id) {
461
616
  reply.status(400).send({
@@ -471,6 +626,8 @@ var createRun = async (request, reply) => {
471
626
  thread_id,
472
627
  command,
473
628
  tenant_id,
629
+ workspace_id,
630
+ project_id,
474
631
  run_id: x_request_id
475
632
  });
476
633
  reply.hijack();
@@ -498,6 +655,8 @@ var createRun = async (request, reply) => {
498
655
  command,
499
656
  thread_id,
500
657
  tenant_id,
658
+ workspace_id,
659
+ project_id,
501
660
  run_id: x_request_id
502
661
  });
503
662
  reply.status(200).send(result);
@@ -1044,77 +1203,8 @@ async function resumeScheduledTask(request, reply) {
1044
1203
  }
1045
1204
  }
1046
1205
 
1047
- // src/config.ts
1048
- var ConfigService = class {
1049
- constructor() {
1050
- this.config = this.loadFromEnv();
1051
- }
1052
- /**
1053
- * Load configuration from environment variables
1054
- */
1055
- loadFromEnv() {
1056
- return {
1057
- port: process.env.PORT ? Number(process.env.PORT) : void 0,
1058
- queueServiceType: process.env.QUEUE_SERVICE_TYPE,
1059
- redisUrl: process.env.REDIS_URL,
1060
- redisPassword: process.env.REDIS_PASSWORD,
1061
- queueName: process.env.QUEUE_NAME
1062
- };
1063
- }
1064
- /**
1065
- * Update configuration from JSON object
1066
- * This will update both the internal config and process.env
1067
- */
1068
- updateConfig(jsonConfig) {
1069
- for (const [key, value] of Object.entries(jsonConfig)) {
1070
- if (value !== null && value !== void 0) {
1071
- if (typeof value === "object" && !Array.isArray(value)) {
1072
- for (const [nestedKey, nestedValue] of Object.entries(value)) {
1073
- const envKey = `${key.toUpperCase()}_${nestedKey.toUpperCase()}`;
1074
- process.env[envKey] = String(nestedValue);
1075
- }
1076
- } else {
1077
- process.env[key.toUpperCase()] = String(value);
1078
- }
1079
- }
1080
- }
1081
- this.config = this.loadFromEnv();
1082
- this.config = this.deepMerge(this.config, jsonConfig);
1083
- }
1084
- /**
1085
- * Deep merge two objects
1086
- */
1087
- deepMerge(target, source) {
1088
- const output = { ...target };
1089
- if (this.isObject(target) && this.isObject(source)) {
1090
- Object.keys(source).forEach((key) => {
1091
- if (this.isObject(source[key])) {
1092
- if (!(key in target)) {
1093
- Object.assign(output, { [key]: source[key] });
1094
- } else {
1095
- output[key] = this.deepMerge(target[key], source[key]);
1096
- }
1097
- } else {
1098
- Object.assign(output, { [key]: source[key] });
1099
- }
1100
- });
1101
- }
1102
- return output;
1103
- }
1104
- /**
1105
- * Check if value is a plain object
1106
- */
1107
- isObject(item) {
1108
- return item && typeof item === "object" && !Array.isArray(item);
1109
- }
1110
- /**
1111
- * Get current configuration
1112
- */
1113
- getConfig() {
1114
- return { ...this.config };
1115
- }
1116
- };
1117
- var configService = new ConfigService();
1206
+ // src/controllers/config.ts
1207
+ init_config();
1118
1208
 
1119
1209
  // src/services/queue_service.ts
1120
1210
  var import_core7 = require("@axiom-lattice/core");
@@ -1126,7 +1216,7 @@ var setQueueServiceType = (type) => {
1126
1216
  queueServiceType = type;
1127
1217
  console.log(`Queue service type set to: ${type}`);
1128
1218
  const queueName = process.env.QUEUE_NAME || "tasks";
1129
- const config = {
1219
+ const config2 = {
1130
1220
  name: "Default Queue Service",
1131
1221
  description: `Default ${type} queue service`,
1132
1222
  type: type === "redis" ? import_protocols.QueueType.REDIS : import_protocols.QueueType.MEMORY,
@@ -1146,7 +1236,7 @@ var setQueueServiceType = (type) => {
1146
1236
  redisPassword: process.env.REDIS_PASSWORD
1147
1237
  });
1148
1238
  }
1149
- (0, import_core7.registerQueueLattice)(DEFAULT_QUEUE_KEY, config, client);
1239
+ (0, import_core7.registerQueueLattice)(DEFAULT_QUEUE_KEY, config2, client);
1150
1240
  };
1151
1241
  var getQueueService = () => {
1152
1242
  if (!import_core7.queueLatticeManager.hasLattice(DEFAULT_QUEUE_KEY)) {
@@ -1238,18 +1328,18 @@ async function getModels(request, reply) {
1238
1328
  try {
1239
1329
  const allLattices = import_core8.modelLatticeManager.getAllLattices();
1240
1330
  const models = allLattices.map((lattice) => {
1241
- const config = lattice.client.config || {};
1331
+ const config2 = lattice.client.config || {};
1242
1332
  return {
1243
1333
  key: lattice.key,
1244
- model: config.model || "",
1245
- provider: config.provider || "openai",
1246
- streaming: config.streaming || false,
1247
- apiKey: config.apiKey || "",
1248
- baseURL: config.baseURL || "",
1249
- maxTokens: config.maxTokens,
1250
- temperature: config.temperature,
1251
- timeout: config.timeout,
1252
- maxRetries: config.maxRetries
1334
+ model: config2.model || "",
1335
+ provider: config2.provider || "openai",
1336
+ streaming: config2.streaming || false,
1337
+ apiKey: config2.apiKey || "",
1338
+ baseURL: config2.baseURL || "",
1339
+ maxTokens: config2.maxTokens,
1340
+ temperature: config2.temperature,
1341
+ timeout: config2.timeout,
1342
+ maxRetries: config2.maxRetries
1253
1343
  };
1254
1344
  });
1255
1345
  return reply.send({
@@ -1709,15 +1799,15 @@ async function getToolConfigs(request, reply) {
1709
1799
  try {
1710
1800
  const allLattices = import_core11.toolLatticeManager.getAllLattices();
1711
1801
  const toolConfigs = allLattices.map((lattice) => {
1712
- const config = { ...lattice.config };
1713
- const serializedSchema = config.schema ? serializeSchema(config.schema) : void 0;
1802
+ const config2 = { ...lattice.config };
1803
+ const serializedSchema = config2.schema ? serializeSchema(config2.schema) : void 0;
1714
1804
  return {
1715
1805
  id: lattice.key,
1716
- name: config.name,
1717
- description: config.description,
1806
+ name: config2.name,
1807
+ description: config2.description,
1718
1808
  schema: serializedSchema,
1719
- returnDirect: config.returnDirect,
1720
- needUserApprove: config.needUserApprove
1809
+ returnDirect: config2.returnDirect,
1810
+ needUserApprove: config2.needUserApprove
1721
1811
  };
1722
1812
  });
1723
1813
  return reply.send({
@@ -2205,8 +2295,8 @@ var sandboxService = new SandboxService();
2205
2295
 
2206
2296
  // src/controllers/sandbox.ts
2207
2297
  var import_core13 = require("@axiom-lattice/core");
2208
- function getFilenameFromPath(path) {
2209
- const segments = path.replace(/\/+$/, "").split("/");
2298
+ function getFilenameFromPath(path2) {
2299
+ const segments = path2.replace(/\/+$/, "").split("/");
2210
2300
  return segments[segments.length - 1] || "download";
2211
2301
  }
2212
2302
  var EXT_TO_MIME = {
@@ -2257,10 +2347,10 @@ function registerSandboxProxyRoutes(app2) {
2257
2347
  const pathValue = pathEntry && typeof pathEntry === "object" && "value" in pathEntry ? String(pathEntry.value) : typeof pathEntry === "string" ? pathEntry : void 0;
2258
2348
  const formData = new FormData();
2259
2349
  formData.append("file", new Blob([buffer]), data.filename ?? "file");
2260
- const path = `/home/gem/uploads/${pathValue ? pathValue : ""}${data.filename}`;
2350
+ const path2 = `/home/gem/uploads/${pathValue ? pathValue : ""}${data.filename}`;
2261
2351
  const uploadResult = await sandbox.file.uploadFile({
2262
2352
  file: buffer,
2263
- path
2353
+ path: path2
2264
2354
  });
2265
2355
  if (!uploadResult.ok) {
2266
2356
  return reply.status(502).send({ error: `Upload error: ${uploadResult.error}` });
@@ -2343,6 +2433,670 @@ function registerSandboxProxyRoutes(app2) {
2343
2433
  );
2344
2434
  }
2345
2435
 
2436
+ // src/controllers/workspace.ts
2437
+ var fs = __toESM(require("fs/promises"));
2438
+ var path = __toESM(require("path"));
2439
+ var import_stream2 = require("stream");
2440
+ var import_core14 = require("@axiom-lattice/core");
2441
+ var import_core15 = require("@axiom-lattice/core");
2442
+ var import_core16 = require("@axiom-lattice/core");
2443
+ var import_uuid3 = require("uuid");
2444
+ var WorkspaceController = class {
2445
+ constructor() {
2446
+ this.workspaceStore = (0, import_core14.getStoreLattice)("default", "workspace").store;
2447
+ this.projectStore = (0, import_core14.getStoreLattice)("default", "project").store;
2448
+ }
2449
+ getTenantId(request) {
2450
+ return request.headers["x-tenant-id"] || "default";
2451
+ }
2452
+ // ==================== Workspace CRUD ====================
2453
+ async listWorkspaces(request, reply) {
2454
+ const tenantId = this.getTenantId(request);
2455
+ const workspaces = await this.workspaceStore.getAllWorkspaces(tenantId);
2456
+ return { success: true, data: workspaces };
2457
+ }
2458
+ async createWorkspace(request, reply) {
2459
+ const tenantId = this.getTenantId(request);
2460
+ const data = request.body;
2461
+ const id = (0, import_uuid3.v4)();
2462
+ const workspace = await this.workspaceStore.createWorkspace(
2463
+ tenantId,
2464
+ id,
2465
+ data
2466
+ );
2467
+ return reply.status(201).send({ success: true, data: workspace });
2468
+ }
2469
+ async getWorkspace(request, reply) {
2470
+ const tenantId = this.getTenantId(request);
2471
+ const { workspaceId } = request.params;
2472
+ const workspace = await this.workspaceStore.getWorkspaceById(
2473
+ tenantId,
2474
+ workspaceId
2475
+ );
2476
+ if (!workspace) {
2477
+ return reply.status(404).send({ success: false, error: "Workspace not found" });
2478
+ }
2479
+ return { success: true, data: workspace };
2480
+ }
2481
+ async updateWorkspace(request, reply) {
2482
+ const tenantId = this.getTenantId(request);
2483
+ const { workspaceId } = request.params;
2484
+ const updates = request.body;
2485
+ const workspace = await this.workspaceStore.updateWorkspace(
2486
+ tenantId,
2487
+ workspaceId,
2488
+ updates
2489
+ );
2490
+ if (!workspace) {
2491
+ return reply.status(404).send({ success: false, error: "Workspace not found" });
2492
+ }
2493
+ return { success: true, data: workspace };
2494
+ }
2495
+ async deleteWorkspace(request, reply) {
2496
+ const tenantId = this.getTenantId(request);
2497
+ const { workspaceId } = request.params;
2498
+ const deleted = await this.workspaceStore.deleteWorkspace(
2499
+ tenantId,
2500
+ workspaceId
2501
+ );
2502
+ if (!deleted) {
2503
+ return reply.status(404).send({ success: false, error: "Workspace not found" });
2504
+ }
2505
+ return { success: true };
2506
+ }
2507
+ // ==================== Project CRUD ====================
2508
+ async listProjects(request, reply) {
2509
+ const tenantId = this.getTenantId(request);
2510
+ const { workspaceId } = request.params;
2511
+ const projects = await this.projectStore.getProjectsByWorkspace(
2512
+ tenantId,
2513
+ workspaceId
2514
+ );
2515
+ return { success: true, data: projects };
2516
+ }
2517
+ async createProject(request, reply) {
2518
+ const tenantId = this.getTenantId(request);
2519
+ const { workspaceId } = request.params;
2520
+ const data = request.body;
2521
+ const id = (0, import_uuid3.v4)();
2522
+ const project = await this.projectStore.createProject(
2523
+ tenantId,
2524
+ workspaceId,
2525
+ id,
2526
+ data
2527
+ );
2528
+ return reply.status(201).send({ success: true, data: project });
2529
+ }
2530
+ async getProject(request, reply) {
2531
+ const tenantId = this.getTenantId(request);
2532
+ const { projectId } = request.params;
2533
+ const project = await this.projectStore.getProjectById(tenantId, projectId);
2534
+ if (!project) {
2535
+ return reply.status(404).send({ success: false, error: "Project not found" });
2536
+ }
2537
+ return { success: true, data: project };
2538
+ }
2539
+ async updateProject(request, reply) {
2540
+ const tenantId = this.getTenantId(request);
2541
+ const { projectId } = request.params;
2542
+ const updates = request.body;
2543
+ const project = await this.projectStore.updateProject(
2544
+ tenantId,
2545
+ projectId,
2546
+ updates
2547
+ );
2548
+ if (!project) {
2549
+ return reply.status(404).send({ success: false, error: "Project not found" });
2550
+ }
2551
+ return { success: true, data: project };
2552
+ }
2553
+ async deleteProject(request, reply) {
2554
+ const tenantId = this.getTenantId(request);
2555
+ const { projectId } = request.params;
2556
+ const deleted = await this.projectStore.deleteProject(tenantId, projectId);
2557
+ if (!deleted) {
2558
+ return reply.status(404).send({ success: false, error: "Project not found" });
2559
+ }
2560
+ return { success: true };
2561
+ }
2562
+ // ==================== File Operations ====================
2563
+ async getBackend(workspaceId, projectId) {
2564
+ const tenantId = "default";
2565
+ const workspace = await this.workspaceStore.getWorkspaceById(
2566
+ tenantId,
2567
+ workspaceId
2568
+ );
2569
+ if (!workspace) {
2570
+ throw new Error("Workspace not found");
2571
+ }
2572
+ if (workspace.storageType === "sandbox") {
2573
+ const sandboxManager = (0, import_core16.getSandBoxManager)("default");
2574
+ const sandboxName = "global";
2575
+ const sandbox = await sandboxManager.createSandbox(sandboxName);
2576
+ return { backend: new import_core15.SandboxFilesystem({
2577
+ sandboxInstance: sandbox,
2578
+ workingDirectory: `/workspaces/${workspaceId}/${projectId}`
2579
+ }), workspace };
2580
+ } else {
2581
+ return { backend: new import_core15.FilesystemBackend({
2582
+ rootDir: `/lattice_store/workspaces/${workspaceId}/${projectId}`,
2583
+ virtualMode: true
2584
+ }), workspace };
2585
+ }
2586
+ }
2587
+ getFilenameFromPath(filePath) {
2588
+ const segments = filePath.split("/");
2589
+ return segments[segments.length - 1] || "download";
2590
+ }
2591
+ getMimeType(filename) {
2592
+ const ext = filename.split(".").pop()?.toLowerCase() || "";
2593
+ const mimeTypes = {
2594
+ pdf: "application/pdf",
2595
+ csv: "text/csv",
2596
+ xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
2597
+ xls: "application/vnd.ms-excel",
2598
+ txt: "text/plain",
2599
+ json: "application/json",
2600
+ png: "image/png",
2601
+ jpg: "image/jpeg",
2602
+ jpeg: "image/jpeg",
2603
+ gif: "image/gif",
2604
+ svg: "image/svg+xml",
2605
+ html: "text/html",
2606
+ htm: "text/html",
2607
+ mp3: "audio/mpeg",
2608
+ mp4: "video/mp4",
2609
+ webm: "video/webm"
2610
+ };
2611
+ return mimeTypes[ext] || "application/octet-stream";
2612
+ }
2613
+ async downloadFile(request, reply) {
2614
+ const { workspaceId, projectId } = request.params;
2615
+ const filePath = request.query.path;
2616
+ if (!filePath) {
2617
+ return reply.status(400).send({ success: false, error: "Path is required" });
2618
+ }
2619
+ try {
2620
+ const { workspace } = await this.getBackend(workspaceId, projectId);
2621
+ const resolvedPath = filePath.startsWith("/") ? filePath : `/${filePath}`;
2622
+ if (workspace.storageType === "sandbox") {
2623
+ const sandboxManager = (0, import_core16.getSandBoxManager)("default");
2624
+ const sandbox = await sandboxManager.createSandbox("global");
2625
+ const realPath = path.join("/home/gem/workspaces", workspaceId, projectId, resolvedPath);
2626
+ const filename2 = this.getFilenameFromPath(resolvedPath);
2627
+ const inferredContentType = this.getMimeType(filename2);
2628
+ const downloadResult = await sandbox.file.downloadFile({
2629
+ path: realPath
2630
+ });
2631
+ if (!downloadResult.ok) {
2632
+ return reply.status(502).send({
2633
+ success: false,
2634
+ error: `Download error: ${JSON.stringify(downloadResult.error)}`
2635
+ });
2636
+ }
2637
+ const body = downloadResult.body;
2638
+ if (typeof body?.stream === "function") {
2639
+ const webStream = body.stream();
2640
+ const nodeStream = import_stream2.Readable.fromWeb(webStream);
2641
+ const contentType2 = body.contentType ?? inferredContentType;
2642
+ const contentDisposition2 = body.contentDisposition ?? `inline; filename*=UTF-8''${encodeURIComponent(filename2)}`;
2643
+ return reply.status(200).type(contentType2).header("Content-Disposition", contentDisposition2).send(nodeStream);
2644
+ }
2645
+ const bodyUnknown = downloadResult.body;
2646
+ let buf;
2647
+ let contentType = inferredContentType;
2648
+ let contentDisposition = `inline; filename*=UTF-8''${encodeURIComponent(filename2)}`;
2649
+ if (bodyUnknown instanceof ArrayBuffer) {
2650
+ buf = Buffer.from(bodyUnknown);
2651
+ } else if (bodyUnknown instanceof Buffer) {
2652
+ buf = bodyUnknown;
2653
+ } else if (bodyUnknown && typeof bodyUnknown.arrayBuffer === "function") {
2654
+ const res = bodyUnknown;
2655
+ buf = Buffer.from(await res.arrayBuffer());
2656
+ if (res.headers?.get("content-type")) contentType = res.headers.get("content-type");
2657
+ if (res.headers?.get("content-disposition")) contentDisposition = res.headers.get("content-disposition");
2658
+ } else if (bodyUnknown && typeof bodyUnknown.blob === "function") {
2659
+ const blob = await bodyUnknown.blob();
2660
+ buf = Buffer.from(await blob.arrayBuffer());
2661
+ } else {
2662
+ return reply.status(502).send({ success: false, error: "Unexpected download response format" });
2663
+ }
2664
+ return reply.status(200).type(contentType).header("Content-Disposition", contentDisposition).send(buf);
2665
+ }
2666
+ const { backend } = await this.getBackend(workspaceId, projectId);
2667
+ const content = await backend.read(resolvedPath, 0, Infinity);
2668
+ const filename = this.getFilenameFromPath(resolvedPath);
2669
+ const mimeType = this.getMimeType(filename);
2670
+ const buffer = Buffer.from(content, "utf-8");
2671
+ return reply.status(200).type(mimeType).header("Content-Disposition", `inline; filename*=UTF-8''${encodeURIComponent(filename)}`).send(buffer);
2672
+ } catch (error) {
2673
+ const message = error instanceof Error ? error.message : String(error);
2674
+ return reply.status(502).send({ success: false, error: `Download proxy error: ${message}` });
2675
+ }
2676
+ }
2677
+ async listPath(request) {
2678
+ const { workspaceId, projectId } = request.params;
2679
+ const path2 = request.query.path || "/";
2680
+ const { backend } = await this.getBackend(workspaceId, projectId);
2681
+ const files = await backend.lsInfo(path2);
2682
+ return { success: true, data: files };
2683
+ }
2684
+ async readFile(request) {
2685
+ const { workspaceId, projectId } = request.params;
2686
+ const { path: path2, offset = 0, limit = 1e3 } = request.query;
2687
+ const { backend } = await this.getBackend(workspaceId, projectId);
2688
+ const content = await backend.read(path2, Number(offset), Number(limit));
2689
+ return { success: true, data: { content, offset, limit } };
2690
+ }
2691
+ /**
2692
+ * Upload a file to the workspace project storage.
2693
+ *
2694
+ * Route: POST /api/workspaces/:workspaceId/projects/:projectId/uploadfile
2695
+ * Accepts multipart/form-data with:
2696
+ * - `file`: the file to upload (required)
2697
+ * - `path`: optional directory path relative to project root (e.g., "docs", "src/utils")
2698
+ * For sandbox storage, delegates to the sandbox upload API.
2699
+ * For filesystem storage, writes directly under /lattice_store/workspaces/{workspaceId}/{projectId}.
2700
+ */
2701
+ async uploadFile(request, reply) {
2702
+ const tenantId = this.getTenantId(request);
2703
+ const { workspaceId, projectId } = request.params;
2704
+ const workspace = await this.workspaceStore.getWorkspaceById(
2705
+ tenantId,
2706
+ workspaceId
2707
+ );
2708
+ if (!workspace) {
2709
+ return reply.status(404).send({ success: false, error: "Workspace not found" });
2710
+ }
2711
+ try {
2712
+ const data = await request.file();
2713
+ if (!data) {
2714
+ return reply.status(400).send({ success: false, error: "No file in request" });
2715
+ }
2716
+ const buffer = await data.toBuffer();
2717
+ const filename = data.filename || "file";
2718
+ const pathEntry = data.fields?.path;
2719
+ const pathValue = pathEntry && typeof pathEntry === "object" && "value" in pathEntry ? String(pathEntry.value) : typeof pathEntry === "string" ? pathEntry : void 0;
2720
+ if (pathValue && !/^[a-zA-Z0-9_./-]+$/.test(pathValue)) {
2721
+ return reply.status(400).send({ success: false, error: "Invalid path parameter" });
2722
+ }
2723
+ if (workspace.storageType === "sandbox") {
2724
+ const sandboxManager = (0, import_core16.getSandBoxManager)("default");
2725
+ const sandboxName = "global";
2726
+ const sandbox = await sandboxManager.createSandbox(sandboxName);
2727
+ const baseDir = path.join("/home/gem/workspaces", workspaceId, projectId);
2728
+ const realPath = pathValue ? path.join(baseDir, pathValue, filename) : path.join(baseDir, filename);
2729
+ const uploadResult = await sandbox.file.uploadFile({
2730
+ file: buffer,
2731
+ path: realPath
2732
+ }, { timeoutInSeconds: 300 });
2733
+ if (!uploadResult.ok) {
2734
+ return reply.status(502).send({
2735
+ success: false,
2736
+ error: `Upload error: ${JSON.stringify(uploadResult.error)}`
2737
+ });
2738
+ }
2739
+ const relativePath = uploadResult.body?.data?.file_path?.replace(path.join("/home/gem/workspaces", workspaceId, projectId), "") || (pathValue ? `/${pathValue}/${filename}` : `/${filename}`);
2740
+ const result2 = {
2741
+ path: relativePath,
2742
+ name: filename,
2743
+ is_dir: false,
2744
+ size: buffer.length,
2745
+ modified_at: (/* @__PURE__ */ new Date()).toISOString()
2746
+ };
2747
+ return reply.status(200).send({ success: true, data: result2 });
2748
+ }
2749
+ const rootDir = `/lattice_store/workspaces/${workspaceId}/${projectId}`;
2750
+ const targetDir = pathValue ? path.join(rootDir, pathValue) : rootDir;
2751
+ const targetPath = path.join(targetDir, filename);
2752
+ await fs.mkdir(path.dirname(targetPath), { recursive: true });
2753
+ await fs.writeFile(targetPath, buffer);
2754
+ const stat2 = await fs.stat(targetPath);
2755
+ const result = {
2756
+ path: pathValue ? `/${pathValue}/${filename}` : `/${filename}`,
2757
+ name: filename,
2758
+ is_dir: false,
2759
+ size: stat2.size,
2760
+ modified_at: stat2.mtime.toISOString()
2761
+ };
2762
+ return reply.status(200).send({ success: true, data: result });
2763
+ } catch (error) {
2764
+ return reply.status(500).send({
2765
+ success: false,
2766
+ error: `Upload handler error: ${error?.message || String(error)}`
2767
+ });
2768
+ }
2769
+ }
2770
+ };
2771
+ function registerWorkspaceRoutes(app2) {
2772
+ const controller = new WorkspaceController();
2773
+ app2.get("/api/workspaces", controller.listWorkspaces.bind(controller));
2774
+ app2.post("/api/workspaces", controller.createWorkspace.bind(controller));
2775
+ app2.get(
2776
+ "/api/workspaces/:workspaceId",
2777
+ controller.getWorkspace.bind(controller)
2778
+ );
2779
+ app2.patch(
2780
+ "/api/workspaces/:workspaceId",
2781
+ controller.updateWorkspace.bind(controller)
2782
+ );
2783
+ app2.delete(
2784
+ "/api/workspaces/:workspaceId",
2785
+ controller.deleteWorkspace.bind(controller)
2786
+ );
2787
+ app2.get(
2788
+ "/api/workspaces/:workspaceId/projects",
2789
+ controller.listProjects.bind(controller)
2790
+ );
2791
+ app2.post(
2792
+ "/api/workspaces/:workspaceId/projects",
2793
+ controller.createProject.bind(controller)
2794
+ );
2795
+ app2.get(
2796
+ "/api/workspaces/:workspaceId/projects/:projectId",
2797
+ controller.getProject.bind(controller)
2798
+ );
2799
+ app2.patch(
2800
+ "/api/workspaces/:workspaceId/projects/:projectId",
2801
+ controller.updateProject.bind(controller)
2802
+ );
2803
+ app2.delete(
2804
+ "/api/workspaces/:workspaceId/projects/:projectId",
2805
+ controller.deleteProject.bind(controller)
2806
+ );
2807
+ app2.get(
2808
+ "/api/workspaces/:workspaceId/projects/:projectId/listpath",
2809
+ controller.listPath.bind(controller)
2810
+ );
2811
+ app2.get(
2812
+ "/api/workspaces/:workspaceId/projects/:projectId/readfile",
2813
+ controller.readFile.bind(controller)
2814
+ );
2815
+ app2.post(
2816
+ "/api/workspaces/:workspaceId/projects/:projectId/uploadfile",
2817
+ controller.uploadFile.bind(controller)
2818
+ );
2819
+ app2.get(
2820
+ "/api/workspaces/:workspaceId/projects/:projectId/downloadfile",
2821
+ controller.downloadFile.bind(controller)
2822
+ );
2823
+ }
2824
+
2825
+ // src/controllers/database-configs.ts
2826
+ var import_core17 = require("@axiom-lattice/core");
2827
+ var import_crypto3 = require("crypto");
2828
+ function getTenantId(request) {
2829
+ return request.headers["x-tenant-id"] || "default";
2830
+ }
2831
+ async function getDatabaseConfigList(request, reply) {
2832
+ const tenantId = getTenantId(request);
2833
+ try {
2834
+ const storeLattice = (0, import_core17.getStoreLattice)("default", "database");
2835
+ const store = storeLattice.store;
2836
+ const configs = await store.getAllConfigs(tenantId);
2837
+ console.log("Backend: getAllConfigs returned:", configs);
2838
+ if (configs.length > 0) {
2839
+ console.log("Backend: First config key:", configs[0].key);
2840
+ }
2841
+ return {
2842
+ success: true,
2843
+ message: "Database configurations retrieved successfully",
2844
+ data: {
2845
+ records: configs,
2846
+ total: configs.length
2847
+ }
2848
+ };
2849
+ } catch (error) {
2850
+ console.error("Failed to get database configs:", error);
2851
+ return {
2852
+ success: false,
2853
+ message: "Failed to retrieve database configurations",
2854
+ data: {
2855
+ records: [],
2856
+ total: 0
2857
+ }
2858
+ };
2859
+ }
2860
+ }
2861
+ async function getDatabaseConfig(request, reply) {
2862
+ const tenantId = getTenantId(request);
2863
+ const { key } = request.params;
2864
+ try {
2865
+ const storeLattice = (0, import_core17.getStoreLattice)("default", "database");
2866
+ const store = storeLattice.store;
2867
+ const config2 = await store.getConfigByKey(tenantId, key);
2868
+ if (!config2) {
2869
+ return {
2870
+ success: false,
2871
+ message: "Database configuration not found"
2872
+ };
2873
+ }
2874
+ return {
2875
+ success: true,
2876
+ message: "Database configuration retrieved successfully",
2877
+ data: config2
2878
+ };
2879
+ } catch (error) {
2880
+ console.error("Failed to get database config:", error);
2881
+ return {
2882
+ success: false,
2883
+ message: "Failed to retrieve database configuration"
2884
+ };
2885
+ }
2886
+ }
2887
+ async function createDatabaseConfig(request, reply) {
2888
+ const tenantId = getTenantId(request);
2889
+ const body = request.body;
2890
+ try {
2891
+ const storeLattice = (0, import_core17.getStoreLattice)("default", "database");
2892
+ const store = storeLattice.store;
2893
+ const existing = await store.getConfigByKey(tenantId, body.key);
2894
+ if (existing) {
2895
+ reply.code(409);
2896
+ return {
2897
+ success: false,
2898
+ message: "Database configuration with this key already exists"
2899
+ };
2900
+ }
2901
+ const id = body.id || (0, import_crypto3.randomUUID)();
2902
+ const config2 = await store.createConfig(tenantId, id, body);
2903
+ try {
2904
+ import_core17.sqlDatabaseManager.registerDatabase(config2.key, config2.config);
2905
+ } catch (error) {
2906
+ console.warn("Failed to auto-register database:", error);
2907
+ }
2908
+ reply.code(201);
2909
+ return {
2910
+ success: true,
2911
+ message: "Database configuration created successfully",
2912
+ data: config2
2913
+ };
2914
+ } catch (error) {
2915
+ console.error("Failed to create database config:", error);
2916
+ return {
2917
+ success: false,
2918
+ message: "Failed to create database configuration"
2919
+ };
2920
+ }
2921
+ }
2922
+ async function updateDatabaseConfig(request, reply) {
2923
+ const tenantId = getTenantId(request);
2924
+ const { key } = request.params;
2925
+ const updates = request.body;
2926
+ try {
2927
+ const storeLattice = (0, import_core17.getStoreLattice)("default", "database");
2928
+ const store = storeLattice.store;
2929
+ const existing = await store.getConfigByKey(tenantId, key);
2930
+ if (!existing) {
2931
+ reply.code(404);
2932
+ return {
2933
+ success: false,
2934
+ message: "Database configuration not found"
2935
+ };
2936
+ }
2937
+ const updated = await store.updateConfig(tenantId, existing.id, updates);
2938
+ if (!updated) {
2939
+ return {
2940
+ success: false,
2941
+ message: "Failed to update database configuration"
2942
+ };
2943
+ }
2944
+ if (updates.config) {
2945
+ try {
2946
+ import_core17.sqlDatabaseManager.registerDatabase(updated.key, updated.config);
2947
+ } catch (error) {
2948
+ console.warn("Failed to re-register database:", error);
2949
+ }
2950
+ }
2951
+ return {
2952
+ success: true,
2953
+ message: "Database configuration updated successfully",
2954
+ data: updated
2955
+ };
2956
+ } catch (error) {
2957
+ console.error("Failed to update database config:", error);
2958
+ return {
2959
+ success: false,
2960
+ message: "Failed to update database configuration"
2961
+ };
2962
+ }
2963
+ }
2964
+ async function deleteDatabaseConfig(request, reply) {
2965
+ const tenantId = getTenantId(request);
2966
+ const { keyOrId } = request.params;
2967
+ try {
2968
+ const storeLattice = (0, import_core17.getStoreLattice)("default", "database");
2969
+ const store = storeLattice.store;
2970
+ console.log("Delete request - keyOrId:", keyOrId);
2971
+ let config2 = await store.getConfigByKey(tenantId, keyOrId);
2972
+ let configKey = keyOrId;
2973
+ if (!config2) {
2974
+ config2 = await store.getConfigById(tenantId, keyOrId);
2975
+ if (config2) {
2976
+ configKey = config2.key;
2977
+ }
2978
+ }
2979
+ if (!config2) {
2980
+ reply.code(404);
2981
+ return {
2982
+ success: false,
2983
+ message: "Database configuration not found"
2984
+ };
2985
+ }
2986
+ console.log("Found config to delete:", { id: config2.id, key: config2.key });
2987
+ const deleted = await store.deleteConfig(tenantId, config2.id);
2988
+ if (!deleted) {
2989
+ return {
2990
+ success: false,
2991
+ message: "Failed to delete database configuration"
2992
+ };
2993
+ }
2994
+ try {
2995
+ if (import_core17.sqlDatabaseManager.hasDatabase(configKey)) {
2996
+ await import_core17.sqlDatabaseManager.removeDatabase(configKey);
2997
+ }
2998
+ } catch (error) {
2999
+ console.warn("Failed to remove from SqlDatabaseManager:", error);
3000
+ }
3001
+ return {
3002
+ success: true,
3003
+ message: "Database configuration deleted successfully"
3004
+ };
3005
+ } catch (error) {
3006
+ console.error("Failed to delete database config:", error);
3007
+ return {
3008
+ success: false,
3009
+ message: "Failed to delete database configuration"
3010
+ };
3011
+ }
3012
+ }
3013
+ async function testDatabaseConnection(request, reply) {
3014
+ const tenantId = getTenantId(request);
3015
+ const { key } = request.params;
3016
+ try {
3017
+ const storeLattice = (0, import_core17.getStoreLattice)("default", "database");
3018
+ const store = storeLattice.store;
3019
+ const config2 = await store.getConfigByKey(tenantId, key);
3020
+ if (!config2) {
3021
+ reply.code(404);
3022
+ return {
3023
+ success: false,
3024
+ message: "Database configuration not found"
3025
+ };
3026
+ }
3027
+ const testKey = `__test_${key}_${Date.now()}`;
3028
+ import_core17.sqlDatabaseManager.registerDatabase(testKey, config2.config);
3029
+ const startTime = Date.now();
3030
+ const db = import_core17.sqlDatabaseManager.getDatabase(testKey);
3031
+ try {
3032
+ await db.connect();
3033
+ await db.listTables();
3034
+ const latency = Date.now() - startTime;
3035
+ await new Promise((resolve) => setTimeout(resolve, 100));
3036
+ await db.disconnect();
3037
+ await import_core17.sqlDatabaseManager.removeDatabase(testKey);
3038
+ return {
3039
+ success: true,
3040
+ message: "Connection test successful",
3041
+ data: {
3042
+ connected: true,
3043
+ latency
3044
+ }
3045
+ };
3046
+ } catch (error) {
3047
+ try {
3048
+ await db.disconnect();
3049
+ await import_core17.sqlDatabaseManager.removeDatabase(testKey);
3050
+ } catch {
3051
+ }
3052
+ return {
3053
+ success: true,
3054
+ message: "Connection test failed",
3055
+ data: {
3056
+ connected: false,
3057
+ error: error instanceof Error ? error.message : "Unknown error"
3058
+ }
3059
+ };
3060
+ }
3061
+ } catch (error) {
3062
+ console.error("Failed to test database connection:", error);
3063
+ return {
3064
+ success: false,
3065
+ message: "Failed to test database connection",
3066
+ data: {
3067
+ connected: false,
3068
+ error: error instanceof Error ? error.message : "Unknown error"
3069
+ }
3070
+ };
3071
+ }
3072
+ }
3073
+ function registerDatabaseConfigRoutes(app2) {
3074
+ app2.get(
3075
+ "/api/database-configs",
3076
+ getDatabaseConfigList
3077
+ );
3078
+ app2.get(
3079
+ "/api/database-configs/:key",
3080
+ getDatabaseConfig
3081
+ );
3082
+ app2.post(
3083
+ "/api/database-configs",
3084
+ createDatabaseConfig
3085
+ );
3086
+ app2.put(
3087
+ "/api/database-configs/:key",
3088
+ updateDatabaseConfig
3089
+ );
3090
+ app2.delete(
3091
+ "/api/database-configs/:keyOrId",
3092
+ deleteDatabaseConfig
3093
+ );
3094
+ app2.post(
3095
+ "/api/database-configs/:key/test",
3096
+ testDatabaseConnection
3097
+ );
3098
+ }
3099
+
2346
3100
  // src/routes/index.ts
2347
3101
  var registerLatticeRoutes = (app2) => {
2348
3102
  app2.post("/api/runs", createRun);
@@ -2462,6 +3216,8 @@ var registerLatticeRoutes = (app2) => {
2462
3216
  filterSkillsByLicense
2463
3217
  );
2464
3218
  registerSandboxProxyRoutes(app2);
3219
+ registerWorkspaceRoutes(app2);
3220
+ registerDatabaseConfigRoutes(app2);
2465
3221
  };
2466
3222
 
2467
3223
  // src/swagger.ts
@@ -2527,7 +3283,7 @@ var configureSwagger = async (app2, customSwaggerConfig, customSwaggerUiConfig)
2527
3283
  };
2528
3284
 
2529
3285
  // src/services/agent_task_consumer.ts
2530
- var import_core14 = require("@axiom-lattice/core");
3286
+ var import_core18 = require("@axiom-lattice/core");
2531
3287
  var handleAgentTask = async (taskRequest, retryCount = 0) => {
2532
3288
  const {
2533
3289
  assistant_id,
@@ -2591,7 +3347,7 @@ var handleAgentTask = async (taskRequest, retryCount = 0) => {
2591
3347
  }
2592
3348
  if (callback_event) {
2593
3349
  const state = await agent_state({ assistant_id, thread_id });
2594
- import_core14.eventBus.publish(callback_event, {
3350
+ import_core18.eventBus.publish(callback_event, {
2595
3351
  success: true,
2596
3352
  state,
2597
3353
  config: { assistant_id, thread_id, tenant_id }
@@ -2605,7 +3361,7 @@ var handleAgentTask = async (taskRequest, retryCount = 0) => {
2605
3361
  await response.text();
2606
3362
  if (callback_event) {
2607
3363
  const state = await agent_state({ assistant_id, thread_id });
2608
- import_core14.eventBus.publish(callback_event, {
3364
+ import_core18.eventBus.publish(callback_event, {
2609
3365
  success: true,
2610
3366
  state,
2611
3367
  config: { assistant_id, thread_id, tenant_id }
@@ -2632,7 +3388,7 @@ var handleAgentTask = async (taskRequest, retryCount = 0) => {
2632
3388
  return handleAgentTask(taskRequest, nextRetryCount);
2633
3389
  }
2634
3390
  if (callback_event) {
2635
- import_core14.eventBus.publish(callback_event, {
3391
+ import_core18.eventBus.publish(callback_event, {
2636
3392
  success: false,
2637
3393
  error: error instanceof Error ? error.message : String(error),
2638
3394
  config: { assistant_id, thread_id, tenant_id }
@@ -2670,7 +3426,7 @@ var _AgentTaskConsumer = class _AgentTaskConsumer {
2670
3426
  * 初始化事件监听和队列轮询
2671
3427
  */
2672
3428
  initialize() {
2673
- import_core14.eventBus.subscribe(import_core14.AGENT_TASK_EVENT, this.trigger_agent_task.bind(this));
3429
+ import_core18.eventBus.subscribe(import_core18.AGENT_TASK_EVENT, this.trigger_agent_task.bind(this));
2674
3430
  this.startPollingQueue();
2675
3431
  console.log("Agent\u4EFB\u52A1\u6D88\u8D39\u8005\u5DF2\u542F\u52A8\u5E76\u76D1\u542C\u4EFB\u52A1\u4E8B\u4EF6\u548C\u961F\u5217");
2676
3432
  }
@@ -2789,7 +3545,7 @@ var _AgentTaskConsumer = class _AgentTaskConsumer {
2789
3545
  handleAgentTask(taskRequest).catch((error) => {
2790
3546
  console.error("\u5904\u7406Agent\u4EFB\u52A1\u65F6\u53D1\u751F\u672A\u6355\u83B7\u7684\u9519\u8BEF:", error);
2791
3547
  if (taskRequest.callback_event) {
2792
- import_core14.eventBus.publish(taskRequest.callback_event, {
3548
+ import_core18.eventBus.publish(taskRequest.callback_event, {
2793
3549
  success: false,
2794
3550
  error: error instanceof Error ? error.message : String(error),
2795
3551
  config: {
@@ -2809,7 +3565,7 @@ _AgentTaskConsumer.agent_run_endpoint = "http://localhost:4001/api/runs";
2809
3565
  var AgentTaskConsumer = _AgentTaskConsumer;
2810
3566
 
2811
3567
  // src/index.ts
2812
- var import_core15 = require("@axiom-lattice/core");
3568
+ var import_core19 = require("@axiom-lattice/core");
2813
3569
  var import_protocols2 = require("@axiom-lattice/protocols");
2814
3570
  process.on("unhandledRejection", (reason, promise) => {
2815
3571
  console.error("\u672A\u5904\u7406\u7684Promise\u62D2\u7EDD:", reason);
@@ -2823,12 +3579,12 @@ var DEFAULT_LOGGER_CONFIG = {
2823
3579
  };
2824
3580
  var loggerLattice = initializeLogger(DEFAULT_LOGGER_CONFIG);
2825
3581
  var logger = loggerLattice.client;
2826
- function initializeLogger(config) {
2827
- if (import_core15.loggerLatticeManager.hasLattice("default")) {
2828
- import_core15.loggerLatticeManager.removeLattice("default");
3582
+ function initializeLogger(config2) {
3583
+ if (import_core19.loggerLatticeManager.hasLattice("default")) {
3584
+ import_core19.loggerLatticeManager.removeLattice("default");
2829
3585
  }
2830
- (0, import_core15.registerLoggerLattice)("default", config);
2831
- return (0, import_core15.getLoggerLattice)("default");
3586
+ (0, import_core19.registerLoggerLattice)("default", config2);
3587
+ return (0, import_core19.getLoggerLattice)("default");
2832
3588
  }
2833
3589
  var app = (0, import_fastify.default)({
2834
3590
  logger: false,
@@ -2868,16 +3624,8 @@ app.addHook("onResponse", (request, reply, done) => {
2868
3624
  });
2869
3625
  app.register(import_cors.default, {
2870
3626
  origin: true,
2871
- methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
2872
- allowedHeaders: [
2873
- "Content-Type",
2874
- "Authorization",
2875
- "X-Requested-With",
2876
- "x-tenant-id",
2877
- "x-request-id",
2878
- "x-assistant-id",
2879
- "x-thread-id"
2880
- ],
3627
+ methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH"],
3628
+ allowedHeaders: "*",
2881
3629
  exposedHeaders: ["Content-Type"],
2882
3630
  credentials: true
2883
3631
  });
@@ -2913,23 +3661,23 @@ app.setErrorHandler((error, request, reply) => {
2913
3661
  error: error.message || "\u670D\u52A1\u5668\u5185\u90E8\u9519\u8BEF"
2914
3662
  });
2915
3663
  });
2916
- var start = async (config) => {
3664
+ var start = async (config2) => {
2917
3665
  try {
2918
- if (config?.loggerConfig) {
3666
+ if (config2?.loggerConfig) {
2919
3667
  const loggerConfig = {
2920
3668
  ...DEFAULT_LOGGER_CONFIG,
2921
- ...config.loggerConfig,
3669
+ ...config2.loggerConfig,
2922
3670
  // Merge file config if provided
2923
- file: config.loggerConfig.file || DEFAULT_LOGGER_CONFIG.file
3671
+ file: config2.loggerConfig.file || DEFAULT_LOGGER_CONFIG.file
2924
3672
  };
2925
3673
  loggerLattice = initializeLogger(loggerConfig);
2926
3674
  logger = loggerLattice.client;
2927
3675
  }
2928
3676
  app.decorate("loggerLattice", loggerLattice);
2929
- const target_port = config?.port || Number(process.env.PORT) || 4001;
3677
+ const target_port = config2?.port || Number(process.env.PORT) || 4001;
2930
3678
  await app.listen({ port: target_port, host: "0.0.0.0" });
2931
3679
  logger.info(`Lattice Gateway is running on port: ${target_port}`);
2932
- const queueServiceConfig = config?.queueServiceConfig;
3680
+ const queueServiceConfig = config2?.queueServiceConfig;
2933
3681
  if (queueServiceConfig) {
2934
3682
  setQueueServiceType(queueServiceConfig.type);
2935
3683
  if (queueServiceConfig.defaultStartPollingQueue) {