@axiom-lattice/core 2.1.33 → 2.1.35

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
@@ -527,7 +527,7 @@ var ModelLattice = class extends import_chat_models.BaseChatModel {
527
527
  streaming: config.streaming
528
528
  });
529
529
  } else if (config.provider === "deepseek") {
530
- return new import_deepseek.ChatDeepSeek({
530
+ const deepseek = new import_deepseek.ChatDeepSeek({
531
531
  model: config.model,
532
532
  temperature: config.temperature || 0,
533
533
  maxTokens: config.maxTokens,
@@ -535,10 +535,12 @@ var ModelLattice = class extends import_chat_models.BaseChatModel {
535
535
  maxRetries: config.maxRetries || 2,
536
536
  apiKey: config.apiKey || process.env[config.apiKeyEnvName || "DEEPSEEK_API_KEY"],
537
537
  streaming: config.streaming,
538
+ enable_thinking: true,
538
539
  configuration: {
539
540
  baseURL: config.baseURL
540
541
  }
541
542
  });
543
+ return deepseek;
542
544
  } else if (config.provider === "siliconcloud") {
543
545
  return new import_openai.ChatOpenAI({
544
546
  model: config.model,
@@ -1621,6 +1623,37 @@ ${databaseKeys.map(
1621
1623
  );
1622
1624
  };
1623
1625
 
1626
+ // src/tool_lattice/metrics/utils.ts
1627
+ function getTenantIdFromConfig2(exeConfig, getTenantId) {
1628
+ const runConfig = exeConfig?.configurable?.runConfig || {};
1629
+ return runConfig.tenantId || (getTenantId ? getTenantId() : "default");
1630
+ }
1631
+ function filterServerKeysByTenant(serverKeys, tenantId, manager = metricsServerManager) {
1632
+ return serverKeys.filter((key) => {
1633
+ return manager.hasServer(tenantId, key);
1634
+ });
1635
+ }
1636
+ function arrayRowsToObjectRows(rows, columns) {
1637
+ if (!rows || rows.length === 0) {
1638
+ return [];
1639
+ }
1640
+ return rows.map((row) => {
1641
+ const obj = {};
1642
+ columns.forEach((col, index) => {
1643
+ obj[col.name] = row[index];
1644
+ });
1645
+ return obj;
1646
+ });
1647
+ }
1648
+ function objectRowsToArrayRows(rows, columns) {
1649
+ if (!rows || rows.length === 0) {
1650
+ return [];
1651
+ }
1652
+ return rows.map(
1653
+ (row) => columns.map((col) => row[col])
1654
+ );
1655
+ }
1656
+
1624
1657
  // src/tool_lattice/metrics/SemanticMetricsClient.ts
1625
1658
  var SemanticMetricsClient = class {
1626
1659
  constructor(config) {
@@ -1750,15 +1783,34 @@ var SemanticMetricsClient = class {
1750
1783
  limit: 1e3
1751
1784
  };
1752
1785
  const result = await this.semanticQuery(request);
1753
- const metricResult = result.results.find((r) => r.metricName === metricName);
1754
- const dataPoints = metricResult?.rows.map((row, index) => ({
1755
- timestamp: index * 1e3,
1756
- // Use index as timestamp if not provided
1757
- value: typeof row.value === "number" ? row.value : 0,
1758
- labels: Object.fromEntries(
1759
- Object.entries(row).map(([k, v]) => [k, String(v)])
1760
- )
1761
- })) || [];
1786
+ const dataPoints = [];
1787
+ if (result.rows && result.rows.length > 0) {
1788
+ const columnNames = result.columns.map((col) => col.name);
1789
+ result.rows.forEach((row, index) => {
1790
+ const rowObj = {};
1791
+ columnNames.forEach((colName, colIndex) => {
1792
+ rowObj[colName] = row[colIndex];
1793
+ });
1794
+ dataPoints.push({
1795
+ timestamp: index * 1e3,
1796
+ // Use index as timestamp if not provided
1797
+ value: typeof rowObj[metricName] === "number" ? rowObj[metricName] : 0,
1798
+ labels: Object.fromEntries(
1799
+ Object.entries(rowObj).map(([k, v]) => [k, String(v)])
1800
+ )
1801
+ });
1802
+ });
1803
+ } else if (result.rowsObject && result.rowsObject.length > 0) {
1804
+ result.rowsObject.forEach((row, index) => {
1805
+ dataPoints.push({
1806
+ timestamp: index * 1e3,
1807
+ value: typeof row[metricName] === "number" ? row[metricName] : 0,
1808
+ labels: Object.fromEntries(
1809
+ Object.entries(row).map(([k, v]) => [k, String(v)])
1810
+ )
1811
+ });
1812
+ });
1813
+ }
1762
1814
  return {
1763
1815
  metricName,
1764
1816
  dataPoints,
@@ -1819,30 +1871,92 @@ var SemanticMetricsClient = class {
1819
1871
  /**
1820
1872
  * Execute a semantic metrics query
1821
1873
  * POST /metrics/query
1874
+ *
1875
+ * @param request - Query request with optional format parameter
1876
+ * @returns Standardized query response based on format specification
1822
1877
  */
1823
1878
  async semanticQuery(request) {
1879
+ const format = request.format ?? "array";
1824
1880
  const response = await fetch(`${this.baseUrl}/metrics/query`, {
1825
1881
  method: "POST",
1826
1882
  headers: {
1827
1883
  ...this.getHeaders(),
1828
1884
  "Content-Type": "application/json"
1829
1885
  },
1830
- body: JSON.stringify(request)
1886
+ body: JSON.stringify({ ...request, debug: true })
1831
1887
  });
1832
1888
  if (!response.ok) {
1833
1889
  throw new Error(`HTTP ${response.status}: ${response.statusText}`);
1834
1890
  }
1835
- const data = await response.json();
1836
- if (data.code !== 200) {
1837
- throw new Error(`API error: ${data.message}`);
1891
+ const apiResponse = await response.json();
1892
+ if (apiResponse.code !== 200) {
1893
+ throw new Error(`API error: ${apiResponse.message}`);
1838
1894
  }
1839
- return data.data;
1895
+ const data = apiResponse.data;
1896
+ const result = {
1897
+ semanticModel: data.semanticModel,
1898
+ columns: data.columns,
1899
+ rowCount: data.rows?.length ?? 0
1900
+ };
1901
+ if (format === "array" || format === "both") {
1902
+ result.rows = data.rows;
1903
+ }
1904
+ if (format === "object" || format === "both") {
1905
+ result.rowsObject = arrayRowsToObjectRows(data.rows, data.columns);
1906
+ }
1907
+ return result;
1908
+ }
1909
+ /**
1910
+ * Execute a table query
1911
+ * GET /api/metrics/table/{tableName}
1912
+ *
1913
+ * @param request - Table query request with optional format parameter
1914
+ * @returns Standardized table query response based on format specification
1915
+ */
1916
+ async tableQuery(request) {
1917
+ const format = request.format ?? "object";
1918
+ const { tableName, limit = 20 } = request;
1919
+ const queryParams = new URLSearchParams();
1920
+ queryParams.append("limit", limit.toString());
1921
+ const response = await fetch(
1922
+ `${this.baseUrl}/api/metrics/table/${encodeURIComponent(tableName)}?${queryParams}`,
1923
+ {
1924
+ method: "GET",
1925
+ headers: this.getHeaders()
1926
+ }
1927
+ );
1928
+ if (!response.ok) {
1929
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
1930
+ }
1931
+ const apiResponse = await response.json();
1932
+ if (apiResponse.code !== 200) {
1933
+ throw new Error(`API error: ${apiResponse.message}`);
1934
+ }
1935
+ const data = apiResponse.data;
1936
+ const result = {
1937
+ tableName: data.tableName,
1938
+ columns: data.columns,
1939
+ rowCount: data.rowCount,
1940
+ executionTimeMs: data.executionTimeMs,
1941
+ executedSql: data.executedSql
1942
+ };
1943
+ if (format === "object" || format === "both") {
1944
+ result.rowsObject = data.rows;
1945
+ }
1946
+ if (format === "array" || format === "both") {
1947
+ result.rows = objectRowsToArrayRows(data.rows, data.columns);
1948
+ }
1949
+ return result;
1840
1950
  }
1841
1951
  /**
1842
1952
  * Execute a custom SQL query
1843
1953
  * POST /metrics/query
1954
+ *
1955
+ * @param request - SQL query request with optional format parameter
1956
+ * @returns Standardized query response based on format specification
1844
1957
  */
1845
1958
  async executeSqlQuery(request) {
1959
+ const format = request.format ?? "object";
1846
1960
  const response = await fetch(`${this.baseUrl}/metrics/query`, {
1847
1961
  method: "POST",
1848
1962
  headers: {
@@ -1854,11 +1968,27 @@ var SemanticMetricsClient = class {
1854
1968
  if (!response.ok) {
1855
1969
  throw new Error(`HTTP ${response.status}: ${response.statusText}`);
1856
1970
  }
1857
- const data = await response.json();
1858
- if (data.code !== 200) {
1859
- throw new Error(`API error: ${data.message}`);
1971
+ const apiResponse = await response.json();
1972
+ if (apiResponse.code !== 200) {
1973
+ throw new Error(`API error: ${apiResponse.message}`);
1974
+ }
1975
+ const data = apiResponse.data;
1976
+ const result = {
1977
+ datasourceId: data.datasourceId,
1978
+ datasourceName: data.datasourceName,
1979
+ tableName: data.tableName,
1980
+ columns: data.columns,
1981
+ rowCount: data.rowCount,
1982
+ executionTimeMs: data.executionTimeMs,
1983
+ executedSql: data.executedSql
1984
+ };
1985
+ if (format === "object" || format === "both") {
1986
+ result.rowsObject = data.rows;
1860
1987
  }
1861
- return data.data;
1988
+ if (format === "array" || format === "both") {
1989
+ result.rows = objectRowsToArrayRows(data.rows, data.columns);
1990
+ }
1991
+ return result;
1862
1992
  }
1863
1993
  /**
1864
1994
  * Get selected data sources for this configuration
@@ -2347,19 +2477,6 @@ var metricsServerManager = MetricsServerManager.getInstance();
2347
2477
  // src/tool_lattice/metrics/list_metrics_servers.ts
2348
2478
  var import_zod7 = __toESM(require("zod"));
2349
2479
  var import_langchain5 = require("langchain");
2350
-
2351
- // src/tool_lattice/metrics/utils.ts
2352
- function getTenantIdFromConfig2(exeConfig, getTenantId) {
2353
- const runConfig = exeConfig?.configurable?.runConfig || {};
2354
- return runConfig.tenantId || (getTenantId ? getTenantId() : "default");
2355
- }
2356
- function filterServerKeysByTenant(serverKeys, tenantId, manager = metricsServerManager) {
2357
- return serverKeys.filter((key) => {
2358
- return manager.hasServer(tenantId, key);
2359
- });
2360
- }
2361
-
2362
- // src/tool_lattice/metrics/list_metrics_servers.ts
2363
2480
  var LIST_METRICS_SERVERS_DESCRIPTION = `List all registered metrics servers. Returns a list of available metrics servers with their keys and types. Use this tool first to understand what metrics servers are available.`;
2364
2481
  var createListMetricsServersTool = ({ serverKeys, serverDescriptions, getTenantId }) => {
2365
2482
  const availableServersText = serverKeys.length > 0 ? `
@@ -2734,176 +2851,7 @@ ${serverKeys.map(
2734
2851
  if (!foundDetail) {
2735
2852
  return `Metric "${metricName}" not found in the specified data sources.`;
2736
2853
  }
2737
- const lines = [];
2738
- lines.push(`# ${foundDetail.displayName} (${foundDetail.metricName})`);
2739
- lines.push("");
2740
- lines.push(`## Basic Information`);
2741
- lines.push("");
2742
- lines.push(`- **Metric Name**: ${foundDetail.metricName}`);
2743
- lines.push(`- **Display Name**: ${foundDetail.displayName}`);
2744
- lines.push(`- **Domain**: ${foundDetail.domain}`);
2745
- lines.push(`- **Data Type**: ${foundDetail.dataType}`);
2746
- lines.push(`- **Format**: ${foundDetail.format}`);
2747
- if (foundDatasourceId) {
2748
- lines.push(`- **Data Source ID**: ${foundDatasourceId}`);
2749
- }
2750
- lines.push("");
2751
- lines.push(`## Description`);
2752
- lines.push("");
2753
- lines.push(foundDetail.description);
2754
- lines.push("");
2755
- if (foundDetail.defaultTimeContext) {
2756
- const dtc = foundDetail.defaultTimeContext;
2757
- lines.push(`## Time Context`);
2758
- lines.push("");
2759
- if (dtc.timeDimension) {
2760
- lines.push(`- **Time Dimension**: ${dtc.timeDimension}${dtc.label ? ` (${dtc.label})` : ""}`);
2761
- }
2762
- if (dtc.granularity) {
2763
- lines.push(`- **Default Granularity**: ${dtc.granularity}`);
2764
- }
2765
- if (dtc.window) {
2766
- lines.push(`- **Default Window**: ${dtc.window}`);
2767
- }
2768
- const grains = dtc.supportedGrains;
2769
- lines.push(`- **Supported Grains**: ${Array.isArray(grains) && grains.length > 0 ? grains.join(", ") : "Not configured"}`);
2770
- lines.push("");
2771
- }
2772
- if (foundDetail.supportedDimensions && foundDetail.supportedDimensions.length > 0) {
2773
- const categoricalDims = foundDetail.supportedDimensions.filter((d) => d.type === "categorical");
2774
- const datetimeDims = foundDetail.supportedDimensions.filter((d) => d.type === "datetime");
2775
- const timeDimension = foundDetail.defaultTimeContext?.timeDimension;
2776
- lines.push(`## Supported Dimensions`);
2777
- lines.push("");
2778
- if (categoricalDims.length > 0) {
2779
- lines.push(`### Categorical Dimensions - ${categoricalDims.length}`);
2780
- lines.push("Supports IN (multiple), EQ (single) operators");
2781
- lines.push("");
2782
- const examples = categoricalDims.slice(0, 2);
2783
- for (const dim of examples) {
2784
- lines.push(`**${dim.dim_id}** (${dim.field_name})`);
2785
- lines.push("```json");
2786
- lines.push(`// Grouping example`);
2787
- lines.push(`"groupBy": ["${dim.dim_id}"]`);
2788
- lines.push("");
2789
- lines.push(`// Filter example`);
2790
- lines.push(`{"dimension": "${dim.dim_id}", "operator": "IN", "values": ["value1", "value2"]}`);
2791
- lines.push("```");
2792
- lines.push("");
2793
- }
2794
- if (categoricalDims.length > 2) {
2795
- const others = categoricalDims.slice(2).map((d) => d.dim_id).join(", ");
2796
- lines.push(`**Other ${categoricalDims.length - 2} dimensions**: ${others}`);
2797
- lines.push("");
2798
- }
2799
- }
2800
- if (datetimeDims.length > 0) {
2801
- lines.push(`### Datetime Dimensions - ${datetimeDims.length}`);
2802
- lines.push("Supports BETWEEN (range), GT/GTE/LT/LTE (comparison) operators");
2803
- lines.push("");
2804
- const primaryDim = datetimeDims.find((d) => d.dim_id === timeDimension) || datetimeDims[0];
2805
- lines.push(`**${primaryDim.dim_id}** (${primaryDim.field_name})`);
2806
- lines.push("```json");
2807
- lines.push(`// Group by time grain`);
2808
- lines.push(`"groupBy": ["${primaryDim.dim_id}__month"] // Options: day, week, month, year`);
2809
- lines.push("");
2810
- lines.push(`// Time range filter`);
2811
- lines.push(`{"dimension": "${primaryDim.dim_id}", "operator": "BETWEEN", "values": ["2025-01-01", "2025-12-31"]}`);
2812
- lines.push("```");
2813
- lines.push("");
2814
- if (datetimeDims.length > 1) {
2815
- const others = datetimeDims.filter((d) => d.dim_id !== primaryDim.dim_id).map((d) => d.dim_id).join(", ");
2816
- lines.push(`**Other time dimensions**: ${others}`);
2817
- lines.push("");
2818
- }
2819
- }
2820
- lines.push("### Quick Reference");
2821
- lines.push("");
2822
- lines.push("**Time grouping format**: `{timeDimension}__{grain}`");
2823
- lines.push("- By day: `DocDate__day`");
2824
- lines.push("- By week: `DocDate__week`");
2825
- lines.push("- By month: `DocDate__month`");
2826
- lines.push("- By year: `DocDate__year`");
2827
- lines.push("");
2828
- }
2829
- if (foundDetail.aiAgentContext) {
2830
- const aiContext = foundDetail.aiAgentContext;
2831
- lines.push(`## AI Analysis Context`);
2832
- lines.push("");
2833
- if (aiContext.polarity) {
2834
- lines.push(`### Metric Polarity`);
2835
- lines.push("");
2836
- lines.push(aiContext.polarity === "positive" ? "Positive metric (higher is better)" : "Negative metric (lower is better)");
2837
- lines.push("");
2838
- }
2839
- if (aiContext.synonyms && aiContext.synonyms.length > 0) {
2840
- lines.push(`### Synonyms/Aliases`);
2841
- lines.push("");
2842
- lines.push(aiContext.synonyms.join(", "));
2843
- lines.push("");
2844
- }
2845
- if (aiContext.thresholds && aiContext.thresholds.length > 0) {
2846
- lines.push(`### Alert Thresholds`);
2847
- lines.push("");
2848
- lines.push("| Metric | Operator | Threshold | Level |");
2849
- lines.push("|--------|----------|-----------|-------|");
2850
- for (const t of aiContext.thresholds) {
2851
- lines.push(`| ${t.metric} | ${t.operator} | ${t.value} | ${t.level} |`);
2852
- }
2853
- lines.push("");
2854
- }
2855
- if (aiContext.diagnosticWorkflow) {
2856
- lines.push(`### Diagnostic Workflow`);
2857
- lines.push("");
2858
- if (aiContext.diagnosticWorkflow.trigger && aiContext.diagnosticWorkflow.trigger.any_of) {
2859
- lines.push(`**Trigger Conditions** (satisfy any):`);
2860
- for (const trigger of aiContext.diagnosticWorkflow.trigger.any_of) {
2861
- if (trigger.metric && trigger.operator) {
2862
- lines.push(`- ${trigger.metric} ${trigger.operator} ${trigger.value ?? "N/A"}`);
2863
- }
2864
- }
2865
- lines.push("");
2866
- }
2867
- if (aiContext.diagnosticWorkflow.actions && aiContext.diagnosticWorkflow.actions.length > 0) {
2868
- lines.push(`**Analysis Actions**:`);
2869
- for (let i = 0; i < aiContext.diagnosticWorkflow.actions.length; i++) {
2870
- const action = aiContext.diagnosticWorkflow.actions[i];
2871
- if (!action) continue;
2872
- lines.push(`${i + 1}. **${action.type ?? "Unnamed Action"}**`);
2873
- if (action.metric) {
2874
- lines.push(` - Comparison Metric: ${action.metric}`);
2875
- }
2876
- if (action.dimensions && action.dimensions.length > 0) {
2877
- lines.push(` - Drill-down Dimensions: ${action.dimensions.join(", ")}`);
2878
- }
2879
- if (action.intent) {
2880
- lines.push(` - Intent: ${action.intent}`);
2881
- }
2882
- }
2883
- lines.push("");
2884
- }
2885
- if (aiContext.diagnosticWorkflow.analysis_logic) {
2886
- lines.push(`**Analysis Logic**: ${aiContext.diagnosticWorkflow.analysis_logic}`);
2887
- lines.push("");
2888
- }
2889
- }
2890
- if (aiContext.humanReadableExplanation) {
2891
- lines.push(`### System Recommendations`);
2892
- lines.push("");
2893
- lines.push(aiContext.humanReadableExplanation);
2894
- lines.push("");
2895
- }
2896
- }
2897
- lines.push(`---`);
2898
- lines.push("");
2899
- lines.push(`## Usage Example`);
2900
- lines.push("");
2901
- lines.push(`To query this metric, use the query_semantic_metric_data tool with parameters:`);
2902
- lines.push(`- **metricName**: "${foundDetail.metricName}"`);
2903
- if (foundDatasourceId) {
2904
- lines.push(`- **datasourceId**: "${foundDatasourceId}"`);
2905
- }
2906
- return lines.join("\n");
2854
+ return JSON.stringify(foundDetail, null, 2);
2907
2855
  } catch (error) {
2908
2856
  return `Error querying metric definition: ${error instanceof Error ? error.message : String(error)}`;
2909
2857
  }
@@ -2941,11 +2889,19 @@ Skip using this tool when:
2941
2889
  Prerequisites - MUST Complete First
2942
2890
  1. Call query_metrics_list to discover available metrics
2943
2891
  2. Call query_metric_definition(metricName) to get:
2944
- - defaultTimeContext.timeDimension (e.g., "DocDate")
2892
+ - defaultTimeContext.timeDimension (e.g., "DocDate","date")
2945
2893
  - defaultTimeContext.supportedGrains (e.g., ["day", "week", "month", "year"])
2946
2894
  - supportedDimensions[].dim_id (use these for groupBy and filters)
2947
2895
  - supportedDimensions[].filter_operators (allowed operators per dimension)
2948
2896
 
2897
+ **Rules**:
2898
+ - To filter by date: Copy the pattern and replace values
2899
+ \`\`\`json
2900
+ {"dimension": "DocDate", "operator": "BETWEEN", "values": ["2025-01-01", "2025-12-31"]}
2901
+ \`\`\`
2902
+ - To group by time: Use \`"{timeDimension}__{supportedGrain}"\` format (e.g., \`"date__month"\`)
2903
+
2904
+
2949
2905
  The Five Query Patterns
2950
2906
 
2951
2907
  Pattern A - Time Trend (most common first query)
@@ -2953,8 +2909,8 @@ Goal: Show how a metric changes over time within a period
2953
2909
  {
2954
2910
  "metrics": ["order_amt_tax_inc"],
2955
2911
  "groupBy": ["DocDate__month"],
2956
- "filters": [{ "dimension": "DocDate", "operator": "BETWEEN", "values": ["2025-01-01", "2025-12-31"] }],
2957
- "orderBy": [{ "field": "DocDate__month", "direction": "ASC" }]
2912
+ "filters": [{ "dimension": "date", "operator": "BETWEEN", "values": ["2025-01-01", "2025-12-31"] }],
2913
+ "orderBy": [{ "field": "date__month", "direction": "ASC" }]
2958
2914
  }
2959
2915
 
2960
2916
  Pattern B - Dimension Breakdown (who/what is top or bottom)
@@ -3019,82 +2975,50 @@ Common Mistakes to Avoid
3019
2975
  - Omitting date filter entirely - ALWAYS include at least one DocDate filter
3020
2976
  - Querying a metric by an unsupported dimension - only use dim_id from supportedDimensions
3021
2977
  - Putting display name in orderBy.field - must match exactly what's in groupBy
3022
-
3023
- Recommended Analysis Flow
3024
- User question
3025
- |
3026
- \u25BC
3027
- Step 1: query_metrics_list - find matching metric(s)
3028
- |
3029
- \u25BC
3030
- Step 2: query_metric_definition - read defaultTimeContext + supportedDimensions
3031
- |
3032
- \u25BC
3033
- Step 3a: Pattern A (time trend) - get the big picture
3034
- |
3035
- \u251C\u2500 anomaly found? \u2500\u2500\u25BA Step 3c: Pattern C (drill down)
3036
- \u251C\u2500 user asks "who"? \u2500\u2500\u25BA Step 3b: Pattern B (dimension breakdown)
3037
- \u2514\u2500 user asks "compare X and Y"? \u2500\u2500\u25BA Step 3d: Pattern D (multi-metric)
3038
-
3039
- Debug Mode
3040
- Set "debug": true to receive executedSqls in the response to verify generated SQL.`;
3041
- function formatSemanticQueryResult(datasourceId, datasourceName, results) {
3042
- if (results.length === 0) {
2978
+ `;
2979
+ function formatSemanticQueryResult(result) {
2980
+ const { semanticModel, columns, rowCount } = result;
2981
+ if (!columns || columns.length === 0 || rowCount === 0) {
3043
2982
  return `No data found for the specified query.
3044
- Data Source: ${datasourceId}${datasourceName ? ` (${datasourceName})` : ""}`;
2983
+ Semantic Model: ${semanticModel}`;
3045
2984
  }
3046
2985
  const lines = [];
3047
2986
  lines.push(`# Metric Query Results`);
3048
2987
  lines.push(`
3049
- **Data Source**: ${datasourceId}${datasourceName ? ` (${datasourceName})` : ""}`);
3050
- lines.push(`**Metrics Count**: ${results.length}`);
2988
+ **Semantic Model**: ${semanticModel}`);
2989
+ lines.push(`**Columns**: ${columns.length}`);
2990
+ lines.push(`**Rows**: ${rowCount}`);
3051
2991
  lines.push(`
3052
2992
  ---
3053
2993
  `);
3054
- for (const metric of results) {
3055
- lines.push(`## ${metric.displayName} (${metric.metricName})`);
3056
- lines.push(`
3057
- - **Data Type**: ${metric.dataType}`);
3058
- lines.push(`- **Format**: ${metric.format}`);
3059
- lines.push(`- **Polarity**: ${metric.polarity}`);
3060
- lines.push(`- **Execution Time**: ${metric.executionTimeMs}ms`);
3061
- lines.push(`- **Rows Returned**: ${metric.rowCount}`);
3062
- if (metric.columns.length > 0 && metric.rows.length > 0) {
3063
- lines.push(`
3064
- ### Data
2994
+ const rows = result.rowsObject ?? result.rows ?? [];
2995
+ if (rows.length === 0) {
2996
+ lines.push(`*No data rows returned*
3065
2997
  `);
3066
- lines.push(`| ${metric.columns.join(" | ")} |`);
3067
- lines.push(`|${metric.columns.map(() => "---").join("|")}|`);
3068
- for (const row of metric.rows) {
3069
- const rowValues = metric.columns.map((col) => {
3070
- const val = row[col];
3071
- return val !== void 0 ? String(val) : "";
3072
- });
3073
- lines.push(`| ${rowValues.join(" | ")} |`);
3074
- }
3075
- }
3076
- if (metric.aiHints) {
3077
- lines.push(`
3078
- ### AI Analysis Suggestions
2998
+ return lines.join("\n");
2999
+ }
3000
+ const columnNames = columns.map((col) => col.name);
3001
+ lines.push(`## Data
3079
3002
  `);
3080
- lines.push(`- **Value Interpretation**: ${metric.aiHints.valueInterpretation}`);
3081
- if (metric.aiHints.thresholds && metric.aiHints.thresholds.length > 0) {
3082
- lines.push(`- **Alert Thresholds**:`);
3083
- for (const t of metric.aiHints.thresholds) {
3084
- lines.push(` - ${t.metric} ${t.operator} ${t.value} (${t.level})`);
3085
- }
3086
- }
3087
- if (metric.aiHints.suggestedFollowup && metric.aiHints.suggestedFollowup.length > 0) {
3088
- lines.push(`- **Suggested Follow-up Analysis**:`);
3089
- for (const suggestion of metric.aiHints.suggestedFollowup) {
3090
- lines.push(` - ${suggestion}`);
3091
- }
3092
- }
3003
+ lines.push(`| ${columnNames.join(" | ")} |`);
3004
+ lines.push(`|${columnNames.map(() => "---").join("|")}|`);
3005
+ if (result.rowsObject) {
3006
+ for (const row of result.rowsObject) {
3007
+ const rowValues = columnNames.map((col) => {
3008
+ const val = row[col];
3009
+ return val !== void 0 && val !== null ? String(val) : "";
3010
+ });
3011
+ lines.push(`| ${rowValues.join(" | ")} |`);
3093
3012
  }
3094
- lines.push(`
3013
+ } else if (result.rows) {
3014
+ for (const row of result.rows) {
3015
+ const rowValues = row.map((val) => val !== void 0 && val !== null ? String(val) : "");
3016
+ lines.push(`| ${rowValues.join(" | ")} |`);
3017
+ }
3018
+ }
3019
+ lines.push(`
3095
3020
  ---
3096
3021
  `);
3097
- }
3098
3022
  return lines.join("\n");
3099
3023
  }
3100
3024
  var createQuerySemanticMetricDataTool = ({ serverKeys, serverDescriptions, getTenantId, connectAll }) => {
@@ -3154,11 +3078,7 @@ ${serverKeys.map(
3154
3078
  filters: semanticFilters,
3155
3079
  limit: limit || 1e3
3156
3080
  });
3157
- return formatSemanticQueryResult(
3158
- result.datasourceId,
3159
- result.datasourceName,
3160
- result.results
3161
- );
3081
+ return formatSemanticQueryResult(result);
3162
3082
  } catch (error) {
3163
3083
  return `Error querying semantic metric data: ${error instanceof Error ? error.message : String(error)}`;
3164
3084
  }
@@ -3477,7 +3397,7 @@ ${serverKeys.map(
3477
3397
  params,
3478
3398
  limit: limit || 100
3479
3399
  });
3480
- const rows = result.result?.rows || [];
3400
+ const rows = result.rowsObject ?? result.rows ?? [];
3481
3401
  return "query_result:\n" + JSON.stringify(rows, null, 2);
3482
3402
  } catch (error) {
3483
3403
  return `Error executing SQL query: ${error instanceof Error ? error.message : String(error)}`;
@@ -8488,7 +8408,7 @@ var ReActAgentGraphBuilder = class {
8488
8408
  let workingDirectory = "/";
8489
8409
  if (workspaceId && projectId) {
8490
8410
  if (tenantId) {
8491
- workingDirectory = `/tenants/${tenantId}/${workspaceId}/${projectId}`;
8411
+ workingDirectory = `/tenants/${tenantId}/workspaces/${workspaceId}/${projectId}`;
8492
8412
  } else {
8493
8413
  workingDirectory = `/${workspaceId}/${projectId}`;
8494
8414
  }
@@ -8872,6 +8792,7 @@ async function executeNode(state) {
8872
8792
  const { assistant_id, thread_id, input, command2, runConfig } = state;
8873
8793
  const callParams = {
8874
8794
  assistant_id,
8795
+ "x-tenant-id": runConfig?.tenantId,
8875
8796
  thread_id,
8876
8797
  input,
8877
8798
  command: command2,
@@ -9128,7 +9049,9 @@ function getSubagents(options) {
9128
9049
  model: defaultModel,
9129
9050
  systemPrompt: DEFAULT_SUBAGENT_PROMPT,
9130
9051
  tools: defaultTools,
9131
- middleware: generalPurposeMiddleware
9052
+ middleware: generalPurposeMiddleware,
9053
+ checkpointer: getCheckpointSaver("default"),
9054
+ name: "general-purpose"
9132
9055
  });
9133
9056
  agents["general-purpose"] = generalPurposeSubagent;
9134
9057
  subagentDescriptions.push(
@@ -9150,7 +9073,8 @@ function getSubagents(options) {
9150
9073
  model: agentParams.model ?? defaultModel,
9151
9074
  systemPrompt: agentParams.systemPrompt,
9152
9075
  tools: agentParams.tools ?? defaultTools,
9153
- middleware
9076
+ middleware,
9077
+ checkpointer: getCheckpointSaver("default")
9154
9078
  });
9155
9079
  }
9156
9080
  }
@@ -9178,6 +9102,24 @@ function createTaskTool(options) {
9178
9102
  return (0, import_langchain49.tool)(
9179
9103
  async (input, config) => {
9180
9104
  const { description, subagent_type } = input;
9105
+ let assistant_id = subagent_type;
9106
+ if (subagent_type === "general-purpose") {
9107
+ assistant_id = config.configurable?.runConfig?.assistant_id + "-general-purpose";
9108
+ const hasAgentLattice = agentLatticeManager.hasAgentLatticeWithTenant(config.configurable?.runConfig?.tenantId, assistant_id);
9109
+ if (!hasAgentLattice) {
9110
+ const client = subagentGraphs["general-purpose"];
9111
+ agentLatticeManager.registerWithTenant(config.configurable?.runConfig?.tenantId, assistant_id, {
9112
+ config: {
9113
+ key: assistant_id,
9114
+ name: "general-purpose",
9115
+ description: DEFAULT_GENERAL_PURPOSE_DESCRIPTION,
9116
+ type: import_protocols.AgentType.REACT,
9117
+ prompt: DEFAULT_SUBAGENT_PROMPT
9118
+ },
9119
+ client
9120
+ });
9121
+ }
9122
+ }
9181
9123
  try {
9182
9124
  if (!(subagent_type in subagentGraphs)) {
9183
9125
  const allowedTypes = Object.keys(subagentGraphs).map((k) => `\`${k}\``).join(", ");
@@ -9185,19 +9127,18 @@ function createTaskTool(options) {
9185
9127
  `Error: invoked agent of type ${subagent_type}, the only allowed types are ${allowedTypes}`
9186
9128
  );
9187
9129
  }
9188
- const subagent = subagentGraphs[subagent_type];
9189
9130
  const currentState = (0, import_langgraph7.getCurrentTaskInput)();
9190
9131
  const subagentState = filterStateForSubagent(currentState);
9191
9132
  subagentState.messages = [new import_messages.HumanMessage({ content: description })];
9192
- const subagent_thread_id = config.configurable?.thread_id + "____" + subagent_type + "_" + config.toolCall.id;
9133
+ const subagent_thread_id = config.configurable?.thread_id + "____" + assistant_id + "_" + config.toolCall.id;
9193
9134
  console.log(subagent_thread_id);
9194
9135
  const workerResult = await agentWorkerGraph.invoke({
9195
- assistant_id: subagent_type,
9136
+ assistant_id,
9196
9137
  thread_id: subagent_thread_id,
9197
9138
  input: { ...subagentState, message: description },
9198
9139
  runConfig: {
9199
9140
  ...config.configurable?.runConfig,
9200
- assistant_id: subagent_type,
9141
+ assistant_id,
9201
9142
  thread_id: subagent_thread_id
9202
9143
  }
9203
9144
  });
@@ -10733,11 +10674,12 @@ ${BASE_PROMPT}` : BASE_PROMPT;
10733
10674
  unsupportedModelBehavior: "ignore"
10734
10675
  }),
10735
10676
  // Subagent middleware: Patches tool calls for compatibility
10736
- createPatchToolCallsMiddleware()
10677
+ createPatchToolCallsMiddleware(),
10678
+ ...customMiddleware
10737
10679
  ],
10738
10680
  defaultInterruptOn: interruptOn,
10739
10681
  subagents,
10740
- generalPurposeAgent: false
10682
+ generalPurposeAgent: true
10741
10683
  }),
10742
10684
  // Automatically summarizes conversation history when token limits are approached
10743
10685
  (0, import_langchain52.summarizationMiddleware)({
@@ -11718,14 +11660,19 @@ You have access to these tools:
11718
11660
  middleware: [...teamMiddleware ?? [], ...spec.middleware ?? []],
11719
11661
  checkpointer: getCheckpointSaver("default")
11720
11662
  });
11721
- registerTeammateAgent(assistantId, agent);
11663
+ registerTeammateAgent(assistantId, agent, ctx.tenantId);
11722
11664
  const teammateThreadId = ctx.parentThreadId ? `${ctx.parentThreadId}____${ctx.teamId}_${spec.name}` : `standalone_${ctx.teamId}_${spec.name}`;
11723
11665
  const startMessage = "Start working";
11724
11666
  try {
11725
11667
  await agentWorkerGraph.invoke({
11726
11668
  assistant_id: assistantId,
11727
11669
  thread_id: teammateThreadId,
11728
- input: { message: startMessage, messages: [{ role: "human", content: startMessage }] }
11670
+ input: { message: startMessage, messages: [{ role: "human", content: startMessage }] },
11671
+ runConfig: {
11672
+ tenantId: ctx.tenantId,
11673
+ workspaceId: ctx.workspaceId,
11674
+ projectId: ctx.projectId
11675
+ }
11729
11676
  });
11730
11677
  } catch (err) {
11731
11678
  const errorMsg = err instanceof Error ? err.message : "Unknown error during teammate execution";
@@ -11749,7 +11696,10 @@ async function spawnTeammate(options) {
11749
11696
  defaultModel,
11750
11697
  parentThreadId = "",
11751
11698
  teamTools,
11752
- teamMiddleware
11699
+ teamMiddleware,
11700
+ tenantId,
11701
+ workspaceId,
11702
+ projectId
11753
11703
  } = options;
11754
11704
  const ctx = {
11755
11705
  teamId,
@@ -11761,12 +11711,15 @@ async function spawnTeammate(options) {
11761
11711
  defaultModel,
11762
11712
  pollIntervalMs: DEFAULT_POLL_INTERVAL_MS,
11763
11713
  scheduleLatticeKey: DEFAULT_SCHEDULE_LATTICE_KEY,
11764
- agentCache: /* @__PURE__ */ new Map()
11714
+ agentCache: /* @__PURE__ */ new Map(),
11715
+ tenantId,
11716
+ workspaceId,
11717
+ projectId
11765
11718
  };
11766
11719
  await getOrCreateTeammateAgent(ctx, spec, teamTools, teamMiddleware);
11767
11720
  }
11768
11721
  function createTeamMiddleware(options) {
11769
- const { teamConfig, taskListStore, mailboxStore } = options;
11722
+ const { teamConfig, taskListStore, mailboxStore, tenantId } = options;
11770
11723
  const defaultModel = teamConfig.model ?? "claude-sonnet-4-5-20250929";
11771
11724
  const createTeamTool = (0, import_langchain54.tool)(
11772
11725
  async (input, config) => {
@@ -11813,6 +11766,7 @@ function createTeamMiddleware(options) {
11813
11766
  await mailboxStore.registerAgent(teamId, spec.name);
11814
11767
  }
11815
11768
  const parentThreadId = config.configurable?.thread_id ?? "";
11769
+ const runConfig = config.configurable?.runConfig;
11816
11770
  matchedSpecs.forEach((spec) => {
11817
11771
  void spawnTeammate({
11818
11772
  teamId,
@@ -11823,7 +11777,10 @@ function createTeamMiddleware(options) {
11823
11777
  defaultModel,
11824
11778
  parentThreadId,
11825
11779
  teamTools: teamConfig.tools,
11826
- teamMiddleware: teamConfig.middleware
11780
+ teamMiddleware: teamConfig.middleware,
11781
+ tenantId,
11782
+ workspaceId: runConfig?.workspaceId,
11783
+ projectId: runConfig?.projectId
11827
11784
  });
11828
11785
  });
11829
11786
  const teamJson = JSON.stringify({
@@ -12393,7 +12350,8 @@ function createAgentTeam(config) {
12393
12350
  const teamMiddleware = createTeamMiddleware({
12394
12351
  teamConfig: teamConfigWithFs,
12395
12352
  taskListStore,
12396
- mailboxStore
12353
+ mailboxStore,
12354
+ tenantId: config.tenantId
12397
12355
  });
12398
12356
  const middleware = [
12399
12357
  teamMiddleware,
@@ -12460,7 +12418,8 @@ var TeamAgentGraphBuilder = class {
12460
12418
  scheduleLatticeKey: config.scheduleLatticeKey,
12461
12419
  pollIntervalMs: config.pollIntervalMs,
12462
12420
  backend: filesystemBackend,
12463
- middleware: middlewares
12421
+ middleware: middlewares,
12422
+ tenantId: params.tenantId
12464
12423
  };
12465
12424
  const teamLead = createAgentTeam(teamConfig);
12466
12425
  return teamLead;
@@ -12820,8 +12779,9 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
12820
12779
  *
12821
12780
  * @param key Unique key (e.g. `team:${teamId}:${agentName}`)
12822
12781
  * @param client Pre-built AgentClient (ReactAgent or CompiledGraph)
12782
+ * @param tenantId Tenant ID (required)
12823
12783
  */
12824
- registerTeammateAgent(key, client) {
12784
+ registerTeammateAgent(key, client, tenantId) {
12825
12785
  const agentLattice = {
12826
12786
  config: {
12827
12787
  key,
@@ -12831,7 +12791,7 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
12831
12791
  },
12832
12792
  client
12833
12793
  };
12834
- this.register(key, agentLattice);
12794
+ this.registerWithTenant(tenantId, key, agentLattice);
12835
12795
  }
12836
12796
  /**
12837
12797
  * Unregister a teammate agent. Call when a team is done to clean up.
@@ -12951,7 +12911,11 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
12951
12911
  this.initializeClient(tenantId, key);
12952
12912
  return this.getAgentLatticeWithTenant(tenantId, key);
12953
12913
  });
12954
- return paramsBuilder.buildParams(agentLattice, options);
12914
+ const params = paramsBuilder.buildParams(agentLattice, options);
12915
+ return {
12916
+ ...params,
12917
+ tenantId
12918
+ };
12955
12919
  }
12956
12920
  /**
12957
12921
  * Create an AgentClient from AgentLattice config
@@ -13035,7 +12999,7 @@ var registerAgentLattices = (tenantId, configs) => {
13035
12999
  var getAgentConfig = (key) => agentLatticeManager.getAgentConfig(key);
13036
13000
  var getAllAgentConfigs = () => agentLatticeManager.getAllAgentConfigs();
13037
13001
  var validateAgentInput = (key, input) => agentLatticeManager.validateAgentInput(key, input);
13038
- var registerTeammateAgent = (key, client) => agentLatticeManager.registerTeammateAgent(key, client);
13002
+ var registerTeammateAgent = (key, client, tenantId) => agentLatticeManager.registerTeammateAgent(key, client, tenantId);
13039
13003
  var unregisterTeammateAgent = (key) => agentLatticeManager.unregisterTeammateAgent(key);
13040
13004
  var getAgentClient = (tenantId, key, options) => agentLatticeManager.initializeClient(tenantId, key, options);
13041
13005
  var createAgentClientFromAgentLattice = async (agentLattice, options) => await agentLatticeManager.createAgentClientFromConfig(agentLattice, options);