@axiom-lattice/gateway 2.1.108 → 2.1.110

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
@@ -104,7 +104,7 @@ function getTenantId12(request) {
104
104
  async function getMcpServerConfigList(request, reply) {
105
105
  const tenantId = getTenantId12(request);
106
106
  try {
107
- const storeLattice = (0, import_core26.getStoreLattice)("default", "mcp");
107
+ const storeLattice = (0, import_core28.getStoreLattice)("default", "mcp");
108
108
  const store2 = storeLattice.store;
109
109
  const configs = await store2.getAllConfigs(tenantId);
110
110
  return {
@@ -131,7 +131,7 @@ async function getMcpServerConfig(request, reply) {
131
131
  const tenantId = getTenantId12(request);
132
132
  const { key } = request.params;
133
133
  try {
134
- const storeLattice = (0, import_core26.getStoreLattice)("default", "mcp");
134
+ const storeLattice = (0, import_core28.getStoreLattice)("default", "mcp");
135
135
  const store2 = storeLattice.store;
136
136
  const config = await store2.getConfigByKey(tenantId, key);
137
137
  if (!config) {
@@ -157,7 +157,7 @@ async function createMcpServerConfig(request, reply) {
157
157
  const tenantId = getTenantId12(request);
158
158
  const body = request.body;
159
159
  try {
160
- const storeLattice = (0, import_core26.getStoreLattice)("default", "mcp");
160
+ const storeLattice = (0, import_core28.getStoreLattice)("default", "mcp");
161
161
  const store2 = storeLattice.store;
162
162
  const existing = await store2.getConfigByKey(tenantId, body.key);
163
163
  if (existing) {
@@ -197,7 +197,7 @@ async function updateMcpServerConfig(request, reply) {
197
197
  const { key } = request.params;
198
198
  const updates = request.body;
199
199
  try {
200
- const storeLattice = (0, import_core26.getStoreLattice)("default", "mcp");
200
+ const storeLattice = (0, import_core28.getStoreLattice)("default", "mcp");
201
201
  const store2 = storeLattice.store;
202
202
  const existing = await store2.getConfigByKey(tenantId, key);
203
203
  if (!existing) {
@@ -217,8 +217,8 @@ async function updateMcpServerConfig(request, reply) {
217
217
  }
218
218
  if (shouldReconnect) {
219
219
  try {
220
- await import_core26.mcpManager.reconnectServer(key);
221
- await import_core26.mcpManager.registerToolsToToolLattice(key, updated.selectedTools);
220
+ await import_core28.mcpManager.reconnectServer(key);
221
+ await import_core28.mcpManager.registerToolsToToolLattice(key, updated.selectedTools);
222
222
  await store2.updateConfig(tenantId, existing.id, { status: "connected" });
223
223
  updated.status = "connected";
224
224
  } catch (error) {
@@ -244,7 +244,7 @@ async function deleteMcpServerConfig(request, reply) {
244
244
  const tenantId = getTenantId12(request);
245
245
  const { keyOrId } = request.params;
246
246
  try {
247
- const storeLattice = (0, import_core26.getStoreLattice)("default", "mcp");
247
+ const storeLattice = (0, import_core28.getStoreLattice)("default", "mcp");
248
248
  const store2 = storeLattice.store;
249
249
  let config = await store2.getConfigByKey(tenantId, keyOrId);
250
250
  let configKey = keyOrId;
@@ -262,8 +262,8 @@ async function deleteMcpServerConfig(request, reply) {
262
262
  };
263
263
  }
264
264
  try {
265
- if (import_core26.mcpManager.hasServer(configKey)) {
266
- await import_core26.mcpManager.removeServer(configKey);
265
+ if (import_core28.mcpManager.hasServer(configKey)) {
266
+ await import_core28.mcpManager.removeServer(configKey);
267
267
  }
268
268
  } catch (error) {
269
269
  console.warn("Failed to remove from MCP manager:", error);
@@ -291,7 +291,7 @@ async function testMcpServerConnection(request, reply) {
291
291
  const tenantId = getTenantId12(request);
292
292
  const { key } = request.params;
293
293
  try {
294
- const storeLattice = (0, import_core26.getStoreLattice)("default", "mcp");
294
+ const storeLattice = (0, import_core28.getStoreLattice)("default", "mcp");
295
295
  const store2 = storeLattice.store;
296
296
  const config = await store2.getConfigByKey(tenantId, key);
297
297
  if (!config) {
@@ -304,7 +304,7 @@ async function testMcpServerConnection(request, reply) {
304
304
  try {
305
305
  const testKey = `__test_${key}_${Date.now()}`;
306
306
  const connection = convertToConnection(config.config);
307
- const { latency } = await import_core26.McpLatticeManager.testConnection(testKey, connection);
307
+ const { latency } = await import_core28.McpLatticeManager.testConnection(testKey, connection);
308
308
  return {
309
309
  success: true,
310
310
  message: "Connection test successful",
@@ -339,7 +339,7 @@ async function listMcpServerTools(request, reply) {
339
339
  const tenantId = getTenantId12(request);
340
340
  const { key } = request.params;
341
341
  try {
342
- const storeLattice = (0, import_core26.getStoreLattice)("default", "mcp");
342
+ const storeLattice = (0, import_core28.getStoreLattice)("default", "mcp");
343
343
  const store2 = storeLattice.store;
344
344
  const config = await store2.getConfigByKey(tenantId, key);
345
345
  if (!config) {
@@ -349,10 +349,10 @@ async function listMcpServerTools(request, reply) {
349
349
  message: "MCP server configuration not found"
350
350
  };
351
351
  }
352
- if (!import_core26.mcpManager.hasServer(key)) {
352
+ if (!import_core28.mcpManager.hasServer(key)) {
353
353
  await connectAndRegisterTools(config);
354
354
  }
355
- const tools = await import_core26.mcpManager.getServerTools(key);
355
+ const tools = await import_core28.mcpManager.getServerTools(key);
356
356
  return {
357
357
  success: true,
358
358
  message: "Tools retrieved successfully",
@@ -372,7 +372,7 @@ async function connectMcpServer(request, reply) {
372
372
  const tenantId = getTenantId12(request);
373
373
  const { key } = request.params;
374
374
  try {
375
- const storeLattice = (0, import_core26.getStoreLattice)("default", "mcp");
375
+ const storeLattice = (0, import_core28.getStoreLattice)("default", "mcp");
376
376
  const store2 = storeLattice.store;
377
377
  const config = await store2.getConfigByKey(tenantId, key);
378
378
  if (!config) {
@@ -393,7 +393,7 @@ async function connectMcpServer(request, reply) {
393
393
  };
394
394
  } catch (error) {
395
395
  console.error("Failed to connect MCP server:", error);
396
- const storeLattice = (0, import_core26.getStoreLattice)("default", "mcp");
396
+ const storeLattice = (0, import_core28.getStoreLattice)("default", "mcp");
397
397
  const store2 = storeLattice.store;
398
398
  const config = await store2.getConfigByKey(tenantId, key);
399
399
  if (config) {
@@ -409,7 +409,7 @@ async function disconnectMcpServer(request, reply) {
409
409
  const tenantId = getTenantId12(request);
410
410
  const { key } = request.params;
411
411
  try {
412
- const storeLattice = (0, import_core26.getStoreLattice)("default", "mcp");
412
+ const storeLattice = (0, import_core28.getStoreLattice)("default", "mcp");
413
413
  const store2 = storeLattice.store;
414
414
  const config = await store2.getConfigByKey(tenantId, key);
415
415
  if (!config) {
@@ -419,8 +419,8 @@ async function disconnectMcpServer(request, reply) {
419
419
  message: "MCP server configuration not found"
420
420
  };
421
421
  }
422
- if (import_core26.mcpManager.hasServer(key)) {
423
- await import_core26.mcpManager.removeServer(key);
422
+ if (import_core28.mcpManager.hasServer(key)) {
423
+ await import_core28.mcpManager.removeServer(key);
424
424
  }
425
425
  const updated = await store2.updateConfig(tenantId, config.id, {
426
426
  status: "disconnected"
@@ -450,7 +450,7 @@ async function testMcpServerTools(request, reply) {
450
450
  }
451
451
  const testKey = `__test_${Date.now()}`;
452
452
  const connection = convertToConnection(body.config);
453
- const { tools } = await import_core26.McpLatticeManager.testConnection(testKey, connection);
453
+ const { tools } = await import_core28.McpLatticeManager.testConnection(testKey, connection);
454
454
  return {
455
455
  success: true,
456
456
  message: "Tools retrieved successfully",
@@ -487,9 +487,9 @@ function convertToConnection(config) {
487
487
  }
488
488
  async function connectAndRegisterTools(config) {
489
489
  const connection = convertToConnection(config.config);
490
- import_core26.mcpManager.addServer(config.key, connection);
491
- await import_core26.mcpManager.connect();
492
- await import_core26.mcpManager.registerToolsToToolLattice(config.key, config.selectedTools);
490
+ import_core28.mcpManager.addServer(config.key, connection);
491
+ await import_core28.mcpManager.connect();
492
+ await import_core28.mcpManager.registerToolsToToolLattice(config.key, config.selectedTools);
493
493
  }
494
494
  function registerMcpServerConfigRoutes(app2) {
495
495
  app2.get("/api/mcp-servers", getMcpServerConfigList);
@@ -503,11 +503,11 @@ function registerMcpServerConfigRoutes(app2) {
503
503
  app2.post("/api/mcp-servers/:key/disconnect", disconnectMcpServer);
504
504
  app2.post("/api/mcp-servers/test-tools", testMcpServerTools);
505
505
  }
506
- var import_core26, import_crypto6;
506
+ var import_core28, import_crypto6;
507
507
  var init_mcp_configs = __esm({
508
508
  "src/controllers/mcp-configs.ts"() {
509
509
  "use strict";
510
- import_core26 = require("@axiom-lattice/core");
510
+ import_core28 = require("@axiom-lattice/core");
511
511
  import_crypto6 = require("crypto");
512
512
  }
513
513
  });
@@ -859,18 +859,18 @@ function extractText(msg) {
859
859
  }
860
860
  return null;
861
861
  }
862
- var import_zod2, logger4, wechatConfigSchema, MAX_RECONNECT_DELAY_MS, BASE_RECONNECT_DELAY_MS, HEARTBEAT_INTERVAL_MS, MSG_TYPE_USER, MSG_ITEM_TEXT, activeConnections2, seenClientIds, wechatChannelAdapter;
862
+ var import_zod3, logger4, wechatConfigSchema, MAX_RECONNECT_DELAY_MS, BASE_RECONNECT_DELAY_MS, HEARTBEAT_INTERVAL_MS, MSG_TYPE_USER, MSG_ITEM_TEXT, activeConnections2, seenClientIds, wechatChannelAdapter;
863
863
  var init_WechatChannelAdapter = __esm({
864
864
  "src/channels/wechat/WechatChannelAdapter.ts"() {
865
865
  "use strict";
866
- import_zod2 = require("zod");
866
+ import_zod3 = require("zod");
867
867
  init_wechat_client();
868
868
  init_context_store();
869
869
  init_Logger();
870
870
  logger4 = new Logger({ serviceName: "lattice/gateway/wechat" });
871
- wechatConfigSchema = import_zod2.z.object({
872
- botToken: import_zod2.z.string(),
873
- uin: import_zod2.z.string().optional()
871
+ wechatConfigSchema = import_zod3.z.object({
872
+ botToken: import_zod3.z.string(),
873
+ uin: import_zod3.z.string().optional()
874
874
  });
875
875
  MAX_RECONNECT_DELAY_MS = 3e4;
876
876
  BASE_RECONNECT_DELAY_MS = 1e3;
@@ -1290,7 +1290,7 @@ async function handleTasksSend(request, reply) {
1290
1290
  taskStore.set(taskId, record);
1291
1291
  let agent;
1292
1292
  try {
1293
- agent = import_core36.agentInstanceManager.getAgent({
1293
+ agent = import_core38.agentInstanceManager.getAgent({
1294
1294
  assistant_id: assistantId,
1295
1295
  thread_id: threadId,
1296
1296
  tenant_id: tenantId,
@@ -1382,7 +1382,7 @@ async function handleTasksCancel(request, reply) {
1382
1382
  return;
1383
1383
  }
1384
1384
  try {
1385
- const agent = import_core36.agentInstanceManager.getAgent({
1385
+ const agent = import_core38.agentInstanceManager.getAgent({
1386
1386
  assistant_id: record.assistantId,
1387
1387
  thread_id: record.threadId,
1388
1388
  tenant_id: record.tenantId,
@@ -1419,7 +1419,7 @@ async function handleTasksStream(request, reply) {
1419
1419
  }
1420
1420
  let agent;
1421
1421
  try {
1422
- agent = import_core36.agentInstanceManager.getAgent({
1422
+ agent = import_core38.agentInstanceManager.getAgent({
1423
1423
  assistant_id: record.assistantId,
1424
1424
  thread_id: record.threadId,
1425
1425
  tenant_id: record.tenantId,
@@ -1614,12 +1614,12 @@ function registerA2ARoutes(app2) {
1614
1614
  handleApiKeyRotate
1615
1615
  );
1616
1616
  }
1617
- var import_uuid10, import_core36, import_protocols4, taskStore, _a2aKeyStore, _storeKeyMap;
1617
+ var import_uuid10, import_core38, import_protocols4, taskStore, _a2aKeyStore, _storeKeyMap;
1618
1618
  var init_a2a = __esm({
1619
1619
  "src/routes/a2a.ts"() {
1620
1620
  "use strict";
1621
1621
  import_uuid10 = require("uuid");
1622
- import_core36 = require("@axiom-lattice/core");
1622
+ import_core38 = require("@axiom-lattice/core");
1623
1623
  import_protocols4 = require("@axiom-lattice/protocols");
1624
1624
  taskStore = /* @__PURE__ */ new Map();
1625
1625
  _a2aKeyStore = null;
@@ -1632,12 +1632,12 @@ var resources_exports = {};
1632
1632
  __export(resources_exports, {
1633
1633
  ResourceController: () => ResourceController
1634
1634
  });
1635
- var import_bcryptjs, import_core37, ResourceController;
1635
+ var import_bcryptjs, import_core39, ResourceController;
1636
1636
  var init_resources = __esm({
1637
1637
  "src/controllers/resources.ts"() {
1638
1638
  "use strict";
1639
1639
  import_bcryptjs = __toESM(require("bcryptjs"));
1640
- import_core37 = require("@axiom-lattice/core");
1640
+ import_core39 = require("@axiom-lattice/core");
1641
1641
  init_mime();
1642
1642
  ResourceController = class {
1643
1643
  constructor(deps) {
@@ -1652,14 +1652,14 @@ var init_resources = __esm({
1652
1652
  if (!workspaceId || !projectId) {
1653
1653
  return reply.status(400).send({ error: "x-workspace-id and x-project-id headers required" });
1654
1654
  }
1655
- const payload = (0, import_core37.createSharePayload)(
1655
+ const payload = (0, import_core39.createSharePayload)(
1656
1656
  tenantId,
1657
1657
  workspaceId,
1658
1658
  projectId,
1659
1659
  userId,
1660
1660
  body
1661
1661
  );
1662
- const token = (0, import_core37.generateToken)();
1662
+ const token = (0, import_core39.generateToken)();
1663
1663
  try {
1664
1664
  await this.deps.store.create({ ...payload, token });
1665
1665
  this.deps.logger.info(
@@ -1675,7 +1675,7 @@ var init_resources = __esm({
1675
1675
  const userId = request.user ? request.user.id ?? "unknown" : "unknown";
1676
1676
  const tenantId = request.headers["x-tenant-id"] || "default";
1677
1677
  const shares = await this.deps.store.listByUser(tenantId, userId);
1678
- return reply.send(shares);
1678
+ return reply.send(shares.filter((r) => r.visibility !== "internal"));
1679
1679
  }
1680
1680
  async updateShare(request, reply) {
1681
1681
  const { token } = request.params;
@@ -1707,15 +1707,24 @@ var init_resources = __esm({
1707
1707
  const { token } = params;
1708
1708
  const subPath = params["*"] ?? "";
1709
1709
  this.deps.logger.info("[share] resolve start", { token, subPath });
1710
- if (subPath && (subPath.endsWith(".js") || subPath.endsWith(".py")) && subPath.startsWith("api/")) {
1710
+ const isApi = subPath && /(^|\/)api\//.test(subPath) && (subPath.endsWith(".js") || subPath.endsWith(".py"));
1711
+ if (request.method !== "GET" && !isApi) {
1712
+ return reply.status(405).send({ error: "Method not allowed" });
1713
+ }
1714
+ if (isApi) {
1711
1715
  const record2 = await this.deps.store.findByToken(token);
1712
1716
  if (!record2 || record2.revoked) return reply.status(404).send("Not found");
1713
1717
  if (record2.expiresAt && new Date(record2.expiresAt) < /* @__PURE__ */ new Date()) {
1714
1718
  return reply.status(410).send("Expired");
1715
1719
  }
1716
- if (!this._isInternalRequest(request) && record2.visibility === "password") {
1717
- if (!this._isUnlocked(request, token)) {
1718
- return reply.status(401).send({ error: "Password required" });
1720
+ if (!this._isInternalRequest(request)) {
1721
+ if (record2.visibility === "internal") {
1722
+ return reply.status(401).send({ error: "Internal access only" });
1723
+ }
1724
+ if (record2.visibility === "password") {
1725
+ if (!this._isUnlocked(request, token)) {
1726
+ return reply.status(401).send({ error: "Password required" });
1727
+ }
1719
1728
  }
1720
1729
  }
1721
1730
  const ext = subPath.endsWith(".py") ? "py" : "js";
@@ -1746,6 +1755,9 @@ var init_resources = __esm({
1746
1755
  });
1747
1756
  const isInternal = this._isInternalRequest(request);
1748
1757
  if (!isInternal) {
1758
+ if (record.visibility === "internal") {
1759
+ return reply.status(401).send({ error: "Internal access only" });
1760
+ }
1749
1761
  if (record.visibility === "password") {
1750
1762
  const unlocked = this._isUnlocked(request, token);
1751
1763
  if (!unlocked) {
@@ -1775,6 +1787,39 @@ var init_resources = __esm({
1775
1787
  });
1776
1788
  return this._serveFile(record.address, token, subPath, sandboxConfig, reply);
1777
1789
  }
1790
+ /**
1791
+ * Thin redirect: /f/{uuidHex3}/{path} → /s/{internal-token}/{path}
1792
+ * Decodes 3 UUIDs (no dashes, 96 hex chars), ensures internal share, 302 redirects.
1793
+ */
1794
+ async resolveDirectFile(request, reply) {
1795
+ const params = request.params;
1796
+ const tenantId = params.tid;
1797
+ const workspaceId = params.wid;
1798
+ const projectId = params.pid;
1799
+ const subPath = params["*"] ?? "";
1800
+ const isApi = subPath && /(^|\/)api\//.test(subPath) && (subPath.endsWith(".js") || subPath.endsWith(".py"));
1801
+ if (request.method !== "GET" && !isApi) {
1802
+ return reply.status(405).send({ error: "Method not allowed" });
1803
+ }
1804
+ if (isApi) {
1805
+ const ext = subPath.endsWith(".py") ? "py" : "js";
1806
+ return this._execApiCore({
1807
+ tenantId,
1808
+ workspaceId,
1809
+ projectId,
1810
+ assistantId: "",
1811
+ resourcePath: subPath
1812
+ }, subPath, ext, request, reply);
1813
+ }
1814
+ const volume = (0, import_core39.buildNamedVolumeName)("p", "project", tenantId, workspaceId, projectId);
1815
+ return this._resolveAndServe(
1816
+ volume,
1817
+ subPath,
1818
+ reply,
1819
+ `/f/${tenantId}/${workspaceId}/${projectId}`,
1820
+ { tenantId, workspaceId, projectId, assistantId: null }
1821
+ );
1822
+ }
1778
1823
  async unlockShare(request, reply) {
1779
1824
  const { token } = request.params;
1780
1825
  const { password } = request.body;
@@ -1801,7 +1846,16 @@ var init_resources = __esm({
1801
1846
  }
1802
1847
  _isInternalRequest(request) {
1803
1848
  const user = request.user;
1804
- return !!user && !!user.id;
1849
+ if (user && user.id) return true;
1850
+ const origin = request.headers.origin || request.headers.referer;
1851
+ if (origin) {
1852
+ try {
1853
+ const { hostname } = new URL(origin);
1854
+ if (hostname === request.hostname) return true;
1855
+ } catch {
1856
+ }
1857
+ }
1858
+ return false;
1805
1859
  }
1806
1860
  _isUnlocked(request, token) {
1807
1861
  const cookie = request.headers.cookie ?? "";
@@ -1811,30 +1865,19 @@ var init_resources = __esm({
1811
1865
  _isFilePath(path3) {
1812
1866
  return /\.[a-zA-Z0-9]+$/.test(path3);
1813
1867
  }
1814
- async _serveFile(address, token, subPath, sandboxConfig, reply) {
1815
- const provider = this.deps.sandboxManager.getDefaultProvider();
1816
- const resolver = provider.getResourceResolver();
1817
- const sandboxPath = subPath ? this._resolveSafeSubPath(address.resourcePath, subPath) : address.resourcePath;
1818
- const entryPath = !subPath && !this._isFilePath(sandboxPath) ? `${sandboxPath}/index.html` : sandboxPath;
1819
- this.deps.logger.info("[share] serving file", {
1820
- token,
1821
- volume: address.volume,
1822
- sandboxPath: entryPath,
1823
- subPath: subPath || "(none)",
1824
- tenantId: sandboxConfig.tenantId,
1825
- workspaceId: sandboxConfig.workspaceId,
1826
- projectId: sandboxConfig.projectId
1827
- });
1868
+ /**
1869
+ * Shared file resolution: directory → index.html, volume FS → sandbox, base tag, response.
1870
+ */
1871
+ async _resolveAndServe(volume, resourcePath, reply, baseTagPrefix, sandboxConfig) {
1872
+ const cleanPath = resourcePath.replace(/\/+$/, "");
1873
+ const entryPath = !cleanPath ? "index.html" : this._isFilePath(cleanPath) ? cleanPath : `${cleanPath}/index.html`;
1874
+ const address = { volume, resourcePath: "" };
1828
1875
  let buf;
1829
1876
  try {
1830
- buf = await resolver.resolve({ ...address, resourcePath: entryPath });
1831
- this.deps.logger.info("[share] resolved via volume FS", { token, size: buf.length });
1832
- } catch (err) {
1833
- this.deps.logger.warn("[share] volume FS failed, trying sandbox fallback", {
1834
- token,
1835
- path: entryPath,
1836
- error: err.message
1837
- });
1877
+ const provider = this.deps.sandboxManager.getDefaultProvider();
1878
+ buf = await provider.getResourceResolver().resolve({ ...address, resourcePath: entryPath });
1879
+ } catch {
1880
+ if (!sandboxConfig) return reply.status(404).send("File not found");
1838
1881
  try {
1839
1882
  const sandbox = await this.deps.sandboxManager.getSandboxFromConfig({
1840
1883
  assistant_id: sandboxConfig.assistantId ?? "",
@@ -1844,37 +1887,60 @@ var init_resources = __esm({
1844
1887
  projectId: sandboxConfig.projectId
1845
1888
  });
1846
1889
  buf = await sandbox.file.downloadFile({ file: `/project/${entryPath}` });
1847
- this.deps.logger.info("[share] resolved via sandbox fallback", { token, size: buf.length });
1848
- } catch (err2) {
1849
- this.deps.logger.warn("[share] all resolution attempts failed", { token, resourcePath: entryPath, error: err2.message });
1890
+ } catch {
1850
1891
  return reply.status(404).send("File not found");
1851
1892
  }
1852
1893
  }
1853
- const fullPath = entryPath;
1854
- const filename = getFilenameFromPath(fullPath);
1855
- const isHtml = !subPath && /\.(html|htm)$/i.test(filename);
1856
- if (isHtml) {
1857
- buf = this._injectBaseTag(buf, token);
1858
- }
1894
+ const filename = entryPath.split("/").pop() || "download";
1859
1895
  const contentType = getContentTypeFromFilename(filename);
1860
- const contentDisposition = `inline; filename="${filename.replace(/"/g, '\\"')}"; filename*=UTF-8''${encodeURIComponent(filename)}`;
1861
- return reply.status(200).type(contentType).header("Content-Disposition", contentDisposition).header("Access-Control-Allow-Origin", "*").send(buf);
1896
+ if (/\.(html|htm)$/i.test(filename)) {
1897
+ const baseDir = cleanPath ? this._isFilePath(cleanPath) ? cleanPath.replace(/[^/]+$/, "") : cleanPath : "";
1898
+ const html = buf.toString("utf-8");
1899
+ if (!/<base\b/i.test(html)) {
1900
+ const baseTag = `<base href="${baseTagPrefix}${baseDir ? "/" + baseDir : ""}/">`;
1901
+ buf = Buffer.from(
1902
+ html.includes("<head>") ? html.replace("<head>", `<head>${baseTag}`) : baseTag + html,
1903
+ "utf-8"
1904
+ );
1905
+ }
1906
+ }
1907
+ return reply.status(200).type(contentType).header("Content-Disposition", `inline; filename*=UTF-8''${encodeURIComponent(filename)}`).header("Access-Control-Allow-Origin", "*").send(buf);
1908
+ }
1909
+ async _serveFile(address, token, subPath, sandboxConfig, reply) {
1910
+ const resourcePath = subPath ? this._resolveSafeSubPath(address.resourcePath, subPath) : address.resourcePath;
1911
+ return this._resolveAndServe(
1912
+ address.volume,
1913
+ resourcePath,
1914
+ reply,
1915
+ `/s/${token}`,
1916
+ sandboxConfig
1917
+ );
1862
1918
  }
1863
1919
  async _execApi(record, apiSubPath, ext, request, reply) {
1920
+ const basePath = this._isFilePath(record.address.resourcePath) ? "" : `${record.address.resourcePath}/`;
1921
+ return this._execApiCore({
1922
+ tenantId: record.tenantId,
1923
+ workspaceId: record.workspaceId,
1924
+ projectId: record.projectId,
1925
+ assistantId: record.assistantId,
1926
+ resourcePath: basePath + apiSubPath
1927
+ }, apiSubPath, ext, request, reply);
1928
+ }
1929
+ async _execApiCore(config, apiSubPath, ext, request, reply) {
1864
1930
  let sandbox;
1865
1931
  try {
1866
1932
  sandbox = await this.deps.sandboxManager.getSandboxFromConfig({
1867
- assistant_id: record.assistantId ?? "",
1933
+ assistant_id: config.assistantId ?? "",
1868
1934
  thread_id: "",
1869
- tenantId: record.tenantId,
1870
- workspaceId: record.workspaceId,
1871
- projectId: record.projectId
1935
+ tenantId: config.tenantId,
1936
+ workspaceId: config.workspaceId,
1937
+ projectId: config.projectId
1872
1938
  });
1873
1939
  } catch (err) {
1874
1940
  this.deps.logger.error("[share] sandbox start failed for API", { error: err.message });
1875
1941
  return reply.status(502).send({ error: "Sandbox unavailable" });
1876
1942
  }
1877
- const scriptPath = `/project/${apiSubPath}`;
1943
+ const scriptPath = `/project/${config.resourcePath}`;
1878
1944
  const cmd = ext === "py" ? `python3 ${scriptPath}` : `node ${scriptPath}`;
1879
1945
  const queryStr = request.url.includes("?") ? request.url.split("?")[1] : "";
1880
1946
  const queryObj = {};
@@ -1889,24 +1955,23 @@ var init_resources = __esm({
1889
1955
  `export API_BODY='${bodyStr.replace(/'/g, "'\\''")}'`,
1890
1956
  `export API_METHOD='${request.method}'`,
1891
1957
  `export API_GATEWAY_URL='${request.protocol}://${request.hostname}'`,
1892
- `export API_TENANT_ID='${record.tenantId}'`,
1893
- `export API_ASSISTANT_ID='${record.assistantId || ""}'`
1958
+ `export API_TENANT_ID='${config.tenantId}'`,
1959
+ `export API_ASSISTANT_ID='${config.assistantId || ""}'`
1894
1960
  ].join(" && ");
1895
1961
  const fullCmd = `${envVars} && ${cmd}`;
1896
- this.deps.logger.info("[share] API exec", { token: record.token, cmd, scriptPath });
1962
+ this.deps.logger.info("[api] exec", { scriptPath, cmd: cmd.substring(0, 80) });
1897
1963
  try {
1898
- const result = await sandbox.shell.exec(fullCmd);
1964
+ const result = await sandbox.shell.execCommand({ command: fullCmd });
1899
1965
  let data;
1900
1966
  try {
1901
- data = JSON.parse(result.stdout.trim() || "{}");
1967
+ data = JSON.parse(result.output?.trim() || "{}");
1902
1968
  } catch {
1903
- data = { output: result.stdout.trim() };
1969
+ data = { output: result.output?.trim() || "" };
1904
1970
  }
1905
1971
  return reply.status(200).type("application/json").send(data);
1906
1972
  } catch (err) {
1907
- this.deps.logger.warn("[share] API exec failed", { token: record.token, cmd, error: err.message });
1908
- const msg = err?.stderr || err.message;
1909
- return reply.status(500).send({ error: msg });
1973
+ this.deps.logger.warn("[api] exec failed", { scriptPath, error: err.message });
1974
+ return reply.status(500).send({ error: err.message });
1910
1975
  }
1911
1976
  }
1912
1977
  _resolveSafeSubPath(entryFile, subPath) {
@@ -1915,21 +1980,6 @@ var init_resources = __esm({
1915
1980
  const entryDir = this._isFilePath(entryFile) ? entryFile.replace(/[^/]+$/, "") : entryFile + "/";
1916
1981
  return (entryDir + subPath).replace(/\/+/g, "/");
1917
1982
  }
1918
- _injectBaseTag(buf, token) {
1919
- const html = buf.toString("utf-8");
1920
- if (/<base\b/i.test(html)) return buf;
1921
- const baseTag = `<base href="/s/${token}/">`;
1922
- if (html.includes("</head>")) {
1923
- return Buffer.from(html.replace("</head>", `${baseTag}</head>`), "utf-8");
1924
- }
1925
- if (html.includes("<head>")) {
1926
- return Buffer.from(html.replace("<head>", `<head>${baseTag}`), "utf-8");
1927
- }
1928
- if (html.includes("<html>")) {
1929
- return Buffer.from(html.replace("<html>", `<html>${baseTag}`), "utf-8");
1930
- }
1931
- return Buffer.from(baseTag + html, "utf-8");
1932
- }
1933
1983
  _passwordPage(token) {
1934
1984
  return `<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Password Protected</title><style>body{font-family:-apple-system,BlinkMacSystemFont,sans-serif;display:flex;align-items:center;justify-content:center;min-height:100vh;margin:0;background:#f5f5f5}.card{background:#fff;padding:32px;border-radius:12px;box-shadow:0 2px 8px rgba(0,0,0,.1);width:100%;max-width:360px;text-align:center}h2{margin:0 0 8px;font-size:20px}p{margin:0 0 20px;color:#666;font-size:14px}input{width:100%;padding:10px 12px;border:1px solid #d9d9d9;border-radius:8px;font-size:14px;box-sizing:border-box;margin-bottom:12px}button{width:100%;padding:10px;background:#6366f1;color:#fff;border:none;border-radius:8px;font-size:14px;cursor:pointer}.error{color:#ef4444;font-size:13px;margin-top:8px;display:none}</style></head><body><div class="card"><h2>Password Protected</h2><p>This share requires a password to access.</p><form id="f"><input type="password" id="p" placeholder="Enter password" required><button type="submit">Unlock</button><div class="error" id="e">Incorrect password</div></form></div><script>document.getElementById('f').onsubmit=async(e)=>{e.preventDefault();const r=await fetch('/s/${token}/unlock',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({password:document.getElementById('p').value})});if(r.ok)location.reload();else document.getElementById('e').style.display='block'}</script></body></html>`;
1935
1985
  }
@@ -4860,6 +4910,15 @@ async function completeTask(request, reply) {
4860
4910
  }
4861
4911
  }
4862
4912
 
4913
+ // src/controllers/middleware-types.ts
4914
+ var import_core18 = require("@axiom-lattice/core");
4915
+ function middlewareTypesRoutes(fastify2) {
4916
+ fastify2.get("/api/middleware-types", async (_request, reply) => {
4917
+ const metas = import_core18.PluginRegistry.listMeta();
4918
+ return reply.send(metas);
4919
+ });
4920
+ }
4921
+
4863
4922
  // src/schemas/data-query.ts
4864
4923
  var dataQuerySchema = {
4865
4924
  description: "Execute data query (semantic or SQL)",
@@ -5201,7 +5260,7 @@ var getHealthSchema = {
5201
5260
  };
5202
5261
 
5203
5262
  // src/controllers/thread_status.ts
5204
- var import_core18 = require("@axiom-lattice/core");
5263
+ var import_core19 = require("@axiom-lattice/core");
5205
5264
  async function removePendingMessageHandler(request, reply) {
5206
5265
  try {
5207
5266
  const { assistant_id, thread_id, message_id } = request.params;
@@ -5214,7 +5273,7 @@ async function removePendingMessageHandler(request, reply) {
5214
5273
  if (!assistant_id) {
5215
5274
  return reply.code(400).send({ error: "Missing assistant_id parameter" });
5216
5275
  }
5217
- const agent = import_core18.agentInstanceManager.getAgent({
5276
+ const agent = import_core19.agentInstanceManager.getAgent({
5218
5277
  assistant_id,
5219
5278
  thread_id,
5220
5279
  tenant_id,
@@ -5248,7 +5307,7 @@ async function removePendingMessageHandler(request, reply) {
5248
5307
  }
5249
5308
 
5250
5309
  // src/services/sandbox_service.ts
5251
- var import_core19 = require("@axiom-lattice/core");
5310
+ var import_core20 = require("@axiom-lattice/core");
5252
5311
  var ERROR_HTML = `<!DOCTYPE html>
5253
5312
  <html lang="zh-CN">
5254
5313
  <head>
@@ -5360,7 +5419,7 @@ var ERROR_HTML = `<!DOCTYPE html>
5360
5419
  </html>`;
5361
5420
  var SandboxService = class {
5362
5421
  getFilesystemVmIsolation(tenantId, assistantId) {
5363
- const agentLattice = import_core19.agentLatticeManager.getAgentLatticeWithTenant(tenantId, assistantId);
5422
+ const agentLattice = import_core20.agentLatticeManager.getAgentLatticeWithTenant(tenantId, assistantId);
5364
5423
  if (!agentLattice) {
5365
5424
  return null;
5366
5425
  }
@@ -5374,9 +5433,9 @@ var SandboxService = class {
5374
5433
  computeSandboxName(assistantId, threadId, vmIsolation, tenantId, workspaceId, projectId) {
5375
5434
  switch (vmIsolation) {
5376
5435
  case "agent":
5377
- return (0, import_core19.normalizeSandboxName)(`${tenantId ?? "default"}-${assistantId}`);
5436
+ return (0, import_core20.normalizeSandboxName)(`${tenantId ?? "default"}-${assistantId}`);
5378
5437
  case "project":
5379
- return (0, import_core19.normalizeSandboxName)(
5438
+ return (0, import_core20.normalizeSandboxName)(
5380
5439
  `${tenantId ?? "default"}-${workspaceId ?? "default"}-${projectId ?? "default"}`
5381
5440
  );
5382
5441
  case "global":
@@ -5432,7 +5491,7 @@ var SandboxService = class {
5432
5491
  var sandboxService = new SandboxService();
5433
5492
 
5434
5493
  // src/controllers/sandbox.ts
5435
- var import_core20 = require("@axiom-lattice/core");
5494
+ var import_core21 = require("@axiom-lattice/core");
5436
5495
  init_mime();
5437
5496
  function registerSandboxProxyRoutes(app2) {
5438
5497
  app2.post(
@@ -5447,7 +5506,7 @@ function registerSandboxProxyRoutes(app2) {
5447
5506
  }
5448
5507
  const workspaceId = request.headers["x-workspace-id"];
5449
5508
  const projectId = request.headers["x-project-id"];
5450
- const sandboxManager = (0, import_core20.getSandBoxManager)();
5509
+ const sandboxManager = (0, import_core21.getSandBoxManager)();
5451
5510
  const sandbox = await sandboxManager.getSandboxFromConfig({
5452
5511
  assistant_id: assistantId,
5453
5512
  thread_id: threadId,
@@ -5495,7 +5554,7 @@ function registerSandboxProxyRoutes(app2) {
5495
5554
  }
5496
5555
  const workspaceId = request.headers["x-workspace-id"];
5497
5556
  const projectId = request.headers["x-project-id"];
5498
- const sandboxManager = (0, import_core20.getSandBoxManager)();
5557
+ const sandboxManager = (0, import_core21.getSandBoxManager)();
5499
5558
  const sandbox = await sandboxManager.getSandboxFromConfig({
5500
5559
  assistant_id: assistantId,
5501
5560
  thread_id: threadId,
@@ -5528,15 +5587,15 @@ function registerSandboxProxyRoutes(app2) {
5528
5587
  // src/controllers/workspace.ts
5529
5588
  var fs = __toESM(require("fs/promises"));
5530
5589
  var path = __toESM(require("path"));
5531
- var import_core21 = require("@axiom-lattice/core");
5532
5590
  var import_core22 = require("@axiom-lattice/core");
5533
5591
  var import_core23 = require("@axiom-lattice/core");
5592
+ var import_core24 = require("@axiom-lattice/core");
5534
5593
  var import_uuid3 = require("uuid");
5535
5594
  init_mime();
5536
5595
  var WorkspaceController = class {
5537
5596
  constructor() {
5538
- this.workspaceStore = (0, import_core21.getStoreLattice)("default", "workspace").store;
5539
- this.projectStore = (0, import_core21.getStoreLattice)("default", "project").store;
5597
+ this.workspaceStore = (0, import_core22.getStoreLattice)("default", "workspace").store;
5598
+ this.projectStore = (0, import_core22.getStoreLattice)("default", "project").store;
5540
5599
  }
5541
5600
  getTenantId(request) {
5542
5601
  const userTenantId = request.user?.tenantId;
@@ -5670,7 +5729,7 @@ var WorkspaceController = class {
5670
5729
  }
5671
5730
  console.log(`[getBackend] storageType=${workspace.storageType} filePath=${filePath}`);
5672
5731
  if (workspace.storageType === "sandbox") {
5673
- const sandboxManager = (0, import_core23.getSandBoxManager)();
5732
+ const sandboxManager = (0, import_core24.getSandBoxManager)();
5674
5733
  const volumeConfig = {
5675
5734
  assistant_id: assistantId || "",
5676
5735
  thread_id: "",
@@ -5688,7 +5747,7 @@ var WorkspaceController = class {
5688
5747
  const sandbox = await sandboxManager.getSandboxFromConfig(volumeConfig);
5689
5748
  console.log(`[getBackend] sandbox acquired, name=${sandbox.name || "unknown"}`);
5690
5749
  return {
5691
- backend: new import_core22.SandboxFilesystem({
5750
+ backend: new import_core23.SandboxFilesystem({
5692
5751
  sandboxInstance: sandbox
5693
5752
  }),
5694
5753
  workspace
@@ -5696,7 +5755,7 @@ var WorkspaceController = class {
5696
5755
  } else {
5697
5756
  console.log(`[getBackend] using FilesystemBackend rootDir=/lattice_store/tenants/${tenantId}/workspaces/${workspaceId}/${projectId}`);
5698
5757
  return {
5699
- backend: new import_core22.FilesystemBackend({
5758
+ backend: new import_core23.FilesystemBackend({
5700
5759
  rootDir: `/lattice_store/tenants/${tenantId}/workspaces/${workspaceId}/${projectId}`,
5701
5760
  virtualMode: true
5702
5761
  }),
@@ -5748,7 +5807,7 @@ var WorkspaceController = class {
5748
5807
  const { workspace } = await this.getBackend(tenantId, workspaceId, projectId, assistantId);
5749
5808
  const resolvedPath = filePath;
5750
5809
  if (workspace.storageType === "sandbox") {
5751
- const sandboxManager = (0, import_core23.getSandBoxManager)();
5810
+ const sandboxManager = (0, import_core24.getSandBoxManager)();
5752
5811
  const volumeConfig = {
5753
5812
  assistant_id: assistantId || "",
5754
5813
  thread_id: "",
@@ -5802,7 +5861,7 @@ var WorkspaceController = class {
5802
5861
  const { workspace } = await this.getBackend(tenantId, workspaceId, projectId, assistantId);
5803
5862
  const resolvedPath = filePath;
5804
5863
  if (workspace.storageType === "sandbox") {
5805
- const sandboxManager = (0, import_core23.getSandBoxManager)();
5864
+ const sandboxManager = (0, import_core24.getSandBoxManager)();
5806
5865
  const volumeConfig = {
5807
5866
  assistant_id: assistantId || "",
5808
5867
  thread_id: "",
@@ -5943,7 +6002,7 @@ var WorkspaceController = class {
5943
6002
  return reply.status(400).send({ success: false, error: "Invalid path parameter" });
5944
6003
  }
5945
6004
  if (workspace.storageType === "sandbox") {
5946
- const sandboxManager = (0, import_core23.getSandBoxManager)();
6005
+ const sandboxManager = (0, import_core24.getSandBoxManager)();
5947
6006
  const volumeConfig = {
5948
6007
  assistant_id: assistantId || "",
5949
6008
  thread_id: "",
@@ -6051,7 +6110,7 @@ function registerWorkspaceRoutes(app2) {
6051
6110
  }
6052
6111
 
6053
6112
  // src/controllers/database-configs.ts
6054
- var import_core24 = require("@axiom-lattice/core");
6113
+ var import_core25 = require("@axiom-lattice/core");
6055
6114
  var import_crypto4 = require("crypto");
6056
6115
  function getTenantId10(request) {
6057
6116
  const userTenantId = request.user?.tenantId;
@@ -6063,7 +6122,7 @@ function getTenantId10(request) {
6063
6122
  async function getDatabaseConfigList(request, reply) {
6064
6123
  const tenantId = getTenantId10(request);
6065
6124
  try {
6066
- const storeLattice = (0, import_core24.getStoreLattice)("default", "database");
6125
+ const storeLattice = (0, import_core25.getStoreLattice)("default", "database");
6067
6126
  const store2 = storeLattice.store;
6068
6127
  const configs = await store2.getAllConfigs(tenantId);
6069
6128
  console.log("Backend: getAllConfigs returned:", configs);
@@ -6094,7 +6153,7 @@ async function getDatabaseConfig(request, reply) {
6094
6153
  const tenantId = getTenantId10(request);
6095
6154
  const { key } = request.params;
6096
6155
  try {
6097
- const storeLattice = (0, import_core24.getStoreLattice)("default", "database");
6156
+ const storeLattice = (0, import_core25.getStoreLattice)("default", "database");
6098
6157
  const store2 = storeLattice.store;
6099
6158
  const config = await store2.getConfigByKey(tenantId, key);
6100
6159
  if (!config) {
@@ -6120,7 +6179,7 @@ async function createDatabaseConfig(request, reply) {
6120
6179
  const tenantId = getTenantId10(request);
6121
6180
  const body = request.body;
6122
6181
  try {
6123
- const storeLattice = (0, import_core24.getStoreLattice)("default", "database");
6182
+ const storeLattice = (0, import_core25.getStoreLattice)("default", "database");
6124
6183
  const store2 = storeLattice.store;
6125
6184
  const existing = await store2.getConfigByKey(tenantId, body.key);
6126
6185
  if (existing) {
@@ -6133,7 +6192,7 @@ async function createDatabaseConfig(request, reply) {
6133
6192
  const id = body.id || (0, import_crypto4.randomUUID)();
6134
6193
  const config = await store2.createConfig(tenantId, id, body);
6135
6194
  try {
6136
- import_core24.sqlDatabaseManager.registerDatabase(tenantId, config.key, config.config);
6195
+ import_core25.sqlDatabaseManager.registerDatabase(tenantId, config.key, config.config);
6137
6196
  } catch (error) {
6138
6197
  console.warn("Failed to auto-register database:", error);
6139
6198
  }
@@ -6156,7 +6215,7 @@ async function updateDatabaseConfig(request, reply) {
6156
6215
  const { key } = request.params;
6157
6216
  const updates = request.body;
6158
6217
  try {
6159
- const storeLattice = (0, import_core24.getStoreLattice)("default", "database");
6218
+ const storeLattice = (0, import_core25.getStoreLattice)("default", "database");
6160
6219
  const store2 = storeLattice.store;
6161
6220
  const existing = await store2.getConfigByKey(tenantId, key);
6162
6221
  if (!existing) {
@@ -6175,7 +6234,7 @@ async function updateDatabaseConfig(request, reply) {
6175
6234
  }
6176
6235
  if (updates.config) {
6177
6236
  try {
6178
- import_core24.sqlDatabaseManager.registerDatabase(tenantId, updated.key, updated.config);
6237
+ import_core25.sqlDatabaseManager.registerDatabase(tenantId, updated.key, updated.config);
6179
6238
  } catch (error) {
6180
6239
  console.warn("Failed to re-register database:", error);
6181
6240
  }
@@ -6197,7 +6256,7 @@ async function deleteDatabaseConfig(request, reply) {
6197
6256
  const tenantId = getTenantId10(request);
6198
6257
  const { keyOrId } = request.params;
6199
6258
  try {
6200
- const storeLattice = (0, import_core24.getStoreLattice)("default", "database");
6259
+ const storeLattice = (0, import_core25.getStoreLattice)("default", "database");
6201
6260
  const store2 = storeLattice.store;
6202
6261
  console.log("Delete request - keyOrId:", keyOrId);
6203
6262
  let config = await store2.getConfigByKey(tenantId, keyOrId);
@@ -6224,8 +6283,8 @@ async function deleteDatabaseConfig(request, reply) {
6224
6283
  };
6225
6284
  }
6226
6285
  try {
6227
- if (import_core24.sqlDatabaseManager.hasDatabase(tenantId, configKey)) {
6228
- await import_core24.sqlDatabaseManager.removeDatabase(tenantId, configKey);
6286
+ if (import_core25.sqlDatabaseManager.hasDatabase(tenantId, configKey)) {
6287
+ await import_core25.sqlDatabaseManager.removeDatabase(tenantId, configKey);
6229
6288
  }
6230
6289
  } catch (error) {
6231
6290
  console.warn("Failed to remove from SqlDatabaseManager:", error);
@@ -6246,7 +6305,7 @@ async function testDatabaseConnection(request, reply) {
6246
6305
  const tenantId = getTenantId10(request);
6247
6306
  const { key } = request.params;
6248
6307
  try {
6249
- const storeLattice = (0, import_core24.getStoreLattice)("default", "database");
6308
+ const storeLattice = (0, import_core25.getStoreLattice)("default", "database");
6250
6309
  const store2 = storeLattice.store;
6251
6310
  const config = await store2.getConfigByKey(tenantId, key);
6252
6311
  if (!config) {
@@ -6257,16 +6316,16 @@ async function testDatabaseConnection(request, reply) {
6257
6316
  };
6258
6317
  }
6259
6318
  const testKey = `__test_${key}_${Date.now()}`;
6260
- import_core24.sqlDatabaseManager.registerDatabase(tenantId, testKey, config.config);
6319
+ import_core25.sqlDatabaseManager.registerDatabase(tenantId, testKey, config.config);
6261
6320
  const startTime = Date.now();
6262
- const db = await import_core24.sqlDatabaseManager.getDatabase(tenantId, testKey);
6321
+ const db = await import_core25.sqlDatabaseManager.getDatabase(tenantId, testKey);
6263
6322
  try {
6264
6323
  await db.connect();
6265
6324
  await db.listTables();
6266
6325
  const latency = Date.now() - startTime;
6267
6326
  await new Promise((resolve) => setTimeout(resolve, 100));
6268
6327
  await db.disconnect();
6269
- await import_core24.sqlDatabaseManager.removeDatabase(tenantId, testKey);
6328
+ await import_core25.sqlDatabaseManager.removeDatabase(tenantId, testKey);
6270
6329
  return {
6271
6330
  success: true,
6272
6331
  message: "Connection test successful",
@@ -6278,7 +6337,7 @@ async function testDatabaseConnection(request, reply) {
6278
6337
  } catch (error) {
6279
6338
  try {
6280
6339
  await db.disconnect();
6281
- await import_core24.sqlDatabaseManager.removeDatabase(tenantId, testKey);
6340
+ await import_core25.sqlDatabaseManager.removeDatabase(tenantId, testKey);
6282
6341
  } catch {
6283
6342
  }
6284
6343
  return {
@@ -6330,7 +6389,7 @@ function registerDatabaseConfigRoutes(app2) {
6330
6389
  }
6331
6390
 
6332
6391
  // src/controllers/metrics-configs.ts
6333
- var import_core25 = require("@axiom-lattice/core");
6392
+ var import_core26 = require("@axiom-lattice/core");
6334
6393
  var import_crypto5 = require("crypto");
6335
6394
  function getTenantId11(request) {
6336
6395
  const userTenantId = request.user?.tenantId;
@@ -6342,7 +6401,7 @@ function getTenantId11(request) {
6342
6401
  async function getMetricsServerConfigList(request, reply) {
6343
6402
  const tenantId = getTenantId11(request);
6344
6403
  try {
6345
- const storeLattice = (0, import_core25.getStoreLattice)("default", "metrics");
6404
+ const storeLattice = (0, import_core26.getStoreLattice)("default", "metrics");
6346
6405
  const store2 = storeLattice.store;
6347
6406
  const configs = await store2.getAllConfigs(tenantId);
6348
6407
  return {
@@ -6369,7 +6428,7 @@ async function getMetricsServerConfig(request, reply) {
6369
6428
  const tenantId = getTenantId11(request);
6370
6429
  const { key } = request.params;
6371
6430
  try {
6372
- const storeLattice = (0, import_core25.getStoreLattice)("default", "metrics");
6431
+ const storeLattice = (0, import_core26.getStoreLattice)("default", "metrics");
6373
6432
  const store2 = storeLattice.store;
6374
6433
  const config = await store2.getConfigByKey(tenantId, key);
6375
6434
  if (!config) {
@@ -6395,7 +6454,7 @@ async function createMetricsServerConfig(request, reply) {
6395
6454
  const tenantId = getTenantId11(request);
6396
6455
  const body = request.body;
6397
6456
  try {
6398
- const storeLattice = (0, import_core25.getStoreLattice)("default", "metrics");
6457
+ const storeLattice = (0, import_core26.getStoreLattice)("default", "metrics");
6399
6458
  const store2 = storeLattice.store;
6400
6459
  const existing = await store2.getConfigByKey(tenantId, body.key);
6401
6460
  if (existing) {
@@ -6424,7 +6483,7 @@ async function createMetricsServerConfig(request, reply) {
6424
6483
  };
6425
6484
  const config = await store2.createConfig(tenantId, id, configData);
6426
6485
  try {
6427
- import_core25.metricsServerManager.registerServer(tenantId, config.key, config.config);
6486
+ import_core26.metricsServerManager.registerServer(tenantId, config.key, config.config);
6428
6487
  } catch (error) {
6429
6488
  console.warn("Failed to auto-register metrics server:", error);
6430
6489
  }
@@ -6447,7 +6506,7 @@ async function updateMetricsServerConfig(request, reply) {
6447
6506
  const { key } = request.params;
6448
6507
  const updates = request.body;
6449
6508
  try {
6450
- const storeLattice = (0, import_core25.getStoreLattice)("default", "metrics");
6509
+ const storeLattice = (0, import_core26.getStoreLattice)("default", "metrics");
6451
6510
  const store2 = storeLattice.store;
6452
6511
  const existing = await store2.getConfigByKey(tenantId, key);
6453
6512
  if (!existing) {
@@ -6475,7 +6534,7 @@ async function updateMetricsServerConfig(request, reply) {
6475
6534
  }
6476
6535
  if (updates.config) {
6477
6536
  try {
6478
- import_core25.metricsServerManager.registerServer(tenantId, updated.key, updated.config);
6537
+ import_core26.metricsServerManager.registerServer(tenantId, updated.key, updated.config);
6479
6538
  } catch (error) {
6480
6539
  console.warn("Failed to re-register metrics server:", error);
6481
6540
  }
@@ -6497,7 +6556,7 @@ async function deleteMetricsServerConfig(request, reply) {
6497
6556
  const tenantId = getTenantId11(request);
6498
6557
  const { keyOrId } = request.params;
6499
6558
  try {
6500
- const storeLattice = (0, import_core25.getStoreLattice)("default", "metrics");
6559
+ const storeLattice = (0, import_core26.getStoreLattice)("default", "metrics");
6501
6560
  const store2 = storeLattice.store;
6502
6561
  let config = await store2.getConfigByKey(tenantId, keyOrId);
6503
6562
  let configKey = keyOrId;
@@ -6522,8 +6581,8 @@ async function deleteMetricsServerConfig(request, reply) {
6522
6581
  };
6523
6582
  }
6524
6583
  try {
6525
- if (import_core25.metricsServerManager.hasServer(tenantId, configKey)) {
6526
- import_core25.metricsServerManager.removeServer(tenantId, configKey);
6584
+ if (import_core26.metricsServerManager.hasServer(tenantId, configKey)) {
6585
+ import_core26.metricsServerManager.removeServer(tenantId, configKey);
6527
6586
  }
6528
6587
  } catch (error) {
6529
6588
  console.warn("Failed to remove from MetricsServerManager:", error);
@@ -6544,7 +6603,7 @@ async function testMetricsServerConnection(request, reply) {
6544
6603
  const tenantId = getTenantId11(request);
6545
6604
  const { key } = request.params;
6546
6605
  try {
6547
- const storeLattice = (0, import_core25.getStoreLattice)("default", "metrics");
6606
+ const storeLattice = (0, import_core26.getStoreLattice)("default", "metrics");
6548
6607
  const store2 = storeLattice.store;
6549
6608
  const config = await store2.getConfigByKey(tenantId, key);
6550
6609
  if (!config) {
@@ -6555,11 +6614,11 @@ async function testMetricsServerConnection(request, reply) {
6555
6614
  };
6556
6615
  }
6557
6616
  const testKey = `__test_${key}_${Date.now()}`;
6558
- import_core25.metricsServerManager.registerServer(tenantId, testKey, config.config);
6617
+ import_core26.metricsServerManager.registerServer(tenantId, testKey, config.config);
6559
6618
  try {
6560
- const client = await import_core25.metricsServerManager.getClient(tenantId, testKey);
6619
+ const client = await import_core26.metricsServerManager.getClient(tenantId, testKey);
6561
6620
  const result = await client.testConnection();
6562
- import_core25.metricsServerManager.removeServer(tenantId, testKey);
6621
+ import_core26.metricsServerManager.removeServer(tenantId, testKey);
6563
6622
  return {
6564
6623
  success: true,
6565
6624
  message: result.connected ? "Connection test successful" : "Connection test failed",
@@ -6567,7 +6626,7 @@ async function testMetricsServerConnection(request, reply) {
6567
6626
  };
6568
6627
  } catch (error) {
6569
6628
  try {
6570
- import_core25.metricsServerManager.removeServer(tenantId, testKey);
6629
+ import_core26.metricsServerManager.removeServer(tenantId, testKey);
6571
6630
  } catch {
6572
6631
  }
6573
6632
  return {
@@ -6595,7 +6654,7 @@ async function listAvailableMetrics(request, reply) {
6595
6654
  const tenantId = getTenantId11(request);
6596
6655
  const { key } = request.params;
6597
6656
  try {
6598
- const storeLattice = (0, import_core25.getStoreLattice)("default", "metrics");
6657
+ const storeLattice = (0, import_core26.getStoreLattice)("default", "metrics");
6599
6658
  const store2 = storeLattice.store;
6600
6659
  const config = await store2.getConfigByKey(tenantId, key);
6601
6660
  if (!config) {
@@ -6605,10 +6664,10 @@ async function listAvailableMetrics(request, reply) {
6605
6664
  message: "Metrics server configuration not found"
6606
6665
  };
6607
6666
  }
6608
- if (!import_core25.metricsServerManager.hasServer(tenantId, key)) {
6609
- import_core25.metricsServerManager.registerServer(tenantId, key, config.config);
6667
+ if (!import_core26.metricsServerManager.hasServer(tenantId, key)) {
6668
+ import_core26.metricsServerManager.registerServer(tenantId, key, config.config);
6610
6669
  }
6611
- const client = await import_core25.metricsServerManager.getClient(tenantId, key);
6670
+ const client = await import_core26.metricsServerManager.getClient(tenantId, key);
6612
6671
  const metrics = await client.listMetrics();
6613
6672
  return {
6614
6673
  success: true,
@@ -6634,7 +6693,7 @@ async function queryMetricsData(request, reply) {
6634
6693
  const { key } = request.params;
6635
6694
  const { metricName, startTime, endTime, step, labels } = request.body;
6636
6695
  try {
6637
- const storeLattice = (0, import_core25.getStoreLattice)("default", "metrics");
6696
+ const storeLattice = (0, import_core26.getStoreLattice)("default", "metrics");
6638
6697
  const store2 = storeLattice.store;
6639
6698
  const config = await store2.getConfigByKey(tenantId, key);
6640
6699
  if (!config) {
@@ -6651,10 +6710,10 @@ async function queryMetricsData(request, reply) {
6651
6710
  message: "metricName is required"
6652
6711
  };
6653
6712
  }
6654
- if (!import_core25.metricsServerManager.hasServer(tenantId, key)) {
6655
- import_core25.metricsServerManager.registerServer(tenantId, key, config.config);
6713
+ if (!import_core26.metricsServerManager.hasServer(tenantId, key)) {
6714
+ import_core26.metricsServerManager.registerServer(tenantId, key, config.config);
6656
6715
  }
6657
- const client = await import_core25.metricsServerManager.getClient(tenantId, key);
6716
+ const client = await import_core26.metricsServerManager.getClient(tenantId, key);
6658
6717
  const result = await client.queryMetricData(metricName, {
6659
6718
  startTime,
6660
6719
  endTime,
@@ -6681,7 +6740,7 @@ async function getDataSources(request, reply) {
6681
6740
  const tenantId = getTenantId11(request);
6682
6741
  const { key } = request.params;
6683
6742
  try {
6684
- const storeLattice = (0, import_core25.getStoreLattice)("default", "metrics");
6743
+ const storeLattice = (0, import_core26.getStoreLattice)("default", "metrics");
6685
6744
  const store2 = storeLattice.store;
6686
6745
  const config = await store2.getConfigByKey(tenantId, key);
6687
6746
  if (!config) {
@@ -6699,7 +6758,7 @@ async function getDataSources(request, reply) {
6699
6758
  };
6700
6759
  }
6701
6760
  const semanticConfig = config.config;
6702
- const client = new import_core25.SemanticMetricsClient(semanticConfig);
6761
+ const client = new import_core26.SemanticMetricsClient(semanticConfig);
6703
6762
  const allDatasources = await client.getDataSources();
6704
6763
  const selectedIds = semanticConfig.selectedDataSources || [];
6705
6764
  const filteredDatasources = selectedIds.length > 0 ? allDatasources.filter((ds) => selectedIds.includes(String(ds.id))) : allDatasources;
@@ -6722,7 +6781,7 @@ async function getDatasourceMetrics(request, reply) {
6722
6781
  const tenantId = getTenantId11(request);
6723
6782
  const { key, datasourceId } = request.params;
6724
6783
  try {
6725
- const storeLattice = (0, import_core25.getStoreLattice)("default", "metrics");
6784
+ const storeLattice = (0, import_core26.getStoreLattice)("default", "metrics");
6726
6785
  const store2 = storeLattice.store;
6727
6786
  const config = await store2.getConfigByKey(tenantId, key);
6728
6787
  if (!config) {
@@ -6740,7 +6799,7 @@ async function getDatasourceMetrics(request, reply) {
6740
6799
  };
6741
6800
  }
6742
6801
  const semanticConfig = config.config;
6743
- const client = new import_core25.SemanticMetricsClient(semanticConfig);
6802
+ const client = new import_core26.SemanticMetricsClient(semanticConfig);
6744
6803
  const metrics = await client.getDatasourceMetrics(datasourceId);
6745
6804
  return {
6746
6805
  success: true,
@@ -6760,7 +6819,7 @@ async function querySemanticMetrics(request, reply) {
6760
6819
  const { key } = request.params;
6761
6820
  const body = request.body;
6762
6821
  try {
6763
- const storeLattice = (0, import_core25.getStoreLattice)("default", "metrics");
6822
+ const storeLattice = (0, import_core26.getStoreLattice)("default", "metrics");
6764
6823
  const store2 = storeLattice.store;
6765
6824
  const config = await store2.getConfigByKey(tenantId, key);
6766
6825
  if (!config) {
@@ -6785,7 +6844,7 @@ async function querySemanticMetrics(request, reply) {
6785
6844
  };
6786
6845
  }
6787
6846
  const semanticConfig = config.config;
6788
- const client = new import_core25.SemanticMetricsClient(semanticConfig);
6847
+ const client = new import_core26.SemanticMetricsClient(semanticConfig);
6789
6848
  const result = await client.semanticQuery(body);
6790
6849
  const columnNames = result.columns.map((col) => col.name);
6791
6850
  const allDataPoints = [];
@@ -6845,7 +6904,7 @@ async function testSemanticDataSources(request, reply) {
6845
6904
  password: body.password,
6846
6905
  headers: body.headers
6847
6906
  };
6848
- const client = new import_core25.SemanticMetricsClient(testConfig);
6907
+ const client = new import_core26.SemanticMetricsClient(testConfig);
6849
6908
  const datasources = await client.getDataSources();
6850
6909
  return {
6851
6910
  success: true,
@@ -6881,7 +6940,7 @@ async function testDatasourceMetrics(request, reply) {
6881
6940
  password: body.password,
6882
6941
  headers: body.headers
6883
6942
  };
6884
- const client = new import_core25.SemanticMetricsClient(testConfig);
6943
+ const client = new import_core26.SemanticMetricsClient(testConfig);
6885
6944
  const metrics = await client.getDatasourceMetrics(datasourceId);
6886
6945
  return {
6887
6946
  success: true,
@@ -6912,16 +6971,170 @@ function registerMetricsServerConfigRoutes(app2) {
6912
6971
  app2.post("/api/metrics-configs/test-datasources/:datasourceId/meta", testDatasourceMetrics);
6913
6972
  }
6914
6973
 
6974
+ // src/controllers/connections.ts
6975
+ var import_core27 = require("@axiom-lattice/core");
6976
+ var import_zod = require("zod");
6977
+ var createBody = import_zod.z.object({
6978
+ type: import_zod.z.string().min(1),
6979
+ key: import_zod.z.string().min(1),
6980
+ name: import_zod.z.string().min(1),
6981
+ description: import_zod.z.string().optional(),
6982
+ config: import_zod.z.record(import_zod.z.unknown())
6983
+ });
6984
+ var testOrDiscoverBody = import_zod.z.object({
6985
+ key: import_zod.z.string().optional(),
6986
+ config: import_zod.z.record(import_zod.z.unknown()).optional()
6987
+ });
6988
+ function getTenant(request) {
6989
+ return request.headers["x-tenant-id"] || "default";
6990
+ }
6991
+ function maskSecrets(config) {
6992
+ const sensitive = /* @__PURE__ */ new Set([
6993
+ "password",
6994
+ "secret",
6995
+ "token",
6996
+ "apikey",
6997
+ "api_key",
6998
+ "session",
6999
+ "privatekey",
7000
+ "private_key",
7001
+ "accesskey",
7002
+ "access_key"
7003
+ ]);
7004
+ const out = {};
7005
+ for (const [k, v] of Object.entries(config)) {
7006
+ out[k] = sensitive.has(k.toLowerCase()) ? "********" : v;
7007
+ }
7008
+ return out;
7009
+ }
7010
+ async function resolveConfig(type, body, tenantId) {
7011
+ if (body.key) {
7012
+ const entry = await import_core27.ConnectionRegistry.get(type, body.key, tenantId);
7013
+ if (!entry) throw { status: 404, error: `Connection "${body.key}" not found` };
7014
+ return entry.config;
7015
+ }
7016
+ if (body.config) return body.config;
7017
+ throw { status: 400, error: "Either 'key' or 'config' is required" };
7018
+ }
7019
+ function connectionRoutes(fastify2) {
7020
+ fastify2.get("/api/connections", async (request, reply) => {
7021
+ const { type } = request.query;
7022
+ if (!type) return reply.status(400).send({ error: "query 'type' required" });
7023
+ const entries = await import_core27.ConnectionRegistry.list(type, getTenant(request));
7024
+ return reply.send({
7025
+ success: true,
7026
+ data: { records: entries.map((e) => ({ ...e, config: maskSecrets(e.config) })), total: entries.length }
7027
+ });
7028
+ });
7029
+ fastify2.post("/api/connections", async (request, reply) => {
7030
+ const parsed = createBody.parse(request.body);
7031
+ const entry = await import_core27.ConnectionRegistry.create({
7032
+ tenantId: getTenant(request),
7033
+ type: parsed.type,
7034
+ key: parsed.key,
7035
+ name: parsed.name,
7036
+ description: parsed.description,
7037
+ config: parsed.config
7038
+ });
7039
+ return reply.status(201).send({
7040
+ success: true,
7041
+ data: { ...entry, config: maskSecrets(entry.config) }
7042
+ });
7043
+ });
7044
+ fastify2.put("/api/connections/:key", async (request, reply) => {
7045
+ const { type } = request.query;
7046
+ if (!type) return reply.status(400).send({ error: "query 'type' required" });
7047
+ const { key } = request.params;
7048
+ const body = request.body;
7049
+ const tenantId = getTenant(request);
7050
+ const existing = await import_core27.ConnectionRegistry.get(type, key, tenantId);
7051
+ if (!existing) return reply.status(404).send({ error: "not found" });
7052
+ const updates = {};
7053
+ if (body.name !== void 0) updates.name = body.name;
7054
+ if (body.description !== void 0) updates.description = body.description;
7055
+ if (body.config) {
7056
+ updates.config = { ...existing.config, ...body.config };
7057
+ }
7058
+ const entry = await import_core27.ConnectionRegistry.update(tenantId, type, key, updates);
7059
+ return reply.send({
7060
+ success: true,
7061
+ data: { ...entry, config: maskSecrets(entry?.config ?? {}) }
7062
+ });
7063
+ });
7064
+ fastify2.delete("/api/connections/:key", async (request, reply) => {
7065
+ const { type } = request.query;
7066
+ if (!type) return reply.status(400).send({ error: "query 'type' required" });
7067
+ const { key } = request.params;
7068
+ const ok = await import_core27.ConnectionRegistry.delete(getTenant(request), type, key);
7069
+ return reply.send({ success: ok });
7070
+ });
7071
+ fastify2.post("/api/connections/test", async (request, reply) => {
7072
+ const { type } = request.query;
7073
+ if (!type) return reply.status(400).send({ error: "query 'type' required" });
7074
+ const plugin = import_core27.PluginRegistry.get(type);
7075
+ if (!plugin?.connection?.test) {
7076
+ return reply.status(400).send({ error: "plugin does not support connection testing" });
7077
+ }
7078
+ try {
7079
+ const body = testOrDiscoverBody.parse(request.body);
7080
+ const targetConfig = await resolveConfig(type, body, getTenant(request));
7081
+ const result = await plugin.connection.test(targetConfig);
7082
+ return reply.send(result);
7083
+ } catch (err) {
7084
+ if (err?.status === 404) {
7085
+ return reply.status(404).send(err);
7086
+ }
7087
+ if (err?.status === 400) {
7088
+ return reply.status(400).send(err);
7089
+ }
7090
+ if (err instanceof import_zod.z.ZodError) {
7091
+ return reply.status(400).send({ error: err.errors });
7092
+ }
7093
+ return reply.status(500).send({
7094
+ ok: false,
7095
+ message: err instanceof Error ? err.message : String(err)
7096
+ });
7097
+ }
7098
+ });
7099
+ fastify2.post("/api/connections/discover", async (request, reply) => {
7100
+ const { type } = request.query;
7101
+ if (!type) return reply.status(400).send({ error: "query 'type' required" });
7102
+ const plugin = import_core27.PluginRegistry.get(type);
7103
+ if (!plugin?.connection?.discover) {
7104
+ return reply.status(400).send({ error: "plugin does not support resource discovery" });
7105
+ }
7106
+ try {
7107
+ const body = testOrDiscoverBody.parse(request.body);
7108
+ const targetConfig = await resolveConfig(type, body, getTenant(request));
7109
+ const resources = await plugin.connection.discover(targetConfig);
7110
+ return reply.send({ resources });
7111
+ } catch (err) {
7112
+ if (err?.status === 404) {
7113
+ return reply.status(404).send(err);
7114
+ }
7115
+ if (err?.status === 400) {
7116
+ return reply.status(400).send(err);
7117
+ }
7118
+ if (err instanceof import_zod.z.ZodError) {
7119
+ return reply.status(400).send({ error: err.errors });
7120
+ }
7121
+ return reply.status(500).send({
7122
+ error: err instanceof Error ? err.message : String(err)
7123
+ });
7124
+ }
7125
+ });
7126
+ }
7127
+
6915
7128
  // src/routes/index.ts
6916
7129
  init_mcp_configs();
6917
7130
 
6918
7131
  // src/controllers/eval.ts
6919
- var import_core28 = require("@axiom-lattice/core");
7132
+ var import_core30 = require("@axiom-lattice/core");
6920
7133
  var import_uuid5 = require("uuid");
6921
7134
 
6922
7135
  // src/services/eval-runner.ts
6923
7136
  var import_events = require("events");
6924
- var import_core27 = require("@axiom-lattice/core");
7137
+ var import_core29 = require("@axiom-lattice/core");
6925
7138
  var import_agent_eval = require("@axiom-lattice/agent-eval");
6926
7139
  var import_uuid4 = require("uuid");
6927
7140
  function mapLogs(logs) {
@@ -6983,7 +7196,7 @@ var EvalRunner = class {
6983
7196
  if (hasModelKey) {
6984
7197
  judgeModelConfig = { modelKey: judgeCfg.modelKey };
6985
7198
  } else if (!hasCredentials) {
6986
- const firstModel = import_core27.modelLatticeManager.getAllLattices()[0];
7199
+ const firstModel = import_core29.modelLatticeManager.getAllLattices()[0];
6987
7200
  if (firstModel) {
6988
7201
  judgeModelConfig = { modelKey: firstModel.key };
6989
7202
  } else {
@@ -7094,7 +7307,7 @@ var EvalRunner = class {
7094
7307
  return this.runs.has(runId);
7095
7308
  }
7096
7309
  getEvalStore() {
7097
- return (0, import_core27.getStoreLattice)("default", "eval").store;
7310
+ return (0, import_core29.getStoreLattice)("default", "eval").store;
7098
7311
  }
7099
7312
  };
7100
7313
  var evalRunner = new EvalRunner();
@@ -7108,7 +7321,7 @@ function getTenantId13(request) {
7108
7321
  return request.headers["x-tenant-id"] || "default";
7109
7322
  }
7110
7323
  function getEvalStore() {
7111
- return (0, import_core28.getStoreLattice)("default", "eval").store;
7324
+ return (0, import_core30.getStoreLattice)("default", "eval").store;
7112
7325
  }
7113
7326
  async function createProject(request, reply) {
7114
7327
  try {
@@ -7494,11 +7707,11 @@ data: ${JSON.stringify(event.data)}
7494
7707
  }
7495
7708
 
7496
7709
  // src/controllers/users.ts
7497
- var import_core29 = require("@axiom-lattice/core");
7710
+ var import_core31 = require("@axiom-lattice/core");
7498
7711
  var import_uuid6 = require("uuid");
7499
7712
  var UsersController = class {
7500
7713
  constructor() {
7501
- this.userStore = (0, import_core29.getStoreLattice)("default", "user").store;
7714
+ this.userStore = (0, import_core31.getStoreLattice)("default", "user").store;
7502
7715
  }
7503
7716
  async listUsers(request, reply) {
7504
7717
  const { email } = request.query;
@@ -7576,11 +7789,11 @@ function registerUserRoutes(app2) {
7576
7789
  }
7577
7790
 
7578
7791
  // src/controllers/tenants.ts
7579
- var import_core30 = require("@axiom-lattice/core");
7792
+ var import_core32 = require("@axiom-lattice/core");
7580
7793
  var import_uuid7 = require("uuid");
7581
7794
  var TenantsController = class {
7582
7795
  constructor() {
7583
- this.tenantStore = (0, import_core30.getStoreLattice)("default", "tenant").store;
7796
+ this.tenantStore = (0, import_core32.getStoreLattice)("default", "tenant").store;
7584
7797
  }
7585
7798
  // ==================== Tenant CRUD ====================
7586
7799
  async listTenants(request, reply) {
@@ -7644,7 +7857,7 @@ function registerTenantRoutes(app2) {
7644
7857
  }
7645
7858
 
7646
7859
  // src/controllers/auth.ts
7647
- var import_core31 = require("@axiom-lattice/core");
7860
+ var import_core33 = require("@axiom-lattice/core");
7648
7861
  var import_uuid8 = require("uuid");
7649
7862
  var defaultAuthConfig = {
7650
7863
  autoApproveUsers: true,
@@ -7653,9 +7866,9 @@ var defaultAuthConfig = {
7653
7866
  };
7654
7867
  var AuthController = class {
7655
7868
  constructor(config = {}) {
7656
- this.userStore = (0, import_core31.getStoreLattice)("default", "user").store;
7657
- this.tenantStore = (0, import_core31.getStoreLattice)("default", "tenant").store;
7658
- this.userTenantLinkStore = (0, import_core31.getStoreLattice)("default", "userTenantLink").store;
7869
+ this.userStore = (0, import_core33.getStoreLattice)("default", "user").store;
7870
+ this.tenantStore = (0, import_core33.getStoreLattice)("default", "tenant").store;
7871
+ this.userTenantLinkStore = (0, import_core33.getStoreLattice)("default", "userTenantLink").store;
7659
7872
  this.config = { ...defaultAuthConfig, ...config };
7660
7873
  }
7661
7874
  async register(request, reply) {
@@ -7813,7 +8026,7 @@ var AuthController = class {
7813
8026
  const linkMeta = link?.metadata || {};
7814
8027
  let personalAssistant = null;
7815
8028
  if (linkMeta.personalAssistantId) {
7816
- const assistantStore = (0, import_core31.getStoreLattice)("default", "assistant").store;
8029
+ const assistantStore = (0, import_core33.getStoreLattice)("default", "assistant").store;
7817
8030
  const exists = await assistantStore.hasAssistant(tenantId, linkMeta.personalAssistantId);
7818
8031
  if (exists) {
7819
8032
  personalAssistant = {
@@ -8038,7 +8251,7 @@ function registerAuthRoutes(app2, config) {
8038
8251
  }
8039
8252
 
8040
8253
  // src/channels/lark/LarkChannelAdapter.ts
8041
- var import_zod = require("zod");
8254
+ var import_zod2 = require("zod");
8042
8255
 
8043
8256
  // src/channels/lark/parser.ts
8044
8257
  function parseLarkMessageEvent(payload) {
@@ -8118,11 +8331,11 @@ function wsEventToInbound(event, installationId, tenantId) {
8118
8331
  }
8119
8332
  };
8120
8333
  }
8121
- var larkConfigSchema = import_zod.z.object({
8122
- appId: import_zod.z.string(),
8123
- appSecret: import_zod.z.string(),
8124
- verificationToken: import_zod.z.string().optional(),
8125
- encryptKey: import_zod.z.string().optional()
8334
+ var larkConfigSchema = import_zod2.z.object({
8335
+ appId: import_zod2.z.string(),
8336
+ appSecret: import_zod2.z.string(),
8337
+ verificationToken: import_zod2.z.string().optional(),
8338
+ encryptKey: import_zod2.z.string().optional()
8126
8339
  });
8127
8340
  var larkChannelAdapter = {
8128
8341
  channel: "lark",
@@ -8637,7 +8850,7 @@ function registerChannelInstallationRoutes(app2) {
8637
8850
  }
8638
8851
 
8639
8852
  // src/controllers/channel-bindings.ts
8640
- var import_core32 = require("@axiom-lattice/core");
8853
+ var import_core34 = require("@axiom-lattice/core");
8641
8854
  function getTenantId15(request) {
8642
8855
  const userTenantId = request.user?.tenantId;
8643
8856
  if (userTenantId) return userTenantId;
@@ -8647,7 +8860,7 @@ async function getBindingList(request, _reply) {
8647
8860
  const tenantId = getTenantId15(request);
8648
8861
  const { channel, agentId, channelInstallationId, limit, offset } = request.query;
8649
8862
  try {
8650
- const registry = (0, import_core32.getBindingRegistry)();
8863
+ const registry = (0, import_core34.getBindingRegistry)();
8651
8864
  const bindings = await registry.list({ channel, agentId, tenantId, channelInstallationId, limit, offset });
8652
8865
  return { success: true, message: "Bindings retrieved", data: { records: bindings, total: bindings.length } };
8653
8866
  } catch (error) {
@@ -8658,7 +8871,7 @@ async function getBindingList(request, _reply) {
8658
8871
  async function getBinding(request, reply) {
8659
8872
  const tenantId = getTenantId15(request);
8660
8873
  try {
8661
- const registry = (0, import_core32.getBindingRegistry)();
8874
+ const registry = (0, import_core34.getBindingRegistry)();
8662
8875
  const bindings = await registry.list({ tenantId });
8663
8876
  const binding = bindings.find((b) => b.id === request.params.id);
8664
8877
  if (!binding || binding.tenantId !== tenantId) {
@@ -8674,7 +8887,7 @@ async function getBinding(request, reply) {
8674
8887
  async function createBinding(request, reply) {
8675
8888
  const tenantId = getTenantId15(request);
8676
8889
  try {
8677
- const registry = (0, import_core32.getBindingRegistry)();
8890
+ const registry = (0, import_core34.getBindingRegistry)();
8678
8891
  const binding = await registry.create({ ...request.body, tenantId });
8679
8892
  reply.status(201);
8680
8893
  return { success: true, message: "Binding created", data: binding };
@@ -8687,7 +8900,7 @@ async function createBinding(request, reply) {
8687
8900
  async function updateBinding(request, reply) {
8688
8901
  try {
8689
8902
  const tenantId = getTenantId15(request);
8690
- const registry = (0, import_core32.getBindingRegistry)();
8903
+ const registry = (0, import_core34.getBindingRegistry)();
8691
8904
  const bindings = await registry.list({ tenantId });
8692
8905
  const existing = bindings.find((b) => b.id === request.params.id);
8693
8906
  if (!existing || existing.tenantId !== tenantId) {
@@ -8705,7 +8918,7 @@ async function updateBinding(request, reply) {
8705
8918
  async function deleteBinding(request, reply) {
8706
8919
  try {
8707
8920
  const tenantId = getTenantId15(request);
8708
- const registry = (0, import_core32.getBindingRegistry)();
8921
+ const registry = (0, import_core34.getBindingRegistry)();
8709
8922
  const bindings = await registry.list({ tenantId });
8710
8923
  const existing = bindings.find((b) => b.id === request.params.id);
8711
8924
  if (!existing || existing.tenantId !== tenantId) {
@@ -8724,7 +8937,7 @@ async function resolveBinding(request, _reply) {
8724
8937
  const tenantId = getTenantId15(request);
8725
8938
  const { channel, senderId, channelInstallationId } = request.query;
8726
8939
  try {
8727
- const registry = (0, import_core32.getBindingRegistry)();
8940
+ const registry = (0, import_core34.getBindingRegistry)();
8728
8941
  const binding = await registry.resolve({ channel, senderId, channelInstallationId, tenantId });
8729
8942
  if (!binding) {
8730
8943
  return { success: false, message: "No binding found", data: null };
@@ -8747,7 +8960,7 @@ function registerChannelBindingRoutes(app2) {
8747
8960
  }
8748
8961
 
8749
8962
  // src/controllers/menu-items.ts
8750
- var import_core33 = require("@axiom-lattice/core");
8963
+ var import_core35 = require("@axiom-lattice/core");
8751
8964
  function getTenantId16(request) {
8752
8965
  const userTenantId = request.user?.tenantId;
8753
8966
  if (userTenantId) return userTenantId;
@@ -8759,7 +8972,7 @@ function errorMessage(err) {
8759
8972
  async function getMenuItemList(request, _reply) {
8760
8973
  const tenantId = getTenantId16(request);
8761
8974
  try {
8762
- const registry = (0, import_core33.getMenuRegistry)();
8975
+ const registry = (0, import_core35.getMenuRegistry)();
8763
8976
  const items = await registry.list({ tenantId, menuTarget: request.query.menuTarget });
8764
8977
  return { success: true, message: "Menu items retrieved", data: { records: items, total: items.length } };
8765
8978
  } catch (error) {
@@ -8771,7 +8984,7 @@ async function getMenuItemList(request, _reply) {
8771
8984
  async function getMenuItem(request, reply) {
8772
8985
  const tenantId = getTenantId16(request);
8773
8986
  try {
8774
- const registry = (0, import_core33.getMenuRegistry)();
8987
+ const registry = (0, import_core35.getMenuRegistry)();
8775
8988
  const item = await registry.getById(request.params.id);
8776
8989
  if (!item || item.tenantId !== tenantId) {
8777
8990
  reply.status(404);
@@ -8788,7 +9001,7 @@ async function getMenuItem(request, reply) {
8788
9001
  async function createMenuItem(request, reply) {
8789
9002
  const tenantId = getTenantId16(request);
8790
9003
  try {
8791
- const registry = (0, import_core33.getMenuRegistry)();
9004
+ const registry = (0, import_core35.getMenuRegistry)();
8792
9005
  const item = await registry.create({ ...request.body, tenantId });
8793
9006
  reply.status(201);
8794
9007
  return { success: true, message: "Menu item created", data: item };
@@ -8802,7 +9015,7 @@ async function createMenuItem(request, reply) {
8802
9015
  async function updateMenuItem(request, reply) {
8803
9016
  try {
8804
9017
  const tenantId = getTenantId16(request);
8805
- const registry = (0, import_core33.getMenuRegistry)();
9018
+ const registry = (0, import_core35.getMenuRegistry)();
8806
9019
  const existing = await registry.getById(request.params.id);
8807
9020
  if (!existing || existing.tenantId !== tenantId) {
8808
9021
  reply.status(404);
@@ -8820,7 +9033,7 @@ async function updateMenuItem(request, reply) {
8820
9033
  async function deleteMenuItem(request, reply) {
8821
9034
  try {
8822
9035
  const tenantId = getTenantId16(request);
8823
- const registry = (0, import_core33.getMenuRegistry)();
9036
+ const registry = (0, import_core35.getMenuRegistry)();
8824
9037
  const existing = await registry.getById(request.params.id);
8825
9038
  if (!existing || existing.tenantId !== tenantId) {
8826
9039
  reply.status(404);
@@ -9166,6 +9379,8 @@ var registerLatticeRoutes = (app2, channelDeps) => {
9166
9379
  registerWorkspaceRoutes(app2);
9167
9380
  registerDatabaseConfigRoutes(app2);
9168
9381
  registerMetricsServerConfigRoutes(app2);
9382
+ connectionRoutes(app2);
9383
+ middlewareTypesRoutes(app2);
9169
9384
  app2.post(
9170
9385
  "/api/data/query",
9171
9386
  { schema: dataQuerySchema },
@@ -9261,6 +9476,9 @@ var registerLatticeRoutes = (app2, channelDeps) => {
9261
9476
  function registerResourceRoutes(app2, controller) {
9262
9477
  app2.get("/s/:token", controller.resolveResource.bind(controller));
9263
9478
  app2.get("/s/:token/*", controller.resolveResource.bind(controller));
9479
+ app2.post("/s/:token/*", controller.resolveResource.bind(controller));
9480
+ app2.put("/s/:token/*", controller.resolveResource.bind(controller));
9481
+ app2.delete("/s/:token/*", controller.resolveResource.bind(controller));
9264
9482
  app2.post("/s/:token/unlock", controller.unlockShare.bind(controller));
9265
9483
  app2.options("/s/:token", async (_req, reply) => {
9266
9484
  reply.header("Access-Control-Allow-Origin", "*");
@@ -9268,6 +9486,12 @@ function registerResourceRoutes(app2, controller) {
9268
9486
  reply.header("Access-Control-Allow-Headers", "Content-Type");
9269
9487
  return reply.status(204).send();
9270
9488
  });
9489
+ const dirFile = controller.resolveDirectFile.bind(controller);
9490
+ app2.get("/f/:tid/:wid/:pid", dirFile);
9491
+ app2.get("/f/:tid/:wid/:pid/*", dirFile);
9492
+ app2.post("/f/:tid/:wid/:pid/*", dirFile);
9493
+ app2.put("/f/:tid/:wid/:pid/*", dirFile);
9494
+ app2.delete("/f/:tid/:wid/:pid/*", dirFile);
9271
9495
  app2.post("/api/resources/share", controller.createShare.bind(controller));
9272
9496
  app2.get("/api/resources/shares", controller.listShares.bind(controller));
9273
9497
  app2.patch("/api/resources/share/:token", controller.updateShare.bind(controller));
@@ -9275,7 +9499,7 @@ function registerResourceRoutes(app2, controller) {
9275
9499
  }
9276
9500
 
9277
9501
  // src/router/MessageRouter.ts
9278
- var import_core34 = require("@axiom-lattice/core");
9502
+ var import_core36 = require("@axiom-lattice/core");
9279
9503
  var import_crypto9 = require("crypto");
9280
9504
  var BindingNotFoundError = class extends Error {
9281
9505
  constructor(message) {
@@ -9436,7 +9660,7 @@ var MessageRouter = class {
9436
9660
  channel: message.channel,
9437
9661
  adapterChannel: adapter.channel
9438
9662
  }, "Thread resolved by adapter strategy");
9439
- const threadStore = (0, import_core34.getStoreLattice)("default", "thread").store;
9663
+ const threadStore = (0, import_core36.getStoreLattice)("default", "thread").store;
9440
9664
  try {
9441
9665
  await threadStore.createThread(
9442
9666
  tenantId,
@@ -9473,7 +9697,7 @@ var MessageRouter = class {
9473
9697
  }
9474
9698
  }
9475
9699
  if (!threadId) {
9476
- const threadStore = (0, import_core34.getStoreLattice)("default", "thread").store;
9700
+ const threadStore = (0, import_core36.getStoreLattice)("default", "thread").store;
9477
9701
  const newThreadId = (0, import_crypto9.randomUUID)();
9478
9702
  console.log({
9479
9703
  event: "dispatch:thread:create",
@@ -9513,7 +9737,7 @@ var MessageRouter = class {
9513
9737
  senderId: message.sender.id,
9514
9738
  contentLength: message.content.text.length
9515
9739
  }, "Dispatching to agent");
9516
- const agent = import_core34.agentInstanceManager.getAgent({
9740
+ const agent = import_core36.agentInstanceManager.getAgent({
9517
9741
  tenant_id: tenantId,
9518
9742
  assistant_id: agentId,
9519
9743
  thread_id: threadId,
@@ -9758,7 +9982,7 @@ function createAuditLoggerMiddleware() {
9758
9982
  }
9759
9983
 
9760
9984
  // src/index.ts
9761
- var import_core38 = require("@axiom-lattice/core");
9985
+ var import_core40 = require("@axiom-lattice/core");
9762
9986
 
9763
9987
  // src/swagger.ts
9764
9988
  var import_swagger = __toESM(require("@fastify/swagger"));
@@ -9823,7 +10047,7 @@ var configureSwagger = async (app2, customSwaggerConfig, customSwaggerUiConfig)
9823
10047
  };
9824
10048
 
9825
10049
  // src/services/agent_task_consumer.ts
9826
- var import_core35 = require("@axiom-lattice/core");
10050
+ var import_core37 = require("@axiom-lattice/core");
9827
10051
  var handleAgentTask = async (taskRequest, retryCount = 0) => {
9828
10052
  const {
9829
10053
  assistant_id,
@@ -9841,17 +10065,17 @@ var handleAgentTask = async (taskRequest, retryCount = 0) => {
9841
10065
  console.log(
9842
10066
  `\u5F00\u59CB\u5904\u7406\u4EFB\u52A1 [assistant_id: ${assistant_id}, thread_id: ${thread_id}]`
9843
10067
  );
9844
- const agent = import_core35.agentInstanceManager.getAgent({ assistant_id, thread_id, tenant_id, workspace_id: runConfig?.workspaceId, project_id: runConfig?.projectId, custom_run_config: runConfig });
9845
- await agent.addMessage({ input, command, custom_run_config: runConfig }, import_core35.QueueMode.STEER);
10068
+ const agent = import_core37.agentInstanceManager.getAgent({ assistant_id, thread_id, tenant_id, workspace_id: runConfig?.workspaceId, project_id: runConfig?.projectId, custom_run_config: runConfig });
10069
+ await agent.addMessage({ input, command, custom_run_config: runConfig }, import_core37.QueueMode.STEER);
9846
10070
  if (callback_event) {
9847
10071
  agent.subscribeOnce("message:completed", (evt) => {
9848
- import_core35.eventBus.publish(callback_event, {
10072
+ import_core37.eventBus.publish(callback_event, {
9849
10073
  success: true,
9850
10074
  state: evt.state
9851
10075
  });
9852
10076
  if (main_thread_id && main_tenant_id) {
9853
10077
  try {
9854
- const mainAgent = import_core35.agentInstanceManager.getAgent({
10078
+ const mainAgent = import_core37.agentInstanceManager.getAgent({
9855
10079
  assistant_id: main_assistant_id ?? assistant_id,
9856
10080
  thread_id: main_thread_id,
9857
10081
  tenant_id: main_tenant_id,
@@ -9881,7 +10105,7 @@ ${summary}`
9881
10105
  }
9882
10106
  });
9883
10107
  agent.subscribeOnce("message:interrupted", (evt) => {
9884
- import_core35.eventBus.publish(callback_event, {
10108
+ import_core37.eventBus.publish(callback_event, {
9885
10109
  success: true,
9886
10110
  state: evt.state
9887
10111
  });
@@ -9904,7 +10128,7 @@ ${summary}`
9904
10128
  return handleAgentTask(taskRequest, nextRetryCount);
9905
10129
  }
9906
10130
  if (callback_event) {
9907
- import_core35.eventBus.publish(callback_event, {
10131
+ import_core37.eventBus.publish(callback_event, {
9908
10132
  success: false,
9909
10133
  error: error instanceof Error ? error.message : String(error)
9910
10134
  });
@@ -9941,7 +10165,7 @@ var _AgentTaskConsumer = class _AgentTaskConsumer {
9941
10165
  * 初始化事件监听和队列轮询
9942
10166
  */
9943
10167
  initialize() {
9944
- import_core35.eventBus.subscribe(import_core35.AGENT_TASK_EVENT, this.trigger_agent_task.bind(this));
10168
+ import_core37.eventBus.subscribe(import_core37.AGENT_TASK_EVENT, this.trigger_agent_task.bind(this));
9945
10169
  this.startPollingQueue();
9946
10170
  console.log("Agent\u4EFB\u52A1\u6D88\u8D39\u8005\u5DF2\u542F\u52A8\u5E76\u76D1\u542C\u4EFB\u52A1\u4E8B\u4EF6\u548C\u961F\u5217");
9947
10171
  }
@@ -10060,7 +10284,7 @@ var _AgentTaskConsumer = class _AgentTaskConsumer {
10060
10284
  handleAgentTask(taskRequest).catch((error) => {
10061
10285
  console.error("\u5904\u7406Agent\u4EFB\u52A1\u65F6\u53D1\u751F\u672A\u6355\u83B7\u7684\u9519\u8BEF:", error);
10062
10286
  if (taskRequest.callback_event) {
10063
- import_core35.eventBus.publish(taskRequest.callback_event, {
10287
+ import_core37.eventBus.publish(taskRequest.callback_event, {
10064
10288
  success: false,
10065
10289
  error: error instanceof Error ? error.message : String(error)
10066
10290
  });
@@ -10075,7 +10299,7 @@ _AgentTaskConsumer.agent_run_endpoint = "http://localhost:4001/api/runs";
10075
10299
  var AgentTaskConsumer = _AgentTaskConsumer;
10076
10300
 
10077
10301
  // src/index.ts
10078
- var import_core39 = require("@axiom-lattice/core");
10302
+ var import_core41 = require("@axiom-lattice/core");
10079
10303
  var import_protocols5 = require("@axiom-lattice/protocols");
10080
10304
  var import_meta = {};
10081
10305
  process.on("unhandledRejection", (reason, promise) => {
@@ -10091,17 +10315,15 @@ var DEFAULT_LOGGER_CONFIG = {
10091
10315
  var loggerLattice = initializeLogger(DEFAULT_LOGGER_CONFIG);
10092
10316
  var logger5 = loggerLattice.client;
10093
10317
  function initializeLogger(config) {
10094
- if (import_core39.loggerLatticeManager.hasLattice("default")) {
10095
- import_core39.loggerLatticeManager.removeLattice("default");
10318
+ if (import_core41.loggerLatticeManager.hasLattice("default")) {
10319
+ import_core41.loggerLatticeManager.removeLattice("default");
10096
10320
  }
10097
- (0, import_core39.registerLoggerLattice)("default", config);
10098
- return (0, import_core39.getLoggerLattice)("default");
10321
+ (0, import_core41.registerLoggerLattice)("default", config);
10322
+ return (0, import_core41.getLoggerLattice)("default");
10099
10323
  }
10100
10324
  var app = (0, import_fastify.default)({
10101
10325
  logger: false,
10102
- // 禁用内置日志记录器
10103
10326
  bodyLimit: Number(process.env.BODY_LIMIT) || 50 * 1024 * 1024
10104
- // Default 50MB, configurable via BODY_LIMIT env var
10105
10327
  });
10106
10328
  app.addContentTypeParser("application/json", { parseAs: "string" }, function(request, body, done) {
10107
10329
  if (request.method === "DELETE" || !body || body.length === 0) {
@@ -10135,6 +10357,7 @@ app.addHook("preHandler", async (request, reply) => {
10135
10357
  if (request.url.startsWith("/s/")) return;
10136
10358
  const urlPath = request.url.split("?")[0];
10137
10359
  if (urlPath.includes("/viewfile") || urlPath.includes("/downloadfile") || urlPath.includes("/uploadfile")) return;
10360
+ if (urlPath.startsWith("/f/") || urlPath === "/f") return;
10138
10361
  return reply.status(401).send({
10139
10362
  success: false,
10140
10363
  error: "Unauthorized - Missing or invalid token"
@@ -10207,7 +10430,7 @@ app.setErrorHandler((error, request, reply) => {
10207
10430
  });
10208
10431
  function getConfiguredSandboxProvider() {
10209
10432
  const sandboxProviderType = process.env.SANDBOX_PROVIDER_TYPE || "microsandbox-remote";
10210
- return (0, import_core39.createSandboxProvider)({
10433
+ return (0, import_core41.createSandboxProvider)({
10211
10434
  type: sandboxProviderType,
10212
10435
  remoteBaseURL: process.env.SANDBOX_BASE_URL,
10213
10436
  microsandboxServiceBaseURL: process.env.MICROSANDBOX_SERVICE_BASE_URL,
@@ -10223,7 +10446,7 @@ function getConfiguredSandboxProvider() {
10223
10446
  }
10224
10447
  async function restoreMcpConnections() {
10225
10448
  try {
10226
- const storeLattice = (0, import_core39.getStoreLattice)("default", "mcp");
10449
+ const storeLattice = (0, import_core41.getStoreLattice)("default", "mcp");
10227
10450
  const store2 = storeLattice.store;
10228
10451
  if (!store2) {
10229
10452
  logger5.info("MCP store not configured, skipping connection restoration");
@@ -10237,15 +10460,15 @@ async function restoreMcpConnections() {
10237
10460
  for (const config of connectedConfigs) {
10238
10461
  try {
10239
10462
  const connection = convertToConnection2(config.config);
10240
- import_core39.mcpManager.addServer(config.key, connection);
10463
+ import_core41.mcpManager.addServer(config.key, connection);
10241
10464
  } catch (err) {
10242
10465
  logger5.warn(`Failed to prepare MCP server "${config.key}" for restoration`, { error: err });
10243
10466
  }
10244
10467
  }
10245
- await import_core39.mcpManager.connect();
10468
+ await import_core41.mcpManager.connect();
10246
10469
  for (const config of connectedConfigs) {
10247
10470
  try {
10248
- await import_core39.mcpManager.registerToolsToToolLattice(config.key, config.selectedTools);
10471
+ await import_core41.mcpManager.registerToolsToToolLattice(config.key, config.selectedTools);
10249
10472
  logger5.info(`MCP server "${config.key}" restored with ${config.selectedTools.length} tools`);
10250
10473
  } catch (err) {
10251
10474
  logger5.warn(`Failed to register tools for MCP server "${config.key}"`, { error: err });
@@ -10278,7 +10501,7 @@ var start = async (config) => {
10278
10501
  const { getStoreLattice: getStore2 } = await import("@axiom-lattice/core");
10279
10502
  const bindingStore = getStore2("default", "channelBinding").store;
10280
10503
  const installationStore = getStore2("default", "channelInstallation").store;
10281
- (0, import_core38.setBindingRegistry)(bindingStore);
10504
+ (0, import_core40.setBindingRegistry)(bindingStore);
10282
10505
  const router = new MessageRouter({
10283
10506
  middlewares: [
10284
10507
  createDeduplicationMiddleware(),
@@ -10304,8 +10527,8 @@ var start = async (config) => {
10304
10527
  });
10305
10528
  }
10306
10529
  try {
10307
- const menuStore = (0, import_core39.getStoreLattice)("default", "menu").store;
10308
- (0, import_core38.setMenuRegistry)(menuStore);
10530
+ const menuStore = (0, import_core41.getStoreLattice)("default", "menu").store;
10531
+ (0, import_core40.setMenuRegistry)(menuStore);
10309
10532
  logger5.info("Menu registry initialized");
10310
10533
  } catch {
10311
10534
  }
@@ -10313,17 +10536,17 @@ var start = async (config) => {
10313
10536
  setChannelControllerDeps({ adapterRegistry, router: channelDeps.router });
10314
10537
  }
10315
10538
  registerLatticeRoutes(app, channelDeps);
10316
- if (!import_core39.sandboxLatticeManager.hasLattice("default")) {
10317
- import_core39.sandboxLatticeManager.registerLattice("default", getConfiguredSandboxProvider());
10539
+ if (!import_core41.sandboxLatticeManager.hasLattice("default")) {
10540
+ import_core41.sandboxLatticeManager.registerLattice("default", getConfiguredSandboxProvider());
10318
10541
  logger5.info("Registered sandbox manager from env configuration");
10319
10542
  }
10320
10543
  try {
10321
10544
  const { ResourceController: ResourceController2 } = await Promise.resolve().then(() => (init_resources(), resources_exports));
10322
- const sharedResourceStore = (0, import_core39.getStoreLattice)("default", "sharedResource").store;
10323
- const cache = new import_core39.TokenCache();
10545
+ const sharedResourceStore = (0, import_core41.getStoreLattice)("default", "sharedResource").store;
10546
+ const cache = new import_core41.TokenCache();
10324
10547
  const resourceController = new ResourceController2({
10325
10548
  store: sharedResourceStore,
10326
- sandboxManager: import_core39.sandboxLatticeManager,
10549
+ sandboxManager: import_core41.sandboxLatticeManager,
10327
10550
  cache,
10328
10551
  logger: logger5
10329
10552
  });
@@ -10363,7 +10586,7 @@ var start = async (config) => {
10363
10586
  agentTaskConsumer.startPollingQueue();
10364
10587
  }
10365
10588
  }
10366
- import_core39.agentInstanceManager.restore().then((stats) => {
10589
+ import_core41.agentInstanceManager.restore().then((stats) => {
10367
10590
  logger5.info(`Agent recovery complete: ${stats.restored} threads restored, ${stats.errors} errors`);
10368
10591
  }).catch((error) => {
10369
10592
  logger5.error("Agent recovery failed", { error });