@axiom-lattice/gateway 2.1.40 → 2.1.41

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.mjs CHANGED
@@ -4,6 +4,8 @@ import cors from "@fastify/cors";
4
4
  import multipart from "@fastify/multipart";
5
5
  import sensible from "@fastify/sensible";
6
6
  import websocket from "@fastify/websocket";
7
+ import staticPlugin from "@fastify/static";
8
+ import path2 from "path";
7
9
 
8
10
  // src/services/agent_service.ts
9
11
  import {
@@ -1841,6 +1843,215 @@ async function getToolConfigs(request, reply) {
1841
1843
  }
1842
1844
  }
1843
1845
 
1846
+ // src/controllers/data-query.ts
1847
+ import {
1848
+ getStoreLattice as getStoreLattice4,
1849
+ metricsServerManager
1850
+ } from "@axiom-lattice/core";
1851
+ function getTenantId5(request) {
1852
+ return request.headers["x-tenant-id"] || "default";
1853
+ }
1854
+ async function executeDataQuery(request, reply) {
1855
+ const tenantId = getTenantId5(request);
1856
+ const body = request.body;
1857
+ try {
1858
+ if (!body.serverKey && !body.datasourceId) {
1859
+ reply.code(400);
1860
+ return {
1861
+ success: false,
1862
+ message: "Either serverKey or datasourceId must be provided"
1863
+ };
1864
+ }
1865
+ const isSemanticQuery = body.metrics && body.metrics.length > 0;
1866
+ const isSqlQuery = body.customSql && body.customSql.trim().length > 0;
1867
+ if (!isSemanticQuery && !isSqlQuery) {
1868
+ reply.code(400);
1869
+ return {
1870
+ success: false,
1871
+ message: "Either metrics (for semantic query) or customSql (for SQL query) must be provided"
1872
+ };
1873
+ }
1874
+ if (isSemanticQuery && isSqlQuery) {
1875
+ reply.code(400);
1876
+ return {
1877
+ success: false,
1878
+ message: "Cannot provide both metrics and customSql. Use one query type only."
1879
+ };
1880
+ }
1881
+ const storeLattice = getStoreLattice4("default", "metrics");
1882
+ const store = storeLattice.store;
1883
+ if (!body.serverKey) {
1884
+ reply.code(400);
1885
+ return {
1886
+ success: false,
1887
+ message: "serverKey is required"
1888
+ };
1889
+ }
1890
+ const config = await store.getConfigByKey(tenantId, body.serverKey);
1891
+ if (!config) {
1892
+ reply.code(404);
1893
+ return {
1894
+ success: false,
1895
+ message: `Metrics server configuration not found: ${body.serverKey}`
1896
+ };
1897
+ }
1898
+ if (config.config.type !== "semantic") {
1899
+ reply.code(400);
1900
+ return {
1901
+ success: false,
1902
+ message: "This endpoint only supports semantic metrics servers"
1903
+ };
1904
+ }
1905
+ if (!body.datasourceId) {
1906
+ reply.code(400);
1907
+ return {
1908
+ success: false,
1909
+ message: "datasourceId is required"
1910
+ };
1911
+ }
1912
+ if (!metricsServerManager.hasServer(tenantId, body.serverKey)) {
1913
+ reply.code(400);
1914
+ return {
1915
+ success: false,
1916
+ message: `Metrics server not registered: ${body.serverKey}. Please register the server first.`
1917
+ };
1918
+ }
1919
+ const client = metricsServerManager.getClient(tenantId, body.serverKey);
1920
+ if (isSemanticQuery) {
1921
+ return await executeSemanticQuery(client, body, reply);
1922
+ } else {
1923
+ return await executeSqlQuery(client, body, reply);
1924
+ }
1925
+ } catch (error) {
1926
+ console.error("Failed to execute data query:", error);
1927
+ reply.code(500);
1928
+ return {
1929
+ success: false,
1930
+ message: `Failed to execute data query: ${error instanceof Error ? error.message : String(error)}`
1931
+ };
1932
+ }
1933
+ }
1934
+ async function executeSemanticQuery(client, body, reply) {
1935
+ const semanticFilters = (body.filters || []).map((f) => ({
1936
+ dimension: f.dimension,
1937
+ operator: f.operator,
1938
+ values: f.values
1939
+ }));
1940
+ const result = await client.semanticQuery({
1941
+ datasourceId: body.datasourceId,
1942
+ metrics: body.metrics,
1943
+ groupBy: body.groupBy,
1944
+ filters: semanticFilters,
1945
+ limit: body.limit || 1e3
1946
+ });
1947
+ return {
1948
+ success: true,
1949
+ message: "Semantic query executed successfully",
1950
+ data: {
1951
+ semanticModel: result.semanticModel,
1952
+ columns: result.columns,
1953
+ rows: result.rows,
1954
+ rowsObject: result.rowsObject,
1955
+ metadata: {
1956
+ rowCount: result.rowCount,
1957
+ executionTimeMs: result.executionTimeMs
1958
+ }
1959
+ }
1960
+ };
1961
+ }
1962
+ async function executeSqlQuery(client, body, reply) {
1963
+ const result = await client.executeSqlQuery({
1964
+ datasourceId: body.datasourceId,
1965
+ customSql: body.customSql,
1966
+ params: body.params,
1967
+ limit: body.limit || 100
1968
+ });
1969
+ return {
1970
+ success: true,
1971
+ message: "SQL query executed successfully",
1972
+ data: {
1973
+ tableName: result.tableName,
1974
+ columns: result.columns.map((name) => ({ name, type: "unknown" })),
1975
+ rows: result.rows,
1976
+ rowsObject: result.rowsObject,
1977
+ executedSql: result.executedSql,
1978
+ metadata: {
1979
+ rowCount: result.rowCount,
1980
+ executionTimeMs: result.executionTimeMs
1981
+ }
1982
+ }
1983
+ };
1984
+ }
1985
+
1986
+ // src/schemas/data-query.ts
1987
+ var dataQuerySchema = {
1988
+ description: "Execute data query (semantic or SQL)",
1989
+ tags: ["Data Query"],
1990
+ summary: "Query Data",
1991
+ body: {
1992
+ type: "object",
1993
+ properties: {
1994
+ serverKey: {
1995
+ type: "string",
1996
+ description: "Target semantic metrics server key (optional if configured in runConfig)"
1997
+ },
1998
+ datasourceId: {
1999
+ type: "string",
2000
+ description: "Data source ID (optional if configured in runConfig)"
2001
+ },
2002
+ // Semantic query parameters
2003
+ metrics: {
2004
+ type: "array",
2005
+ items: { type: "string" },
2006
+ description: "Array of metric names for semantic query"
2007
+ },
2008
+ groupBy: {
2009
+ type: "array",
2010
+ items: { type: "string" },
2011
+ description: "Optional array of dimensions to group by"
2012
+ },
2013
+ filters: {
2014
+ type: "array",
2015
+ items: {
2016
+ type: "object",
2017
+ properties: {
2018
+ dimension: { type: "string" },
2019
+ operator: { type: "string" },
2020
+ values: {
2021
+ type: "array",
2022
+ items: { type: ["string", "number", "boolean"] }
2023
+ }
2024
+ },
2025
+ required: ["dimension", "operator", "values"]
2026
+ },
2027
+ description: "Optional array of filters"
2028
+ },
2029
+ // SQL query parameters
2030
+ customSql: {
2031
+ type: "string",
2032
+ description: "Custom SQL query string with named parameters"
2033
+ },
2034
+ params: {
2035
+ type: "object",
2036
+ additionalProperties: { type: ["string", "number", "boolean"] },
2037
+ description: "Optional parameters for SQL query"
2038
+ },
2039
+ // Common parameters
2040
+ limit: {
2041
+ type: "number",
2042
+ description: "Maximum number of results (default: 1000)"
2043
+ },
2044
+ format: {
2045
+ type: "string",
2046
+ enum: ["echarts", "raw"],
2047
+ description: "Response format (default: echarts)"
2048
+ }
2049
+ }
2050
+ }
2051
+ // Response schema temporarily removed - format not yet finalized
2052
+ // TODO: Add proper response schema once data format is confirmed
2053
+ };
2054
+
1844
2055
  // src/schemas/index.ts
1845
2056
  var getAllMemoryItemsSchema = {
1846
2057
  description: "Get all memory items for an assistant thread",
@@ -2302,8 +2513,8 @@ var sandboxService = new SandboxService();
2302
2513
 
2303
2514
  // src/controllers/sandbox.ts
2304
2515
  import { getSandBoxManager as getSandBoxManager2 } from "@axiom-lattice/core";
2305
- function getFilenameFromPath(path2) {
2306
- const segments = path2.replace(/\/+$/, "").split("/");
2516
+ function getFilenameFromPath(path3) {
2517
+ const segments = path3.replace(/\/+$/, "").split("/");
2307
2518
  return segments[segments.length - 1] || "download";
2308
2519
  }
2309
2520
  var EXT_TO_MIME = {
@@ -2355,10 +2566,10 @@ function registerSandboxProxyRoutes(app2) {
2355
2566
  const pathValue = pathEntry && typeof pathEntry === "object" && "value" in pathEntry ? String(pathEntry.value) : typeof pathEntry === "string" ? pathEntry : void 0;
2356
2567
  const formData = new FormData();
2357
2568
  formData.append("file", new Blob([buffer]), data.filename ?? "file");
2358
- const path2 = `/home/gem/uploads/${pathValue ? pathValue : ""}${data.filename}`;
2569
+ const path3 = `/home/gem/uploads/${pathValue ? pathValue : ""}${data.filename}`;
2359
2570
  const uploadResult = await sandbox.file.uploadFile({
2360
2571
  file: buffer,
2361
- path: path2
2572
+ path: path3
2362
2573
  });
2363
2574
  if (!uploadResult.ok) {
2364
2575
  return reply.status(502).send({ error: `Upload error: ${uploadResult.error}` });
@@ -2446,14 +2657,14 @@ function registerSandboxProxyRoutes(app2) {
2446
2657
  import * as fs from "fs/promises";
2447
2658
  import * as path from "path";
2448
2659
  import { Readable as Readable2 } from "stream";
2449
- import { getStoreLattice as getStoreLattice4 } from "@axiom-lattice/core";
2660
+ import { getStoreLattice as getStoreLattice5 } from "@axiom-lattice/core";
2450
2661
  import { SandboxFilesystem, FilesystemBackend } from "@axiom-lattice/core";
2451
2662
  import { getSandBoxManager as getSandBoxManager3 } from "@axiom-lattice/core";
2452
2663
  import { v4 as uuidv4 } from "uuid";
2453
2664
  var WorkspaceController = class {
2454
2665
  constructor() {
2455
- this.workspaceStore = getStoreLattice4("default", "workspace").store;
2456
- this.projectStore = getStoreLattice4("default", "project").store;
2666
+ this.workspaceStore = getStoreLattice5("default", "workspace").store;
2667
+ this.projectStore = getStoreLattice5("default", "project").store;
2457
2668
  }
2458
2669
  getTenantId(request) {
2459
2670
  const userTenantId = request.user?.tenantId;
@@ -2731,6 +2942,33 @@ var WorkspaceController = class {
2731
2942
  const webStream = body.stream();
2732
2943
  const nodeStream = Readable2.fromWeb(webStream);
2733
2944
  const contentType2 = body.contentType ?? inferredContentType;
2945
+ console.log(`[viewFile] Sandbox returned stream, contentType: ${contentType2}, filename: ${filename2}`);
2946
+ const isHtml2 = contentType2?.toLowerCase().includes("text/html") || filename2.toLowerCase().endsWith(".html") || filename2.toLowerCase().endsWith(".htm");
2947
+ if (isHtml2) {
2948
+ console.log(`[viewFile] HTML stream detected, collecting for context injection`);
2949
+ const chunks = [];
2950
+ for await (const chunk of nodeStream) {
2951
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
2952
+ }
2953
+ let content2 = Buffer.concat(chunks).toString("utf-8");
2954
+ const contextScript = `<script>window.__AI2APP_CONTEXT__=${JSON.stringify({
2955
+ tenantId,
2956
+ workspaceId,
2957
+ projectId,
2958
+ timestamp: Date.now()
2959
+ })};</script>`;
2960
+ if (content2.toLowerCase().includes("</head>")) {
2961
+ content2 = content2.replace(/<\/head>/i, `${contextScript}</head>`);
2962
+ console.log(`[viewFile] Context script injected before </head> (stream)`);
2963
+ } else if (content2.toLowerCase().includes("<html>")) {
2964
+ content2 = content2.replace(/<html>/i, `<html>${contextScript}`);
2965
+ console.log(`[viewFile] Context script injected after <html> (stream)`);
2966
+ } else {
2967
+ content2 = contextScript + content2;
2968
+ console.log(`[viewFile] Context script prepended to content (stream)`);
2969
+ }
2970
+ return reply.status(200).type(contentType2).header("Content-Disposition", "inline").send(Buffer.from(content2, "utf-8"));
2971
+ }
2734
2972
  return reply.status(200).type(contentType2).header("Content-Disposition", "inline").send(nodeStream);
2735
2973
  }
2736
2974
  const bodyUnknown = downloadResult.body;
@@ -2750,13 +2988,56 @@ var WorkspaceController = class {
2750
2988
  } else {
2751
2989
  return reply.status(502).send({ success: false, error: "Unexpected view response format" });
2752
2990
  }
2991
+ const isHtml = contentType?.toLowerCase().includes("text/html") || filename2.toLowerCase().endsWith(".html") || filename2.toLowerCase().endsWith(".htm");
2992
+ if (isHtml) {
2993
+ console.log(`[viewFile] Injecting AI2APP context for sandbox HTML file: ${filename2}, tenantId: ${tenantId}, contentType: ${contentType}`);
2994
+ let content2 = buf.toString("utf-8");
2995
+ const contextScript = `<script>window.__AI2APP_CONTEXT__=${JSON.stringify({
2996
+ tenantId,
2997
+ workspaceId,
2998
+ projectId,
2999
+ timestamp: Date.now()
3000
+ })};</script>`;
3001
+ if (content2.toLowerCase().includes("</head>")) {
3002
+ content2 = content2.replace(/<\/head>/i, `${contextScript}</head>`);
3003
+ console.log(`[viewFile] Context script injected before </head>`);
3004
+ } else if (content2.toLowerCase().includes("<html>")) {
3005
+ content2 = content2.replace(/<html>/i, `<html>${contextScript}`);
3006
+ console.log(`[viewFile] Context script injected after <html>`);
3007
+ } else {
3008
+ content2 = contextScript + content2;
3009
+ console.log(`[viewFile] Context script prepended to content`);
3010
+ }
3011
+ buf = Buffer.from(content2, "utf-8");
3012
+ }
2753
3013
  return reply.status(200).type(contentType).header("Content-Disposition", "inline").send(buf);
2754
3014
  }
2755
3015
  const { backend } = await this.getBackend(tenantId, workspaceId, projectId);
2756
3016
  const content = await backend.read(resolvedPath, 0, Infinity);
2757
3017
  const filename = this.getFilenameFromPath(resolvedPath);
2758
3018
  const mimeType = this.getMimeType(filename);
2759
- const buffer = Buffer.from(content, "utf-8");
3019
+ let finalContent = content;
3020
+ const isHtmlFs = mimeType?.toLowerCase().includes("text/html") || filename.toLowerCase().endsWith(".html") || filename.toLowerCase().endsWith(".htm");
3021
+ if (isHtmlFs) {
3022
+ console.log(`[viewFile] Injecting AI2APP context for filesystem HTML file: ${filename}, tenantId: ${tenantId}, mimeType: ${mimeType}`);
3023
+ const contextScript = `<script>window.__AI2APP_CONTEXT__=${JSON.stringify({
3024
+ tenantId,
3025
+ workspaceId,
3026
+ projectId,
3027
+ timestamp: Date.now()
3028
+ })};</script>`;
3029
+ if (content.toLowerCase().includes("</head>")) {
3030
+ finalContent = content.replace(/<\/head>/i, `${contextScript}</head>`);
3031
+ console.log(`[viewFile] Context script injected before </head>`);
3032
+ } else if (content.toLowerCase().includes("</html>")) {
3033
+ finalContent = content.replace(/<\/html>/i, `${contextScript}</html>`);
3034
+ console.log(`[viewFile] Context script injected before </html>`);
3035
+ } else {
3036
+ finalContent = content + contextScript;
3037
+ console.log(`[viewFile] Context script appended to content`);
3038
+ }
3039
+ }
3040
+ const buffer = Buffer.from(finalContent, "utf-8");
2760
3041
  return reply.status(200).type(mimeType).header("Content-Disposition", "inline").send(buffer);
2761
3042
  } catch (error) {
2762
3043
  const message = error instanceof Error ? error.message : String(error);
@@ -2766,17 +3047,17 @@ var WorkspaceController = class {
2766
3047
  async listPath(request) {
2767
3048
  const tenantId = this.getTenantId(request);
2768
3049
  const { workspaceId, projectId } = request.params;
2769
- const path2 = request.query.path || "/";
3050
+ const path3 = request.query.path || "/";
2770
3051
  const { backend } = await this.getBackend(tenantId, workspaceId, projectId);
2771
- const files = await backend.lsInfo(path2);
3052
+ const files = await backend.lsInfo(path3);
2772
3053
  return { success: true, data: files };
2773
3054
  }
2774
3055
  async readFile(request) {
2775
3056
  const tenantId = this.getTenantId(request);
2776
3057
  const { workspaceId, projectId } = request.params;
2777
- const { path: path2, offset = 0, limit = 1e3 } = request.query;
3058
+ const { path: path3, offset = 0, limit = 1e3 } = request.query;
2778
3059
  const { backend } = await this.getBackend(tenantId, workspaceId, projectId);
2779
- const content = await backend.read(path2, Number(offset), Number(limit));
3060
+ const content = await backend.read(path3, Number(offset), Number(limit));
2780
3061
  return { success: true, data: { content, offset, limit } };
2781
3062
  }
2782
3063
  /**
@@ -2919,11 +3200,11 @@ function registerWorkspaceRoutes(app2) {
2919
3200
 
2920
3201
  // src/controllers/database-configs.ts
2921
3202
  import {
2922
- getStoreLattice as getStoreLattice5,
3203
+ getStoreLattice as getStoreLattice6,
2923
3204
  sqlDatabaseManager
2924
3205
  } from "@axiom-lattice/core";
2925
3206
  import { randomUUID as randomUUID3 } from "crypto";
2926
- function getTenantId5(request) {
3207
+ function getTenantId6(request) {
2927
3208
  const userTenantId = request.user?.tenantId;
2928
3209
  if (userTenantId) {
2929
3210
  return userTenantId;
@@ -2931,9 +3212,9 @@ function getTenantId5(request) {
2931
3212
  return request.headers["x-tenant-id"] || "default";
2932
3213
  }
2933
3214
  async function getDatabaseConfigList(request, reply) {
2934
- const tenantId = getTenantId5(request);
3215
+ const tenantId = getTenantId6(request);
2935
3216
  try {
2936
- const storeLattice = getStoreLattice5("default", "database");
3217
+ const storeLattice = getStoreLattice6("default", "database");
2937
3218
  const store = storeLattice.store;
2938
3219
  const configs = await store.getAllConfigs(tenantId);
2939
3220
  console.log("Backend: getAllConfigs returned:", configs);
@@ -2961,10 +3242,10 @@ async function getDatabaseConfigList(request, reply) {
2961
3242
  }
2962
3243
  }
2963
3244
  async function getDatabaseConfig(request, reply) {
2964
- const tenantId = getTenantId5(request);
3245
+ const tenantId = getTenantId6(request);
2965
3246
  const { key } = request.params;
2966
3247
  try {
2967
- const storeLattice = getStoreLattice5("default", "database");
3248
+ const storeLattice = getStoreLattice6("default", "database");
2968
3249
  const store = storeLattice.store;
2969
3250
  const config = await store.getConfigByKey(tenantId, key);
2970
3251
  if (!config) {
@@ -2987,10 +3268,10 @@ async function getDatabaseConfig(request, reply) {
2987
3268
  }
2988
3269
  }
2989
3270
  async function createDatabaseConfig(request, reply) {
2990
- const tenantId = getTenantId5(request);
3271
+ const tenantId = getTenantId6(request);
2991
3272
  const body = request.body;
2992
3273
  try {
2993
- const storeLattice = getStoreLattice5("default", "database");
3274
+ const storeLattice = getStoreLattice6("default", "database");
2994
3275
  const store = storeLattice.store;
2995
3276
  const existing = await store.getConfigByKey(tenantId, body.key);
2996
3277
  if (existing) {
@@ -3022,11 +3303,11 @@ async function createDatabaseConfig(request, reply) {
3022
3303
  }
3023
3304
  }
3024
3305
  async function updateDatabaseConfig(request, reply) {
3025
- const tenantId = getTenantId5(request);
3306
+ const tenantId = getTenantId6(request);
3026
3307
  const { key } = request.params;
3027
3308
  const updates = request.body;
3028
3309
  try {
3029
- const storeLattice = getStoreLattice5("default", "database");
3310
+ const storeLattice = getStoreLattice6("default", "database");
3030
3311
  const store = storeLattice.store;
3031
3312
  const existing = await store.getConfigByKey(tenantId, key);
3032
3313
  if (!existing) {
@@ -3064,10 +3345,10 @@ async function updateDatabaseConfig(request, reply) {
3064
3345
  }
3065
3346
  }
3066
3347
  async function deleteDatabaseConfig(request, reply) {
3067
- const tenantId = getTenantId5(request);
3348
+ const tenantId = getTenantId6(request);
3068
3349
  const { keyOrId } = request.params;
3069
3350
  try {
3070
- const storeLattice = getStoreLattice5("default", "database");
3351
+ const storeLattice = getStoreLattice6("default", "database");
3071
3352
  const store = storeLattice.store;
3072
3353
  console.log("Delete request - keyOrId:", keyOrId);
3073
3354
  let config = await store.getConfigByKey(tenantId, keyOrId);
@@ -3113,10 +3394,10 @@ async function deleteDatabaseConfig(request, reply) {
3113
3394
  }
3114
3395
  }
3115
3396
  async function testDatabaseConnection(request, reply) {
3116
- const tenantId = getTenantId5(request);
3397
+ const tenantId = getTenantId6(request);
3117
3398
  const { key } = request.params;
3118
3399
  try {
3119
- const storeLattice = getStoreLattice5("default", "database");
3400
+ const storeLattice = getStoreLattice6("default", "database");
3120
3401
  const store = storeLattice.store;
3121
3402
  const config = await store.getConfigByKey(tenantId, key);
3122
3403
  if (!config) {
@@ -3201,12 +3482,12 @@ function registerDatabaseConfigRoutes(app2) {
3201
3482
 
3202
3483
  // src/controllers/metrics-configs.ts
3203
3484
  import {
3204
- getStoreLattice as getStoreLattice6,
3205
- metricsServerManager,
3206
- SemanticMetricsClient
3485
+ getStoreLattice as getStoreLattice7,
3486
+ metricsServerManager as metricsServerManager2,
3487
+ SemanticMetricsClient as SemanticMetricsClient2
3207
3488
  } from "@axiom-lattice/core";
3208
3489
  import { randomUUID as randomUUID4 } from "crypto";
3209
- function getTenantId6(request) {
3490
+ function getTenantId7(request) {
3210
3491
  const userTenantId = request.user?.tenantId;
3211
3492
  if (userTenantId) {
3212
3493
  return userTenantId;
@@ -3214,9 +3495,9 @@ function getTenantId6(request) {
3214
3495
  return request.headers["x-tenant-id"] || "default";
3215
3496
  }
3216
3497
  async function getMetricsServerConfigList(request, reply) {
3217
- const tenantId = getTenantId6(request);
3498
+ const tenantId = getTenantId7(request);
3218
3499
  try {
3219
- const storeLattice = getStoreLattice6("default", "metrics");
3500
+ const storeLattice = getStoreLattice7("default", "metrics");
3220
3501
  const store = storeLattice.store;
3221
3502
  const configs = await store.getAllConfigs(tenantId);
3222
3503
  return {
@@ -3240,10 +3521,10 @@ async function getMetricsServerConfigList(request, reply) {
3240
3521
  }
3241
3522
  }
3242
3523
  async function getMetricsServerConfig(request, reply) {
3243
- const tenantId = getTenantId6(request);
3524
+ const tenantId = getTenantId7(request);
3244
3525
  const { key } = request.params;
3245
3526
  try {
3246
- const storeLattice = getStoreLattice6("default", "metrics");
3527
+ const storeLattice = getStoreLattice7("default", "metrics");
3247
3528
  const store = storeLattice.store;
3248
3529
  const config = await store.getConfigByKey(tenantId, key);
3249
3530
  if (!config) {
@@ -3266,10 +3547,10 @@ async function getMetricsServerConfig(request, reply) {
3266
3547
  }
3267
3548
  }
3268
3549
  async function createMetricsServerConfig(request, reply) {
3269
- const tenantId = getTenantId6(request);
3550
+ const tenantId = getTenantId7(request);
3270
3551
  const body = request.body;
3271
3552
  try {
3272
- const storeLattice = getStoreLattice6("default", "metrics");
3553
+ const storeLattice = getStoreLattice7("default", "metrics");
3273
3554
  const store = storeLattice.store;
3274
3555
  const existing = await store.getConfigByKey(tenantId, body.key);
3275
3556
  if (existing) {
@@ -3298,7 +3579,7 @@ async function createMetricsServerConfig(request, reply) {
3298
3579
  };
3299
3580
  const config = await store.createConfig(tenantId, id, configData);
3300
3581
  try {
3301
- metricsServerManager.registerServer(tenantId, config.key, config.config);
3582
+ metricsServerManager2.registerServer(tenantId, config.key, config.config);
3302
3583
  } catch (error) {
3303
3584
  console.warn("Failed to auto-register metrics server:", error);
3304
3585
  }
@@ -3317,11 +3598,11 @@ async function createMetricsServerConfig(request, reply) {
3317
3598
  }
3318
3599
  }
3319
3600
  async function updateMetricsServerConfig(request, reply) {
3320
- const tenantId = getTenantId6(request);
3601
+ const tenantId = getTenantId7(request);
3321
3602
  const { key } = request.params;
3322
3603
  const updates = request.body;
3323
3604
  try {
3324
- const storeLattice = getStoreLattice6("default", "metrics");
3605
+ const storeLattice = getStoreLattice7("default", "metrics");
3325
3606
  const store = storeLattice.store;
3326
3607
  const existing = await store.getConfigByKey(tenantId, key);
3327
3608
  if (!existing) {
@@ -3349,7 +3630,7 @@ async function updateMetricsServerConfig(request, reply) {
3349
3630
  }
3350
3631
  if (updates.config) {
3351
3632
  try {
3352
- metricsServerManager.registerServer(tenantId, updated.key, updated.config);
3633
+ metricsServerManager2.registerServer(tenantId, updated.key, updated.config);
3353
3634
  } catch (error) {
3354
3635
  console.warn("Failed to re-register metrics server:", error);
3355
3636
  }
@@ -3368,10 +3649,10 @@ async function updateMetricsServerConfig(request, reply) {
3368
3649
  }
3369
3650
  }
3370
3651
  async function deleteMetricsServerConfig(request, reply) {
3371
- const tenantId = getTenantId6(request);
3652
+ const tenantId = getTenantId7(request);
3372
3653
  const { keyOrId } = request.params;
3373
3654
  try {
3374
- const storeLattice = getStoreLattice6("default", "metrics");
3655
+ const storeLattice = getStoreLattice7("default", "metrics");
3375
3656
  const store = storeLattice.store;
3376
3657
  let config = await store.getConfigByKey(tenantId, keyOrId);
3377
3658
  let configKey = keyOrId;
@@ -3396,8 +3677,8 @@ async function deleteMetricsServerConfig(request, reply) {
3396
3677
  };
3397
3678
  }
3398
3679
  try {
3399
- if (metricsServerManager.hasServer(tenantId, configKey)) {
3400
- metricsServerManager.removeServer(tenantId, configKey);
3680
+ if (metricsServerManager2.hasServer(tenantId, configKey)) {
3681
+ metricsServerManager2.removeServer(tenantId, configKey);
3401
3682
  }
3402
3683
  } catch (error) {
3403
3684
  console.warn("Failed to remove from MetricsServerManager:", error);
@@ -3415,10 +3696,10 @@ async function deleteMetricsServerConfig(request, reply) {
3415
3696
  }
3416
3697
  }
3417
3698
  async function testMetricsServerConnection(request, reply) {
3418
- const tenantId = getTenantId6(request);
3699
+ const tenantId = getTenantId7(request);
3419
3700
  const { key } = request.params;
3420
3701
  try {
3421
- const storeLattice = getStoreLattice6("default", "metrics");
3702
+ const storeLattice = getStoreLattice7("default", "metrics");
3422
3703
  const store = storeLattice.store;
3423
3704
  const config = await store.getConfigByKey(tenantId, key);
3424
3705
  if (!config) {
@@ -3429,11 +3710,11 @@ async function testMetricsServerConnection(request, reply) {
3429
3710
  };
3430
3711
  }
3431
3712
  const testKey = `__test_${key}_${Date.now()}`;
3432
- metricsServerManager.registerServer(tenantId, testKey, config.config);
3713
+ metricsServerManager2.registerServer(tenantId, testKey, config.config);
3433
3714
  try {
3434
- const client = metricsServerManager.getClient(tenantId, testKey);
3715
+ const client = metricsServerManager2.getClient(tenantId, testKey);
3435
3716
  const result = await client.testConnection();
3436
- metricsServerManager.removeServer(tenantId, testKey);
3717
+ metricsServerManager2.removeServer(tenantId, testKey);
3437
3718
  return {
3438
3719
  success: true,
3439
3720
  message: result.connected ? "Connection test successful" : "Connection test failed",
@@ -3441,7 +3722,7 @@ async function testMetricsServerConnection(request, reply) {
3441
3722
  };
3442
3723
  } catch (error) {
3443
3724
  try {
3444
- metricsServerManager.removeServer(tenantId, testKey);
3725
+ metricsServerManager2.removeServer(tenantId, testKey);
3445
3726
  } catch {
3446
3727
  }
3447
3728
  return {
@@ -3466,10 +3747,10 @@ async function testMetricsServerConnection(request, reply) {
3466
3747
  }
3467
3748
  }
3468
3749
  async function listAvailableMetrics(request, reply) {
3469
- const tenantId = getTenantId6(request);
3750
+ const tenantId = getTenantId7(request);
3470
3751
  const { key } = request.params;
3471
3752
  try {
3472
- const storeLattice = getStoreLattice6("default", "metrics");
3753
+ const storeLattice = getStoreLattice7("default", "metrics");
3473
3754
  const store = storeLattice.store;
3474
3755
  const config = await store.getConfigByKey(tenantId, key);
3475
3756
  if (!config) {
@@ -3479,10 +3760,10 @@ async function listAvailableMetrics(request, reply) {
3479
3760
  message: "Metrics server configuration not found"
3480
3761
  };
3481
3762
  }
3482
- if (!metricsServerManager.hasServer(tenantId, key)) {
3483
- metricsServerManager.registerServer(tenantId, key, config.config);
3763
+ if (!metricsServerManager2.hasServer(tenantId, key)) {
3764
+ metricsServerManager2.registerServer(tenantId, key, config.config);
3484
3765
  }
3485
- const client = metricsServerManager.getClient(tenantId, key);
3766
+ const client = metricsServerManager2.getClient(tenantId, key);
3486
3767
  const metrics = await client.listMetrics();
3487
3768
  return {
3488
3769
  success: true,
@@ -3504,11 +3785,11 @@ async function listAvailableMetrics(request, reply) {
3504
3785
  }
3505
3786
  }
3506
3787
  async function queryMetricsData(request, reply) {
3507
- const tenantId = getTenantId6(request);
3788
+ const tenantId = getTenantId7(request);
3508
3789
  const { key } = request.params;
3509
3790
  const { metricName, startTime, endTime, step, labels } = request.body;
3510
3791
  try {
3511
- const storeLattice = getStoreLattice6("default", "metrics");
3792
+ const storeLattice = getStoreLattice7("default", "metrics");
3512
3793
  const store = storeLattice.store;
3513
3794
  const config = await store.getConfigByKey(tenantId, key);
3514
3795
  if (!config) {
@@ -3525,10 +3806,10 @@ async function queryMetricsData(request, reply) {
3525
3806
  message: "metricName is required"
3526
3807
  };
3527
3808
  }
3528
- if (!metricsServerManager.hasServer(tenantId, key)) {
3529
- metricsServerManager.registerServer(tenantId, key, config.config);
3809
+ if (!metricsServerManager2.hasServer(tenantId, key)) {
3810
+ metricsServerManager2.registerServer(tenantId, key, config.config);
3530
3811
  }
3531
- const client = metricsServerManager.getClient(tenantId, key);
3812
+ const client = metricsServerManager2.getClient(tenantId, key);
3532
3813
  const result = await client.queryMetricData(metricName, {
3533
3814
  startTime,
3534
3815
  endTime,
@@ -3552,10 +3833,10 @@ async function queryMetricsData(request, reply) {
3552
3833
  }
3553
3834
  }
3554
3835
  async function getDataSources(request, reply) {
3555
- const tenantId = getTenantId6(request);
3836
+ const tenantId = getTenantId7(request);
3556
3837
  const { key } = request.params;
3557
3838
  try {
3558
- const storeLattice = getStoreLattice6("default", "metrics");
3839
+ const storeLattice = getStoreLattice7("default", "metrics");
3559
3840
  const store = storeLattice.store;
3560
3841
  const config = await store.getConfigByKey(tenantId, key);
3561
3842
  if (!config) {
@@ -3573,7 +3854,7 @@ async function getDataSources(request, reply) {
3573
3854
  };
3574
3855
  }
3575
3856
  const semanticConfig = config.config;
3576
- const client = new SemanticMetricsClient(semanticConfig);
3857
+ const client = new SemanticMetricsClient2(semanticConfig);
3577
3858
  const allDatasources = await client.getDataSources();
3578
3859
  const selectedIds = semanticConfig.selectedDataSources || [];
3579
3860
  const filteredDatasources = selectedIds.length > 0 ? allDatasources.filter((ds) => selectedIds.includes(String(ds.id))) : allDatasources;
@@ -3593,10 +3874,10 @@ async function getDataSources(request, reply) {
3593
3874
  }
3594
3875
  }
3595
3876
  async function getDatasourceMetrics(request, reply) {
3596
- const tenantId = getTenantId6(request);
3877
+ const tenantId = getTenantId7(request);
3597
3878
  const { key, datasourceId } = request.params;
3598
3879
  try {
3599
- const storeLattice = getStoreLattice6("default", "metrics");
3880
+ const storeLattice = getStoreLattice7("default", "metrics");
3600
3881
  const store = storeLattice.store;
3601
3882
  const config = await store.getConfigByKey(tenantId, key);
3602
3883
  if (!config) {
@@ -3614,7 +3895,7 @@ async function getDatasourceMetrics(request, reply) {
3614
3895
  };
3615
3896
  }
3616
3897
  const semanticConfig = config.config;
3617
- const client = new SemanticMetricsClient(semanticConfig);
3898
+ const client = new SemanticMetricsClient2(semanticConfig);
3618
3899
  const metrics = await client.getDatasourceMetrics(datasourceId);
3619
3900
  return {
3620
3901
  success: true,
@@ -3630,11 +3911,11 @@ async function getDatasourceMetrics(request, reply) {
3630
3911
  }
3631
3912
  }
3632
3913
  async function querySemanticMetrics(request, reply) {
3633
- const tenantId = getTenantId6(request);
3914
+ const tenantId = getTenantId7(request);
3634
3915
  const { key } = request.params;
3635
3916
  const body = request.body;
3636
3917
  try {
3637
- const storeLattice = getStoreLattice6("default", "metrics");
3918
+ const storeLattice = getStoreLattice7("default", "metrics");
3638
3919
  const store = storeLattice.store;
3639
3920
  const config = await store.getConfigByKey(tenantId, key);
3640
3921
  if (!config) {
@@ -3659,33 +3940,37 @@ async function querySemanticMetrics(request, reply) {
3659
3940
  };
3660
3941
  }
3661
3942
  const semanticConfig = config.config;
3662
- const client = new SemanticMetricsClient(semanticConfig);
3943
+ const client = new SemanticMetricsClient2(semanticConfig);
3663
3944
  const result = await client.semanticQuery(body);
3945
+ const columnNames = result.columns.map((col) => col.name);
3664
3946
  const allDataPoints = [];
3665
- const metricNames = [];
3666
- for (const metricResult of result.results) {
3667
- metricNames.push(metricResult.metricName);
3668
- for (const row of metricResult.rows) {
3669
- allDataPoints.push({
3670
- timestamp: row.timestamp ? new Date(row.timestamp).getTime() : void 0,
3671
- value: typeof row.value === "number" ? row.value : 0,
3672
- metricName: metricResult.metricName,
3673
- labels: Object.fromEntries(
3674
- Object.entries(row).filter(([k]) => k !== "value" && k !== "timestamp").map(([k, v]) => [k, String(v)])
3675
- )
3676
- });
3677
- }
3947
+ const timestampColIdx = columnNames.findIndex(
3948
+ (col) => col.toLowerCase().includes("date") || col.toLowerCase().includes("time")
3949
+ );
3950
+ const valueColIdx = columnNames.findIndex(
3951
+ (col) => col.toLowerCase().includes("value") || col.toLowerCase().includes("rate") || col.toLowerCase().includes("amt")
3952
+ );
3953
+ for (const row of result.rows) {
3954
+ const timestamp = timestampColIdx >= 0 ? row[timestampColIdx] : void 0;
3955
+ const value = valueColIdx >= 0 ? row[valueColIdx] : row[row.length - 1];
3956
+ allDataPoints.push({
3957
+ timestamp: timestamp ? new Date(String(timestamp)).getTime() : void 0,
3958
+ value: typeof value === "number" ? value : Number(value) || 0,
3959
+ labels: Object.fromEntries(
3960
+ columnNames.map((col, idx) => [col, String(row[idx] ?? "")])
3961
+ )
3962
+ });
3678
3963
  }
3679
3964
  return {
3680
3965
  success: true,
3681
3966
  message: "Semantic query executed successfully",
3682
3967
  data: {
3683
- datasourceId: result.datasourceId,
3684
- metrics: metricNames,
3968
+ semanticModel: result.semanticModel,
3969
+ columns: columnNames,
3685
3970
  dataPoints: allDataPoints,
3686
3971
  metadata: {
3687
- rowCount: allDataPoints.length,
3688
- queryTimeMs: result.totalExecutionTimeMs
3972
+ rowCount: result.rows.length,
3973
+ columnCount: result.columns.length
3689
3974
  }
3690
3975
  }
3691
3976
  };
@@ -3715,7 +4000,7 @@ async function testSemanticDataSources(request, reply) {
3715
4000
  password: body.password,
3716
4001
  headers: body.headers
3717
4002
  };
3718
- const client = new SemanticMetricsClient(testConfig);
4003
+ const client = new SemanticMetricsClient2(testConfig);
3719
4004
  const datasources = await client.getDataSources();
3720
4005
  return {
3721
4006
  success: true,
@@ -3751,7 +4036,7 @@ async function testDatasourceMetrics(request, reply) {
3751
4036
  password: body.password,
3752
4037
  headers: body.headers
3753
4038
  };
3754
- const client = new SemanticMetricsClient(testConfig);
4039
+ const client = new SemanticMetricsClient2(testConfig);
3755
4040
  const metrics = await client.getDatasourceMetrics(datasourceId);
3756
4041
  return {
3757
4042
  success: true,
@@ -3784,12 +4069,12 @@ function registerMetricsServerConfigRoutes(app2) {
3784
4069
 
3785
4070
  // src/controllers/mcp-configs.ts
3786
4071
  import {
3787
- getStoreLattice as getStoreLattice7,
4072
+ getStoreLattice as getStoreLattice8,
3788
4073
  mcpManager,
3789
4074
  toolLatticeManager as toolLatticeManager2
3790
4075
  } from "@axiom-lattice/core";
3791
4076
  import { randomUUID as randomUUID5 } from "crypto";
3792
- function getTenantId7(request) {
4077
+ function getTenantId8(request) {
3793
4078
  const userTenantId = request.user?.tenantId;
3794
4079
  if (userTenantId) {
3795
4080
  return userTenantId;
@@ -3797,9 +4082,9 @@ function getTenantId7(request) {
3797
4082
  return request.headers["x-tenant-id"] || "default";
3798
4083
  }
3799
4084
  async function getMcpServerConfigList(request, reply) {
3800
- const tenantId = getTenantId7(request);
4085
+ const tenantId = getTenantId8(request);
3801
4086
  try {
3802
- const storeLattice = getStoreLattice7("default", "mcp");
4087
+ const storeLattice = getStoreLattice8("default", "mcp");
3803
4088
  const store = storeLattice.store;
3804
4089
  const configs = await store.getAllConfigs(tenantId);
3805
4090
  return {
@@ -3823,10 +4108,10 @@ async function getMcpServerConfigList(request, reply) {
3823
4108
  }
3824
4109
  }
3825
4110
  async function getMcpServerConfig(request, reply) {
3826
- const tenantId = getTenantId7(request);
4111
+ const tenantId = getTenantId8(request);
3827
4112
  const { key } = request.params;
3828
4113
  try {
3829
- const storeLattice = getStoreLattice7("default", "mcp");
4114
+ const storeLattice = getStoreLattice8("default", "mcp");
3830
4115
  const store = storeLattice.store;
3831
4116
  const config = await store.getConfigByKey(tenantId, key);
3832
4117
  if (!config) {
@@ -3849,10 +4134,10 @@ async function getMcpServerConfig(request, reply) {
3849
4134
  }
3850
4135
  }
3851
4136
  async function createMcpServerConfig(request, reply) {
3852
- const tenantId = getTenantId7(request);
4137
+ const tenantId = getTenantId8(request);
3853
4138
  const body = request.body;
3854
4139
  try {
3855
- const storeLattice = getStoreLattice7("default", "mcp");
4140
+ const storeLattice = getStoreLattice8("default", "mcp");
3856
4141
  const store = storeLattice.store;
3857
4142
  const existing = await store.getConfigByKey(tenantId, body.key);
3858
4143
  if (existing) {
@@ -3888,11 +4173,11 @@ async function createMcpServerConfig(request, reply) {
3888
4173
  }
3889
4174
  }
3890
4175
  async function updateMcpServerConfig(request, reply) {
3891
- const tenantId = getTenantId7(request);
4176
+ const tenantId = getTenantId8(request);
3892
4177
  const { key } = request.params;
3893
4178
  const updates = request.body;
3894
4179
  try {
3895
- const storeLattice = getStoreLattice7("default", "mcp");
4180
+ const storeLattice = getStoreLattice8("default", "mcp");
3896
4181
  const store = storeLattice.store;
3897
4182
  const existing = await store.getConfigByKey(tenantId, key);
3898
4183
  if (!existing) {
@@ -3938,10 +4223,10 @@ async function updateMcpServerConfig(request, reply) {
3938
4223
  }
3939
4224
  }
3940
4225
  async function deleteMcpServerConfig(request, reply) {
3941
- const tenantId = getTenantId7(request);
4226
+ const tenantId = getTenantId8(request);
3942
4227
  const { keyOrId } = request.params;
3943
4228
  try {
3944
- const storeLattice = getStoreLattice7("default", "mcp");
4229
+ const storeLattice = getStoreLattice8("default", "mcp");
3945
4230
  const store = storeLattice.store;
3946
4231
  let config = await store.getConfigByKey(tenantId, keyOrId);
3947
4232
  let configKey = keyOrId;
@@ -3985,10 +4270,10 @@ async function deleteMcpServerConfig(request, reply) {
3985
4270
  }
3986
4271
  }
3987
4272
  async function testMcpServerConnection(request, reply) {
3988
- const tenantId = getTenantId7(request);
4273
+ const tenantId = getTenantId8(request);
3989
4274
  const { key } = request.params;
3990
4275
  try {
3991
- const storeLattice = getStoreLattice7("default", "mcp");
4276
+ const storeLattice = getStoreLattice8("default", "mcp");
3992
4277
  const store = storeLattice.store;
3993
4278
  const config = await store.getConfigByKey(tenantId, key);
3994
4279
  if (!config) {
@@ -4038,10 +4323,10 @@ async function testMcpServerConnection(request, reply) {
4038
4323
  }
4039
4324
  }
4040
4325
  async function listMcpServerTools(request, reply) {
4041
- const tenantId = getTenantId7(request);
4326
+ const tenantId = getTenantId8(request);
4042
4327
  const { key } = request.params;
4043
4328
  try {
4044
- const storeLattice = getStoreLattice7("default", "mcp");
4329
+ const storeLattice = getStoreLattice8("default", "mcp");
4045
4330
  const store = storeLattice.store;
4046
4331
  const config = await store.getConfigByKey(tenantId, key);
4047
4332
  if (!config) {
@@ -4071,10 +4356,10 @@ async function listMcpServerTools(request, reply) {
4071
4356
  }
4072
4357
  }
4073
4358
  async function connectMcpServer(request, reply) {
4074
- const tenantId = getTenantId7(request);
4359
+ const tenantId = getTenantId8(request);
4075
4360
  const { key } = request.params;
4076
4361
  try {
4077
- const storeLattice = getStoreLattice7("default", "mcp");
4362
+ const storeLattice = getStoreLattice8("default", "mcp");
4078
4363
  const store = storeLattice.store;
4079
4364
  const config = await store.getConfigByKey(tenantId, key);
4080
4365
  if (!config) {
@@ -4095,7 +4380,7 @@ async function connectMcpServer(request, reply) {
4095
4380
  };
4096
4381
  } catch (error) {
4097
4382
  console.error("Failed to connect MCP server:", error);
4098
- const storeLattice = getStoreLattice7("default", "mcp");
4383
+ const storeLattice = getStoreLattice8("default", "mcp");
4099
4384
  const store = storeLattice.store;
4100
4385
  const config = await store.getConfigByKey(tenantId, key);
4101
4386
  if (config) {
@@ -4108,10 +4393,10 @@ async function connectMcpServer(request, reply) {
4108
4393
  }
4109
4394
  }
4110
4395
  async function disconnectMcpServer(request, reply) {
4111
- const tenantId = getTenantId7(request);
4396
+ const tenantId = getTenantId8(request);
4112
4397
  const { key } = request.params;
4113
4398
  try {
4114
- const storeLattice = getStoreLattice7("default", "mcp");
4399
+ const storeLattice = getStoreLattice8("default", "mcp");
4115
4400
  const store = storeLattice.store;
4116
4401
  const config = await store.getConfigByKey(tenantId, key);
4117
4402
  if (!config) {
@@ -4216,11 +4501,11 @@ function registerMcpServerConfigRoutes(app2) {
4216
4501
  }
4217
4502
 
4218
4503
  // src/controllers/users.ts
4219
- import { getStoreLattice as getStoreLattice8 } from "@axiom-lattice/core";
4504
+ import { getStoreLattice as getStoreLattice9 } from "@axiom-lattice/core";
4220
4505
  import { v4 as uuidv42 } from "uuid";
4221
4506
  var UsersController = class {
4222
4507
  constructor() {
4223
- this.userStore = getStoreLattice8("default", "user").store;
4508
+ this.userStore = getStoreLattice9("default", "user").store;
4224
4509
  }
4225
4510
  async listUsers(request, reply) {
4226
4511
  const { email } = request.query;
@@ -4298,11 +4583,11 @@ function registerUserRoutes(app2) {
4298
4583
  }
4299
4584
 
4300
4585
  // src/controllers/tenants.ts
4301
- import { getStoreLattice as getStoreLattice9 } from "@axiom-lattice/core";
4586
+ import { getStoreLattice as getStoreLattice10 } from "@axiom-lattice/core";
4302
4587
  import { v4 as uuidv43 } from "uuid";
4303
4588
  var TenantsController = class {
4304
4589
  constructor() {
4305
- this.tenantStore = getStoreLattice9("default", "tenant").store;
4590
+ this.tenantStore = getStoreLattice10("default", "tenant").store;
4306
4591
  }
4307
4592
  // ==================== Tenant CRUD ====================
4308
4593
  async listTenants(request, reply) {
@@ -4366,7 +4651,7 @@ function registerTenantRoutes(app2) {
4366
4651
  }
4367
4652
 
4368
4653
  // src/controllers/auth.ts
4369
- import { getStoreLattice as getStoreLattice10 } from "@axiom-lattice/core";
4654
+ import { getStoreLattice as getStoreLattice11 } from "@axiom-lattice/core";
4370
4655
  import { v4 as uuidv44 } from "uuid";
4371
4656
  var defaultAuthConfig = {
4372
4657
  autoApproveUsers: true,
@@ -4375,9 +4660,9 @@ var defaultAuthConfig = {
4375
4660
  };
4376
4661
  var AuthController = class {
4377
4662
  constructor(config = {}) {
4378
- this.userStore = getStoreLattice10("default", "user").store;
4379
- this.tenantStore = getStoreLattice10("default", "tenant").store;
4380
- this.userTenantLinkStore = getStoreLattice10("default", "userTenantLink").store;
4663
+ this.userStore = getStoreLattice11("default", "user").store;
4664
+ this.tenantStore = getStoreLattice11("default", "tenant").store;
4665
+ this.userTenantLinkStore = getStoreLattice11("default", "userTenantLink").store;
4381
4666
  this.config = { ...defaultAuthConfig, ...config };
4382
4667
  }
4383
4668
  async register(request, reply) {
@@ -4814,6 +5099,11 @@ var registerLatticeRoutes = (app2) => {
4814
5099
  registerWorkspaceRoutes(app2);
4815
5100
  registerDatabaseConfigRoutes(app2);
4816
5101
  registerMetricsServerConfigRoutes(app2);
5102
+ app2.post(
5103
+ "/api/data/query",
5104
+ { schema: dataQuerySchema },
5105
+ executeDataQuery
5106
+ );
4817
5107
  registerMcpServerConfigRoutes(app2);
4818
5108
  registerUserRoutes(app2);
4819
5109
  registerTenantRoutes(app2);
@@ -4915,7 +5205,9 @@ var handleAgentTask = async (taskRequest, retryCount = 0) => {
4915
5205
  }),
4916
5206
  headers: {
4917
5207
  "Content-Type": "application/json",
4918
- "x-tenant-id": tenant_id
5208
+ "x-tenant-id": tenant_id,
5209
+ "x-workspace-id": runConfig?.workspaceId,
5210
+ "x-project-id": runConfig?.projectId
4919
5211
  }
4920
5212
  }).catch((err) => {
4921
5213
  console.error(`fetch\u8BF7\u6C42\u5931\u8D25: ${err.message || String(err)}`);
@@ -5248,6 +5540,10 @@ app.register(multipart, {
5248
5540
  }
5249
5541
  });
5250
5542
  app.register(websocket);
5543
+ app.register(staticPlugin, {
5544
+ root: path2.join(__dirname, "../public"),
5545
+ prefix: "/"
5546
+ });
5251
5547
  app.setErrorHandler((error, request, reply) => {
5252
5548
  const getHeaderValue = (header) => {
5253
5549
  if (Array.isArray(header)) {
@@ -5286,6 +5582,7 @@ var start = async (config) => {
5286
5582
  logger = loggerLattice.client;
5287
5583
  }
5288
5584
  app.decorate("loggerLattice", loggerLattice);
5585
+ registerLatticeRoutes(app);
5289
5586
  if (!sandboxLatticeManager2.hasLattice("default")) {
5290
5587
  const sandboxBaseURL = process.env.SANDBOX_BASE_URL || "http://localhost:8080";
5291
5588
  sandboxLatticeManager2.registerLattice("default", {