@axiom-lattice/gateway 2.1.40 → 2.1.42

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
@@ -38,6 +38,8 @@ var import_cors = __toESM(require("@fastify/cors"));
38
38
  var import_multipart = __toESM(require("@fastify/multipart"));
39
39
  var import_sensible = __toESM(require("@fastify/sensible"));
40
40
  var import_websocket = __toESM(require("@fastify/websocket"));
41
+ var import_static = __toESM(require("@fastify/static"));
42
+ var import_path = __toESM(require("path"));
41
43
 
42
44
  // src/services/agent_service.ts
43
45
  var import_messages = require("@langchain/core/messages");
@@ -1861,6 +1863,212 @@ async function getToolConfigs(request, reply) {
1861
1863
  }
1862
1864
  }
1863
1865
 
1866
+ // src/controllers/data-query.ts
1867
+ var import_core12 = require("@axiom-lattice/core");
1868
+ function getTenantId5(request) {
1869
+ return request.headers["x-tenant-id"] || "default";
1870
+ }
1871
+ async function executeDataQuery(request, reply) {
1872
+ const tenantId = getTenantId5(request);
1873
+ const body = request.body;
1874
+ try {
1875
+ if (!body.serverKey && !body.datasourceId) {
1876
+ reply.code(400);
1877
+ return {
1878
+ success: false,
1879
+ message: "Either serverKey or datasourceId must be provided"
1880
+ };
1881
+ }
1882
+ const isSemanticQuery = body.metrics && body.metrics.length > 0;
1883
+ const isSqlQuery = body.customSql && body.customSql.trim().length > 0;
1884
+ if (!isSemanticQuery && !isSqlQuery) {
1885
+ reply.code(400);
1886
+ return {
1887
+ success: false,
1888
+ message: "Either metrics (for semantic query) or customSql (for SQL query) must be provided"
1889
+ };
1890
+ }
1891
+ if (isSemanticQuery && isSqlQuery) {
1892
+ reply.code(400);
1893
+ return {
1894
+ success: false,
1895
+ message: "Cannot provide both metrics and customSql. Use one query type only."
1896
+ };
1897
+ }
1898
+ const storeLattice = (0, import_core12.getStoreLattice)("default", "metrics");
1899
+ const store = storeLattice.store;
1900
+ if (!body.serverKey) {
1901
+ reply.code(400);
1902
+ return {
1903
+ success: false,
1904
+ message: "serverKey is required"
1905
+ };
1906
+ }
1907
+ const config = await store.getConfigByKey(tenantId, body.serverKey);
1908
+ if (!config) {
1909
+ reply.code(404);
1910
+ return {
1911
+ success: false,
1912
+ message: `Metrics server configuration not found: ${body.serverKey}`
1913
+ };
1914
+ }
1915
+ if (config.config.type !== "semantic") {
1916
+ reply.code(400);
1917
+ return {
1918
+ success: false,
1919
+ message: "This endpoint only supports semantic metrics servers"
1920
+ };
1921
+ }
1922
+ if (!body.datasourceId) {
1923
+ reply.code(400);
1924
+ return {
1925
+ success: false,
1926
+ message: "datasourceId is required"
1927
+ };
1928
+ }
1929
+ if (!import_core12.metricsServerManager.hasServer(tenantId, body.serverKey)) {
1930
+ reply.code(400);
1931
+ return {
1932
+ success: false,
1933
+ message: `Metrics server not registered: ${body.serverKey}. Please register the server first.`
1934
+ };
1935
+ }
1936
+ const client = import_core12.metricsServerManager.getClient(tenantId, body.serverKey);
1937
+ if (isSemanticQuery) {
1938
+ return await executeSemanticQuery(client, body, reply);
1939
+ } else {
1940
+ return await executeSqlQuery(client, body, reply);
1941
+ }
1942
+ } catch (error) {
1943
+ console.error("Failed to execute data query:", error);
1944
+ reply.code(500);
1945
+ return {
1946
+ success: false,
1947
+ message: `Failed to execute data query: ${error instanceof Error ? error.message : String(error)}`
1948
+ };
1949
+ }
1950
+ }
1951
+ async function executeSemanticQuery(client, body, reply) {
1952
+ const semanticFilters = (body.filters || []).map((f) => ({
1953
+ dimension: f.dimension,
1954
+ operator: f.operator,
1955
+ values: f.values
1956
+ }));
1957
+ const result = await client.semanticQuery({
1958
+ datasourceId: body.datasourceId,
1959
+ metrics: body.metrics,
1960
+ groupBy: body.groupBy,
1961
+ filters: semanticFilters,
1962
+ limit: body.limit || 1e3
1963
+ });
1964
+ return {
1965
+ success: true,
1966
+ message: "Semantic query executed successfully",
1967
+ data: {
1968
+ semanticModel: result.semanticModel,
1969
+ columns: result.columns,
1970
+ rows: result.rows,
1971
+ rowsObject: result.rowsObject,
1972
+ metadata: {
1973
+ rowCount: result.rowCount,
1974
+ executionTimeMs: result.executionTimeMs
1975
+ }
1976
+ }
1977
+ };
1978
+ }
1979
+ async function executeSqlQuery(client, body, reply) {
1980
+ const result = await client.executeSqlQuery({
1981
+ datasourceId: body.datasourceId,
1982
+ customSql: body.customSql,
1983
+ params: body.params,
1984
+ limit: body.limit || 100
1985
+ });
1986
+ return {
1987
+ success: true,
1988
+ message: "SQL query executed successfully",
1989
+ data: {
1990
+ tableName: result.tableName,
1991
+ columns: result.columns.map((name) => ({ name, type: "unknown" })),
1992
+ rows: result.rows,
1993
+ rowsObject: result.rowsObject,
1994
+ executedSql: result.executedSql,
1995
+ metadata: {
1996
+ rowCount: result.rowCount,
1997
+ executionTimeMs: result.executionTimeMs
1998
+ }
1999
+ }
2000
+ };
2001
+ }
2002
+
2003
+ // src/schemas/data-query.ts
2004
+ var dataQuerySchema = {
2005
+ description: "Execute data query (semantic or SQL)",
2006
+ tags: ["Data Query"],
2007
+ summary: "Query Data",
2008
+ body: {
2009
+ type: "object",
2010
+ properties: {
2011
+ serverKey: {
2012
+ type: "string",
2013
+ description: "Target semantic metrics server key (optional if configured in runConfig)"
2014
+ },
2015
+ datasourceId: {
2016
+ type: "string",
2017
+ description: "Data source ID (optional if configured in runConfig)"
2018
+ },
2019
+ // Semantic query parameters
2020
+ metrics: {
2021
+ type: "array",
2022
+ items: { type: "string" },
2023
+ description: "Array of metric names for semantic query"
2024
+ },
2025
+ groupBy: {
2026
+ type: "array",
2027
+ items: { type: "string" },
2028
+ description: "Optional array of dimensions to group by"
2029
+ },
2030
+ filters: {
2031
+ type: "array",
2032
+ items: {
2033
+ type: "object",
2034
+ properties: {
2035
+ dimension: { type: "string" },
2036
+ operator: { type: "string" },
2037
+ values: {
2038
+ type: "array",
2039
+ items: { type: ["string", "number", "boolean"] }
2040
+ }
2041
+ },
2042
+ required: ["dimension", "operator", "values"]
2043
+ },
2044
+ description: "Optional array of filters"
2045
+ },
2046
+ // SQL query parameters
2047
+ customSql: {
2048
+ type: "string",
2049
+ description: "Custom SQL query string with named parameters"
2050
+ },
2051
+ params: {
2052
+ type: "object",
2053
+ additionalProperties: { type: ["string", "number", "boolean"] },
2054
+ description: "Optional parameters for SQL query"
2055
+ },
2056
+ // Common parameters
2057
+ limit: {
2058
+ type: "number",
2059
+ description: "Maximum number of results (default: 1000)"
2060
+ },
2061
+ format: {
2062
+ type: "string",
2063
+ enum: ["echarts", "raw"],
2064
+ description: "Response format (default: echarts)"
2065
+ }
2066
+ }
2067
+ }
2068
+ // Response schema temporarily removed - format not yet finalized
2069
+ // TODO: Add proper response schema once data format is confirmed
2070
+ };
2071
+
1864
2072
  // src/schemas/index.ts
1865
2073
  var getAllMemoryItemsSchema = {
1866
2074
  description: "Get all memory items for an assistant thread",
@@ -2136,7 +2344,7 @@ var getHealthSchema = {
2136
2344
  var import_stream = require("stream");
2137
2345
 
2138
2346
  // src/services/sandbox_service.ts
2139
- var import_core12 = require("@axiom-lattice/core");
2347
+ var import_core13 = require("@axiom-lattice/core");
2140
2348
  var ERROR_HTML = `<!DOCTYPE html>
2141
2349
  <html lang="zh-CN">
2142
2350
  <head>
@@ -2248,7 +2456,7 @@ var ERROR_HTML = `<!DOCTYPE html>
2248
2456
  </html>`;
2249
2457
  var SandboxService = class {
2250
2458
  getFilesystemIsolatedLevel(tenantId, assistantId) {
2251
- const agentLattice = import_core12.agentLatticeManager.getAgentLatticeWithTenant(tenantId, assistantId);
2459
+ const agentLattice = import_core13.agentLatticeManager.getAgentLatticeWithTenant(tenantId, assistantId);
2252
2460
  if (!agentLattice) {
2253
2461
  return null;
2254
2462
  }
@@ -2273,10 +2481,10 @@ var SandboxService = class {
2273
2481
  sandboxName = "global";
2274
2482
  break;
2275
2483
  }
2276
- return (0, import_core12.normalizeSandboxName)(sandboxName);
2484
+ return (0, import_core13.normalizeSandboxName)(sandboxName);
2277
2485
  }
2278
2486
  getTargetUrl(sandboxName) {
2279
- const sandboxManager = (0, import_core12.getSandBoxManager)();
2487
+ const sandboxManager = (0, import_core13.getSandBoxManager)();
2280
2488
  return `${sandboxManager.getBaseURL()}/sandbox/${sandboxName}`;
2281
2489
  }
2282
2490
  async getVncHtml(sandboxName) {
@@ -2321,9 +2529,9 @@ var SandboxService = class {
2321
2529
  var sandboxService = new SandboxService();
2322
2530
 
2323
2531
  // src/controllers/sandbox.ts
2324
- var import_core13 = require("@axiom-lattice/core");
2325
- function getFilenameFromPath(path2) {
2326
- const segments = path2.replace(/\/+$/, "").split("/");
2532
+ var import_core14 = require("@axiom-lattice/core");
2533
+ function getFilenameFromPath(path3) {
2534
+ const segments = path3.replace(/\/+$/, "").split("/");
2327
2535
  return segments[segments.length - 1] || "download";
2328
2536
  }
2329
2537
  var EXT_TO_MIME = {
@@ -2363,7 +2571,7 @@ function registerSandboxProxyRoutes(app2) {
2363
2571
  threadId,
2364
2572
  isolatedLevel
2365
2573
  );
2366
- const sandboxManager = (0, import_core13.getSandBoxManager)();
2574
+ const sandboxManager = (0, import_core14.getSandBoxManager)();
2367
2575
  const sandbox = await sandboxManager.createSandbox(sandboxName);
2368
2576
  try {
2369
2577
  const data = await request.file();
@@ -2375,10 +2583,10 @@ function registerSandboxProxyRoutes(app2) {
2375
2583
  const pathValue = pathEntry && typeof pathEntry === "object" && "value" in pathEntry ? String(pathEntry.value) : typeof pathEntry === "string" ? pathEntry : void 0;
2376
2584
  const formData = new FormData();
2377
2585
  formData.append("file", new Blob([buffer]), data.filename ?? "file");
2378
- const path2 = `/home/gem/uploads/${pathValue ? pathValue : ""}${data.filename}`;
2586
+ const path3 = `/home/gem/uploads/${pathValue ? pathValue : ""}${data.filename}`;
2379
2587
  const uploadResult = await sandbox.file.uploadFile({
2380
2588
  file: buffer,
2381
- path: path2
2589
+ path: path3
2382
2590
  });
2383
2591
  if (!uploadResult.ok) {
2384
2592
  return reply.status(502).send({ error: `Upload error: ${uploadResult.error}` });
@@ -2410,7 +2618,7 @@ function registerSandboxProxyRoutes(app2) {
2410
2618
  threadId,
2411
2619
  isolatedLevel
2412
2620
  );
2413
- const sandboxManager = (0, import_core13.getSandBoxManager)();
2621
+ const sandboxManager = (0, import_core14.getSandBoxManager)();
2414
2622
  const sandbox = await sandboxManager.createSandbox(sandboxName);
2415
2623
  try {
2416
2624
  const resolvedPath = filePath.startsWith("/home/gem") ? filePath : `/home/gem/${filePath.replace(/^\//, "")}`;
@@ -2466,14 +2674,14 @@ function registerSandboxProxyRoutes(app2) {
2466
2674
  var fs = __toESM(require("fs/promises"));
2467
2675
  var path = __toESM(require("path"));
2468
2676
  var import_stream2 = require("stream");
2469
- var import_core14 = require("@axiom-lattice/core");
2470
2677
  var import_core15 = require("@axiom-lattice/core");
2471
2678
  var import_core16 = require("@axiom-lattice/core");
2679
+ var import_core17 = require("@axiom-lattice/core");
2472
2680
  var import_uuid3 = require("uuid");
2473
2681
  var WorkspaceController = class {
2474
2682
  constructor() {
2475
- this.workspaceStore = (0, import_core14.getStoreLattice)("default", "workspace").store;
2476
- this.projectStore = (0, import_core14.getStoreLattice)("default", "project").store;
2683
+ this.workspaceStore = (0, import_core15.getStoreLattice)("default", "workspace").store;
2684
+ this.projectStore = (0, import_core15.getStoreLattice)("default", "project").store;
2477
2685
  }
2478
2686
  getTenantId(request) {
2479
2687
  const userTenantId = request.user?.tenantId;
@@ -2606,11 +2814,11 @@ var WorkspaceController = class {
2606
2814
  throw new Error("Workspace not found");
2607
2815
  }
2608
2816
  if (workspace.storageType === "sandbox") {
2609
- const sandboxManager = (0, import_core16.getSandBoxManager)();
2817
+ const sandboxManager = (0, import_core17.getSandBoxManager)();
2610
2818
  const sandboxName = "global";
2611
2819
  const sandbox = await sandboxManager.createSandbox(sandboxName);
2612
2820
  return {
2613
- backend: new import_core15.SandboxFilesystem({
2821
+ backend: new import_core16.SandboxFilesystem({
2614
2822
  sandboxInstance: sandbox,
2615
2823
  workingDirectory: `/tenants/${tenantId}/workspaces/${workspaceId}/${projectId}`
2616
2824
  }),
@@ -2618,7 +2826,7 @@ var WorkspaceController = class {
2618
2826
  };
2619
2827
  } else {
2620
2828
  return {
2621
- backend: new import_core15.FilesystemBackend({
2829
+ backend: new import_core16.FilesystemBackend({
2622
2830
  rootDir: `/lattice_store/tenants/${tenantId}/workspaces/${workspaceId}/${projectId}`,
2623
2831
  virtualMode: true
2624
2832
  }),
@@ -2663,7 +2871,7 @@ var WorkspaceController = class {
2663
2871
  const { workspace } = await this.getBackend(tenantId, workspaceId, projectId);
2664
2872
  const resolvedPath = filePath.startsWith("/") ? filePath : `/${filePath}`;
2665
2873
  if (workspace.storageType === "sandbox") {
2666
- const sandboxManager = (0, import_core16.getSandBoxManager)();
2874
+ const sandboxManager = (0, import_core17.getSandBoxManager)();
2667
2875
  const sandbox = await sandboxManager.createSandbox("global");
2668
2876
  const realPath = path.join("/home/gem/tenants", tenantId, "workspaces", workspaceId, projectId, resolvedPath);
2669
2877
  const filename2 = this.getFilenameFromPath(resolvedPath);
@@ -2732,7 +2940,7 @@ var WorkspaceController = class {
2732
2940
  const { workspace } = await this.getBackend(tenantId, workspaceId, projectId);
2733
2941
  const resolvedPath = filePath.startsWith("/") ? filePath : `/${filePath}`;
2734
2942
  if (workspace.storageType === "sandbox") {
2735
- const sandboxManager = (0, import_core16.getSandBoxManager)();
2943
+ const sandboxManager = (0, import_core17.getSandBoxManager)();
2736
2944
  const sandbox = await sandboxManager.createSandbox("global");
2737
2945
  const realPath = path.join("/home/gem/tenants", tenantId, "workspaces", workspaceId, projectId, resolvedPath);
2738
2946
  const filename2 = this.getFilenameFromPath(resolvedPath);
@@ -2751,6 +2959,33 @@ var WorkspaceController = class {
2751
2959
  const webStream = body.stream();
2752
2960
  const nodeStream = import_stream2.Readable.fromWeb(webStream);
2753
2961
  const contentType2 = body.contentType ?? inferredContentType;
2962
+ console.log(`[viewFile] Sandbox returned stream, contentType: ${contentType2}, filename: ${filename2}`);
2963
+ const isHtml2 = contentType2?.toLowerCase().includes("text/html") || filename2.toLowerCase().endsWith(".html") || filename2.toLowerCase().endsWith(".htm");
2964
+ if (isHtml2) {
2965
+ console.log(`[viewFile] HTML stream detected, collecting for context injection`);
2966
+ const chunks = [];
2967
+ for await (const chunk of nodeStream) {
2968
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
2969
+ }
2970
+ let content2 = Buffer.concat(chunks).toString("utf-8");
2971
+ const contextScript = `<script>window.__AI2APP_CONTEXT__=${JSON.stringify({
2972
+ tenantId,
2973
+ workspaceId,
2974
+ projectId,
2975
+ timestamp: Date.now()
2976
+ })};</script>`;
2977
+ if (content2.toLowerCase().includes("</head>")) {
2978
+ content2 = content2.replace(/<\/head>/i, `${contextScript}</head>`);
2979
+ console.log(`[viewFile] Context script injected before </head> (stream)`);
2980
+ } else if (content2.toLowerCase().includes("<html>")) {
2981
+ content2 = content2.replace(/<html>/i, `<html>${contextScript}`);
2982
+ console.log(`[viewFile] Context script injected after <html> (stream)`);
2983
+ } else {
2984
+ content2 = contextScript + content2;
2985
+ console.log(`[viewFile] Context script prepended to content (stream)`);
2986
+ }
2987
+ return reply.status(200).type(contentType2).header("Content-Disposition", "inline").send(Buffer.from(content2, "utf-8"));
2988
+ }
2754
2989
  return reply.status(200).type(contentType2).header("Content-Disposition", "inline").send(nodeStream);
2755
2990
  }
2756
2991
  const bodyUnknown = downloadResult.body;
@@ -2770,13 +3005,56 @@ var WorkspaceController = class {
2770
3005
  } else {
2771
3006
  return reply.status(502).send({ success: false, error: "Unexpected view response format" });
2772
3007
  }
3008
+ const isHtml = contentType?.toLowerCase().includes("text/html") || filename2.toLowerCase().endsWith(".html") || filename2.toLowerCase().endsWith(".htm");
3009
+ if (isHtml) {
3010
+ console.log(`[viewFile] Injecting AI2APP context for sandbox HTML file: ${filename2}, tenantId: ${tenantId}, contentType: ${contentType}`);
3011
+ let content2 = buf.toString("utf-8");
3012
+ const contextScript = `<script>window.__AI2APP_CONTEXT__=${JSON.stringify({
3013
+ tenantId,
3014
+ workspaceId,
3015
+ projectId,
3016
+ timestamp: Date.now()
3017
+ })};</script>`;
3018
+ if (content2.toLowerCase().includes("</head>")) {
3019
+ content2 = content2.replace(/<\/head>/i, `${contextScript}</head>`);
3020
+ console.log(`[viewFile] Context script injected before </head>`);
3021
+ } else if (content2.toLowerCase().includes("<html>")) {
3022
+ content2 = content2.replace(/<html>/i, `<html>${contextScript}`);
3023
+ console.log(`[viewFile] Context script injected after <html>`);
3024
+ } else {
3025
+ content2 = contextScript + content2;
3026
+ console.log(`[viewFile] Context script prepended to content`);
3027
+ }
3028
+ buf = Buffer.from(content2, "utf-8");
3029
+ }
2773
3030
  return reply.status(200).type(contentType).header("Content-Disposition", "inline").send(buf);
2774
3031
  }
2775
3032
  const { backend } = await this.getBackend(tenantId, workspaceId, projectId);
2776
3033
  const content = await backend.read(resolvedPath, 0, Infinity);
2777
3034
  const filename = this.getFilenameFromPath(resolvedPath);
2778
3035
  const mimeType = this.getMimeType(filename);
2779
- const buffer = Buffer.from(content, "utf-8");
3036
+ let finalContent = content;
3037
+ const isHtmlFs = mimeType?.toLowerCase().includes("text/html") || filename.toLowerCase().endsWith(".html") || filename.toLowerCase().endsWith(".htm");
3038
+ if (isHtmlFs) {
3039
+ console.log(`[viewFile] Injecting AI2APP context for filesystem HTML file: ${filename}, tenantId: ${tenantId}, mimeType: ${mimeType}`);
3040
+ const contextScript = `<script>window.__AI2APP_CONTEXT__=${JSON.stringify({
3041
+ tenantId,
3042
+ workspaceId,
3043
+ projectId,
3044
+ timestamp: Date.now()
3045
+ })};</script>`;
3046
+ if (content.toLowerCase().includes("</head>")) {
3047
+ finalContent = content.replace(/<\/head>/i, `${contextScript}</head>`);
3048
+ console.log(`[viewFile] Context script injected before </head>`);
3049
+ } else if (content.toLowerCase().includes("</html>")) {
3050
+ finalContent = content.replace(/<\/html>/i, `${contextScript}</html>`);
3051
+ console.log(`[viewFile] Context script injected before </html>`);
3052
+ } else {
3053
+ finalContent = content + contextScript;
3054
+ console.log(`[viewFile] Context script appended to content`);
3055
+ }
3056
+ }
3057
+ const buffer = Buffer.from(finalContent, "utf-8");
2780
3058
  return reply.status(200).type(mimeType).header("Content-Disposition", "inline").send(buffer);
2781
3059
  } catch (error) {
2782
3060
  const message = error instanceof Error ? error.message : String(error);
@@ -2786,17 +3064,17 @@ var WorkspaceController = class {
2786
3064
  async listPath(request) {
2787
3065
  const tenantId = this.getTenantId(request);
2788
3066
  const { workspaceId, projectId } = request.params;
2789
- const path2 = request.query.path || "/";
3067
+ const path3 = request.query.path || "/";
2790
3068
  const { backend } = await this.getBackend(tenantId, workspaceId, projectId);
2791
- const files = await backend.lsInfo(path2);
3069
+ const files = await backend.lsInfo(path3);
2792
3070
  return { success: true, data: files };
2793
3071
  }
2794
3072
  async readFile(request) {
2795
3073
  const tenantId = this.getTenantId(request);
2796
3074
  const { workspaceId, projectId } = request.params;
2797
- const { path: path2, offset = 0, limit = 1e3 } = request.query;
3075
+ const { path: path3, offset = 0, limit = 1e3 } = request.query;
2798
3076
  const { backend } = await this.getBackend(tenantId, workspaceId, projectId);
2799
- const content = await backend.read(path2, Number(offset), Number(limit));
3077
+ const content = await backend.read(path3, Number(offset), Number(limit));
2800
3078
  return { success: true, data: { content, offset, limit } };
2801
3079
  }
2802
3080
  /**
@@ -2832,7 +3110,7 @@ var WorkspaceController = class {
2832
3110
  return reply.status(400).send({ success: false, error: "Invalid path parameter" });
2833
3111
  }
2834
3112
  if (workspace.storageType === "sandbox") {
2835
- const sandboxManager = (0, import_core16.getSandBoxManager)();
3113
+ const sandboxManager = (0, import_core17.getSandBoxManager)();
2836
3114
  const sandboxName = "global";
2837
3115
  const sandbox = await sandboxManager.createSandbox(sandboxName);
2838
3116
  const baseDir = path.join("/home/gem/tenants", tenantId, "workspaces", workspaceId, projectId);
@@ -2938,9 +3216,9 @@ function registerWorkspaceRoutes(app2) {
2938
3216
  }
2939
3217
 
2940
3218
  // src/controllers/database-configs.ts
2941
- var import_core17 = require("@axiom-lattice/core");
3219
+ var import_core18 = require("@axiom-lattice/core");
2942
3220
  var import_crypto3 = require("crypto");
2943
- function getTenantId5(request) {
3221
+ function getTenantId6(request) {
2944
3222
  const userTenantId = request.user?.tenantId;
2945
3223
  if (userTenantId) {
2946
3224
  return userTenantId;
@@ -2948,9 +3226,9 @@ function getTenantId5(request) {
2948
3226
  return request.headers["x-tenant-id"] || "default";
2949
3227
  }
2950
3228
  async function getDatabaseConfigList(request, reply) {
2951
- const tenantId = getTenantId5(request);
3229
+ const tenantId = getTenantId6(request);
2952
3230
  try {
2953
- const storeLattice = (0, import_core17.getStoreLattice)("default", "database");
3231
+ const storeLattice = (0, import_core18.getStoreLattice)("default", "database");
2954
3232
  const store = storeLattice.store;
2955
3233
  const configs = await store.getAllConfigs(tenantId);
2956
3234
  console.log("Backend: getAllConfigs returned:", configs);
@@ -2978,10 +3256,10 @@ async function getDatabaseConfigList(request, reply) {
2978
3256
  }
2979
3257
  }
2980
3258
  async function getDatabaseConfig(request, reply) {
2981
- const tenantId = getTenantId5(request);
3259
+ const tenantId = getTenantId6(request);
2982
3260
  const { key } = request.params;
2983
3261
  try {
2984
- const storeLattice = (0, import_core17.getStoreLattice)("default", "database");
3262
+ const storeLattice = (0, import_core18.getStoreLattice)("default", "database");
2985
3263
  const store = storeLattice.store;
2986
3264
  const config = await store.getConfigByKey(tenantId, key);
2987
3265
  if (!config) {
@@ -3004,10 +3282,10 @@ async function getDatabaseConfig(request, reply) {
3004
3282
  }
3005
3283
  }
3006
3284
  async function createDatabaseConfig(request, reply) {
3007
- const tenantId = getTenantId5(request);
3285
+ const tenantId = getTenantId6(request);
3008
3286
  const body = request.body;
3009
3287
  try {
3010
- const storeLattice = (0, import_core17.getStoreLattice)("default", "database");
3288
+ const storeLattice = (0, import_core18.getStoreLattice)("default", "database");
3011
3289
  const store = storeLattice.store;
3012
3290
  const existing = await store.getConfigByKey(tenantId, body.key);
3013
3291
  if (existing) {
@@ -3020,7 +3298,7 @@ async function createDatabaseConfig(request, reply) {
3020
3298
  const id = body.id || (0, import_crypto3.randomUUID)();
3021
3299
  const config = await store.createConfig(tenantId, id, body);
3022
3300
  try {
3023
- import_core17.sqlDatabaseManager.registerDatabase(tenantId, config.key, config.config);
3301
+ import_core18.sqlDatabaseManager.registerDatabase(tenantId, config.key, config.config);
3024
3302
  } catch (error) {
3025
3303
  console.warn("Failed to auto-register database:", error);
3026
3304
  }
@@ -3039,11 +3317,11 @@ async function createDatabaseConfig(request, reply) {
3039
3317
  }
3040
3318
  }
3041
3319
  async function updateDatabaseConfig(request, reply) {
3042
- const tenantId = getTenantId5(request);
3320
+ const tenantId = getTenantId6(request);
3043
3321
  const { key } = request.params;
3044
3322
  const updates = request.body;
3045
3323
  try {
3046
- const storeLattice = (0, import_core17.getStoreLattice)("default", "database");
3324
+ const storeLattice = (0, import_core18.getStoreLattice)("default", "database");
3047
3325
  const store = storeLattice.store;
3048
3326
  const existing = await store.getConfigByKey(tenantId, key);
3049
3327
  if (!existing) {
@@ -3062,7 +3340,7 @@ async function updateDatabaseConfig(request, reply) {
3062
3340
  }
3063
3341
  if (updates.config) {
3064
3342
  try {
3065
- import_core17.sqlDatabaseManager.registerDatabase(tenantId, updated.key, updated.config);
3343
+ import_core18.sqlDatabaseManager.registerDatabase(tenantId, updated.key, updated.config);
3066
3344
  } catch (error) {
3067
3345
  console.warn("Failed to re-register database:", error);
3068
3346
  }
@@ -3081,10 +3359,10 @@ async function updateDatabaseConfig(request, reply) {
3081
3359
  }
3082
3360
  }
3083
3361
  async function deleteDatabaseConfig(request, reply) {
3084
- const tenantId = getTenantId5(request);
3362
+ const tenantId = getTenantId6(request);
3085
3363
  const { keyOrId } = request.params;
3086
3364
  try {
3087
- const storeLattice = (0, import_core17.getStoreLattice)("default", "database");
3365
+ const storeLattice = (0, import_core18.getStoreLattice)("default", "database");
3088
3366
  const store = storeLattice.store;
3089
3367
  console.log("Delete request - keyOrId:", keyOrId);
3090
3368
  let config = await store.getConfigByKey(tenantId, keyOrId);
@@ -3111,8 +3389,8 @@ async function deleteDatabaseConfig(request, reply) {
3111
3389
  };
3112
3390
  }
3113
3391
  try {
3114
- if (import_core17.sqlDatabaseManager.hasDatabase(tenantId, configKey)) {
3115
- await import_core17.sqlDatabaseManager.removeDatabase(tenantId, configKey);
3392
+ if (import_core18.sqlDatabaseManager.hasDatabase(tenantId, configKey)) {
3393
+ await import_core18.sqlDatabaseManager.removeDatabase(tenantId, configKey);
3116
3394
  }
3117
3395
  } catch (error) {
3118
3396
  console.warn("Failed to remove from SqlDatabaseManager:", error);
@@ -3130,10 +3408,10 @@ async function deleteDatabaseConfig(request, reply) {
3130
3408
  }
3131
3409
  }
3132
3410
  async function testDatabaseConnection(request, reply) {
3133
- const tenantId = getTenantId5(request);
3411
+ const tenantId = getTenantId6(request);
3134
3412
  const { key } = request.params;
3135
3413
  try {
3136
- const storeLattice = (0, import_core17.getStoreLattice)("default", "database");
3414
+ const storeLattice = (0, import_core18.getStoreLattice)("default", "database");
3137
3415
  const store = storeLattice.store;
3138
3416
  const config = await store.getConfigByKey(tenantId, key);
3139
3417
  if (!config) {
@@ -3144,16 +3422,16 @@ async function testDatabaseConnection(request, reply) {
3144
3422
  };
3145
3423
  }
3146
3424
  const testKey = `__test_${key}_${Date.now()}`;
3147
- import_core17.sqlDatabaseManager.registerDatabase(tenantId, testKey, config.config);
3425
+ import_core18.sqlDatabaseManager.registerDatabase(tenantId, testKey, config.config);
3148
3426
  const startTime = Date.now();
3149
- const db = import_core17.sqlDatabaseManager.getDatabase(tenantId, testKey);
3427
+ const db = import_core18.sqlDatabaseManager.getDatabase(tenantId, testKey);
3150
3428
  try {
3151
3429
  await db.connect();
3152
3430
  await db.listTables();
3153
3431
  const latency = Date.now() - startTime;
3154
3432
  await new Promise((resolve) => setTimeout(resolve, 100));
3155
3433
  await db.disconnect();
3156
- await import_core17.sqlDatabaseManager.removeDatabase(tenantId, testKey);
3434
+ await import_core18.sqlDatabaseManager.removeDatabase(tenantId, testKey);
3157
3435
  return {
3158
3436
  success: true,
3159
3437
  message: "Connection test successful",
@@ -3165,7 +3443,7 @@ async function testDatabaseConnection(request, reply) {
3165
3443
  } catch (error) {
3166
3444
  try {
3167
3445
  await db.disconnect();
3168
- await import_core17.sqlDatabaseManager.removeDatabase(tenantId, testKey);
3446
+ await import_core18.sqlDatabaseManager.removeDatabase(tenantId, testKey);
3169
3447
  } catch {
3170
3448
  }
3171
3449
  return {
@@ -3217,9 +3495,9 @@ function registerDatabaseConfigRoutes(app2) {
3217
3495
  }
3218
3496
 
3219
3497
  // src/controllers/metrics-configs.ts
3220
- var import_core18 = require("@axiom-lattice/core");
3498
+ var import_core19 = require("@axiom-lattice/core");
3221
3499
  var import_crypto4 = require("crypto");
3222
- function getTenantId6(request) {
3500
+ function getTenantId7(request) {
3223
3501
  const userTenantId = request.user?.tenantId;
3224
3502
  if (userTenantId) {
3225
3503
  return userTenantId;
@@ -3227,9 +3505,9 @@ function getTenantId6(request) {
3227
3505
  return request.headers["x-tenant-id"] || "default";
3228
3506
  }
3229
3507
  async function getMetricsServerConfigList(request, reply) {
3230
- const tenantId = getTenantId6(request);
3508
+ const tenantId = getTenantId7(request);
3231
3509
  try {
3232
- const storeLattice = (0, import_core18.getStoreLattice)("default", "metrics");
3510
+ const storeLattice = (0, import_core19.getStoreLattice)("default", "metrics");
3233
3511
  const store = storeLattice.store;
3234
3512
  const configs = await store.getAllConfigs(tenantId);
3235
3513
  return {
@@ -3253,10 +3531,10 @@ async function getMetricsServerConfigList(request, reply) {
3253
3531
  }
3254
3532
  }
3255
3533
  async function getMetricsServerConfig(request, reply) {
3256
- const tenantId = getTenantId6(request);
3534
+ const tenantId = getTenantId7(request);
3257
3535
  const { key } = request.params;
3258
3536
  try {
3259
- const storeLattice = (0, import_core18.getStoreLattice)("default", "metrics");
3537
+ const storeLattice = (0, import_core19.getStoreLattice)("default", "metrics");
3260
3538
  const store = storeLattice.store;
3261
3539
  const config = await store.getConfigByKey(tenantId, key);
3262
3540
  if (!config) {
@@ -3279,10 +3557,10 @@ async function getMetricsServerConfig(request, reply) {
3279
3557
  }
3280
3558
  }
3281
3559
  async function createMetricsServerConfig(request, reply) {
3282
- const tenantId = getTenantId6(request);
3560
+ const tenantId = getTenantId7(request);
3283
3561
  const body = request.body;
3284
3562
  try {
3285
- const storeLattice = (0, import_core18.getStoreLattice)("default", "metrics");
3563
+ const storeLattice = (0, import_core19.getStoreLattice)("default", "metrics");
3286
3564
  const store = storeLattice.store;
3287
3565
  const existing = await store.getConfigByKey(tenantId, body.key);
3288
3566
  if (existing) {
@@ -3311,7 +3589,7 @@ async function createMetricsServerConfig(request, reply) {
3311
3589
  };
3312
3590
  const config = await store.createConfig(tenantId, id, configData);
3313
3591
  try {
3314
- import_core18.metricsServerManager.registerServer(tenantId, config.key, config.config);
3592
+ import_core19.metricsServerManager.registerServer(tenantId, config.key, config.config);
3315
3593
  } catch (error) {
3316
3594
  console.warn("Failed to auto-register metrics server:", error);
3317
3595
  }
@@ -3330,11 +3608,11 @@ async function createMetricsServerConfig(request, reply) {
3330
3608
  }
3331
3609
  }
3332
3610
  async function updateMetricsServerConfig(request, reply) {
3333
- const tenantId = getTenantId6(request);
3611
+ const tenantId = getTenantId7(request);
3334
3612
  const { key } = request.params;
3335
3613
  const updates = request.body;
3336
3614
  try {
3337
- const storeLattice = (0, import_core18.getStoreLattice)("default", "metrics");
3615
+ const storeLattice = (0, import_core19.getStoreLattice)("default", "metrics");
3338
3616
  const store = storeLattice.store;
3339
3617
  const existing = await store.getConfigByKey(tenantId, key);
3340
3618
  if (!existing) {
@@ -3362,7 +3640,7 @@ async function updateMetricsServerConfig(request, reply) {
3362
3640
  }
3363
3641
  if (updates.config) {
3364
3642
  try {
3365
- import_core18.metricsServerManager.registerServer(tenantId, updated.key, updated.config);
3643
+ import_core19.metricsServerManager.registerServer(tenantId, updated.key, updated.config);
3366
3644
  } catch (error) {
3367
3645
  console.warn("Failed to re-register metrics server:", error);
3368
3646
  }
@@ -3381,10 +3659,10 @@ async function updateMetricsServerConfig(request, reply) {
3381
3659
  }
3382
3660
  }
3383
3661
  async function deleteMetricsServerConfig(request, reply) {
3384
- const tenantId = getTenantId6(request);
3662
+ const tenantId = getTenantId7(request);
3385
3663
  const { keyOrId } = request.params;
3386
3664
  try {
3387
- const storeLattice = (0, import_core18.getStoreLattice)("default", "metrics");
3665
+ const storeLattice = (0, import_core19.getStoreLattice)("default", "metrics");
3388
3666
  const store = storeLattice.store;
3389
3667
  let config = await store.getConfigByKey(tenantId, keyOrId);
3390
3668
  let configKey = keyOrId;
@@ -3409,8 +3687,8 @@ async function deleteMetricsServerConfig(request, reply) {
3409
3687
  };
3410
3688
  }
3411
3689
  try {
3412
- if (import_core18.metricsServerManager.hasServer(tenantId, configKey)) {
3413
- import_core18.metricsServerManager.removeServer(tenantId, configKey);
3690
+ if (import_core19.metricsServerManager.hasServer(tenantId, configKey)) {
3691
+ import_core19.metricsServerManager.removeServer(tenantId, configKey);
3414
3692
  }
3415
3693
  } catch (error) {
3416
3694
  console.warn("Failed to remove from MetricsServerManager:", error);
@@ -3428,10 +3706,10 @@ async function deleteMetricsServerConfig(request, reply) {
3428
3706
  }
3429
3707
  }
3430
3708
  async function testMetricsServerConnection(request, reply) {
3431
- const tenantId = getTenantId6(request);
3709
+ const tenantId = getTenantId7(request);
3432
3710
  const { key } = request.params;
3433
3711
  try {
3434
- const storeLattice = (0, import_core18.getStoreLattice)("default", "metrics");
3712
+ const storeLattice = (0, import_core19.getStoreLattice)("default", "metrics");
3435
3713
  const store = storeLattice.store;
3436
3714
  const config = await store.getConfigByKey(tenantId, key);
3437
3715
  if (!config) {
@@ -3442,11 +3720,11 @@ async function testMetricsServerConnection(request, reply) {
3442
3720
  };
3443
3721
  }
3444
3722
  const testKey = `__test_${key}_${Date.now()}`;
3445
- import_core18.metricsServerManager.registerServer(tenantId, testKey, config.config);
3723
+ import_core19.metricsServerManager.registerServer(tenantId, testKey, config.config);
3446
3724
  try {
3447
- const client = import_core18.metricsServerManager.getClient(tenantId, testKey);
3725
+ const client = import_core19.metricsServerManager.getClient(tenantId, testKey);
3448
3726
  const result = await client.testConnection();
3449
- import_core18.metricsServerManager.removeServer(tenantId, testKey);
3727
+ import_core19.metricsServerManager.removeServer(tenantId, testKey);
3450
3728
  return {
3451
3729
  success: true,
3452
3730
  message: result.connected ? "Connection test successful" : "Connection test failed",
@@ -3454,7 +3732,7 @@ async function testMetricsServerConnection(request, reply) {
3454
3732
  };
3455
3733
  } catch (error) {
3456
3734
  try {
3457
- import_core18.metricsServerManager.removeServer(tenantId, testKey);
3735
+ import_core19.metricsServerManager.removeServer(tenantId, testKey);
3458
3736
  } catch {
3459
3737
  }
3460
3738
  return {
@@ -3479,10 +3757,10 @@ async function testMetricsServerConnection(request, reply) {
3479
3757
  }
3480
3758
  }
3481
3759
  async function listAvailableMetrics(request, reply) {
3482
- const tenantId = getTenantId6(request);
3760
+ const tenantId = getTenantId7(request);
3483
3761
  const { key } = request.params;
3484
3762
  try {
3485
- const storeLattice = (0, import_core18.getStoreLattice)("default", "metrics");
3763
+ const storeLattice = (0, import_core19.getStoreLattice)("default", "metrics");
3486
3764
  const store = storeLattice.store;
3487
3765
  const config = await store.getConfigByKey(tenantId, key);
3488
3766
  if (!config) {
@@ -3492,10 +3770,10 @@ async function listAvailableMetrics(request, reply) {
3492
3770
  message: "Metrics server configuration not found"
3493
3771
  };
3494
3772
  }
3495
- if (!import_core18.metricsServerManager.hasServer(tenantId, key)) {
3496
- import_core18.metricsServerManager.registerServer(tenantId, key, config.config);
3773
+ if (!import_core19.metricsServerManager.hasServer(tenantId, key)) {
3774
+ import_core19.metricsServerManager.registerServer(tenantId, key, config.config);
3497
3775
  }
3498
- const client = import_core18.metricsServerManager.getClient(tenantId, key);
3776
+ const client = import_core19.metricsServerManager.getClient(tenantId, key);
3499
3777
  const metrics = await client.listMetrics();
3500
3778
  return {
3501
3779
  success: true,
@@ -3517,11 +3795,11 @@ async function listAvailableMetrics(request, reply) {
3517
3795
  }
3518
3796
  }
3519
3797
  async function queryMetricsData(request, reply) {
3520
- const tenantId = getTenantId6(request);
3798
+ const tenantId = getTenantId7(request);
3521
3799
  const { key } = request.params;
3522
3800
  const { metricName, startTime, endTime, step, labels } = request.body;
3523
3801
  try {
3524
- const storeLattice = (0, import_core18.getStoreLattice)("default", "metrics");
3802
+ const storeLattice = (0, import_core19.getStoreLattice)("default", "metrics");
3525
3803
  const store = storeLattice.store;
3526
3804
  const config = await store.getConfigByKey(tenantId, key);
3527
3805
  if (!config) {
@@ -3538,10 +3816,10 @@ async function queryMetricsData(request, reply) {
3538
3816
  message: "metricName is required"
3539
3817
  };
3540
3818
  }
3541
- if (!import_core18.metricsServerManager.hasServer(tenantId, key)) {
3542
- import_core18.metricsServerManager.registerServer(tenantId, key, config.config);
3819
+ if (!import_core19.metricsServerManager.hasServer(tenantId, key)) {
3820
+ import_core19.metricsServerManager.registerServer(tenantId, key, config.config);
3543
3821
  }
3544
- const client = import_core18.metricsServerManager.getClient(tenantId, key);
3822
+ const client = import_core19.metricsServerManager.getClient(tenantId, key);
3545
3823
  const result = await client.queryMetricData(metricName, {
3546
3824
  startTime,
3547
3825
  endTime,
@@ -3565,10 +3843,10 @@ async function queryMetricsData(request, reply) {
3565
3843
  }
3566
3844
  }
3567
3845
  async function getDataSources(request, reply) {
3568
- const tenantId = getTenantId6(request);
3846
+ const tenantId = getTenantId7(request);
3569
3847
  const { key } = request.params;
3570
3848
  try {
3571
- const storeLattice = (0, import_core18.getStoreLattice)("default", "metrics");
3849
+ const storeLattice = (0, import_core19.getStoreLattice)("default", "metrics");
3572
3850
  const store = storeLattice.store;
3573
3851
  const config = await store.getConfigByKey(tenantId, key);
3574
3852
  if (!config) {
@@ -3586,7 +3864,7 @@ async function getDataSources(request, reply) {
3586
3864
  };
3587
3865
  }
3588
3866
  const semanticConfig = config.config;
3589
- const client = new import_core18.SemanticMetricsClient(semanticConfig);
3867
+ const client = new import_core19.SemanticMetricsClient(semanticConfig);
3590
3868
  const allDatasources = await client.getDataSources();
3591
3869
  const selectedIds = semanticConfig.selectedDataSources || [];
3592
3870
  const filteredDatasources = selectedIds.length > 0 ? allDatasources.filter((ds) => selectedIds.includes(String(ds.id))) : allDatasources;
@@ -3606,10 +3884,10 @@ async function getDataSources(request, reply) {
3606
3884
  }
3607
3885
  }
3608
3886
  async function getDatasourceMetrics(request, reply) {
3609
- const tenantId = getTenantId6(request);
3887
+ const tenantId = getTenantId7(request);
3610
3888
  const { key, datasourceId } = request.params;
3611
3889
  try {
3612
- const storeLattice = (0, import_core18.getStoreLattice)("default", "metrics");
3890
+ const storeLattice = (0, import_core19.getStoreLattice)("default", "metrics");
3613
3891
  const store = storeLattice.store;
3614
3892
  const config = await store.getConfigByKey(tenantId, key);
3615
3893
  if (!config) {
@@ -3627,7 +3905,7 @@ async function getDatasourceMetrics(request, reply) {
3627
3905
  };
3628
3906
  }
3629
3907
  const semanticConfig = config.config;
3630
- const client = new import_core18.SemanticMetricsClient(semanticConfig);
3908
+ const client = new import_core19.SemanticMetricsClient(semanticConfig);
3631
3909
  const metrics = await client.getDatasourceMetrics(datasourceId);
3632
3910
  return {
3633
3911
  success: true,
@@ -3643,11 +3921,11 @@ async function getDatasourceMetrics(request, reply) {
3643
3921
  }
3644
3922
  }
3645
3923
  async function querySemanticMetrics(request, reply) {
3646
- const tenantId = getTenantId6(request);
3924
+ const tenantId = getTenantId7(request);
3647
3925
  const { key } = request.params;
3648
3926
  const body = request.body;
3649
3927
  try {
3650
- const storeLattice = (0, import_core18.getStoreLattice)("default", "metrics");
3928
+ const storeLattice = (0, import_core19.getStoreLattice)("default", "metrics");
3651
3929
  const store = storeLattice.store;
3652
3930
  const config = await store.getConfigByKey(tenantId, key);
3653
3931
  if (!config) {
@@ -3672,33 +3950,37 @@ async function querySemanticMetrics(request, reply) {
3672
3950
  };
3673
3951
  }
3674
3952
  const semanticConfig = config.config;
3675
- const client = new import_core18.SemanticMetricsClient(semanticConfig);
3953
+ const client = new import_core19.SemanticMetricsClient(semanticConfig);
3676
3954
  const result = await client.semanticQuery(body);
3955
+ const columnNames = result.columns.map((col) => col.name);
3677
3956
  const allDataPoints = [];
3678
- const metricNames = [];
3679
- for (const metricResult of result.results) {
3680
- metricNames.push(metricResult.metricName);
3681
- for (const row of metricResult.rows) {
3682
- allDataPoints.push({
3683
- timestamp: row.timestamp ? new Date(row.timestamp).getTime() : void 0,
3684
- value: typeof row.value === "number" ? row.value : 0,
3685
- metricName: metricResult.metricName,
3686
- labels: Object.fromEntries(
3687
- Object.entries(row).filter(([k]) => k !== "value" && k !== "timestamp").map(([k, v]) => [k, String(v)])
3688
- )
3689
- });
3690
- }
3957
+ const timestampColIdx = columnNames.findIndex(
3958
+ (col) => col.toLowerCase().includes("date") || col.toLowerCase().includes("time")
3959
+ );
3960
+ const valueColIdx = columnNames.findIndex(
3961
+ (col) => col.toLowerCase().includes("value") || col.toLowerCase().includes("rate") || col.toLowerCase().includes("amt")
3962
+ );
3963
+ for (const row of result.rows) {
3964
+ const timestamp = timestampColIdx >= 0 ? row[timestampColIdx] : void 0;
3965
+ const value = valueColIdx >= 0 ? row[valueColIdx] : row[row.length - 1];
3966
+ allDataPoints.push({
3967
+ timestamp: timestamp ? new Date(String(timestamp)).getTime() : void 0,
3968
+ value: typeof value === "number" ? value : Number(value) || 0,
3969
+ labels: Object.fromEntries(
3970
+ columnNames.map((col, idx) => [col, String(row[idx] ?? "")])
3971
+ )
3972
+ });
3691
3973
  }
3692
3974
  return {
3693
3975
  success: true,
3694
3976
  message: "Semantic query executed successfully",
3695
3977
  data: {
3696
- datasourceId: result.datasourceId,
3697
- metrics: metricNames,
3978
+ semanticModel: result.semanticModel,
3979
+ columns: columnNames,
3698
3980
  dataPoints: allDataPoints,
3699
3981
  metadata: {
3700
- rowCount: allDataPoints.length,
3701
- queryTimeMs: result.totalExecutionTimeMs
3982
+ rowCount: result.rows.length,
3983
+ columnCount: result.columns.length
3702
3984
  }
3703
3985
  }
3704
3986
  };
@@ -3728,7 +4010,7 @@ async function testSemanticDataSources(request, reply) {
3728
4010
  password: body.password,
3729
4011
  headers: body.headers
3730
4012
  };
3731
- const client = new import_core18.SemanticMetricsClient(testConfig);
4013
+ const client = new import_core19.SemanticMetricsClient(testConfig);
3732
4014
  const datasources = await client.getDataSources();
3733
4015
  return {
3734
4016
  success: true,
@@ -3764,7 +4046,7 @@ async function testDatasourceMetrics(request, reply) {
3764
4046
  password: body.password,
3765
4047
  headers: body.headers
3766
4048
  };
3767
- const client = new import_core18.SemanticMetricsClient(testConfig);
4049
+ const client = new import_core19.SemanticMetricsClient(testConfig);
3768
4050
  const metrics = await client.getDatasourceMetrics(datasourceId);
3769
4051
  return {
3770
4052
  success: true,
@@ -3796,9 +4078,9 @@ function registerMetricsServerConfigRoutes(app2) {
3796
4078
  }
3797
4079
 
3798
4080
  // src/controllers/mcp-configs.ts
3799
- var import_core19 = require("@axiom-lattice/core");
4081
+ var import_core20 = require("@axiom-lattice/core");
3800
4082
  var import_crypto5 = require("crypto");
3801
- function getTenantId7(request) {
4083
+ function getTenantId8(request) {
3802
4084
  const userTenantId = request.user?.tenantId;
3803
4085
  if (userTenantId) {
3804
4086
  return userTenantId;
@@ -3806,9 +4088,9 @@ function getTenantId7(request) {
3806
4088
  return request.headers["x-tenant-id"] || "default";
3807
4089
  }
3808
4090
  async function getMcpServerConfigList(request, reply) {
3809
- const tenantId = getTenantId7(request);
4091
+ const tenantId = getTenantId8(request);
3810
4092
  try {
3811
- const storeLattice = (0, import_core19.getStoreLattice)("default", "mcp");
4093
+ const storeLattice = (0, import_core20.getStoreLattice)("default", "mcp");
3812
4094
  const store = storeLattice.store;
3813
4095
  const configs = await store.getAllConfigs(tenantId);
3814
4096
  return {
@@ -3832,10 +4114,10 @@ async function getMcpServerConfigList(request, reply) {
3832
4114
  }
3833
4115
  }
3834
4116
  async function getMcpServerConfig(request, reply) {
3835
- const tenantId = getTenantId7(request);
4117
+ const tenantId = getTenantId8(request);
3836
4118
  const { key } = request.params;
3837
4119
  try {
3838
- const storeLattice = (0, import_core19.getStoreLattice)("default", "mcp");
4120
+ const storeLattice = (0, import_core20.getStoreLattice)("default", "mcp");
3839
4121
  const store = storeLattice.store;
3840
4122
  const config = await store.getConfigByKey(tenantId, key);
3841
4123
  if (!config) {
@@ -3858,10 +4140,10 @@ async function getMcpServerConfig(request, reply) {
3858
4140
  }
3859
4141
  }
3860
4142
  async function createMcpServerConfig(request, reply) {
3861
- const tenantId = getTenantId7(request);
4143
+ const tenantId = getTenantId8(request);
3862
4144
  const body = request.body;
3863
4145
  try {
3864
- const storeLattice = (0, import_core19.getStoreLattice)("default", "mcp");
4146
+ const storeLattice = (0, import_core20.getStoreLattice)("default", "mcp");
3865
4147
  const store = storeLattice.store;
3866
4148
  const existing = await store.getConfigByKey(tenantId, body.key);
3867
4149
  if (existing) {
@@ -3897,11 +4179,11 @@ async function createMcpServerConfig(request, reply) {
3897
4179
  }
3898
4180
  }
3899
4181
  async function updateMcpServerConfig(request, reply) {
3900
- const tenantId = getTenantId7(request);
4182
+ const tenantId = getTenantId8(request);
3901
4183
  const { key } = request.params;
3902
4184
  const updates = request.body;
3903
4185
  try {
3904
- const storeLattice = (0, import_core19.getStoreLattice)("default", "mcp");
4186
+ const storeLattice = (0, import_core20.getStoreLattice)("default", "mcp");
3905
4187
  const store = storeLattice.store;
3906
4188
  const existing = await store.getConfigByKey(tenantId, key);
3907
4189
  if (!existing) {
@@ -3921,8 +4203,8 @@ async function updateMcpServerConfig(request, reply) {
3921
4203
  }
3922
4204
  if (shouldReconnect) {
3923
4205
  try {
3924
- if (import_core19.mcpManager.hasServer(key)) {
3925
- await import_core19.mcpManager.removeServer(key);
4206
+ if (import_core20.mcpManager.hasServer(key)) {
4207
+ await import_core20.mcpManager.removeServer(key);
3926
4208
  }
3927
4209
  await connectAndRegisterTools(updated);
3928
4210
  await store.updateConfig(tenantId, existing.id, { status: "connected" });
@@ -3947,10 +4229,10 @@ async function updateMcpServerConfig(request, reply) {
3947
4229
  }
3948
4230
  }
3949
4231
  async function deleteMcpServerConfig(request, reply) {
3950
- const tenantId = getTenantId7(request);
4232
+ const tenantId = getTenantId8(request);
3951
4233
  const { keyOrId } = request.params;
3952
4234
  try {
3953
- const storeLattice = (0, import_core19.getStoreLattice)("default", "mcp");
4235
+ const storeLattice = (0, import_core20.getStoreLattice)("default", "mcp");
3954
4236
  const store = storeLattice.store;
3955
4237
  let config = await store.getConfigByKey(tenantId, keyOrId);
3956
4238
  let configKey = keyOrId;
@@ -3968,8 +4250,8 @@ async function deleteMcpServerConfig(request, reply) {
3968
4250
  };
3969
4251
  }
3970
4252
  try {
3971
- if (import_core19.mcpManager.hasServer(configKey)) {
3972
- await import_core19.mcpManager.removeServer(configKey);
4253
+ if (import_core20.mcpManager.hasServer(configKey)) {
4254
+ await import_core20.mcpManager.removeServer(configKey);
3973
4255
  }
3974
4256
  } catch (error) {
3975
4257
  console.warn("Failed to remove from MCP manager:", error);
@@ -3994,10 +4276,10 @@ async function deleteMcpServerConfig(request, reply) {
3994
4276
  }
3995
4277
  }
3996
4278
  async function testMcpServerConnection(request, reply) {
3997
- const tenantId = getTenantId7(request);
4279
+ const tenantId = getTenantId8(request);
3998
4280
  const { key } = request.params;
3999
4281
  try {
4000
- const storeLattice = (0, import_core19.getStoreLattice)("default", "mcp");
4282
+ const storeLattice = (0, import_core20.getStoreLattice)("default", "mcp");
4001
4283
  const store = storeLattice.store;
4002
4284
  const config = await store.getConfigByKey(tenantId, key);
4003
4285
  if (!config) {
@@ -4011,11 +4293,11 @@ async function testMcpServerConnection(request, reply) {
4011
4293
  try {
4012
4294
  const testKey = `__test_${key}_${Date.now()}`;
4013
4295
  const connection = convertToConnection(config.config);
4014
- import_core19.mcpManager.addServer(testKey, connection);
4015
- await import_core19.mcpManager.connect();
4016
- const tools = await import_core19.mcpManager.getAllTools();
4296
+ import_core20.mcpManager.addServer(testKey, connection);
4297
+ await import_core20.mcpManager.connect();
4298
+ const tools = await import_core20.mcpManager.getAllTools();
4017
4299
  const latency = Date.now() - startTime;
4018
- await import_core19.mcpManager.removeServer(testKey);
4300
+ await import_core20.mcpManager.removeServer(testKey);
4019
4301
  return {
4020
4302
  success: true,
4021
4303
  message: "Connection test successful",
@@ -4047,10 +4329,10 @@ async function testMcpServerConnection(request, reply) {
4047
4329
  }
4048
4330
  }
4049
4331
  async function listMcpServerTools(request, reply) {
4050
- const tenantId = getTenantId7(request);
4332
+ const tenantId = getTenantId8(request);
4051
4333
  const { key } = request.params;
4052
4334
  try {
4053
- const storeLattice = (0, import_core19.getStoreLattice)("default", "mcp");
4335
+ const storeLattice = (0, import_core20.getStoreLattice)("default", "mcp");
4054
4336
  const store = storeLattice.store;
4055
4337
  const config = await store.getConfigByKey(tenantId, key);
4056
4338
  if (!config) {
@@ -4060,10 +4342,10 @@ async function listMcpServerTools(request, reply) {
4060
4342
  message: "MCP server configuration not found"
4061
4343
  };
4062
4344
  }
4063
- if (!import_core19.mcpManager.hasServer(key)) {
4345
+ if (!import_core20.mcpManager.hasServer(key)) {
4064
4346
  await connectAndRegisterTools(config);
4065
4347
  }
4066
- const tools = await import_core19.mcpManager.getAllTools();
4348
+ const tools = await import_core20.mcpManager.getAllTools();
4067
4349
  return {
4068
4350
  success: true,
4069
4351
  message: "Tools retrieved successfully",
@@ -4080,10 +4362,10 @@ async function listMcpServerTools(request, reply) {
4080
4362
  }
4081
4363
  }
4082
4364
  async function connectMcpServer(request, reply) {
4083
- const tenantId = getTenantId7(request);
4365
+ const tenantId = getTenantId8(request);
4084
4366
  const { key } = request.params;
4085
4367
  try {
4086
- const storeLattice = (0, import_core19.getStoreLattice)("default", "mcp");
4368
+ const storeLattice = (0, import_core20.getStoreLattice)("default", "mcp");
4087
4369
  const store = storeLattice.store;
4088
4370
  const config = await store.getConfigByKey(tenantId, key);
4089
4371
  if (!config) {
@@ -4104,7 +4386,7 @@ async function connectMcpServer(request, reply) {
4104
4386
  };
4105
4387
  } catch (error) {
4106
4388
  console.error("Failed to connect MCP server:", error);
4107
- const storeLattice = (0, import_core19.getStoreLattice)("default", "mcp");
4389
+ const storeLattice = (0, import_core20.getStoreLattice)("default", "mcp");
4108
4390
  const store = storeLattice.store;
4109
4391
  const config = await store.getConfigByKey(tenantId, key);
4110
4392
  if (config) {
@@ -4117,10 +4399,10 @@ async function connectMcpServer(request, reply) {
4117
4399
  }
4118
4400
  }
4119
4401
  async function disconnectMcpServer(request, reply) {
4120
- const tenantId = getTenantId7(request);
4402
+ const tenantId = getTenantId8(request);
4121
4403
  const { key } = request.params;
4122
4404
  try {
4123
- const storeLattice = (0, import_core19.getStoreLattice)("default", "mcp");
4405
+ const storeLattice = (0, import_core20.getStoreLattice)("default", "mcp");
4124
4406
  const store = storeLattice.store;
4125
4407
  const config = await store.getConfigByKey(tenantId, key);
4126
4408
  if (!config) {
@@ -4130,8 +4412,8 @@ async function disconnectMcpServer(request, reply) {
4130
4412
  message: "MCP server configuration not found"
4131
4413
  };
4132
4414
  }
4133
- if (import_core19.mcpManager.hasServer(key)) {
4134
- await import_core19.mcpManager.removeServer(key);
4415
+ if (import_core20.mcpManager.hasServer(key)) {
4416
+ await import_core20.mcpManager.removeServer(key);
4135
4417
  }
4136
4418
  const updated = await store.updateConfig(tenantId, config.id, {
4137
4419
  status: "disconnected"
@@ -4161,10 +4443,10 @@ async function testMcpServerTools(request, reply) {
4161
4443
  }
4162
4444
  const testKey = `__test_${Date.now()}`;
4163
4445
  const connection = convertToConnection(body.config);
4164
- import_core19.mcpManager.addServer(testKey, connection);
4165
- await import_core19.mcpManager.connect();
4166
- const tools = await import_core19.mcpManager.getAllTools();
4167
- await import_core19.mcpManager.removeServer(testKey);
4446
+ import_core20.mcpManager.addServer(testKey, connection);
4447
+ await import_core20.mcpManager.connect();
4448
+ const tools = await import_core20.mcpManager.getAllTools();
4449
+ await import_core20.mcpManager.removeServer(testKey);
4168
4450
  return {
4169
4451
  success: true,
4170
4452
  message: "Tools retrieved successfully",
@@ -4201,14 +4483,14 @@ function convertToConnection(config) {
4201
4483
  }
4202
4484
  async function connectAndRegisterTools(config) {
4203
4485
  const connection = convertToConnection(config.config);
4204
- import_core19.mcpManager.addServer(config.key, connection);
4205
- await import_core19.mcpManager.connect();
4206
- const allTools = await import_core19.mcpManager.getAllTools();
4486
+ import_core20.mcpManager.addServer(config.key, connection);
4487
+ await import_core20.mcpManager.connect();
4488
+ const allTools = await import_core20.mcpManager.getAllTools();
4207
4489
  const selectedTools = allTools.filter(
4208
4490
  (tool) => config.selectedTools.includes(tool.name)
4209
4491
  );
4210
4492
  for (const tool of selectedTools) {
4211
- import_core19.toolLatticeManager.registerExistingTool(tool.name, tool);
4493
+ import_core20.toolLatticeManager.registerExistingTool(tool.name, tool);
4212
4494
  }
4213
4495
  }
4214
4496
  function registerMcpServerConfigRoutes(app2) {
@@ -4225,11 +4507,11 @@ function registerMcpServerConfigRoutes(app2) {
4225
4507
  }
4226
4508
 
4227
4509
  // src/controllers/users.ts
4228
- var import_core20 = require("@axiom-lattice/core");
4510
+ var import_core21 = require("@axiom-lattice/core");
4229
4511
  var import_uuid4 = require("uuid");
4230
4512
  var UsersController = class {
4231
4513
  constructor() {
4232
- this.userStore = (0, import_core20.getStoreLattice)("default", "user").store;
4514
+ this.userStore = (0, import_core21.getStoreLattice)("default", "user").store;
4233
4515
  }
4234
4516
  async listUsers(request, reply) {
4235
4517
  const { email } = request.query;
@@ -4307,11 +4589,11 @@ function registerUserRoutes(app2) {
4307
4589
  }
4308
4590
 
4309
4591
  // src/controllers/tenants.ts
4310
- var import_core21 = require("@axiom-lattice/core");
4592
+ var import_core22 = require("@axiom-lattice/core");
4311
4593
  var import_uuid5 = require("uuid");
4312
4594
  var TenantsController = class {
4313
4595
  constructor() {
4314
- this.tenantStore = (0, import_core21.getStoreLattice)("default", "tenant").store;
4596
+ this.tenantStore = (0, import_core22.getStoreLattice)("default", "tenant").store;
4315
4597
  }
4316
4598
  // ==================== Tenant CRUD ====================
4317
4599
  async listTenants(request, reply) {
@@ -4375,7 +4657,7 @@ function registerTenantRoutes(app2) {
4375
4657
  }
4376
4658
 
4377
4659
  // src/controllers/auth.ts
4378
- var import_core22 = require("@axiom-lattice/core");
4660
+ var import_core23 = require("@axiom-lattice/core");
4379
4661
  var import_uuid6 = require("uuid");
4380
4662
  var defaultAuthConfig = {
4381
4663
  autoApproveUsers: true,
@@ -4384,9 +4666,9 @@ var defaultAuthConfig = {
4384
4666
  };
4385
4667
  var AuthController = class {
4386
4668
  constructor(config = {}) {
4387
- this.userStore = (0, import_core22.getStoreLattice)("default", "user").store;
4388
- this.tenantStore = (0, import_core22.getStoreLattice)("default", "tenant").store;
4389
- this.userTenantLinkStore = (0, import_core22.getStoreLattice)("default", "userTenantLink").store;
4669
+ this.userStore = (0, import_core23.getStoreLattice)("default", "user").store;
4670
+ this.tenantStore = (0, import_core23.getStoreLattice)("default", "tenant").store;
4671
+ this.userTenantLinkStore = (0, import_core23.getStoreLattice)("default", "userTenantLink").store;
4390
4672
  this.config = { ...defaultAuthConfig, ...config };
4391
4673
  }
4392
4674
  async register(request, reply) {
@@ -4823,6 +5105,11 @@ var registerLatticeRoutes = (app2) => {
4823
5105
  registerWorkspaceRoutes(app2);
4824
5106
  registerDatabaseConfigRoutes(app2);
4825
5107
  registerMetricsServerConfigRoutes(app2);
5108
+ app2.post(
5109
+ "/api/data/query",
5110
+ { schema: dataQuerySchema },
5111
+ executeDataQuery
5112
+ );
4826
5113
  registerMcpServerConfigRoutes(app2);
4827
5114
  registerUserRoutes(app2);
4828
5115
  registerTenantRoutes(app2);
@@ -4895,7 +5182,7 @@ var configureSwagger = async (app2, customSwaggerConfig, customSwaggerUiConfig)
4895
5182
  };
4896
5183
 
4897
5184
  // src/services/agent_task_consumer.ts
4898
- var import_core23 = require("@axiom-lattice/core");
5185
+ var import_core24 = require("@axiom-lattice/core");
4899
5186
  var handleAgentTask = async (taskRequest, retryCount = 0) => {
4900
5187
  const {
4901
5188
  assistant_id,
@@ -4924,7 +5211,9 @@ var handleAgentTask = async (taskRequest, retryCount = 0) => {
4924
5211
  }),
4925
5212
  headers: {
4926
5213
  "Content-Type": "application/json",
4927
- "x-tenant-id": tenant_id
5214
+ "x-tenant-id": tenant_id,
5215
+ "x-workspace-id": runConfig?.workspaceId,
5216
+ "x-project-id": runConfig?.projectId
4928
5217
  }
4929
5218
  }).catch((err) => {
4930
5219
  console.error(`fetch\u8BF7\u6C42\u5931\u8D25: ${err.message || String(err)}`);
@@ -4961,7 +5250,7 @@ var handleAgentTask = async (taskRequest, retryCount = 0) => {
4961
5250
  }
4962
5251
  if (callback_event) {
4963
5252
  const state = await agent_state({ assistant_id, thread_id, tenant_id });
4964
- import_core23.eventBus.publish(callback_event, {
5253
+ import_core24.eventBus.publish(callback_event, {
4965
5254
  success: true,
4966
5255
  state,
4967
5256
  config: { assistant_id, thread_id, tenant_id }
@@ -4975,7 +5264,7 @@ var handleAgentTask = async (taskRequest, retryCount = 0) => {
4975
5264
  await response.text();
4976
5265
  if (callback_event) {
4977
5266
  const state = await agent_state({ assistant_id, thread_id, tenant_id });
4978
- import_core23.eventBus.publish(callback_event, {
5267
+ import_core24.eventBus.publish(callback_event, {
4979
5268
  success: true,
4980
5269
  state,
4981
5270
  config: { assistant_id, thread_id, tenant_id }
@@ -5002,7 +5291,7 @@ var handleAgentTask = async (taskRequest, retryCount = 0) => {
5002
5291
  return handleAgentTask(taskRequest, nextRetryCount);
5003
5292
  }
5004
5293
  if (callback_event) {
5005
- import_core23.eventBus.publish(callback_event, {
5294
+ import_core24.eventBus.publish(callback_event, {
5006
5295
  success: false,
5007
5296
  error: error instanceof Error ? error.message : String(error),
5008
5297
  config: { assistant_id, thread_id, tenant_id }
@@ -5040,7 +5329,7 @@ var _AgentTaskConsumer = class _AgentTaskConsumer {
5040
5329
  * 初始化事件监听和队列轮询
5041
5330
  */
5042
5331
  initialize() {
5043
- import_core23.eventBus.subscribe(import_core23.AGENT_TASK_EVENT, this.trigger_agent_task.bind(this));
5332
+ import_core24.eventBus.subscribe(import_core24.AGENT_TASK_EVENT, this.trigger_agent_task.bind(this));
5044
5333
  this.startPollingQueue();
5045
5334
  console.log("Agent\u4EFB\u52A1\u6D88\u8D39\u8005\u5DF2\u542F\u52A8\u5E76\u76D1\u542C\u4EFB\u52A1\u4E8B\u4EF6\u548C\u961F\u5217");
5046
5335
  }
@@ -5159,7 +5448,7 @@ var _AgentTaskConsumer = class _AgentTaskConsumer {
5159
5448
  handleAgentTask(taskRequest).catch((error) => {
5160
5449
  console.error("\u5904\u7406Agent\u4EFB\u52A1\u65F6\u53D1\u751F\u672A\u6355\u83B7\u7684\u9519\u8BEF:", error);
5161
5450
  if (taskRequest.callback_event) {
5162
- import_core23.eventBus.publish(taskRequest.callback_event, {
5451
+ import_core24.eventBus.publish(taskRequest.callback_event, {
5163
5452
  success: false,
5164
5453
  error: error instanceof Error ? error.message : String(error),
5165
5454
  config: {
@@ -5179,7 +5468,7 @@ _AgentTaskConsumer.agent_run_endpoint = "http://localhost:4001/api/runs";
5179
5468
  var AgentTaskConsumer = _AgentTaskConsumer;
5180
5469
 
5181
5470
  // src/index.ts
5182
- var import_core24 = require("@axiom-lattice/core");
5471
+ var import_core25 = require("@axiom-lattice/core");
5183
5472
  var import_protocols2 = require("@axiom-lattice/protocols");
5184
5473
  process.on("unhandledRejection", (reason, promise) => {
5185
5474
  console.error("\u672A\u5904\u7406\u7684Promise\u62D2\u7EDD:", reason);
@@ -5194,11 +5483,11 @@ var DEFAULT_LOGGER_CONFIG = {
5194
5483
  var loggerLattice = initializeLogger(DEFAULT_LOGGER_CONFIG);
5195
5484
  var logger = loggerLattice.client;
5196
5485
  function initializeLogger(config) {
5197
- if (import_core24.loggerLatticeManager.hasLattice("default")) {
5198
- import_core24.loggerLatticeManager.removeLattice("default");
5486
+ if (import_core25.loggerLatticeManager.hasLattice("default")) {
5487
+ import_core25.loggerLatticeManager.removeLattice("default");
5199
5488
  }
5200
- (0, import_core24.registerLoggerLattice)("default", config);
5201
- return (0, import_core24.getLoggerLattice)("default");
5489
+ (0, import_core25.registerLoggerLattice)("default", config);
5490
+ return (0, import_core25.getLoggerLattice)("default");
5202
5491
  }
5203
5492
  var app = (0, import_fastify.default)({
5204
5493
  logger: false,
@@ -5250,6 +5539,10 @@ app.register(import_multipart.default, {
5250
5539
  }
5251
5540
  });
5252
5541
  app.register(import_websocket.default);
5542
+ app.register(import_static.default, {
5543
+ root: import_path.default.join(__dirname, "../public"),
5544
+ prefix: "/"
5545
+ });
5253
5546
  app.setErrorHandler((error, request, reply) => {
5254
5547
  const getHeaderValue = (header) => {
5255
5548
  if (Array.isArray(header)) {
@@ -5288,9 +5581,10 @@ var start = async (config) => {
5288
5581
  logger = loggerLattice.client;
5289
5582
  }
5290
5583
  app.decorate("loggerLattice", loggerLattice);
5291
- if (!import_core24.sandboxLatticeManager.hasLattice("default")) {
5584
+ registerLatticeRoutes(app);
5585
+ if (!import_core25.sandboxLatticeManager.hasLattice("default")) {
5292
5586
  const sandboxBaseURL = process.env.SANDBOX_BASE_URL || "http://localhost:8080";
5293
- import_core24.sandboxLatticeManager.registerLattice("default", {
5587
+ import_core25.sandboxLatticeManager.registerLattice("default", {
5294
5588
  baseURL: sandboxBaseURL
5295
5589
  });
5296
5590
  logger.info(`Registered sandbox manager with baseURL: ${sandboxBaseURL}`);