@axiom-lattice/core 2.1.24 → 2.1.25

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
@@ -508,11 +508,11 @@ var ToolLatticeManager = class _ToolLatticeManager extends BaseLatticeManager {
508
508
  * @param key Lattice键名
509
509
  * @param tool 已有的StructuredTool实例
510
510
  */
511
- registerExistingTool(key, tool38) {
511
+ registerExistingTool(key, tool46) {
512
512
  const config = {
513
- name: tool38.name,
514
- description: tool38.description,
515
- schema: tool38.schema,
513
+ name: tool46.name,
514
+ description: tool46.description,
515
+ schema: tool46.schema,
516
516
  // StructuredTool的schema已经是Zod兼容的
517
517
  needUserApprove: false
518
518
  // MCP工具默认不需要用户批准
@@ -520,7 +520,7 @@ var ToolLatticeManager = class _ToolLatticeManager extends BaseLatticeManager {
520
520
  const toolLattice = {
521
521
  key,
522
522
  config,
523
- client: tool38
523
+ client: tool46
524
524
  };
525
525
  this.register(key, toolLattice);
526
526
  }
@@ -546,7 +546,7 @@ var ToolLatticeManager = class _ToolLatticeManager extends BaseLatticeManager {
546
546
  };
547
547
  var toolLatticeManager = ToolLatticeManager.getInstance();
548
548
  var registerToolLattice = (key, config, executor) => toolLatticeManager.registerLattice(key, config, executor);
549
- var registerExistingTool = (key, tool38) => toolLatticeManager.registerExistingTool(key, tool38);
549
+ var registerExistingTool = (key, tool46) => toolLatticeManager.registerExistingTool(key, tool46);
550
550
  var getToolLattice = (key) => toolLatticeManager.getToolLattice(key);
551
551
  var getToolDefinition = (key) => toolLatticeManager.getToolDefinition(key);
552
552
  var getToolClient = (key) => toolLatticeManager.getToolClient(key);
@@ -1217,8 +1217,1595 @@ ${databaseKeys.map(
1217
1217
  );
1218
1218
  };
1219
1219
 
1220
+ // src/tool_lattice/metrics/SemanticMetricsClient.ts
1221
+ var SemanticMetricsClient = class {
1222
+ constructor(config) {
1223
+ this.config = config;
1224
+ this.baseUrl = config.serverUrl.replace(/\/$/, "");
1225
+ }
1226
+ /**
1227
+ * Test connection to the semantic metrics server
1228
+ * Attempts to fetch data sources as a connectivity test
1229
+ */
1230
+ async testConnection() {
1231
+ const startTime = Date.now();
1232
+ try {
1233
+ const response = await fetch(`${this.baseUrl}/datasources`, {
1234
+ method: "GET",
1235
+ headers: this.getHeaders()
1236
+ });
1237
+ if (!response.ok) {
1238
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
1239
+ }
1240
+ const data = await response.json();
1241
+ if (data.code !== 200) {
1242
+ throw new Error(`API error: ${data.message}`);
1243
+ }
1244
+ const latency = Date.now() - startTime;
1245
+ return { connected: true, latency };
1246
+ } catch (error) {
1247
+ return {
1248
+ connected: false,
1249
+ error: error instanceof Error ? error.message : String(error)
1250
+ };
1251
+ }
1252
+ }
1253
+ /**
1254
+ * Get list of available metrics from all selected data sources
1255
+ * Aggregates metrics across selected datasources
1256
+ */
1257
+ async listMetrics() {
1258
+ const selectedIds = this.config.selectedDataSources || [];
1259
+ if (selectedIds.length === 0) {
1260
+ return [];
1261
+ }
1262
+ const allMetrics = [];
1263
+ const seenMetrics = /* @__PURE__ */ new Set();
1264
+ for (const datasourceId of selectedIds) {
1265
+ try {
1266
+ const metaData = await this.getDatasourceMetrics(datasourceId);
1267
+ for (const item of metaData.index.metrics) {
1268
+ if (!seenMetrics.has(item.metricName)) {
1269
+ seenMetrics.add(item.metricName);
1270
+ const detail = metaData.metricsDetails.find((d) => d.metricName === item.metricName);
1271
+ allMetrics.push({
1272
+ name: item.metricName,
1273
+ type: detail?.dataType || "number",
1274
+ description: item.shortDesc || detail?.description,
1275
+ labels: [],
1276
+ unit: void 0
1277
+ });
1278
+ }
1279
+ }
1280
+ } catch (error) {
1281
+ console.warn(`Failed to get metrics for datasource ${datasourceId}:`, error);
1282
+ }
1283
+ }
1284
+ return allMetrics;
1285
+ }
1286
+ /**
1287
+ * Get metadata for a specific metric
1288
+ * Searches across selected datasources for the metric
1289
+ */
1290
+ async getMetricMeta(metricName) {
1291
+ const selectedIds = this.config.selectedDataSources || [];
1292
+ for (const datasourceId of selectedIds) {
1293
+ try {
1294
+ const metaData = await this.getDatasourceMetrics(datasourceId);
1295
+ const item = metaData.index.metrics.find((m) => m.metricName === metricName);
1296
+ if (item) {
1297
+ const detail = metaData.metricsDetails.find((d) => d.metricName === metricName);
1298
+ return {
1299
+ name: item.metricName,
1300
+ type: detail?.dataType || "number",
1301
+ description: item.shortDesc || detail?.description,
1302
+ labels: [],
1303
+ unit: void 0
1304
+ };
1305
+ }
1306
+ } catch (error) {
1307
+ console.warn(`Failed to get metric meta from datasource ${datasourceId}:`, error);
1308
+ }
1309
+ }
1310
+ return null;
1311
+ }
1312
+ /**
1313
+ * Query metric data - delegates to semanticQuery
1314
+ * Note: For semantic server, use semanticQuery() directly for full functionality
1315
+ */
1316
+ async queryMetricData(metricName, options) {
1317
+ const selectedIds = this.config.selectedDataSources || [];
1318
+ if (selectedIds.length === 0) {
1319
+ throw new Error("No data sources selected for this semantic metrics server");
1320
+ }
1321
+ const datasourceId = selectedIds[0];
1322
+ const filters = [];
1323
+ if (options.startTime && options.endTime) {
1324
+ filters.push({
1325
+ dimension: "timestamp",
1326
+ operator: "BETWEEN",
1327
+ values: [
1328
+ new Date(options.startTime * 1e3).toISOString(),
1329
+ new Date(options.endTime * 1e3).toISOString()
1330
+ ]
1331
+ });
1332
+ }
1333
+ if (options.labels) {
1334
+ for (const [key, value] of Object.entries(options.labels)) {
1335
+ filters.push({
1336
+ dimension: key,
1337
+ operator: "=",
1338
+ values: [value]
1339
+ });
1340
+ }
1341
+ }
1342
+ const request = {
1343
+ datasourceId,
1344
+ metrics: [metricName],
1345
+ filters,
1346
+ limit: 1e3
1347
+ };
1348
+ const result = await this.semanticQuery(request);
1349
+ const metricResult = result.results.find((r) => r.metricName === metricName);
1350
+ const dataPoints = metricResult?.rows.map((row, index) => ({
1351
+ timestamp: index * 1e3,
1352
+ // Use index as timestamp if not provided
1353
+ value: typeof row.value === "number" ? row.value : 0,
1354
+ labels: Object.fromEntries(
1355
+ Object.entries(row).map(([k, v]) => [k, String(v)])
1356
+ )
1357
+ })) || [];
1358
+ return {
1359
+ metricName,
1360
+ dataPoints,
1361
+ metadata: {
1362
+ startTime: options.startTime ? options.startTime * 1e3 : void 0,
1363
+ endTime: options.endTime ? options.endTime * 1e3 : void 0
1364
+ }
1365
+ };
1366
+ }
1367
+ /**
1368
+ * Get the server type
1369
+ */
1370
+ getServerType() {
1371
+ return "semantic";
1372
+ }
1373
+ /**
1374
+ * Get all available data sources from the semantic server
1375
+ * GET /datasources
1376
+ */
1377
+ async getDataSources() {
1378
+ const response = await fetch(`${this.baseUrl}/datasources`, {
1379
+ method: "GET",
1380
+ headers: this.getHeaders()
1381
+ });
1382
+ if (!response.ok) {
1383
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
1384
+ }
1385
+ const data = await response.json();
1386
+ if (data.code !== 200) {
1387
+ throw new Error(`API error: ${data.message}`);
1388
+ }
1389
+ return data.data || [];
1390
+ }
1391
+ /**
1392
+ * Get metrics meta for a specific data source
1393
+ * GET /datasources/{id}/meta
1394
+ */
1395
+ async getDatasourceMetrics(datasourceId) {
1396
+ const response = await fetch(
1397
+ `${this.baseUrl}/datasources/${encodeURIComponent(datasourceId)}/meta`,
1398
+ {
1399
+ method: "GET",
1400
+ headers: this.getHeaders()
1401
+ }
1402
+ );
1403
+ if (!response.ok) {
1404
+ if (response.status === 404) {
1405
+ return { index: { datasourceId: 0, datasourceName: "", catalogVersion: "", domainCategories: [], metrics: [], tables: [] }, metricsDetails: [] };
1406
+ }
1407
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
1408
+ }
1409
+ const data = await response.json();
1410
+ if (data.code !== 200) {
1411
+ throw new Error(`API error: ${data.message}`);
1412
+ }
1413
+ return data.data;
1414
+ }
1415
+ /**
1416
+ * Execute a semantic metrics query
1417
+ * POST /metrics/query
1418
+ */
1419
+ async semanticQuery(request) {
1420
+ const response = await fetch(`${this.baseUrl}/metrics/query`, {
1421
+ method: "POST",
1422
+ headers: {
1423
+ ...this.getHeaders(),
1424
+ "Content-Type": "application/json"
1425
+ },
1426
+ body: JSON.stringify(request)
1427
+ });
1428
+ if (!response.ok) {
1429
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
1430
+ }
1431
+ const data = await response.json();
1432
+ if (data.code !== 200) {
1433
+ throw new Error(`API error: ${data.message}`);
1434
+ }
1435
+ return data.data;
1436
+ }
1437
+ /**
1438
+ * Get selected data sources for this configuration
1439
+ */
1440
+ getSelectedDataSources() {
1441
+ return this.config.selectedDataSources || [];
1442
+ }
1443
+ /**
1444
+ * Build request headers with authentication
1445
+ */
1446
+ getHeaders() {
1447
+ const headers = {
1448
+ Accept: "application/json",
1449
+ ...this.config.headers
1450
+ };
1451
+ if (this.config.apiKey) {
1452
+ headers["Authorization"] = `Bearer ${this.config.apiKey}`;
1453
+ } else if (this.config.username && this.config.password) {
1454
+ const auth = Buffer.from(`${this.config.username}:${this.config.password}`).toString("base64");
1455
+ headers["Authorization"] = `Basic ${auth}`;
1456
+ }
1457
+ return headers;
1458
+ }
1459
+ };
1460
+
1461
+ // src/tool_lattice/metrics/MetricsServerManager.ts
1462
+ var PrometheusClient = class {
1463
+ constructor(config) {
1464
+ this.config = config;
1465
+ }
1466
+ async testConnection() {
1467
+ const startTime = Date.now();
1468
+ try {
1469
+ const response = await fetch(`${this.config.serverUrl}/api/v1/status/buildinfo`, {
1470
+ method: "GET",
1471
+ headers: this.getHeaders()
1472
+ });
1473
+ if (!response.ok) {
1474
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
1475
+ }
1476
+ const latency = Date.now() - startTime;
1477
+ return { connected: true, latency };
1478
+ } catch (error) {
1479
+ return {
1480
+ connected: false,
1481
+ error: error instanceof Error ? error.message : String(error)
1482
+ };
1483
+ }
1484
+ }
1485
+ async listMetrics() {
1486
+ try {
1487
+ const response = await fetch(`${this.config.serverUrl}/api/v1/label/__name__/values`, {
1488
+ method: "GET",
1489
+ headers: this.getHeaders()
1490
+ });
1491
+ if (!response.ok) {
1492
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
1493
+ }
1494
+ const data = await response.json();
1495
+ if (data.status !== "success") {
1496
+ throw new Error(`Prometheus error: ${data.error || "Unknown error"}`);
1497
+ }
1498
+ const metrics = [];
1499
+ for (const name of data.data || []) {
1500
+ const meta = await this.getMetricMeta(name);
1501
+ if (meta) {
1502
+ metrics.push(meta);
1503
+ } else {
1504
+ metrics.push({ name });
1505
+ }
1506
+ }
1507
+ return metrics;
1508
+ } catch (error) {
1509
+ throw new Error(`Failed to list metrics: ${error instanceof Error ? error.message : String(error)}`);
1510
+ }
1511
+ }
1512
+ async getMetricMeta(metricName) {
1513
+ try {
1514
+ const response = await fetch(
1515
+ `${this.config.serverUrl}/api/v1/metadata?metric=${encodeURIComponent(metricName)}`,
1516
+ {
1517
+ method: "GET",
1518
+ headers: this.getHeaders()
1519
+ }
1520
+ );
1521
+ if (!response.ok) {
1522
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
1523
+ }
1524
+ const data = await response.json();
1525
+ if (data.status !== "success" || !data.data[metricName]) {
1526
+ return { name: metricName };
1527
+ }
1528
+ const metadata = data.data[metricName][0];
1529
+ return {
1530
+ name: metricName,
1531
+ type: metadata.type,
1532
+ description: metadata.help,
1533
+ unit: metadata.unit
1534
+ };
1535
+ } catch (error) {
1536
+ console.warn(`Failed to get metric metadata for ${metricName}:`, error);
1537
+ return { name: metricName };
1538
+ }
1539
+ }
1540
+ async queryMetricData(metricName, options) {
1541
+ const endTime = options.endTime || Math.floor(Date.now() / 1e3);
1542
+ const startTime = options.startTime || endTime - 3600;
1543
+ const step = options.step || 60;
1544
+ let query = metricName;
1545
+ if (options.labels && Object.keys(options.labels).length > 0) {
1546
+ const labelSelectors = Object.entries(options.labels).map(([key, value]) => `${key}="${value}"`).join(",");
1547
+ query = `${metricName}{${labelSelectors}}`;
1548
+ }
1549
+ try {
1550
+ const response = await fetch(
1551
+ `${this.config.serverUrl}/api/v1/query_range?query=${encodeURIComponent(query)}&start=${startTime}&end=${endTime}&step=${step}`,
1552
+ {
1553
+ method: "GET",
1554
+ headers: this.getHeaders()
1555
+ }
1556
+ );
1557
+ if (!response.ok) {
1558
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
1559
+ }
1560
+ const data = await response.json();
1561
+ if (data.status !== "success") {
1562
+ throw new Error(`Prometheus error: ${data.error || "Unknown error"}`);
1563
+ }
1564
+ const dataPoints = [];
1565
+ const result = data.data?.result || [];
1566
+ for (const series of result) {
1567
+ const labels = series.metric || {};
1568
+ for (const [timestamp, value] of series.values || []) {
1569
+ dataPoints.push({
1570
+ timestamp: parseFloat(timestamp) * 1e3,
1571
+ // Convert to milliseconds
1572
+ value: parseFloat(value),
1573
+ labels
1574
+ });
1575
+ }
1576
+ }
1577
+ return {
1578
+ metricName,
1579
+ dataPoints,
1580
+ metadata: {
1581
+ startTime: startTime * 1e3,
1582
+ endTime: endTime * 1e3,
1583
+ step: step * 1e3
1584
+ }
1585
+ };
1586
+ } catch (error) {
1587
+ throw new Error(`Failed to query metric data: ${error instanceof Error ? error.message : String(error)}`);
1588
+ }
1589
+ }
1590
+ getServerType() {
1591
+ return "prometheus";
1592
+ }
1593
+ getHeaders() {
1594
+ const headers = {
1595
+ Accept: "application/json",
1596
+ ...this.config.headers
1597
+ };
1598
+ if (this.config.apiKey) {
1599
+ headers["Authorization"] = `Bearer ${this.config.apiKey}`;
1600
+ } else if (this.config.username && this.config.password) {
1601
+ const auth = Buffer.from(`${this.config.username}:${this.config.password}`).toString("base64");
1602
+ headers["Authorization"] = `Basic ${auth}`;
1603
+ }
1604
+ return headers;
1605
+ }
1606
+ };
1607
+ var CustomMetricsClient = class {
1608
+ constructor(config) {
1609
+ this.config = config;
1610
+ }
1611
+ async testConnection() {
1612
+ const startTime = Date.now();
1613
+ try {
1614
+ const response = await fetch(`${this.config.serverUrl}/health`, {
1615
+ method: "GET",
1616
+ headers: this.getHeaders()
1617
+ });
1618
+ if (!response.ok) {
1619
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
1620
+ }
1621
+ const latency = Date.now() - startTime;
1622
+ return { connected: true, latency };
1623
+ } catch (error) {
1624
+ return {
1625
+ connected: false,
1626
+ error: error instanceof Error ? error.message : String(error)
1627
+ };
1628
+ }
1629
+ }
1630
+ async listMetrics() {
1631
+ try {
1632
+ const response = await fetch(`${this.config.serverUrl}/api/metrics`, {
1633
+ method: "GET",
1634
+ headers: this.getHeaders()
1635
+ });
1636
+ if (!response.ok) {
1637
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
1638
+ }
1639
+ const data = await response.json();
1640
+ return data.metrics || [];
1641
+ } catch (error) {
1642
+ throw new Error(`Failed to list metrics: ${error instanceof Error ? error.message : String(error)}`);
1643
+ }
1644
+ }
1645
+ async getMetricMeta(metricName) {
1646
+ try {
1647
+ const response = await fetch(
1648
+ `${this.config.serverUrl}/api/metrics/${encodeURIComponent(metricName)}/meta`,
1649
+ {
1650
+ method: "GET",
1651
+ headers: this.getHeaders()
1652
+ }
1653
+ );
1654
+ if (!response.ok) {
1655
+ if (response.status === 404) {
1656
+ return null;
1657
+ }
1658
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
1659
+ }
1660
+ return await response.json();
1661
+ } catch (error) {
1662
+ throw new Error(`Failed to get metric metadata: ${error instanceof Error ? error.message : String(error)}`);
1663
+ }
1664
+ }
1665
+ async queryMetricData(metricName, options) {
1666
+ try {
1667
+ const queryParams = new URLSearchParams();
1668
+ if (options.startTime) queryParams.append("start", options.startTime.toString());
1669
+ if (options.endTime) queryParams.append("end", options.endTime.toString());
1670
+ if (options.step) queryParams.append("step", options.step.toString());
1671
+ if (options.labels) {
1672
+ queryParams.append("labels", JSON.stringify(options.labels));
1673
+ }
1674
+ const response = await fetch(
1675
+ `${this.config.serverUrl}/api/metrics/${encodeURIComponent(metricName)}/data?${queryParams}`,
1676
+ {
1677
+ method: "GET",
1678
+ headers: this.getHeaders()
1679
+ }
1680
+ );
1681
+ if (!response.ok) {
1682
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
1683
+ }
1684
+ return await response.json();
1685
+ } catch (error) {
1686
+ throw new Error(`Failed to query metric data: ${error instanceof Error ? error.message : String(error)}`);
1687
+ }
1688
+ }
1689
+ getServerType() {
1690
+ return "custom";
1691
+ }
1692
+ getHeaders() {
1693
+ const headers = {
1694
+ Accept: "application/json",
1695
+ ...this.config.headers
1696
+ };
1697
+ if (this.config.apiKey) {
1698
+ headers["Authorization"] = `Bearer ${this.config.apiKey}`;
1699
+ } else if (this.config.username && this.config.password) {
1700
+ const auth = Buffer.from(`${this.config.username}:${this.config.password}`).toString("base64");
1701
+ headers["Authorization"] = `Basic ${auth}`;
1702
+ }
1703
+ return headers;
1704
+ }
1705
+ };
1706
+ var MetricsServerManager = class _MetricsServerManager {
1707
+ constructor() {
1708
+ this.clients = /* @__PURE__ */ new Map();
1709
+ this.configs = /* @__PURE__ */ new Map();
1710
+ this.defaultServerKey = null;
1711
+ }
1712
+ /**
1713
+ * Get the singleton instance
1714
+ */
1715
+ static getInstance() {
1716
+ if (!_MetricsServerManager.instance) {
1717
+ _MetricsServerManager.instance = new _MetricsServerManager();
1718
+ }
1719
+ return _MetricsServerManager.instance;
1720
+ }
1721
+ /**
1722
+ * Register a metrics server
1723
+ * @param key - Unique identifier for the server
1724
+ * @param config - Metrics server configuration
1725
+ */
1726
+ registerServer(key, config) {
1727
+ let client;
1728
+ switch (config.type) {
1729
+ case "prometheus":
1730
+ client = new PrometheusClient(config);
1731
+ break;
1732
+ case "custom":
1733
+ client = new CustomMetricsClient(config);
1734
+ break;
1735
+ case "semantic":
1736
+ client = new SemanticMetricsClient(config);
1737
+ break;
1738
+ default:
1739
+ throw new Error(`Unsupported metrics server type: ${config.type}`);
1740
+ }
1741
+ this.clients.set(key, client);
1742
+ this.configs.set(key, config);
1743
+ if (this.defaultServerKey === null) {
1744
+ this.defaultServerKey = key;
1745
+ }
1746
+ }
1747
+ /**
1748
+ * Set the default metrics server
1749
+ * @param key - Server key to set as default
1750
+ */
1751
+ setDefaultServer(key) {
1752
+ if (!this.clients.has(key)) {
1753
+ throw new Error(`Metrics server '${key}' not found`);
1754
+ }
1755
+ this.defaultServerKey = key;
1756
+ }
1757
+ /**
1758
+ * Get a metrics server client by key
1759
+ * @param key - Server key (optional, uses default if not provided)
1760
+ */
1761
+ getClient(key) {
1762
+ const serverKey = key || this.defaultServerKey;
1763
+ if (!serverKey) {
1764
+ throw new Error("No metrics server registered");
1765
+ }
1766
+ const client = this.clients.get(serverKey);
1767
+ if (!client) {
1768
+ throw new Error(`Metrics server '${serverKey}' not found`);
1769
+ }
1770
+ return client;
1771
+ }
1772
+ /**
1773
+ * Get metrics server configuration by key
1774
+ * @param key - Server key (optional, uses default if not provided)
1775
+ */
1776
+ getConfig(key) {
1777
+ const serverKey = key || this.defaultServerKey;
1778
+ if (!serverKey) {
1779
+ throw new Error("No metrics server registered");
1780
+ }
1781
+ const config = this.configs.get(serverKey);
1782
+ if (!config) {
1783
+ throw new Error(`Metrics server '${serverKey}' not found`);
1784
+ }
1785
+ return config;
1786
+ }
1787
+ /**
1788
+ * Check if a metrics server is registered
1789
+ * @param key - Server key
1790
+ */
1791
+ hasServer(key) {
1792
+ return this.clients.has(key);
1793
+ }
1794
+ /**
1795
+ * Get all registered metrics server keys with their types
1796
+ */
1797
+ getServerKeys() {
1798
+ return Array.from(this.configs.entries()).map(([key, config]) => ({
1799
+ key,
1800
+ type: config.type
1801
+ }));
1802
+ }
1803
+ /**
1804
+ * Remove a metrics server
1805
+ * @param key - Server key
1806
+ */
1807
+ removeServer(key) {
1808
+ this.clients.delete(key);
1809
+ this.configs.delete(key);
1810
+ if (this.defaultServerKey === key) {
1811
+ this.defaultServerKey = this.clients.size > 0 ? this.clients.keys().next().value || null : null;
1812
+ }
1813
+ }
1814
+ /**
1815
+ * Load metrics server configurations from a store
1816
+ * and register them with this manager
1817
+ *
1818
+ * @param store - The metrics server configuration store
1819
+ * @param tenantId - Tenant identifier
1820
+ */
1821
+ async loadConfigsFromStore(store, tenantId) {
1822
+ const configs = await store.getAllConfigs(tenantId);
1823
+ for (const entry of configs) {
1824
+ this.registerServer(entry.key, entry.config);
1825
+ }
1826
+ }
1827
+ /**
1828
+ * Load all metrics server configurations from a store
1829
+ * across all tenants and register them with this manager
1830
+ *
1831
+ * @param store - The metrics server configuration store
1832
+ */
1833
+ async loadAllConfigsFromStore(store) {
1834
+ const configs = await store.getAllConfigsWithoutTenant();
1835
+ for (const entry of configs) {
1836
+ this.registerServer(entry.key, entry.config);
1837
+ }
1838
+ }
1839
+ };
1840
+ var metricsServerManager = MetricsServerManager.getInstance();
1841
+
1842
+ // src/tool_lattice/metrics/list_metrics_servers.ts
1843
+ import z7 from "zod";
1844
+ import { tool as tool6 } from "langchain";
1845
+ 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.`;
1846
+ var createListMetricsServersTool = ({ serverKeys, serverDescriptions }) => {
1847
+ const availableServersText = serverKeys.length > 0 ? `
1848
+
1849
+ Available metrics servers:
1850
+ ${serverKeys.map(
1851
+ (key) => `- ${key}${serverDescriptions?.[key] ? `: ${serverDescriptions[key]}` : ""}`
1852
+ ).join("\n")}` : "";
1853
+ return tool6(
1854
+ async (_input, _exeConfig) => {
1855
+ try {
1856
+ const servers = metricsServerManager.getServerKeys();
1857
+ if (servers.length === 0) {
1858
+ return "No metrics servers registered.";
1859
+ }
1860
+ const lines = servers.map(({ key, type }) => {
1861
+ const desc = serverDescriptions?.[key] ? ` - ${serverDescriptions[key]}` : "";
1862
+ return `- ${key} (${type})${desc}`;
1863
+ });
1864
+ return `Available metrics servers:
1865
+ ${lines.join("\n")}`;
1866
+ } catch (error) {
1867
+ return `Error listing metrics servers: ${error instanceof Error ? error.message : String(error)}`;
1868
+ }
1869
+ },
1870
+ {
1871
+ name: "list_metrics_servers",
1872
+ description: `${LIST_METRICS_SERVERS_DESCRIPTION}${availableServersText}`,
1873
+ schema: z7.object({})
1874
+ }
1875
+ );
1876
+ };
1877
+
1878
+ // src/tool_lattice/metrics/list_metrics_datasources.ts
1879
+ import z8 from "zod";
1880
+ import { tool as tool7 } from "langchain";
1881
+ var LIST_METRICS_DATASOURCES_DESCRIPTION = `List all available datasources from all configured metrics servers. Returns a table with Server Key, DataSource ID, and DataSource Name. Use this tool first to discover what datasources are available before querying metrics.`;
1882
+ var createListMetricsDataSourcesTool = ({ serverKeys, serverDescriptions }) => {
1883
+ const availableServersText = serverKeys.length > 0 ? `
1884
+
1885
+ Configured metrics servers:
1886
+ ${serverKeys.map(
1887
+ (key) => `- ${key}${serverDescriptions?.[key] ? `: ${serverDescriptions[key]}` : ""}`
1888
+ ).join("\n")}` : "";
1889
+ return tool7(
1890
+ async (_input, _exeConfig) => {
1891
+ try {
1892
+ if (serverKeys.length === 0) {
1893
+ return "No metrics servers configured.";
1894
+ }
1895
+ const allDataSources = [];
1896
+ for (const serverKey of serverKeys) {
1897
+ try {
1898
+ const config = metricsServerManager.getConfig(serverKey);
1899
+ if (config.type !== "semantic") {
1900
+ console.warn(`Server "${serverKey}" is not a semantic metrics server, skipping.`);
1901
+ continue;
1902
+ }
1903
+ const client = metricsServerManager.getClient(serverKey);
1904
+ const dataSources = await client.getDataSources();
1905
+ for (const ds of dataSources) {
1906
+ allDataSources.push({
1907
+ serverKey,
1908
+ datasourceId: String(ds.id),
1909
+ datasourceName: ds.name || String(ds.id)
1910
+ });
1911
+ }
1912
+ } catch (error) {
1913
+ console.warn(`Failed to get datasources from server "${serverKey}":`, error);
1914
+ }
1915
+ }
1916
+ if (allDataSources.length === 0) {
1917
+ return `No datasources found in any configured metrics servers.`;
1918
+ }
1919
+ const lines = [];
1920
+ lines.push(`Found ${allDataSources.length} datasource(s) from ${serverKeys.length} server(s):
1921
+ `);
1922
+ lines.push("| Server Key | DataSource ID | Name |");
1923
+ lines.push("|------------|---------------|------|");
1924
+ for (const ds of allDataSources) {
1925
+ lines.push(`| ${ds.serverKey} | ${ds.datasourceId} | ${ds.datasourceName} |`);
1926
+ }
1927
+ lines.push("\nUse the Server Key and DataSource ID when calling other metrics tools.");
1928
+ return lines.join("\n");
1929
+ } catch (error) {
1930
+ return `Error listing datasources: ${error instanceof Error ? error.message : String(error)}`;
1931
+ }
1932
+ },
1933
+ {
1934
+ name: "list_metrics_datasources",
1935
+ description: `${LIST_METRICS_DATASOURCES_DESCRIPTION}${availableServersText}`,
1936
+ schema: z8.object({})
1937
+ }
1938
+ );
1939
+ };
1940
+
1941
+ // src/tool_lattice/metrics/query_metrics_list.ts
1942
+ import z9 from "zod";
1943
+ import { tool as tool8 } from "langchain";
1944
+ var QUERY_METRICS_LIST_DESCRIPTION = `Query Available Metrics - Step 1 of the Metrics Workflow
1945
+
1946
+ Discover what metrics exist in the semantic metrics server. This tool returns a list of available metrics with their domains and descriptions.
1947
+
1948
+ When to Use This Tool
1949
+ Use this tool proactively in these scenarios:
1950
+ - When the user asks about business metrics but does not specify exact metric names
1951
+ - When you need to find metrics matching a specific domain (e.g., "sales performance", "pricing")
1952
+ - At the start of ANY metrics-related conversation to understand available data
1953
+ - When the user asks "what metrics do we have?" or "show me available KPIs"
1954
+
1955
+ When NOT to Use This Tool
1956
+ Skip using this tool when:
1957
+ - The user has already provided exact metric names (proceed directly to query_metric_definition)
1958
+ - You have cached metric metadata from a recent call (within the same conversation)
1959
+ - The query is purely about retrieving data, not discovering what's available
1960
+
1961
+ The Three-Step Metrics Workflow
1962
+ 1. query_metrics_list (THIS TOOL) \u2192 discover available metrics
1963
+ 2. query_metric_definition \u2192 read metric metadata before querying
1964
+ 3. query_semantic_metric_data \u2192 execute the query with correct parameters
1965
+
1966
+ Response Fields Reference
1967
+ | Field | How to Use It |
1968
+ |-------|---------------|
1969
+ | metricName | The identifier passed to query_metric_definition and query_semantic_metric_data |
1970
+ | domain | Groups related metrics (e.g., sales_performance, pricing_and_margin) |
1971
+ | shortDesc | One-line description to present to the user |
1972
+ | displayName | Human-readable name of the metric |
1973
+
1974
+ Next Step
1975
+ After finding relevant metrics, call query_metric_definition with the metricName to get detailed metadata including time dimensions and supported filters.`;
1976
+ var createQueryMetricsListTool = ({ serverKeys, serverDescriptions }) => {
1977
+ const availableServersText = serverKeys.length > 0 ? `
1978
+
1979
+ Available metrics servers:
1980
+ ${serverKeys.map(
1981
+ (key) => `- ${key}${serverDescriptions?.[key] ? `: ${serverDescriptions[key]}` : ""}`
1982
+ ).join("\n")}` : "";
1983
+ return tool8(
1984
+ async ({
1985
+ serverKey,
1986
+ datasourceIds
1987
+ }, _exeConfig) => {
1988
+ try {
1989
+ if (!serverKey) {
1990
+ return "Error: serverKey parameter is required. Available servers: " + serverKeys.join(", ");
1991
+ }
1992
+ if (!serverKeys.includes(serverKey)) {
1993
+ return `Error: serverKey "${serverKey}" is not in the allowed list: [${serverKeys.join(", ")}]`;
1994
+ }
1995
+ const config = metricsServerManager.getConfig(serverKey);
1996
+ if (config.type !== "semantic") {
1997
+ return `Error: Server "${serverKey}" is not a semantic metrics server. This tool only works with semantic servers.`;
1998
+ }
1999
+ const client = metricsServerManager.getClient(serverKey);
2000
+ const targetDatasourceIds = datasourceIds && datasourceIds.length > 0 ? datasourceIds : client.getSelectedDataSources();
2001
+ if (targetDatasourceIds.length === 0) {
2002
+ return `Error: No data sources specified and no default data sources configured for server "${serverKey}".`;
2003
+ }
2004
+ const allMetrics = /* @__PURE__ */ new Map();
2005
+ for (const datasourceId of targetDatasourceIds) {
2006
+ try {
2007
+ const metaData = await client.getDatasourceMetrics(datasourceId);
2008
+ const index = metaData.index;
2009
+ for (const item of index.metrics) {
2010
+ if (allMetrics.has(item.metricName)) {
2011
+ const existing = allMetrics.get(item.metricName);
2012
+ if (!existing.datasources.includes(datasourceId)) {
2013
+ existing.datasources.push(datasourceId);
2014
+ }
2015
+ } else {
2016
+ allMetrics.set(item.metricName, {
2017
+ metricName: item.metricName,
2018
+ displayName: item.displayName,
2019
+ domain: item.domain,
2020
+ shortDesc: item.shortDesc,
2021
+ datasources: [datasourceId]
2022
+ });
2023
+ }
2024
+ }
2025
+ } catch (error) {
2026
+ console.warn(`Failed to get metrics for datasource ${datasourceId}:`, error);
2027
+ }
2028
+ }
2029
+ const metricsByDatasource = /* @__PURE__ */ new Map();
2030
+ for (const metric of allMetrics.values()) {
2031
+ for (const dsId of metric.datasources) {
2032
+ if (!metricsByDatasource.has(dsId)) {
2033
+ metricsByDatasource.set(dsId, []);
2034
+ }
2035
+ metricsByDatasource.get(dsId).push(metric);
2036
+ }
2037
+ }
2038
+ if (metricsByDatasource.size === 0) {
2039
+ return `\u672A\u5728\u6307\u5B9A\u7684\u6570\u636E\u6E90\u4E2D\u627E\u5230\u6307\u6807\u3002`;
2040
+ }
2041
+ const lines = [];
2042
+ lines.push(`## \u4E1A\u52A1\u6307\u6807\u5217\u8868\uFF08serverKey: ${serverKey}\uFF09
2043
+ `);
2044
+ const sortedDatasourceIds = Array.from(metricsByDatasource.keys()).sort();
2045
+ for (const dsId of sortedDatasourceIds) {
2046
+ const metrics = metricsByDatasource.get(dsId);
2047
+ const sortedMetrics = metrics.sort((a, b) => {
2048
+ if (a.domain !== b.domain) {
2049
+ return a.domain.localeCompare(b.domain);
2050
+ }
2051
+ return a.metricName.localeCompare(b.metricName);
2052
+ });
2053
+ lines.push(`### datasourceId: ${dsId}\uFF08${metrics.length} \u4E2A\u6307\u6807\uFF09
2054
+ `);
2055
+ lines.push("| metricName | displayName | domain | shortDesc |");
2056
+ lines.push("|------------|-------------|--------|-----------|");
2057
+ for (const metric of sortedMetrics) {
2058
+ const shortDesc = metric.shortDesc || "";
2059
+ lines.push(`| ${metric.metricName} | ${metric.displayName} | ${metric.domain} | ${shortDesc} |`);
2060
+ }
2061
+ lines.push("");
2062
+ }
2063
+ lines.push("---");
2064
+ lines.push("");
2065
+ lines.push("\u5982\u9700\u67E5\u770B\u6307\u6807\u7684\u8BE6\u7EC6\u5B9A\u4E49\uFF0C\u8BF7\u4F7F\u7528 **query_metric_definition** \u5DE5\u5177\uFF0C\u4F20\u5165\u53C2\u6570\uFF1A`serverKey`\u3001`metricName`\u3001`datasourceId`");
2066
+ return lines.join("\n");
2067
+ } catch (error) {
2068
+ return `Error querying metrics list: ${error instanceof Error ? error.message : String(error)}`;
2069
+ }
2070
+ },
2071
+ {
2072
+ name: "query_metrics_list",
2073
+ description: `${QUERY_METRICS_LIST_DESCRIPTION}${availableServersText}`,
2074
+ schema: z9.object({
2075
+ serverKey: z9.string().describe(`Target semantic metrics server. Choose from: ${serverKeys.join(", ")}`),
2076
+ datasourceIds: z9.array(z9.string()).optional().describe("Optional array of datasource IDs to query. If not provided, uses all selected datasources.")
2077
+ })
2078
+ }
2079
+ );
2080
+ };
2081
+
2082
+ // src/tool_lattice/metrics/query_metric_definition.ts
2083
+ import z10 from "zod";
2084
+ import { tool as tool9 } from "langchain";
2085
+ var QUERY_METRIC_DEFINITION_DESCRIPTION = `Get Metric Definition - Step 2 of the Metrics Workflow
2086
+
2087
+ Read detailed metadata for a specific metric before querying it.
2088
+
2089
+ When to Use This Tool
2090
+ - BEFORE calling query_semantic_metric_data for any metric
2091
+ - When you need to understand time dimensions and supported grains
2092
+ - When you need to know which dimensions are available for GROUP BY and filtering
2093
+
2094
+ When NOT to Use This Tool
2095
+ - You have already retrieved the metric definition in this conversation
2096
+ - You are only listing available metrics (use query_metrics_list instead)
2097
+
2098
+ Key Response Sections
2099
+
2100
+ 1. defaultTimeContext - Time Configuration
2101
+ - timeDimension: Primary date field (e.g., "DocDate")
2102
+ - supportedGrains: Available grains ["day", "week", "month", "year"]
2103
+ - Format: Use "{timeDimension}__{grain}" for time grouping
2104
+
2105
+ 2. supportedDimensions - Available Axes
2106
+ Each dimension has: dim_id, field_name, type (categorical/datetime)
2107
+
2108
+ Filter Patterns by Type:
2109
+ - categorical \u2192 {"dimension": "dim_id", "operator": "IN", "values": ["v1", "v2"]}
2110
+ - datetime \u2192 {"dimension": "dim_id", "operator": "BETWEEN", "values": ["2025-01-01", "2025-12-31"]}
2111
+
2112
+ GroupBy Patterns:
2113
+ - categorical \u2192 Use dim_id directly (e.g., "org_region")
2114
+ - datetime \u2192 Use "{dim_id}__{grain}" (e.g., "DocDate__month")
2115
+
2116
+ Rules
2117
+ - Use dim_id (never field_name) in filters and groupBy
2118
+ - Time grain format: lowercase (day/week/month/year)
2119
+ - Categorical: IN for multiple, EQ for single
2120
+ - Datetime: BETWEEN for ranges, GT/LT for open-ended
2121
+
2122
+ Next Step
2123
+ Call query_semantic_metric_data with parameters derived from this definition.`;
2124
+ var createQueryMetricDefinitionTool = ({ serverKeys, serverDescriptions }) => {
2125
+ const availableServersText = serverKeys.length > 0 ? `
2126
+
2127
+ Available metrics servers:
2128
+ ${serverKeys.map(
2129
+ (key) => `- ${key}${serverDescriptions?.[key] ? `: ${serverDescriptions[key]}` : ""}`
2130
+ ).join("\n")}` : "";
2131
+ return tool9(
2132
+ async ({
2133
+ serverKey,
2134
+ metricName,
2135
+ datasourceId
2136
+ }, _exeConfig) => {
2137
+ try {
2138
+ if (!serverKey) {
2139
+ return "Error: serverKey parameter is required. Available servers: " + serverKeys.join(", ");
2140
+ }
2141
+ if (!serverKeys.includes(serverKey)) {
2142
+ return `Error: serverKey "${serverKey}" is not in the allowed list: [${serverKeys.join(", ")}]`;
2143
+ }
2144
+ if (!metricName) {
2145
+ return "Error: metricName parameter is required.";
2146
+ }
2147
+ const config = metricsServerManager.getConfig(serverKey);
2148
+ if (config.type !== "semantic") {
2149
+ return `Error: Server "${serverKey}" is not a semantic metrics server. This tool only works with semantic servers.`;
2150
+ }
2151
+ const client = metricsServerManager.getClient(serverKey);
2152
+ const targetDatasourceIds = datasourceId ? [datasourceId] : client.getSelectedDataSources();
2153
+ if (targetDatasourceIds.length === 0) {
2154
+ return `Error: No datasourceId specified and no default data sources configured for server "${serverKey}".`;
2155
+ }
2156
+ let foundDetail = null;
2157
+ let foundDatasourceId = null;
2158
+ for (const dsId of targetDatasourceIds) {
2159
+ try {
2160
+ const metaData = await client.getDatasourceMetrics(dsId);
2161
+ const item = metaData.index.metrics.find((m) => m.metricName === metricName);
2162
+ if (item) {
2163
+ const detail = metaData.metricsDetails.find((d) => d.metricName === metricName);
2164
+ if (detail) {
2165
+ foundDetail = detail;
2166
+ foundDatasourceId = dsId;
2167
+ }
2168
+ break;
2169
+ }
2170
+ } catch (error) {
2171
+ console.warn(`Failed to get metrics for datasource ${dsId}:`, error);
2172
+ }
2173
+ }
2174
+ if (!foundDetail) {
2175
+ return `Metric "${metricName}" not found in the specified data sources.`;
2176
+ }
2177
+ const lines = [];
2178
+ lines.push(`# ${foundDetail.displayName} (${foundDetail.metricName})`);
2179
+ lines.push("");
2180
+ lines.push(`## \u57FA\u672C\u4FE1\u606F`);
2181
+ lines.push("");
2182
+ lines.push(`- **\u6307\u6807\u540D\u79F0**: ${foundDetail.metricName}`);
2183
+ lines.push(`- **\u663E\u793A\u540D\u79F0**: ${foundDetail.displayName}`);
2184
+ lines.push(`- **\u6240\u5C5E\u9886\u57DF**: ${foundDetail.domain}`);
2185
+ lines.push(`- **\u6570\u636E\u7C7B\u578B**: ${foundDetail.dataType}`);
2186
+ lines.push(`- **\u663E\u793A\u683C\u5F0F**: ${foundDetail.format}`);
2187
+ if (foundDatasourceId) {
2188
+ lines.push(`- **\u6570\u636E\u6E90ID**: ${foundDatasourceId}`);
2189
+ }
2190
+ lines.push("");
2191
+ lines.push(`## \u6307\u6807\u63CF\u8FF0`);
2192
+ lines.push("");
2193
+ lines.push(foundDetail.description);
2194
+ lines.push("");
2195
+ if (foundDetail.defaultTimeContext) {
2196
+ lines.push(`## \u65F6\u95F4\u4E0A\u4E0B\u6587`);
2197
+ lines.push("");
2198
+ lines.push(`- **\u65F6\u95F4\u7EF4\u5EA6**: ${foundDetail.defaultTimeContext.timeDimension} (${foundDetail.defaultTimeContext.label})`);
2199
+ lines.push(`- **\u9ED8\u8BA4\u7C92\u5EA6**: ${foundDetail.defaultTimeContext.granularity}`);
2200
+ lines.push(`- **\u9ED8\u8BA4\u7A97\u53E3**: ${foundDetail.defaultTimeContext.window}`);
2201
+ lines.push(`- **\u652F\u6301\u7684\u7C92\u5EA6**: ${foundDetail.defaultTimeContext.supportedGrains.join("\u3001")}`);
2202
+ lines.push("");
2203
+ }
2204
+ if (foundDetail.supportedDimensions && foundDetail.supportedDimensions.length > 0) {
2205
+ const categoricalDims = foundDetail.supportedDimensions.filter((d) => d.type === "categorical");
2206
+ const datetimeDims = foundDetail.supportedDimensions.filter((d) => d.type === "datetime");
2207
+ const timeDimension = foundDetail.defaultTimeContext?.timeDimension;
2208
+ lines.push(`## \u652F\u6301\u7684\u7EF4\u5EA6`);
2209
+ lines.push("");
2210
+ if (categoricalDims.length > 0) {
2211
+ lines.push(`### \u5206\u7C7B\u7EF4\u5EA6 (categorical) - ${categoricalDims.length} \u4E2A`);
2212
+ lines.push("\u652F\u6301 IN\uFF08\u591A\u9009\uFF09\u3001EQ\uFF08\u5355\u9009\uFF09\u64CD\u4F5C\u7B26");
2213
+ lines.push("");
2214
+ const examples = categoricalDims.slice(0, 2);
2215
+ for (const dim of examples) {
2216
+ lines.push(`**${dim.dim_id}** (${dim.field_name})`);
2217
+ lines.push("```json");
2218
+ lines.push(`// \u5206\u7EC4\u793A\u4F8B`);
2219
+ lines.push(`"groupBy": ["${dim.dim_id}"]`);
2220
+ lines.push("");
2221
+ lines.push(`// \u8FC7\u6EE4\u793A\u4F8B`);
2222
+ lines.push(`{"dimension": "${dim.dim_id}", "operator": "IN", "values": ["value1", "value2"]}`);
2223
+ lines.push("```");
2224
+ lines.push("");
2225
+ }
2226
+ if (categoricalDims.length > 2) {
2227
+ const others = categoricalDims.slice(2).map((d) => d.dim_id).join("\u3001");
2228
+ lines.push(`**\u5176\u4ED6 ${categoricalDims.length - 2} \u4E2A\u7EF4\u5EA6**: ${others}`);
2229
+ lines.push("");
2230
+ }
2231
+ }
2232
+ if (datetimeDims.length > 0) {
2233
+ lines.push(`### \u65F6\u95F4\u7EF4\u5EA6 (datetime) - ${datetimeDims.length} \u4E2A`);
2234
+ lines.push("\u652F\u6301 BETWEEN\uFF08\u8303\u56F4\uFF09\u3001GT/GTE/LT/LTE\uFF08\u6BD4\u8F83\uFF09\u64CD\u4F5C\u7B26");
2235
+ lines.push("");
2236
+ const primaryDim = datetimeDims.find((d) => d.dim_id === timeDimension) || datetimeDims[0];
2237
+ lines.push(`**${primaryDim.dim_id}** (${primaryDim.field_name})`);
2238
+ lines.push("```json");
2239
+ lines.push(`// \u6309\u65F6\u95F4\u7C92\u5EA6\u5206\u7EC4`);
2240
+ lines.push(`"groupBy": ["${primaryDim.dim_id}__month"] // \u53EF\u9009: day, week, month, year`);
2241
+ lines.push("");
2242
+ lines.push(`// \u65F6\u95F4\u8303\u56F4\u8FC7\u6EE4`);
2243
+ lines.push(`{"dimension": "${primaryDim.dim_id}", "operator": "BETWEEN", "values": ["2025-01-01", "2025-12-31"]}`);
2244
+ lines.push("```");
2245
+ lines.push("");
2246
+ if (datetimeDims.length > 1) {
2247
+ const others = datetimeDims.filter((d) => d.dim_id !== primaryDim.dim_id).map((d) => d.dim_id).join("\u3001");
2248
+ lines.push(`**\u5176\u4ED6\u65F6\u95F4\u7EF4\u5EA6**: ${others}`);
2249
+ lines.push("");
2250
+ }
2251
+ }
2252
+ lines.push("### \u5FEB\u901F\u53C2\u8003");
2253
+ lines.push("");
2254
+ lines.push("**\u65F6\u95F4\u5206\u7EC4\u683C\u5F0F**: `{timeDimension}__{grain}`");
2255
+ lines.push("- \u6309\u5929: `DocDate__day`");
2256
+ lines.push("- \u6309\u5468: `DocDate__week`");
2257
+ lines.push("- \u6309\u6708: `DocDate__month`");
2258
+ lines.push("- \u6309\u5E74: `DocDate__year`");
2259
+ lines.push("");
2260
+ }
2261
+ if (foundDetail.aiAgentContext) {
2262
+ const aiContext = foundDetail.aiAgentContext;
2263
+ lines.push(`## AI \u5206\u6790\u4E0A\u4E0B\u6587`);
2264
+ lines.push("");
2265
+ lines.push(`### \u6307\u6807\u6781\u6027`);
2266
+ lines.push("");
2267
+ lines.push(aiContext.polarity === "positive" ? "\u6B63\u5411\u6307\u6807\uFF08\u8D8A\u9AD8\u8D8A\u597D\uFF09" : "\u8D1F\u5411\u6307\u6807\uFF08\u8D8A\u4F4E\u8D8A\u597D\uFF09");
2268
+ lines.push("");
2269
+ if (aiContext.synonyms && aiContext.synonyms.length > 0) {
2270
+ lines.push(`### \u540C\u4E49\u8BCD/\u522B\u540D`);
2271
+ lines.push("");
2272
+ lines.push(aiContext.synonyms.join("\u3001"));
2273
+ lines.push("");
2274
+ }
2275
+ if (aiContext.thresholds && aiContext.thresholds.length > 0) {
2276
+ lines.push(`### \u9884\u8B66\u9608\u503C`);
2277
+ lines.push("");
2278
+ lines.push("| \u6307\u6807 | \u8FD0\u7B97\u7B26 | \u9608\u503C | \u7EA7\u522B |");
2279
+ lines.push("|------|--------|------|------|");
2280
+ for (const t of aiContext.thresholds) {
2281
+ lines.push(`| ${t.metric} | ${t.operator} | ${t.value} | ${t.level} |`);
2282
+ }
2283
+ lines.push("");
2284
+ }
2285
+ if (aiContext.diagnosticWorkflow) {
2286
+ lines.push(`### \u8BCA\u65AD\u5DE5\u4F5C\u6D41`);
2287
+ lines.push("");
2288
+ if (aiContext.diagnosticWorkflow.trigger && aiContext.diagnosticWorkflow.trigger.any_of) {
2289
+ lines.push(`**\u89E6\u53D1\u6761\u4EF6** (\u6EE1\u8DB3\u4EFB\u4E00):`);
2290
+ for (const trigger of aiContext.diagnosticWorkflow.trigger.any_of) {
2291
+ lines.push(`- ${trigger.metric} ${trigger.operator} ${trigger.value}`);
2292
+ }
2293
+ lines.push("");
2294
+ }
2295
+ if (aiContext.diagnosticWorkflow.actions && aiContext.diagnosticWorkflow.actions.length > 0) {
2296
+ lines.push(`**\u5206\u6790\u52A8\u4F5C**:`);
2297
+ for (let i = 0; i < aiContext.diagnosticWorkflow.actions.length; i++) {
2298
+ const action = aiContext.diagnosticWorkflow.actions[i];
2299
+ lines.push(`${i + 1}. **${action.type}**`);
2300
+ if (action.metric) {
2301
+ lines.push(` - \u5BF9\u6BD4\u6307\u6807: ${action.metric}`);
2302
+ }
2303
+ if (action.dimensions && action.dimensions.length > 0) {
2304
+ lines.push(` - \u4E0B\u94BB\u7EF4\u5EA6: ${action.dimensions.join("\u3001")}`);
2305
+ }
2306
+ lines.push(` - \u76EE\u7684: ${action.intent}`);
2307
+ }
2308
+ lines.push("");
2309
+ }
2310
+ if (aiContext.diagnosticWorkflow.analysis_logic) {
2311
+ lines.push(`**\u5206\u6790\u903B\u8F91**: ${aiContext.diagnosticWorkflow.analysis_logic}`);
2312
+ lines.push("");
2313
+ }
2314
+ }
2315
+ if (aiContext.humanReadableExplanation) {
2316
+ lines.push(`### \u7CFB\u7EDF\u5EFA\u8BAE`);
2317
+ lines.push("");
2318
+ lines.push(aiContext.humanReadableExplanation);
2319
+ lines.push("");
2320
+ }
2321
+ }
2322
+ lines.push(`---`);
2323
+ lines.push("");
2324
+ lines.push(`## \u4F7F\u7528\u793A\u4F8B`);
2325
+ lines.push("");
2326
+ lines.push(`\u67E5\u8BE2\u6B64\u6307\u6807\u65F6\uFF0C\u4F7F\u7528 query_semantic_metric_data \u5DE5\u5177\uFF0C\u53C2\u6570:`);
2327
+ lines.push(`- **metricName**: "${foundDetail.metricName}"`);
2328
+ if (foundDatasourceId) {
2329
+ lines.push(`- **datasourceId**: "${foundDatasourceId}"`);
2330
+ }
2331
+ return lines.join("\n");
2332
+ } catch (error) {
2333
+ return `Error querying metric definition: ${error instanceof Error ? error.message : String(error)}`;
2334
+ }
2335
+ },
2336
+ {
2337
+ name: "query_metric_definition",
2338
+ description: `${QUERY_METRIC_DEFINITION_DESCRIPTION}${availableServersText}`,
2339
+ schema: z10.object({
2340
+ serverKey: z10.string().describe(`Target semantic metrics server. Choose from: ${serverKeys.join(", ")}`),
2341
+ metricName: z10.string().describe("The name of the metric to get definition for."),
2342
+ datasourceId: z10.string().optional().describe("Optional specific datasource ID to search in. If not provided, searches all selected datasources.")
2343
+ })
2344
+ }
2345
+ );
2346
+ };
2347
+
2348
+ // src/tool_lattice/metrics/query_semantic_metric_data.ts
2349
+ import z11 from "zod";
2350
+ import { tool as tool10 } from "langchain";
2351
+ var QUERY_SEMANTIC_METRIC_DATA_DESCRIPTION = `Query Metric Data - Step 3 of the Metrics Workflow
2352
+
2353
+ Execute queries with the correct parameters derived from metric definitions. This tool requires you to have already discovered and understood the metric metadata.
2354
+
2355
+ When to Use This Tool
2356
+ Use this tool proactively in these scenarios:
2357
+ - When you have the metricName and have read its definition via query_metric_definition
2358
+ - When executing time trend analysis, dimension breakdowns, or drill-downs
2359
+ - When comparing multiple metrics side-by-side
2360
+
2361
+ When NOT to Use This Tool
2362
+ Skip using this tool when:
2363
+ - You haven't retrieved the metric definition yet (call query_metric_definition first)
2364
+ - You're unsure about supported dimensions or time grains for this metric
2365
+
2366
+ Prerequisites - MUST Complete First
2367
+ 1. Call query_metrics_list to discover available metrics
2368
+ 2. Call query_metric_definition(metricName) to get:
2369
+ - defaultTimeContext.timeDimension (e.g., "DocDate")
2370
+ - defaultTimeContext.supportedGrains (e.g., ["day", "week", "month", "year"])
2371
+ - supportedDimensions[].dim_id (use these for groupBy and filters)
2372
+ - supportedDimensions[].filter_operators (allowed operators per dimension)
2373
+
2374
+ The Five Query Patterns
2375
+
2376
+ Pattern A - Time Trend (most common first query)
2377
+ Goal: Show how a metric changes over time within a period
2378
+ {
2379
+ "metrics": ["order_amt_tax_inc"],
2380
+ "groupBy": ["DocDate__month"],
2381
+ "filters": [{ "dimension": "DocDate", "operator": "BETWEEN", "values": ["2025-01-01", "2025-12-31"] }],
2382
+ "orderBy": [{ "field": "DocDate__month", "direction": "ASC" }]
2383
+ }
2384
+
2385
+ Pattern B - Dimension Breakdown (who/what is top or bottom)
2386
+ Goal: Rank performance across a categorical dimension in a fixed period
2387
+ {
2388
+ "metrics": ["order_amt_tax_inc"],
2389
+ "groupBy": ["org_region"],
2390
+ "filters": [{ "dimension": "DocDate", "operator": "BETWEEN", "values": ["2025-01-01", "2025-03-31"] }],
2391
+ "orderBy": [{ "field": "value", "direction": "DESC" }],
2392
+ "limit": 10
2393
+ }
2394
+
2395
+ Pattern C - Drill Down (zoom into an anomaly)
2396
+ Goal: After Pattern A reveals a bad month, find which segment caused it
2397
+ Step 1 - Monthly trend to find anomaly (Pattern A)
2398
+ Step 2 - Drill into that month by adding categorical dimension:
2399
+ {
2400
+ "groupBy": ["sales_person"],
2401
+ "filters": [
2402
+ { "dimension": "DocDate", "operator": "BETWEEN", "values": ["2025-06-01", "2025-06-30"] },
2403
+ { "dimension": "org_region", "operator": "EQ", "values": ["\u534E\u4E1C"] }
2404
+ ],
2405
+ "orderBy": [{ "field": "value", "direction": "ASC" }]
2406
+ }
2407
+
2408
+ Pattern D - Multi-Metric Comparison
2409
+ Goal: Query two or more metrics in one call to compare side-by-side
2410
+ {
2411
+ "metrics": ["order_amt_tax_inc", "net_sales_amt"],
2412
+ "groupBy": ["DocDate__month"],
2413
+ "filters": [{ "dimension": "DocDate", "operator": "BETWEEN", "values": ["2025-01-01", "2025-12-31"] }],
2414
+ "orderBy": [{ "field": "DocDate__month", "direction": "ASC" }]
2415
+ }
2416
+
2417
+ Pattern E - Time x Dimension Cross-Analysis
2418
+ Goal: See how a dimension behaves across time (e.g., monthly sales by region)
2419
+ {
2420
+ "metrics": ["order_amt_tax_inc"],
2421
+ "groupBy": ["DocDate__month", "org_region"],
2422
+ "filters": [{ "dimension": "DocDate", "operator": "BETWEEN", "values": ["2025-01-01", "2025-06-30"] }],
2423
+ "orderBy": [
2424
+ { "field": "DocDate__month", "direction": "ASC" },
2425
+ { "field": "org_region", "direction": "ASC" }
2426
+ ]
2427
+ }
2428
+
2429
+ Filter Operator Reference
2430
+ | Operator | Applies To | Values Array |
2431
+ |----------|------------|--------------|
2432
+ | BETWEEN | datetime, number | [min, max] (inclusive) |
2433
+ | IN | categorical | ["v1", "v2", ...] |
2434
+ | EQ | any | ["v"] |
2435
+ | NEQ | any | ["v"] |
2436
+ | GT / GTE | datetime, number | ["v"] |
2437
+ | LT / LTE | datetime, number | ["v"] |
2438
+ | LIKE | string | ["%pattern%"] |
2439
+ | NOT_NULL | any | [] |
2440
+
2441
+ Common Mistakes to Avoid
2442
+ - Using field_name (e.g., "SlpName") instead of dim_id (e.g., "sales_person")
2443
+ - Writing "DocDate__Month" (capital M) - always lowercase: "DocDate__month"
2444
+ - Omitting date filter entirely - ALWAYS include at least one DocDate filter
2445
+ - Querying a metric by an unsupported dimension - only use dim_id from supportedDimensions
2446
+ - Putting display name in orderBy.field - must match exactly what's in groupBy
2447
+
2448
+ Recommended Analysis Flow
2449
+ User question
2450
+ |
2451
+ \u25BC
2452
+ Step 1: query_metrics_list - find matching metric(s)
2453
+ |
2454
+ \u25BC
2455
+ Step 2: query_metric_definition - read defaultTimeContext + supportedDimensions
2456
+ |
2457
+ \u25BC
2458
+ Step 3a: Pattern A (time trend) - get the big picture
2459
+ |
2460
+ \u251C\u2500 anomaly found? \u2500\u2500\u25BA Step 3c: Pattern C (drill down)
2461
+ \u251C\u2500 user asks "who"? \u2500\u2500\u25BA Step 3b: Pattern B (dimension breakdown)
2462
+ \u2514\u2500 user asks "compare X and Y"? \u2500\u2500\u25BA Step 3d: Pattern D (multi-metric)
2463
+
2464
+ Debug Mode
2465
+ Set "debug": true to receive executedSqls in the response to verify generated SQL.`;
2466
+ function formatSemanticQueryResult(datasourceId, datasourceName, results) {
2467
+ if (results.length === 0) {
2468
+ return `No data found for the specified query.
2469
+ Data Source: ${datasourceId}${datasourceName ? ` (${datasourceName})` : ""}`;
2470
+ }
2471
+ const lines = [];
2472
+ lines.push(`# \u6307\u6807\u67E5\u8BE2\u7ED3\u679C`);
2473
+ lines.push(`
2474
+ **\u6570\u636E\u6E90**: ${datasourceId}${datasourceName ? ` (${datasourceName})` : ""}`);
2475
+ lines.push(`**\u6307\u6807\u6570**: ${results.length}`);
2476
+ lines.push(`
2477
+ ---
2478
+ `);
2479
+ for (const metric of results) {
2480
+ lines.push(`## ${metric.displayName} (${metric.metricName})`);
2481
+ lines.push(`
2482
+ - **\u6570\u636E\u7C7B\u578B**: ${metric.dataType}`);
2483
+ lines.push(`- **\u683C\u5F0F**: ${metric.format}`);
2484
+ lines.push(`- **\u6781\u6027**: ${metric.polarity}`);
2485
+ lines.push(`- **\u6267\u884C\u8017\u65F6**: ${metric.executionTimeMs}ms`);
2486
+ lines.push(`- **\u8FD4\u56DE\u884C\u6570**: ${metric.rowCount}`);
2487
+ if (metric.columns.length > 0 && metric.rows.length > 0) {
2488
+ lines.push(`
2489
+ ### \u6570\u636E
2490
+ `);
2491
+ lines.push(`| ${metric.columns.join(" | ")} |`);
2492
+ lines.push(`|${metric.columns.map(() => "---").join("|")}|`);
2493
+ for (const row of metric.rows) {
2494
+ const rowValues = metric.columns.map((col) => {
2495
+ const val = row[col];
2496
+ return val !== void 0 ? String(val) : "";
2497
+ });
2498
+ lines.push(`| ${rowValues.join(" | ")} |`);
2499
+ }
2500
+ }
2501
+ if (metric.aiHints) {
2502
+ lines.push(`
2503
+ ### AI \u5206\u6790\u5EFA\u8BAE
2504
+ `);
2505
+ lines.push(`- **\u6307\u6807\u89E3\u91CA**: ${metric.aiHints.valueInterpretation}`);
2506
+ if (metric.aiHints.thresholds && metric.aiHints.thresholds.length > 0) {
2507
+ lines.push(`- **\u9884\u8B66\u9608\u503C**:`);
2508
+ for (const t of metric.aiHints.thresholds) {
2509
+ lines.push(` - ${t.metric} ${t.operator} ${t.value} (${t.level})`);
2510
+ }
2511
+ }
2512
+ if (metric.aiHints.suggestedFollowup && metric.aiHints.suggestedFollowup.length > 0) {
2513
+ lines.push(`- **\u5EFA\u8BAE\u540E\u7EED\u5206\u6790**:`);
2514
+ for (const suggestion of metric.aiHints.suggestedFollowup) {
2515
+ lines.push(` - ${suggestion}`);
2516
+ }
2517
+ }
2518
+ }
2519
+ lines.push(`
2520
+ ---
2521
+ `);
2522
+ }
2523
+ return lines.join("\n");
2524
+ }
2525
+ var createQuerySemanticMetricDataTool = ({ serverKeys, serverDescriptions }) => {
2526
+ const availableServersText = serverKeys.length > 0 ? `
2527
+
2528
+ Available metrics servers:
2529
+ ${serverKeys.map(
2530
+ (key) => `- ${key}${serverDescriptions?.[key] ? `: ${serverDescriptions[key]}` : ""}`
2531
+ ).join("\n")}` : "";
2532
+ return tool10(
2533
+ async ({
2534
+ serverKey,
2535
+ datasourceId,
2536
+ metrics,
2537
+ groupBy,
2538
+ filters,
2539
+ limit
2540
+ }, _exeConfig) => {
2541
+ try {
2542
+ if (!serverKey) {
2543
+ return "Error: serverKey parameter is required. Available servers: " + serverKeys.join(", ");
2544
+ }
2545
+ if (!serverKeys.includes(serverKey)) {
2546
+ return `Error: serverKey "${serverKey}" is not in the allowed list: [${serverKeys.join(", ")}]`;
2547
+ }
2548
+ if (!datasourceId) {
2549
+ return "Error: datasourceId parameter is required.";
2550
+ }
2551
+ if (!metrics || metrics.length === 0) {
2552
+ return "Error: metrics parameter is required (at least one metric name).";
2553
+ }
2554
+ const config = metricsServerManager.getConfig(serverKey);
2555
+ if (config.type !== "semantic") {
2556
+ return `Error: Server "${serverKey}" is not a semantic metrics server. This tool only works with semantic servers.`;
2557
+ }
2558
+ const client = metricsServerManager.getClient(serverKey);
2559
+ const semanticFilters = (filters || []).map((f) => ({
2560
+ dimension: f.dimension,
2561
+ operator: f.operator,
2562
+ values: f.values
2563
+ }));
2564
+ const result = await client.semanticQuery({
2565
+ datasourceId,
2566
+ metrics,
2567
+ groupBy,
2568
+ filters: semanticFilters,
2569
+ limit: limit || 1e3
2570
+ });
2571
+ return formatSemanticQueryResult(
2572
+ result.datasourceId,
2573
+ result.datasourceName,
2574
+ result.results
2575
+ );
2576
+ } catch (error) {
2577
+ return `Error querying semantic metric data: ${error instanceof Error ? error.message : String(error)}`;
2578
+ }
2579
+ },
2580
+ {
2581
+ name: "query_semantic_metric_data",
2582
+ description: `${QUERY_SEMANTIC_METRIC_DATA_DESCRIPTION}${availableServersText}`,
2583
+ schema: z11.object({
2584
+ serverKey: z11.string().describe(`Target semantic metrics server. Choose from: ${serverKeys.join(", ")}`),
2585
+ datasourceId: z11.string().describe("The data source ID to query metrics from."),
2586
+ metrics: z11.array(z11.string()).describe("Array of metric names to query (e.g., ['net_sales_amt', 'gross_profit'])."),
2587
+ groupBy: z11.array(z11.string()).optional().describe("Optional array of dimensions to group by (e.g., ['DocDate__month', 'CustomerCode'])."),
2588
+ filters: z11.array(z11.object({
2589
+ dimension: z11.string().describe("Dimension/column name to filter on"),
2590
+ operator: z11.string().describe("Operator (e.g., 'BETWEEN', '=', '>', '<')"),
2591
+ values: z11.array(z11.union([z11.string(), z11.number(), z11.boolean()])).describe("Filter values")
2592
+ })).optional().describe("Optional array of filters to apply to the query."),
2593
+ limit: z11.number().optional().describe("Maximum number of results to return (default: 1000).")
2594
+ })
2595
+ }
2596
+ );
2597
+ };
2598
+
2599
+ // src/tool_lattice/metrics/query_tables_list.ts
2600
+ import z12 from "zod";
2601
+ import { tool as tool11 } from "langchain";
2602
+ var QUERY_TABLES_LIST_DESCRIPTION = `Query available tables from a semantic metrics server. Returns a list of data tables with their schemas and descriptions. Use this tool to discover what tables are available in the data source.`;
2603
+ var createQueryTablesListTool = ({ serverKeys, serverDescriptions }) => {
2604
+ const availableServersText = serverKeys.length > 0 ? `
2605
+
2606
+ Available metrics servers:
2607
+ ${serverKeys.map(
2608
+ (key) => `- ${key}${serverDescriptions?.[key] ? `: ${serverDescriptions[key]}` : ""}`
2609
+ ).join("\n")}` : "";
2610
+ return tool11(
2611
+ async ({
2612
+ serverKey,
2613
+ datasourceIds
2614
+ }, _exeConfig) => {
2615
+ try {
2616
+ if (!serverKey) {
2617
+ return "Error: serverKey parameter is required. Available servers: " + serverKeys.join(", ");
2618
+ }
2619
+ if (!serverKeys.includes(serverKey)) {
2620
+ return `Error: serverKey "${serverKey}" is not in the allowed list: [${serverKeys.join(", ")}]`;
2621
+ }
2622
+ const config = metricsServerManager.getConfig(serverKey);
2623
+ if (config.type !== "semantic") {
2624
+ return `Error: Server "${serverKey}" is not a semantic metrics server. This tool only works with semantic servers.`;
2625
+ }
2626
+ const client = metricsServerManager.getClient(serverKey);
2627
+ const targetDatasourceIds = datasourceIds && datasourceIds.length > 0 ? datasourceIds : client.getSelectedDataSources();
2628
+ if (targetDatasourceIds.length === 0) {
2629
+ return `Error: No data sources specified and no default data sources configured for server "${serverKey}".`;
2630
+ }
2631
+ const allTables = /* @__PURE__ */ new Map();
2632
+ for (const datasourceId of targetDatasourceIds) {
2633
+ try {
2634
+ const metaData = await client.getDatasourceMetrics(datasourceId);
2635
+ const index = metaData.index;
2636
+ for (const item of index.tables) {
2637
+ const tableKey = item.tableName;
2638
+ if (allTables.has(tableKey)) {
2639
+ const existing = allTables.get(tableKey);
2640
+ if (!existing.datasources.includes(datasourceId)) {
2641
+ existing.datasources.push(datasourceId);
2642
+ }
2643
+ } else {
2644
+ allTables.set(tableKey, {
2645
+ tableName: item.tableName,
2646
+ displayName: item.displayName,
2647
+ docType: item.docType,
2648
+ docTypeEn: item.docTypeEn,
2649
+ mainTable: item.mainTable,
2650
+ lineTable: item.lineTable,
2651
+ columnCount: item.columnCount,
2652
+ shortDesc: item.shortDesc,
2653
+ datasources: [datasourceId]
2654
+ });
2655
+ }
2656
+ }
2657
+ } catch (error) {
2658
+ console.warn(`Failed to get tables for datasource ${datasourceId}:`, error);
2659
+ }
2660
+ }
2661
+ if (allTables.size === 0) {
2662
+ return `\u672A\u5728\u6307\u5B9A\u7684\u6570\u636E\u6E90\u4E2D\u627E\u5230\u6570\u636E\u8868\u3002`;
2663
+ }
2664
+ const lines = [];
2665
+ lines.push(`## \u6570\u636E\u8868\u5217\u8868\uFF08\u5171 ${allTables.size} \u4E2A\uFF09
2666
+ `);
2667
+ const sortedTables = Array.from(allTables.values()).sort(
2668
+ (a, b) => a.tableName.localeCompare(b.tableName)
2669
+ );
2670
+ lines.push("| \u8868\u540D | \u663E\u793A\u540D\u79F0 | \u5355\u636E\u7C7B\u578B | \u5217\u6570 | \u63CF\u8FF0 |");
2671
+ lines.push("|------|---------|---------|------|------|");
2672
+ for (const table of sortedTables) {
2673
+ const mainTableInfo = table.mainTable ? ` (\u4E3B\u8868: ${table.mainTable})` : "";
2674
+ const lineTableInfo = table.lineTable ? ` (\u884C\u8868: ${table.lineTable})` : "";
2675
+ const tableRelation = mainTableInfo + lineTableInfo;
2676
+ lines.push(`| ${table.tableName} | ${table.displayName} | ${table.docType}${tableRelation} | ${table.columnCount} | ${table.shortDesc} |`);
2677
+ }
2678
+ return lines.join("\n");
2679
+ } catch (error) {
2680
+ return `Error querying tables list: ${error instanceof Error ? error.message : String(error)}`;
2681
+ }
2682
+ },
2683
+ {
2684
+ name: "query_tables_list",
2685
+ description: `${QUERY_TABLES_LIST_DESCRIPTION}${availableServersText}`,
2686
+ schema: z12.object({
2687
+ serverKey: z12.string().describe(`Target semantic metrics server. Choose from: ${serverKeys.join(", ")}`),
2688
+ datasourceIds: z12.array(z12.string()).optional().describe("Optional array of datasource IDs to query. If not provided, uses all selected datasources.")
2689
+ })
2690
+ }
2691
+ );
2692
+ };
2693
+
2694
+ // src/tool_lattice/metrics/query_table_definition.ts
2695
+ import z13 from "zod";
2696
+ import { tool as tool12 } from "langchain";
2697
+ var QUERY_TABLE_DEFINITION_DESCRIPTION = `Get detailed definition and schema for a specific table from a semantic metrics server. Returns comprehensive information including column definitions, SQL query, and table relationships.`;
2698
+ var createQueryTableDefinitionTool = ({ serverKeys, serverDescriptions }) => {
2699
+ const availableServersText = serverKeys.length > 0 ? `
2700
+
2701
+ Available metrics servers:
2702
+ ${serverKeys.map(
2703
+ (key) => `- ${key}${serverDescriptions?.[key] ? `: ${serverDescriptions[key]}` : ""}`
2704
+ ).join("\n")}` : "";
2705
+ return tool12(
2706
+ async ({
2707
+ serverKey,
2708
+ tableName,
2709
+ datasourceId
2710
+ }, _exeConfig) => {
2711
+ try {
2712
+ if (!serverKey) {
2713
+ return "Error: serverKey parameter is required. Available servers: " + serverKeys.join(", ");
2714
+ }
2715
+ if (!serverKeys.includes(serverKey)) {
2716
+ return `Error: serverKey "${serverKey}" is not in the allowed list: [${serverKeys.join(", ")}]`;
2717
+ }
2718
+ if (!tableName) {
2719
+ return "Error: tableName parameter is required.";
2720
+ }
2721
+ const config = metricsServerManager.getConfig(serverKey);
2722
+ if (config.type !== "semantic") {
2723
+ return `Error: Server "${serverKey}" is not a semantic metrics server. This tool only works with semantic servers.`;
2724
+ }
2725
+ const client = metricsServerManager.getClient(serverKey);
2726
+ const targetDatasourceIds = datasourceId ? [datasourceId] : client.getSelectedDataSources();
2727
+ if (targetDatasourceIds.length === 0) {
2728
+ return `Error: No datasourceId specified and no default data sources configured for server "${serverKey}".`;
2729
+ }
2730
+ let foundTable = null;
2731
+ let foundDatasourceId = null;
2732
+ for (const dsId of targetDatasourceIds) {
2733
+ try {
2734
+ const metaData = await client.getDatasourceMetrics(dsId);
2735
+ const tableDetail = metaData.tablesDetails?.find((t) => t.tableName === tableName);
2736
+ if (tableDetail) {
2737
+ foundTable = tableDetail;
2738
+ foundDatasourceId = dsId;
2739
+ break;
2740
+ }
2741
+ } catch (error) {
2742
+ console.warn(`Failed to get table definition for datasource ${dsId}:`, error);
2743
+ }
2744
+ }
2745
+ if (!foundTable) {
2746
+ return `Table "${tableName}" not found in the specified data sources.`;
2747
+ }
2748
+ const lines = [];
2749
+ lines.push(`# ${foundTable.tableName}`);
2750
+ lines.push("");
2751
+ lines.push(`## \u57FA\u672C\u4FE1\u606F`);
2752
+ lines.push("");
2753
+ lines.push(`- **\u8868\u540D**: ${foundTable.tableName}`);
2754
+ lines.push(`- **\u5355\u636E\u7C7B\u578B**: ${foundTable.docType}`);
2755
+ lines.push(`- **\u5355\u636E\u7C7B\u578B(\u82F1\u6587)**: ${foundTable.docTypeEn}`);
2756
+ if (foundTable.objTypeCode) {
2757
+ lines.push(`- **\u5BF9\u8C61\u7C7B\u578B\u4EE3\u7801**: ${foundTable.objTypeCode}`);
2758
+ }
2759
+ if (foundTable.mainTable) {
2760
+ lines.push(`- **\u4E3B\u8868**: ${foundTable.mainTable}`);
2761
+ }
2762
+ if (foundTable.lineTable) {
2763
+ lines.push(`- **\u884C\u8868**: ${foundTable.lineTable}`);
2764
+ }
2765
+ if (foundDatasourceId) {
2766
+ lines.push(`- **\u6570\u636E\u6E90ID**: ${foundDatasourceId}`);
2767
+ }
2768
+ lines.push("");
2769
+ if (foundTable.columns && foundTable.columns.length > 0) {
2770
+ const validColumns = foundTable.columns.filter((col) => col !== null);
2771
+ lines.push(`## \u5217\u5B9A\u4E49 (${validColumns.length} \u5217)`);
2772
+ lines.push("");
2773
+ lines.push("| \u5217\u540D | \u6807\u7B7E | \u7C7B\u578B | \u793A\u4F8B\u503C |");
2774
+ lines.push("|------|------|------|--------|");
2775
+ for (const col of validColumns) {
2776
+ const type = col.type || "-";
2777
+ const example = col.example || "-";
2778
+ lines.push(`| ${col.name} | ${col.label} | ${type} | ${example} |`);
2779
+ }
2780
+ lines.push("");
2781
+ }
2782
+ if (foundTable.selectSql) {
2783
+ lines.push(`## SQL \u67E5\u8BE2`);
2784
+ lines.push("");
2785
+ lines.push("```sql");
2786
+ lines.push(foundTable.selectSql);
2787
+ lines.push("```");
2788
+ lines.push("");
2789
+ }
2790
+ return lines.join("\n");
2791
+ } catch (error) {
2792
+ return `Error querying table definition: ${error instanceof Error ? error.message : String(error)}`;
2793
+ }
2794
+ },
2795
+ {
2796
+ name: "query_table_definition",
2797
+ description: `${QUERY_TABLE_DEFINITION_DESCRIPTION}${availableServersText}`,
2798
+ schema: z13.object({
2799
+ serverKey: z13.string().describe(`Target semantic metrics server. Choose from: ${serverKeys.join(", ")}`),
2800
+ tableName: z13.string().describe("The name of the table to get definition for."),
2801
+ datasourceId: z13.string().optional().describe("Optional specific datasource ID to search in. If not provided, searches all selected datasources.")
2802
+ })
2803
+ }
2804
+ );
2805
+ };
2806
+
1220
2807
  // src/tool_lattice/code_eval/index.ts
1221
- import z7 from "zod";
2808
+ import z14 from "zod";
1222
2809
 
1223
2810
  // src/sandbox_lattice/SandboxLatticeManager.ts
1224
2811
  import { SandboxClient } from "@agent-infra/sandbox";
@@ -1457,7 +3044,7 @@ var getSandBoxManager = (key = "default") => {
1457
3044
  };
1458
3045
 
1459
3046
  // src/tool_lattice/code_eval/index.ts
1460
- import { tool as tool6 } from "langchain";
3047
+ import { tool as tool13 } from "langchain";
1461
3048
  var CODE_EVAL_DESCRIPTION = `Execute code in Python or JavaScript runtime.
1462
3049
 
1463
3050
  Args:
@@ -1467,7 +3054,7 @@ Args:
1467
3054
  Returns:
1468
3055
  Dict containing output, errors, and execution details`;
1469
3056
  var createCodeEvalTool = ({ isolatedLevel }) => {
1470
- return tool6(async (input, exe_config) => {
3057
+ return tool13(async (input, exe_config) => {
1471
3058
  try {
1472
3059
  const runConfig = exe_config.configurable?.runConfig;
1473
3060
  const sandboxManager = getSandBoxManager();
@@ -1508,16 +3095,16 @@ ${traceback.join("\n")}`);
1508
3095
  }, {
1509
3096
  name: "execute_code",
1510
3097
  description: CODE_EVAL_DESCRIPTION,
1511
- schema: z7.object({
1512
- language: z7.enum(["python", "javascript"]).describe("Programming language: 'python' or 'javascript'"),
1513
- code: z7.string().describe("Code to execute")
3098
+ schema: z14.object({
3099
+ language: z14.enum(["python", "javascript"]).describe("Programming language: 'python' or 'javascript'"),
3100
+ code: z14.string().describe("Code to execute")
1514
3101
  })
1515
3102
  });
1516
3103
  };
1517
3104
 
1518
3105
  // src/tool_lattice/code_execute_file/index.ts
1519
- import z8 from "zod";
1520
- import { tool as tool7 } from "langchain";
3106
+ import z15 from "zod";
3107
+ import { tool as tool14 } from "langchain";
1521
3108
  import * as path from "path";
1522
3109
  var CODE_EXECUTE_FILE_DESCRIPTION = `Execute a code file from the sandbox filesystem. Only supports Python (.py) and JavaScript (.js, .mjs) files. Other file types are not supported. The tool reads the file content and executes it in an isolated sandbox environment. Language is automatically inferred from the file extension. Output is returned via stdout; errors appear in stderr and traceback.`;
1523
3110
  function inferLanguageFromPath(filePath) {
@@ -1530,7 +3117,7 @@ function inferLanguageFromPath(filePath) {
1530
3117
  return null;
1531
3118
  }
1532
3119
  var createCodeExecuteFileTool = ({ isolatedLevel }) => {
1533
- return tool7(
3120
+ return tool14(
1534
3121
  async (input, exe_config) => {
1535
3122
  try {
1536
3123
  const runConfig = exe_config.configurable?.runConfig;
@@ -1593,15 +3180,15 @@ ${traceback.join("\n")}`);
1593
3180
  {
1594
3181
  name: "execute_code_file",
1595
3182
  description: CODE_EXECUTE_FILE_DESCRIPTION,
1596
- schema: z8.object({
1597
- file_path: z8.string().describe("Path to the code file to execute (absolute path in sandbox filesystem). Only supports .py (Python) and .js/.mjs (JavaScript) files.")
3183
+ schema: z15.object({
3184
+ file_path: z15.string().describe("Path to the code file to execute (absolute path in sandbox filesystem). Only supports .py (Python) and .js/.mjs (JavaScript) files.")
1598
3185
  })
1599
3186
  }
1600
3187
  );
1601
3188
  };
1602
3189
 
1603
3190
  // src/tool_lattice/convert_to_markdown/index.ts
1604
- import z9 from "zod";
3191
+ import z16 from "zod";
1605
3192
  var CONVERT_TO_MARKDOWN_DESCRIPTION = `Convert a resource described by an http:, https:, file: or data: URI to markdown.
1606
3193
 
1607
3194
  Args:
@@ -1618,8 +3205,8 @@ registerToolLattice(
1618
3205
  name: "convert_to_markdown",
1619
3206
  description: CONVERT_TO_MARKDOWN_DESCRIPTION,
1620
3207
  needUserApprove: false,
1621
- schema: z9.object({
1622
- uri: z9.string().describe("The URI to convert.")
3208
+ schema: z16.object({
3209
+ uri: z16.string().describe("The URI to convert.")
1623
3210
  })
1624
3211
  },
1625
3212
  async (input, exe_config) => {
@@ -1642,15 +3229,15 @@ registerToolLattice(
1642
3229
  );
1643
3230
 
1644
3231
  // src/tool_lattice/browser/browser_navigate.ts
1645
- import z10 from "zod";
1646
- import { tool as tool8 } from "langchain";
3232
+ import z17 from "zod";
3233
+ import { tool as tool15 } from "langchain";
1647
3234
  var BROWSER_NAVIGATE_DESCRIPTION = `Navigate to a URL.
1648
3235
 
1649
3236
  Args:
1650
3237
  url (str): The URL to navigate to.
1651
3238
  `;
1652
3239
  var createBrowserNavigateTool = ({ isolatedLevel }) => {
1653
- return tool8(
3240
+ return tool15(
1654
3241
  async (input, exe_config) => {
1655
3242
  try {
1656
3243
  const runConfig = exe_config.configurable?.runConfig;
@@ -1670,23 +3257,23 @@ var createBrowserNavigateTool = ({ isolatedLevel }) => {
1670
3257
  {
1671
3258
  name: "browser_navigate",
1672
3259
  description: BROWSER_NAVIGATE_DESCRIPTION,
1673
- schema: z10.object({
1674
- url: z10.string().describe("The URL to navigate to.")
3260
+ schema: z17.object({
3261
+ url: z17.string().describe("The URL to navigate to.")
1675
3262
  })
1676
3263
  }
1677
3264
  );
1678
3265
  };
1679
3266
 
1680
3267
  // src/tool_lattice/browser/browser_click.ts
1681
- import z11 from "zod";
1682
- import { tool as tool9 } from "langchain";
3268
+ import z18 from "zod";
3269
+ import { tool as tool16 } from "langchain";
1683
3270
  var BROWSER_CLICK_DESCRIPTION = `Click an element on the page, before using the tool, use \`browser_get_clickable_elements\` to get the index of the element, but not call \`browser_get_clickable_elements\` multiple times.
1684
3271
 
1685
3272
  Args:
1686
3273
  index (int): Index of the element to click
1687
3274
  `;
1688
3275
  var createBrowserClickTool = ({ isolatedLevel }) => {
1689
- return tool9(
3276
+ return tool16(
1690
3277
  async (input, exe_config) => {
1691
3278
  try {
1692
3279
  const runConfig = exe_config.configurable?.runConfig;
@@ -1706,23 +3293,23 @@ var createBrowserClickTool = ({ isolatedLevel }) => {
1706
3293
  {
1707
3294
  name: "browser_click",
1708
3295
  description: BROWSER_CLICK_DESCRIPTION,
1709
- schema: z11.object({
1710
- index: z11.number().describe("Index of the element to click")
3296
+ schema: z18.object({
3297
+ index: z18.number().describe("Index of the element to click")
1711
3298
  })
1712
3299
  }
1713
3300
  );
1714
3301
  };
1715
3302
 
1716
3303
  // src/tool_lattice/browser/browser_get_text.ts
1717
- import z12 from "zod";
1718
- import { tool as tool10 } from "langchain";
3304
+ import z19 from "zod";
3305
+ import { tool as tool17 } from "langchain";
1719
3306
  var BROWSER_GET_TEXT_DESCRIPTION = `Get the text content of the current page.
1720
3307
 
1721
3308
  Args:
1722
3309
  None
1723
3310
  `;
1724
3311
  var createBrowserGetTextTool = ({ isolatedLevel }) => {
1725
- return tool10(
3312
+ return tool17(
1726
3313
  async (input, exe_config) => {
1727
3314
  try {
1728
3315
  const runConfig = exe_config.configurable?.runConfig;
@@ -1740,21 +3327,21 @@ var createBrowserGetTextTool = ({ isolatedLevel }) => {
1740
3327
  {
1741
3328
  name: "browser_get_text",
1742
3329
  description: BROWSER_GET_TEXT_DESCRIPTION,
1743
- schema: z12.object({})
3330
+ schema: z19.object({})
1744
3331
  }
1745
3332
  );
1746
3333
  };
1747
3334
 
1748
3335
  // src/tool_lattice/browser/browser_get_markdown.ts
1749
- import z13 from "zod";
1750
- import { tool as tool11 } from "langchain";
3336
+ import z20 from "zod";
3337
+ import { tool as tool18 } from "langchain";
1751
3338
  var BROWSER_GET_MARKDOWN_DESCRIPTION = `Get the markdown content of the current page.
1752
3339
 
1753
3340
  Args:
1754
3341
  None
1755
3342
  `;
1756
3343
  var createBrowserGetMarkdownTool = ({ isolatedLevel }) => {
1757
- return tool11(
3344
+ return tool18(
1758
3345
  async (input, exe_config) => {
1759
3346
  try {
1760
3347
  const runConfig = exe_config.configurable?.runConfig;
@@ -1772,21 +3359,21 @@ var createBrowserGetMarkdownTool = ({ isolatedLevel }) => {
1772
3359
  {
1773
3360
  name: "browser_get_markdown",
1774
3361
  description: BROWSER_GET_MARKDOWN_DESCRIPTION,
1775
- schema: z13.object({})
3362
+ schema: z20.object({})
1776
3363
  }
1777
3364
  );
1778
3365
  };
1779
3366
 
1780
3367
  // src/tool_lattice/browser/browser_evaluate.ts
1781
- import z14 from "zod";
1782
- import { tool as tool12 } from "langchain";
3368
+ import z21 from "zod";
3369
+ import { tool as tool19 } from "langchain";
1783
3370
  var BROWSER_EVALUATE_DESCRIPTION = `Execute JavaScript in the browser console.
1784
3371
 
1785
3372
  Args:
1786
3373
  script (str): JavaScript code to execute, () => { /* code */ }
1787
3374
  `;
1788
3375
  var createBrowserEvaluateTool = ({ isolatedLevel }) => {
1789
- return tool12(
3376
+ return tool19(
1790
3377
  async (input, exe_config) => {
1791
3378
  try {
1792
3379
  const runConfig = exe_config.configurable?.runConfig;
@@ -1806,16 +3393,16 @@ var createBrowserEvaluateTool = ({ isolatedLevel }) => {
1806
3393
  {
1807
3394
  name: "browser_evaluate",
1808
3395
  description: BROWSER_EVALUATE_DESCRIPTION,
1809
- schema: z14.object({
1810
- script: z14.string().describe("JavaScript code to execute, () => { /* code */ }")
3396
+ schema: z21.object({
3397
+ script: z21.string().describe("JavaScript code to execute, () => { /* code */ }")
1811
3398
  })
1812
3399
  }
1813
3400
  );
1814
3401
  };
1815
3402
 
1816
3403
  // src/tool_lattice/browser/browser_screenshot.ts
1817
- import z15 from "zod";
1818
- import { tool as tool13 } from "langchain";
3404
+ import z22 from "zod";
3405
+ import { tool as tool20 } from "langchain";
1819
3406
  var BROWSER_SCREENSHOT_DESCRIPTION = `Take a screenshot of the current page or a specific element.
1820
3407
 
1821
3408
  Args:
@@ -1828,7 +3415,7 @@ Args:
1828
3415
  highlight (bool): Highlight the element
1829
3416
  `;
1830
3417
  var createBrowserScreenshotTool = ({ isolatedLevel }) => {
1831
- return tool13(
3418
+ return tool20(
1832
3419
  async (input, exe_config) => {
1833
3420
  try {
1834
3421
  const runConfig = exe_config.configurable?.runConfig;
@@ -1880,29 +3467,29 @@ var createBrowserScreenshotTool = ({ isolatedLevel }) => {
1880
3467
  {
1881
3468
  name: "browser_screenshot",
1882
3469
  description: BROWSER_SCREENSHOT_DESCRIPTION,
1883
- schema: z15.object({
1884
- name: z15.string().optional().describe("Name for the screenshot"),
1885
- selector: z15.string().optional().describe("CSS selector for element to screenshot"),
1886
- index: z15.number().optional().describe("index of the element to screenshot"),
1887
- width: z15.number().optional().describe("Width in pixels (default: viewport width)"),
1888
- height: z15.number().optional().describe("Height in pixels (default: viewport height)"),
1889
- fullPage: z15.boolean().optional().describe("Full page screenshot (default: false)"),
1890
- highlight: z15.boolean().default(false).describe("Highlight the element")
3470
+ schema: z22.object({
3471
+ name: z22.string().optional().describe("Name for the screenshot"),
3472
+ selector: z22.string().optional().describe("CSS selector for element to screenshot"),
3473
+ index: z22.number().optional().describe("index of the element to screenshot"),
3474
+ width: z22.number().optional().describe("Width in pixels (default: viewport width)"),
3475
+ height: z22.number().optional().describe("Height in pixels (default: viewport height)"),
3476
+ fullPage: z22.boolean().optional().describe("Full page screenshot (default: false)"),
3477
+ highlight: z22.boolean().default(false).describe("Highlight the element")
1891
3478
  })
1892
3479
  }
1893
3480
  );
1894
3481
  };
1895
3482
 
1896
3483
  // src/tool_lattice/browser/browser_scroll.ts
1897
- import z16 from "zod";
1898
- import { tool as tool14 } from "langchain";
3484
+ import z23 from "zod";
3485
+ import { tool as tool21 } from "langchain";
1899
3486
  var BROWSER_SCROLL_DESCRIPTION = `Scroll the page.
1900
3487
 
1901
3488
  Args:
1902
3489
  amount (int): Pixels to scroll (positive for down, negative for up), if the amount is not provided, scroll to the bottom of the page
1903
3490
  `;
1904
3491
  var createBrowserScrollTool = ({ isolatedLevel }) => {
1905
- return tool14(
3492
+ return tool21(
1906
3493
  async (input, exe_config) => {
1907
3494
  try {
1908
3495
  const runConfig = exe_config.configurable?.runConfig;
@@ -1922,16 +3509,16 @@ var createBrowserScrollTool = ({ isolatedLevel }) => {
1922
3509
  {
1923
3510
  name: "browser_scroll",
1924
3511
  description: BROWSER_SCROLL_DESCRIPTION,
1925
- schema: z16.object({
1926
- amount: z16.number().optional().describe("Pixels to scroll (positive for down, negative for up)")
3512
+ schema: z23.object({
3513
+ amount: z23.number().optional().describe("Pixels to scroll (positive for down, negative for up)")
1927
3514
  })
1928
3515
  }
1929
3516
  );
1930
3517
  };
1931
3518
 
1932
3519
  // src/tool_lattice/browser/browser_form_input_fill.ts
1933
- import z17 from "zod";
1934
- import { tool as tool15 } from "langchain";
3520
+ import z24 from "zod";
3521
+ import { tool as tool22 } from "langchain";
1935
3522
  var BROWSER_FORM_INPUT_FILL_DESCRIPTION = `Fill out an input field, before using the tool, Either 'index' or 'selector' must be provided.
1936
3523
 
1937
3524
  Args:
@@ -1941,7 +3528,7 @@ Args:
1941
3528
  clear (bool): Whether to clear existing text before filling
1942
3529
  `;
1943
3530
  var createBrowserFormInputFillTool = ({ isolatedLevel }) => {
1944
- return tool15(
3531
+ return tool22(
1945
3532
  async (input, exe_config) => {
1946
3533
  try {
1947
3534
  const runConfig = exe_config.configurable?.runConfig;
@@ -1964,19 +3551,19 @@ var createBrowserFormInputFillTool = ({ isolatedLevel }) => {
1964
3551
  {
1965
3552
  name: "browser_form_input_fill",
1966
3553
  description: BROWSER_FORM_INPUT_FILL_DESCRIPTION,
1967
- schema: z17.object({
1968
- selector: z17.string().optional().describe("CSS selector for input field"),
1969
- index: z17.number().optional().describe("Index of the element to fill"),
1970
- value: z17.string().describe("Value to fill"),
1971
- clear: z17.boolean().default(false).describe("Whether to clear existing text before filling")
3554
+ schema: z24.object({
3555
+ selector: z24.string().optional().describe("CSS selector for input field"),
3556
+ index: z24.number().optional().describe("Index of the element to fill"),
3557
+ value: z24.string().describe("Value to fill"),
3558
+ clear: z24.boolean().default(false).describe("Whether to clear existing text before filling")
1972
3559
  })
1973
3560
  }
1974
3561
  );
1975
3562
  };
1976
3563
 
1977
3564
  // src/tool_lattice/browser/browser_select.ts
1978
- import z18 from "zod";
1979
- import { tool as tool16 } from "langchain";
3565
+ import z25 from "zod";
3566
+ import { tool as tool23 } from "langchain";
1980
3567
  var BROWSER_SELECT_DESCRIPTION = `Select an element on the page with index, Either 'index' or 'selector' must be provided.
1981
3568
 
1982
3569
  Args:
@@ -1985,7 +3572,7 @@ Args:
1985
3572
  value (str): Value to select
1986
3573
  `;
1987
3574
  var createBrowserSelectTool = ({ isolatedLevel }) => {
1988
- return tool16(
3575
+ return tool23(
1989
3576
  async (input, exe_config) => {
1990
3577
  try {
1991
3578
  const runConfig = exe_config.configurable?.runConfig;
@@ -2007,18 +3594,18 @@ var createBrowserSelectTool = ({ isolatedLevel }) => {
2007
3594
  {
2008
3595
  name: "browser_select",
2009
3596
  description: BROWSER_SELECT_DESCRIPTION,
2010
- schema: z18.object({
2011
- index: z18.number().optional().describe("Index of the element to select"),
2012
- selector: z18.string().optional().describe("CSS selector for element to select"),
2013
- value: z18.string().describe("Value to select")
3597
+ schema: z25.object({
3598
+ index: z25.number().optional().describe("Index of the element to select"),
3599
+ selector: z25.string().optional().describe("CSS selector for element to select"),
3600
+ value: z25.string().describe("Value to select")
2014
3601
  })
2015
3602
  }
2016
3603
  );
2017
3604
  };
2018
3605
 
2019
3606
  // src/tool_lattice/browser/browser_hover.ts
2020
- import z19 from "zod";
2021
- import { tool as tool17 } from "langchain";
3607
+ import z26 from "zod";
3608
+ import { tool as tool24 } from "langchain";
2022
3609
  var BROWSER_HOVER_DESCRIPTION = `Hover an element on the page, Either 'index' or 'selector' must be provided.
2023
3610
 
2024
3611
  Args:
@@ -2026,7 +3613,7 @@ Args:
2026
3613
  selector (str): CSS selector for element to hover
2027
3614
  `;
2028
3615
  var createBrowserHoverTool = ({ isolatedLevel }) => {
2029
- return tool17(
3616
+ return tool24(
2030
3617
  async (input, exe_config) => {
2031
3618
  try {
2032
3619
  const runConfig = exe_config.configurable?.runConfig;
@@ -2047,24 +3634,24 @@ var createBrowserHoverTool = ({ isolatedLevel }) => {
2047
3634
  {
2048
3635
  name: "browser_hover",
2049
3636
  description: BROWSER_HOVER_DESCRIPTION,
2050
- schema: z19.object({
2051
- index: z19.number().optional().describe("Index of the element to hover"),
2052
- selector: z19.string().optional().describe("CSS selector for element to hover")
3637
+ schema: z26.object({
3638
+ index: z26.number().optional().describe("Index of the element to hover"),
3639
+ selector: z26.string().optional().describe("CSS selector for element to hover")
2053
3640
  })
2054
3641
  }
2055
3642
  );
2056
3643
  };
2057
3644
 
2058
3645
  // src/tool_lattice/browser/browser_go_back.ts
2059
- import z20 from "zod";
2060
- import { tool as tool18 } from "langchain";
3646
+ import z27 from "zod";
3647
+ import { tool as tool25 } from "langchain";
2061
3648
  var BROWSER_GO_BACK_DESCRIPTION = `Go back to the previous page.
2062
3649
 
2063
3650
  Args:
2064
3651
  None
2065
3652
  `;
2066
3653
  var createBrowserGoBackTool = ({ isolatedLevel }) => {
2067
- return tool18(
3654
+ return tool25(
2068
3655
  async (input, exe_config) => {
2069
3656
  try {
2070
3657
  const runConfig = exe_config.configurable?.runConfig;
@@ -2082,21 +3669,21 @@ var createBrowserGoBackTool = ({ isolatedLevel }) => {
2082
3669
  {
2083
3670
  name: "browser_go_back",
2084
3671
  description: BROWSER_GO_BACK_DESCRIPTION,
2085
- schema: z20.object({})
3672
+ schema: z27.object({})
2086
3673
  }
2087
3674
  );
2088
3675
  };
2089
3676
 
2090
3677
  // src/tool_lattice/browser/browser_go_forward.ts
2091
- import z21 from "zod";
2092
- import { tool as tool19 } from "langchain";
3678
+ import z28 from "zod";
3679
+ import { tool as tool26 } from "langchain";
2093
3680
  var BROWSER_GO_FORWARD_DESCRIPTION = `Go forward to the next page.
2094
3681
 
2095
3682
  Args:
2096
3683
  None
2097
3684
  `;
2098
3685
  var createBrowserGoForwardTool = ({ isolatedLevel }) => {
2099
- return tool19(
3686
+ return tool26(
2100
3687
  async (input, exe_config) => {
2101
3688
  try {
2102
3689
  const runConfig = exe_config.configurable?.runConfig;
@@ -2114,21 +3701,21 @@ var createBrowserGoForwardTool = ({ isolatedLevel }) => {
2114
3701
  {
2115
3702
  name: "browser_go_forward",
2116
3703
  description: BROWSER_GO_FORWARD_DESCRIPTION,
2117
- schema: z21.object({})
3704
+ schema: z28.object({})
2118
3705
  }
2119
3706
  );
2120
3707
  };
2121
3708
 
2122
3709
  // src/tool_lattice/browser/browser_new_tab.ts
2123
- import z22 from "zod";
2124
- import { tool as tool20 } from "langchain";
3710
+ import z29 from "zod";
3711
+ import { tool as tool27 } from "langchain";
2125
3712
  var BROWSER_NEW_TAB_DESCRIPTION = `Open a new tab.
2126
3713
 
2127
3714
  Args:
2128
3715
  url (str): URL to open in the new tab
2129
3716
  `;
2130
3717
  var createBrowserNewTabTool = ({ isolatedLevel }) => {
2131
- return tool20(
3718
+ return tool27(
2132
3719
  async (input, exe_config) => {
2133
3720
  try {
2134
3721
  const runConfig = exe_config.configurable?.runConfig;
@@ -2148,23 +3735,23 @@ var createBrowserNewTabTool = ({ isolatedLevel }) => {
2148
3735
  {
2149
3736
  name: "browser_new_tab",
2150
3737
  description: BROWSER_NEW_TAB_DESCRIPTION,
2151
- schema: z22.object({
2152
- url: z22.string().describe("URL to open in the new tab")
3738
+ schema: z29.object({
3739
+ url: z29.string().describe("URL to open in the new tab")
2153
3740
  })
2154
3741
  }
2155
3742
  );
2156
3743
  };
2157
3744
 
2158
3745
  // src/tool_lattice/browser/browser_tab_list.ts
2159
- import z23 from "zod";
2160
- import { tool as tool21 } from "langchain";
3746
+ import z30 from "zod";
3747
+ import { tool as tool28 } from "langchain";
2161
3748
  var BROWSER_TAB_LIST_DESCRIPTION = `Get the list of tabs.
2162
3749
 
2163
3750
  Args:
2164
3751
  None
2165
3752
  `;
2166
3753
  var createBrowserTabListTool = ({ isolatedLevel }) => {
2167
- return tool21(
3754
+ return tool28(
2168
3755
  async (input, exe_config) => {
2169
3756
  try {
2170
3757
  const runConfig = exe_config.configurable?.runConfig;
@@ -2182,21 +3769,21 @@ var createBrowserTabListTool = ({ isolatedLevel }) => {
2182
3769
  {
2183
3770
  name: "browser_tab_list",
2184
3771
  description: BROWSER_TAB_LIST_DESCRIPTION,
2185
- schema: z23.object({})
3772
+ schema: z30.object({})
2186
3773
  }
2187
3774
  );
2188
3775
  };
2189
3776
 
2190
3777
  // src/tool_lattice/browser/browser_switch_tab.ts
2191
- import z24 from "zod";
2192
- import { tool as tool22 } from "langchain";
3778
+ import z31 from "zod";
3779
+ import { tool as tool29 } from "langchain";
2193
3780
  var BROWSER_SWITCH_TAB_DESCRIPTION = `Switch to a specific tab.
2194
3781
 
2195
3782
  Args:
2196
3783
  index (int): Tab index to switch to
2197
3784
  `;
2198
3785
  var createBrowserSwitchTabTool = ({ isolatedLevel }) => {
2199
- return tool22(
3786
+ return tool29(
2200
3787
  async (input, exe_config) => {
2201
3788
  try {
2202
3789
  const runConfig = exe_config.configurable?.runConfig;
@@ -2216,23 +3803,23 @@ var createBrowserSwitchTabTool = ({ isolatedLevel }) => {
2216
3803
  {
2217
3804
  name: "browser_switch_tab",
2218
3805
  description: BROWSER_SWITCH_TAB_DESCRIPTION,
2219
- schema: z24.object({
2220
- index: z24.number().describe("Tab index to switch to")
3806
+ schema: z31.object({
3807
+ index: z31.number().describe("Tab index to switch to")
2221
3808
  })
2222
3809
  }
2223
3810
  );
2224
3811
  };
2225
3812
 
2226
3813
  // src/tool_lattice/browser/browser_close_tab.ts
2227
- import z25 from "zod";
2228
- import { tool as tool23 } from "langchain";
3814
+ import z32 from "zod";
3815
+ import { tool as tool30 } from "langchain";
2229
3816
  var BROWSER_CLOSE_TAB_DESCRIPTION = `Close the current tab.
2230
3817
 
2231
3818
  Args:
2232
3819
  None
2233
3820
  `;
2234
3821
  var createBrowserCloseTabTool = ({ isolatedLevel }) => {
2235
- return tool23(
3822
+ return tool30(
2236
3823
  async (input, exe_config) => {
2237
3824
  try {
2238
3825
  const runConfig = exe_config.configurable?.runConfig;
@@ -2250,21 +3837,21 @@ var createBrowserCloseTabTool = ({ isolatedLevel }) => {
2250
3837
  {
2251
3838
  name: "browser_close_tab",
2252
3839
  description: BROWSER_CLOSE_TAB_DESCRIPTION,
2253
- schema: z25.object({})
3840
+ schema: z32.object({})
2254
3841
  }
2255
3842
  );
2256
3843
  };
2257
3844
 
2258
3845
  // src/tool_lattice/browser/browser_close.ts
2259
- import z26 from "zod";
2260
- import { tool as tool24 } from "langchain";
3846
+ import z33 from "zod";
3847
+ import { tool as tool31 } from "langchain";
2261
3848
  var BROWSER_CLOSE_DESCRIPTION = `Close the browser when the task is done and the browser is not needed anymore.
2262
3849
 
2263
3850
  Args:
2264
3851
  None
2265
3852
  `;
2266
3853
  var createBrowserCloseTool = ({ isolatedLevel }) => {
2267
- return tool24(
3854
+ return tool31(
2268
3855
  async (input, exe_config) => {
2269
3856
  try {
2270
3857
  const runConfig = exe_config.configurable?.runConfig;
@@ -2282,21 +3869,21 @@ var createBrowserCloseTool = ({ isolatedLevel }) => {
2282
3869
  {
2283
3870
  name: "browser_close",
2284
3871
  description: BROWSER_CLOSE_DESCRIPTION,
2285
- schema: z26.object({})
3872
+ schema: z33.object({})
2286
3873
  }
2287
3874
  );
2288
3875
  };
2289
3876
 
2290
3877
  // src/tool_lattice/browser/browser_press_key.ts
2291
- import z27 from "zod";
2292
- import { tool as tool25 } from "langchain";
3878
+ import z34 from "zod";
3879
+ import { tool as tool32 } from "langchain";
2293
3880
  var BROWSER_PRESS_KEY_DESCRIPTION = `Press a key on the keyboard.
2294
3881
 
2295
3882
  Args:
2296
3883
  key (str): Name of the key to press or a character to generate, such as Enter, Tab, Escape, Backspace, Delete, Insert, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, ArrowLeft, ArrowRight, ArrowUp, ArrowDown, PageUp, PageDown, Home, End, ShiftLeft, ShiftRight, ControlLeft, ControlRight, AltLeft, AltRight, MetaLeft, MetaRight, CapsLock, PrintScreen, ScrollLock, Pause, ContextMenu
2297
3884
  `;
2298
3885
  var createBrowserPressKeyTool = ({ isolatedLevel }) => {
2299
- return tool25(
3886
+ return tool32(
2300
3887
  async (input, exe_config) => {
2301
3888
  try {
2302
3889
  const runConfig = exe_config.configurable?.runConfig;
@@ -2316,8 +3903,8 @@ var createBrowserPressKeyTool = ({ isolatedLevel }) => {
2316
3903
  {
2317
3904
  name: "browser_press_key",
2318
3905
  description: BROWSER_PRESS_KEY_DESCRIPTION,
2319
- schema: z27.object({
2320
- key: z27.enum([
3906
+ schema: z34.object({
3907
+ key: z34.enum([
2321
3908
  "Enter",
2322
3909
  "Tab",
2323
3910
  "Escape",
@@ -2364,15 +3951,15 @@ var createBrowserPressKeyTool = ({ isolatedLevel }) => {
2364
3951
  };
2365
3952
 
2366
3953
  // src/tool_lattice/browser/browser_read_links.ts
2367
- import z28 from "zod";
2368
- import { tool as tool26 } from "langchain";
3954
+ import z35 from "zod";
3955
+ import { tool as tool33 } from "langchain";
2369
3956
  var BROWSER_READ_LINKS_DESCRIPTION = `Get all links on the current page.
2370
3957
 
2371
3958
  Args:
2372
3959
  None
2373
3960
  `;
2374
3961
  var createBrowserReadLinksTool = ({ isolatedLevel }) => {
2375
- return tool26(
3962
+ return tool33(
2376
3963
  async (input, exe_config) => {
2377
3964
  try {
2378
3965
  const runConfig = exe_config.configurable?.runConfig;
@@ -2390,21 +3977,21 @@ var createBrowserReadLinksTool = ({ isolatedLevel }) => {
2390
3977
  {
2391
3978
  name: "browser_read_links",
2392
3979
  description: BROWSER_READ_LINKS_DESCRIPTION,
2393
- schema: z28.object({})
3980
+ schema: z35.object({})
2394
3981
  }
2395
3982
  );
2396
3983
  };
2397
3984
 
2398
3985
  // src/tool_lattice/browser/browser_get_clickable_elements.ts
2399
- import z29 from "zod";
2400
- import { tool as tool27 } from "langchain";
3986
+ import z36 from "zod";
3987
+ import { tool as tool34 } from "langchain";
2401
3988
  var BROWSER_GET_CLICKABLE_ELEMENTS_DESCRIPTION = `Get the clickable or hoverable or selectable elements on the current page, don't call this tool multiple times.
2402
3989
 
2403
3990
  Args:
2404
3991
  None
2405
3992
  `;
2406
3993
  var createBrowserGetClickableElementsTool = ({ isolatedLevel }) => {
2407
- return tool27(
3994
+ return tool34(
2408
3995
  async (input, exe_config) => {
2409
3996
  try {
2410
3997
  const runConfig = exe_config.configurable?.runConfig;
@@ -2422,21 +4009,21 @@ var createBrowserGetClickableElementsTool = ({ isolatedLevel }) => {
2422
4009
  {
2423
4010
  name: "browser_get_clickable_elements",
2424
4011
  description: BROWSER_GET_CLICKABLE_ELEMENTS_DESCRIPTION,
2425
- schema: z29.object({})
4012
+ schema: z36.object({})
2426
4013
  }
2427
4014
  );
2428
4015
  };
2429
4016
 
2430
4017
  // src/tool_lattice/browser/browser_get_download_list.ts
2431
- import z30 from "zod";
2432
- import { tool as tool28 } from "langchain";
4018
+ import z37 from "zod";
4019
+ import { tool as tool35 } from "langchain";
2433
4020
  var BROWSER_GET_DOWNLOAD_LIST_DESCRIPTION = `Get the list of downloaded files.
2434
4021
 
2435
4022
  Args:
2436
4023
  None
2437
4024
  `;
2438
4025
  var createBrowserGetDownloadListTool = ({ isolatedLevel }) => {
2439
- return tool28(
4026
+ return tool35(
2440
4027
  async (input, exe_config) => {
2441
4028
  try {
2442
4029
  const runConfig = exe_config.configurable?.runConfig;
@@ -2454,14 +4041,14 @@ var createBrowserGetDownloadListTool = ({ isolatedLevel }) => {
2454
4041
  {
2455
4042
  name: "browser_get_download_list",
2456
4043
  description: BROWSER_GET_DOWNLOAD_LIST_DESCRIPTION,
2457
- schema: z30.object({})
4044
+ schema: z37.object({})
2458
4045
  }
2459
4046
  );
2460
4047
  };
2461
4048
 
2462
4049
  // src/tool_lattice/browser/get_info.ts
2463
- import z31 from "zod";
2464
- import { tool as tool29 } from "langchain";
4050
+ import z38 from "zod";
4051
+ import { tool as tool36 } from "langchain";
2465
4052
  var BROWSER_GET_INFO_DESCRIPTION = `Get information about browser, like CDP URL, viewport size, etc.
2466
4053
 
2467
4054
  Args:
@@ -2470,7 +4057,7 @@ Args:
2470
4057
  Returns:
2471
4058
  Dict containing browser information including CDP URL, viewport dimensions, and other browser metadata.`;
2472
4059
  var createBrowserGetInfoTool = ({ isolatedLevel }) => {
2473
- return tool29(
4060
+ return tool36(
2474
4061
  async (input, exe_config) => {
2475
4062
  try {
2476
4063
  const runConfig = exe_config.configurable?.runConfig;
@@ -2488,7 +4075,7 @@ var createBrowserGetInfoTool = ({ isolatedLevel }) => {
2488
4075
  {
2489
4076
  name: "browser_get_info",
2490
4077
  description: BROWSER_GET_INFO_DESCRIPTION,
2491
- schema: z31.object({})
4078
+ schema: z38.object({})
2492
4079
  }
2493
4080
  );
2494
4081
  };
@@ -2641,8 +4228,8 @@ var SandboxFilesystem = class {
2641
4228
  */
2642
4229
  toVirtualPath(realPath) {
2643
4230
  const rootPath = path2.join(this.homeDir, this.workingDirectory);
2644
- const relative3 = path2.relative(rootPath, realPath);
2645
- const normalized = relative3.split(path2.sep).join("/");
4231
+ const relative4 = path2.relative(rootPath, realPath);
4232
+ const normalized = relative4.split(path2.sep).join("/");
2646
4233
  return "/" + normalized;
2647
4234
  }
2648
4235
  /**
@@ -3595,7 +5182,58 @@ ${body}` : `${frontmatter}
3595
5182
  subSkills.push(subSkill);
3596
5183
  }
3597
5184
  }
3598
- return subSkills;
5185
+ return subSkills;
5186
+ }
5187
+ /**
5188
+ * List all resources in a skill's resources directory
5189
+ * @param skillName The skill name
5190
+ * @returns Array of resource paths relative to resources/ directory
5191
+ */
5192
+ async listSkillResources(skillName) {
5193
+ const skillDir = this.getSkillDirectoryPath(skillName);
5194
+ const resourcesDir = path3.join(skillDir, "resources");
5195
+ try {
5196
+ const entries = await fs.readdir(resourcesDir, { withFileTypes: true, recursive: true });
5197
+ const resources = [];
5198
+ for (const entry of entries) {
5199
+ if (!entry.isDirectory()) {
5200
+ const fullPath = path3.join(entry.path, entry.name);
5201
+ const relativePath = path3.relative(resourcesDir, fullPath);
5202
+ resources.push(relativePath.replace(/\\/g, "/"));
5203
+ }
5204
+ }
5205
+ return resources.sort();
5206
+ } catch (error) {
5207
+ if (error.code === "ENOENT") {
5208
+ return [];
5209
+ }
5210
+ throw error;
5211
+ }
5212
+ }
5213
+ /**
5214
+ * Load a specific resource from a skill's resources directory
5215
+ * @param skillName The skill name
5216
+ * @param resourcePath Path to the resource relative to resources/ directory
5217
+ * @returns The resource content as string
5218
+ */
5219
+ async loadSkillResource(skillName, resourcePath) {
5220
+ const skillDir = this.getSkillDirectoryPath(skillName);
5221
+ const resourcesDir = path3.join(skillDir, "resources");
5222
+ const fullPath = path3.join(resourcesDir, resourcePath);
5223
+ const resolvedPath = path3.resolve(fullPath);
5224
+ const resolvedResourcesDir = path3.resolve(resourcesDir);
5225
+ if (!resolvedPath.startsWith(resolvedResourcesDir)) {
5226
+ throw new Error(`Invalid resource path: ${resourcePath}`);
5227
+ }
5228
+ try {
5229
+ const content = await fs.readFile(fullPath, "utf-8");
5230
+ return content;
5231
+ } catch (error) {
5232
+ if (error.code === "ENOENT") {
5233
+ return null;
5234
+ }
5235
+ throw error;
5236
+ }
3599
5237
  }
3600
5238
  };
3601
5239
 
@@ -3851,6 +5489,291 @@ var InMemoryDatabaseConfigStore = class {
3851
5489
  }
3852
5490
  };
3853
5491
 
5492
+ // src/store_lattice/InMemoryMetricsServerConfigStore.ts
5493
+ var InMemoryMetricsServerConfigStore = class {
5494
+ constructor() {
5495
+ this.configs = /* @__PURE__ */ new Map();
5496
+ }
5497
+ /**
5498
+ * Get composite key for storage
5499
+ */
5500
+ getKey(tenantId, id) {
5501
+ return `${tenantId}:${id}`;
5502
+ }
5503
+ /**
5504
+ * Get all metrics server configurations for a tenant
5505
+ */
5506
+ async getAllConfigs(tenantId) {
5507
+ return Array.from(this.configs.values()).filter(
5508
+ (config) => config.tenantId === tenantId
5509
+ );
5510
+ }
5511
+ /**
5512
+ * Get all metrics server configurations across all tenants
5513
+ */
5514
+ async getAllConfigsWithoutTenant() {
5515
+ return Array.from(this.configs.values());
5516
+ }
5517
+ /**
5518
+ * Get metrics server configuration by ID
5519
+ */
5520
+ async getConfigById(tenantId, id) {
5521
+ const key = this.getKey(tenantId, id);
5522
+ return this.configs.get(key) || null;
5523
+ }
5524
+ /**
5525
+ * Get metrics server configuration by business key
5526
+ */
5527
+ async getConfigByKey(tenantId, key) {
5528
+ const configs = await this.getAllConfigs(tenantId);
5529
+ return configs.find((config) => config.key === key) || null;
5530
+ }
5531
+ /**
5532
+ * Create a new metrics server configuration
5533
+ */
5534
+ async createConfig(tenantId, id, data) {
5535
+ const now = /* @__PURE__ */ new Date();
5536
+ const entry = {
5537
+ id,
5538
+ tenantId,
5539
+ key: data.key,
5540
+ config: data.config,
5541
+ name: data.name,
5542
+ description: data.description,
5543
+ createdAt: now,
5544
+ updatedAt: now
5545
+ };
5546
+ const storageKey = this.getKey(tenantId, id);
5547
+ this.configs.set(storageKey, entry);
5548
+ return entry;
5549
+ }
5550
+ /**
5551
+ * Update an existing metrics server configuration
5552
+ */
5553
+ async updateConfig(tenantId, id, updates) {
5554
+ const key = this.getKey(tenantId, id);
5555
+ const existing = this.configs.get(key);
5556
+ if (!existing) {
5557
+ return null;
5558
+ }
5559
+ const updated = {
5560
+ ...existing,
5561
+ ...updates,
5562
+ config: updates.config ? { ...existing.config, ...updates.config } : existing.config,
5563
+ key: updates.key || existing.key,
5564
+ name: updates.name !== void 0 ? updates.name : existing.name,
5565
+ description: updates.description !== void 0 ? updates.description : existing.description,
5566
+ updatedAt: /* @__PURE__ */ new Date()
5567
+ };
5568
+ this.configs.set(key, updated);
5569
+ return updated;
5570
+ }
5571
+ /**
5572
+ * Delete a metrics server configuration by ID
5573
+ */
5574
+ async deleteConfig(tenantId, id) {
5575
+ const key = this.getKey(tenantId, id);
5576
+ return this.configs.delete(key);
5577
+ }
5578
+ /**
5579
+ * Check if configuration exists
5580
+ */
5581
+ async hasConfig(tenantId, id) {
5582
+ const key = this.getKey(tenantId, id);
5583
+ return this.configs.has(key);
5584
+ }
5585
+ /**
5586
+ * Clear all configurations (useful for testing)
5587
+ */
5588
+ clear() {
5589
+ this.configs.clear();
5590
+ }
5591
+ /**
5592
+ * Clear configurations for a specific tenant
5593
+ */
5594
+ clearByTenant(tenantId) {
5595
+ for (const key of this.configs.keys()) {
5596
+ if (key.startsWith(`${tenantId}:`)) {
5597
+ this.configs.delete(key);
5598
+ }
5599
+ }
5600
+ }
5601
+ };
5602
+
5603
+ // src/store_lattice/InMemoryUserStore.ts
5604
+ var InMemoryUserStore = class {
5605
+ constructor() {
5606
+ this.users = /* @__PURE__ */ new Map();
5607
+ }
5608
+ async getAllUsers() {
5609
+ return Array.from(this.users.values());
5610
+ }
5611
+ async getUserById(id) {
5612
+ return this.users.get(id) || null;
5613
+ }
5614
+ async getUserByEmail(email) {
5615
+ for (const user of this.users.values()) {
5616
+ if (user.email === email) {
5617
+ return user;
5618
+ }
5619
+ }
5620
+ return null;
5621
+ }
5622
+ async createUser(id, data) {
5623
+ const now = /* @__PURE__ */ new Date();
5624
+ const user = {
5625
+ id,
5626
+ email: data.email,
5627
+ name: data.name,
5628
+ status: data.status || "pending",
5629
+ metadata: data.metadata ?? {},
5630
+ createdAt: now,
5631
+ updatedAt: now
5632
+ };
5633
+ this.users.set(id, user);
5634
+ return user;
5635
+ }
5636
+ async updateUser(id, updates) {
5637
+ const existing = this.users.get(id);
5638
+ if (!existing) {
5639
+ return null;
5640
+ }
5641
+ const updated = {
5642
+ ...existing,
5643
+ ...updates,
5644
+ metadata: updates.metadata ?? existing.metadata,
5645
+ updatedAt: /* @__PURE__ */ new Date()
5646
+ };
5647
+ this.users.set(id, updated);
5648
+ return updated;
5649
+ }
5650
+ async deleteUser(id) {
5651
+ return this.users.delete(id);
5652
+ }
5653
+ clear() {
5654
+ this.users.clear();
5655
+ }
5656
+ };
5657
+
5658
+ // src/store_lattice/InMemoryTenantStore.ts
5659
+ var InMemoryTenantStore = class {
5660
+ constructor() {
5661
+ this.tenants = /* @__PURE__ */ new Map();
5662
+ this.initDefaultData();
5663
+ }
5664
+ initDefaultData() {
5665
+ const defaultTenant = {
5666
+ id: "default",
5667
+ name: "Default Tenant",
5668
+ description: "Default tenant for single-tenant setups",
5669
+ status: "active",
5670
+ metadata: {},
5671
+ createdAt: /* @__PURE__ */ new Date(),
5672
+ updatedAt: /* @__PURE__ */ new Date()
5673
+ };
5674
+ this.tenants.set("default", defaultTenant);
5675
+ }
5676
+ async getAllTenants() {
5677
+ return Array.from(this.tenants.values());
5678
+ }
5679
+ async getTenantById(id) {
5680
+ return this.tenants.get(id) || null;
5681
+ }
5682
+ async createTenant(id, data) {
5683
+ const now = /* @__PURE__ */ new Date();
5684
+ const tenant = {
5685
+ id,
5686
+ name: data.name,
5687
+ description: data.description,
5688
+ status: data.status || "active",
5689
+ metadata: data.metadata || {},
5690
+ createdAt: now,
5691
+ updatedAt: now
5692
+ };
5693
+ this.tenants.set(id, tenant);
5694
+ return tenant;
5695
+ }
5696
+ async updateTenant(id, updates) {
5697
+ const existing = this.tenants.get(id);
5698
+ if (!existing) {
5699
+ return null;
5700
+ }
5701
+ const updated = {
5702
+ ...existing,
5703
+ ...updates,
5704
+ updatedAt: /* @__PURE__ */ new Date()
5705
+ };
5706
+ this.tenants.set(id, updated);
5707
+ return updated;
5708
+ }
5709
+ async deleteTenant(id) {
5710
+ return this.tenants.delete(id);
5711
+ }
5712
+ clear() {
5713
+ this.tenants.clear();
5714
+ this.initDefaultData();
5715
+ }
5716
+ };
5717
+
5718
+ // src/store_lattice/InMemoryUserTenantLinkStore.ts
5719
+ var InMemoryUserTenantLinkStore = class {
5720
+ constructor() {
5721
+ this.links = /* @__PURE__ */ new Map();
5722
+ }
5723
+ getKey(userId, tenantId) {
5724
+ return `${userId}:${tenantId}`;
5725
+ }
5726
+ async getTenantsByUser(userId) {
5727
+ return Array.from(this.links.values()).filter(
5728
+ (link) => link.userId === userId
5729
+ );
5730
+ }
5731
+ async getUsersByTenant(tenantId) {
5732
+ return Array.from(this.links.values()).filter(
5733
+ (link) => link.tenantId === tenantId
5734
+ );
5735
+ }
5736
+ async getLink(userId, tenantId) {
5737
+ const key = this.getKey(userId, tenantId);
5738
+ return this.links.get(key) || null;
5739
+ }
5740
+ async createLink(data) {
5741
+ const link = {
5742
+ userId: data.userId,
5743
+ tenantId: data.tenantId,
5744
+ role: data.role || "member",
5745
+ joinedAt: /* @__PURE__ */ new Date(),
5746
+ metadata: data.metadata ?? {}
5747
+ };
5748
+ const key = this.getKey(data.userId, data.tenantId);
5749
+ this.links.set(key, link);
5750
+ return link;
5751
+ }
5752
+ async updateLink(userId, tenantId, updates) {
5753
+ const key = this.getKey(userId, tenantId);
5754
+ const existing = this.links.get(key);
5755
+ if (!existing) return null;
5756
+ const updated = {
5757
+ ...existing,
5758
+ ...updates,
5759
+ metadata: updates.metadata ?? existing.metadata
5760
+ };
5761
+ this.links.set(key, updated);
5762
+ return updated;
5763
+ }
5764
+ async deleteLink(userId, tenantId) {
5765
+ const key = this.getKey(userId, tenantId);
5766
+ return this.links.delete(key);
5767
+ }
5768
+ async hasLink(userId, tenantId) {
5769
+ const key = this.getKey(userId, tenantId);
5770
+ return this.links.has(key);
5771
+ }
5772
+ clear() {
5773
+ this.links.clear();
5774
+ }
5775
+ };
5776
+
3854
5777
  // src/store_lattice/StoreLatticeManager.ts
3855
5778
  var StoreLatticeManager = class _StoreLatticeManager extends BaseLatticeManager {
3856
5779
  /**
@@ -3981,6 +5904,7 @@ var defaultSkillStore = new FileSystemSkillStore();
3981
5904
  var defaultWorkspaceStore = new InMemoryWorkspaceStore();
3982
5905
  var defaultProjectStore = new InMemoryProjectStore();
3983
5906
  var defaultDatabaseConfigStore = new InMemoryDatabaseConfigStore();
5907
+ var defaultMetricsServerConfigStore = new InMemoryMetricsServerConfigStore();
3984
5908
  storeLatticeManager.registerLattice("default", "thread", defaultThreadStore);
3985
5909
  storeLatticeManager.registerLattice(
3986
5910
  "default",
@@ -3991,13 +5915,20 @@ storeLatticeManager.registerLattice("default", "skill", defaultSkillStore);
3991
5915
  storeLatticeManager.registerLattice("default", "workspace", defaultWorkspaceStore);
3992
5916
  storeLatticeManager.registerLattice("default", "project", defaultProjectStore);
3993
5917
  storeLatticeManager.registerLattice("default", "database", defaultDatabaseConfigStore);
5918
+ storeLatticeManager.registerLattice("default", "metrics", defaultMetricsServerConfigStore);
5919
+ var defaultUserStore = new InMemoryUserStore();
5920
+ var defaultTenantStore = new InMemoryTenantStore();
5921
+ var defaultUserTenantLinkStore = new InMemoryUserTenantLinkStore();
5922
+ storeLatticeManager.registerLattice("default", "user", defaultUserStore);
5923
+ storeLatticeManager.registerLattice("default", "tenant", defaultTenantStore);
5924
+ storeLatticeManager.registerLattice("default", "userTenantLink", defaultUserTenantLinkStore);
3994
5925
 
3995
5926
  // src/tool_lattice/skill/load_skills.ts
3996
- import z32 from "zod";
3997
- import { tool as tool31 } from "langchain";
5927
+ import z39 from "zod";
5928
+ import { tool as tool38 } from "langchain";
3998
5929
  var LOAD_SKILLS_DESCRIPTION = `Load all available skills and return their metadata (name, description, license, compatibility, metadata, and subSkills) without the content. This tool returns skill information including hierarchical relationships (subSkills). Use this to discover what skills are available and their structure.`;
3999
5930
  var createLoadSkillsTool = ({ skills } = {}) => {
4000
- return tool31(
5931
+ return tool38(
4001
5932
  async (_input, _exe_config) => {
4002
5933
  try {
4003
5934
  const storeLattice = getStoreLattice("default", "skill");
@@ -4021,17 +5952,17 @@ var createLoadSkillsTool = ({ skills } = {}) => {
4021
5952
  {
4022
5953
  name: "load_skills",
4023
5954
  description: LOAD_SKILLS_DESCRIPTION,
4024
- schema: z32.object({})
5955
+ schema: z39.object({})
4025
5956
  }
4026
5957
  );
4027
5958
  };
4028
5959
 
4029
5960
  // src/tool_lattice/skill/load_skill_content.ts
4030
- import z33 from "zod";
4031
- import { tool as tool32 } from "langchain";
4032
- var LOAD_SKILL_CONTENT_DESCRIPTION = `Load a specific skill's content by name and return its full content including markdown body. This tool returns the complete skill content including frontmatter and markdown body. Use this tool to get the complete skill content for a skill that you want to use.`;
5961
+ import z40 from "zod";
5962
+ import { tool as tool39 } from "langchain";
5963
+ var LOAD_SKILL_CONTENT_DESCRIPTION = `Load a specific skill's content by name and return its full content including markdown body. This tool returns the complete skill content including frontmatter and markdown body. If the skill has resources, they will be listed at the end of the content with instructions on how to access them. Use this tool to get the complete skill content for a skill that you want to use.`;
4033
5964
  var createLoadSkillContentTool = () => {
4034
- return tool32(
5965
+ return tool39(
4035
5966
  async (input, _exe_config) => {
4036
5967
  try {
4037
5968
  const storeLattice = getStoreLattice("default", "skill");
@@ -4065,8 +5996,23 @@ var createLoadSkillContentTool = () => {
4065
5996
  }
4066
5997
  frontmatter.push("---");
4067
5998
  const content = skill.content || "";
4068
- return `${frontmatter.join("\n")}
5999
+ let result = `${frontmatter.join("\n")}
4069
6000
  ${content}`;
6001
+ const fsStore = skillStore;
6002
+ if (fsStore.listSkillResources) {
6003
+ try {
6004
+ const resources = await fsStore.listSkillResources(input.skill_name);
6005
+ if (resources.length > 0) {
6006
+ result += "\n\n---\n\n**Resources** (use `load_skill_resource` tool to access):\n";
6007
+ resources.forEach((resource) => {
6008
+ result += `- ${resource}
6009
+ `;
6010
+ });
6011
+ }
6012
+ } catch {
6013
+ }
6014
+ }
6015
+ return result;
4070
6016
  } catch (error) {
4071
6017
  return `Error loading skill content: ${error instanceof Error ? error.message : String(error)}`;
4072
6018
  }
@@ -4074,16 +6020,55 @@ ${content}`;
4074
6020
  {
4075
6021
  name: "load_skill_content",
4076
6022
  description: LOAD_SKILL_CONTENT_DESCRIPTION,
4077
- schema: z33.object({
4078
- skill_name: z33.string().describe("The name of the skill to load")
6023
+ schema: z40.object({
6024
+ skill_name: z40.string().describe("The name of the skill to load")
6025
+ })
6026
+ }
6027
+ );
6028
+ };
6029
+
6030
+ // src/tool_lattice/skill/load_skill_resource.ts
6031
+ import z41 from "zod";
6032
+ import { tool as tool40 } from "langchain";
6033
+ var LOAD_SKILL_RESOURCE_DESCRIPTION = `Load a specific resource file from a skill's resources directory. Use this tool when you need to access template files, example data, or other resources bundled with a skill. The resource paths are listed in the skill content when using the load_skill_content tool.`;
6034
+ var createLoadSkillResourceTool = () => {
6035
+ return tool40(
6036
+ async (input, _exe_config) => {
6037
+ try {
6038
+ const storeLattice = getStoreLattice("default", "skill");
6039
+ const skillStore = storeLattice.store;
6040
+ const fsStore = skillStore;
6041
+ if (!fsStore.loadSkillResource) {
6042
+ return `Error: This skill store does not support resource loading.`;
6043
+ }
6044
+ const content = await fsStore.loadSkillResource(input.skill_name, input.resource_path);
6045
+ if (!content) {
6046
+ return `Resource "${input.resource_path}" not found for skill "${input.skill_name}".`;
6047
+ }
6048
+ return content;
6049
+ } catch (error) {
6050
+ return `Error loading skill resource: ${error instanceof Error ? error.message : String(error)}`;
6051
+ }
6052
+ },
6053
+ {
6054
+ name: "load_skill_resource",
6055
+ description: LOAD_SKILL_RESOURCE_DESCRIPTION,
6056
+ schema: z41.object({
6057
+ skill_name: z41.string().describe("The name of the skill containing the resource"),
6058
+ resource_path: z41.string().describe("The path to the resource relative to the skill's resources/ directory")
4079
6059
  })
4080
6060
  }
4081
6061
  );
4082
6062
  };
4083
6063
 
4084
6064
  // src/middlewares/skillMiddleware.ts
4085
- var DEFAULT_HEADING = "## Available Skills";
4086
- var DEFAULT_EXTRA_NOTE = "Use the load_skill_content tool when you need detailed information about handling a specific type of request.";
6065
+ var DEFAULT_HEADING = "To better accomplish the user's objective, you can use the following skills to access best practices.";
6066
+ var DEFAULT_EXTRA_NOTE = `
6067
+ you must:
6068
+ 1) systematically evaluate every available skill for relevance,
6069
+ 2) explicitly activate all skills you judge relevant using the \`load_skill_content\` tool to get the best practices *before* working on the task, and
6070
+ 3) implement your solution using the guidance and best practices from those activated skills, explaining trade\u2011offs when they matter.
6071
+ `;
4087
6072
  function createSkillMiddleware(params = {}) {
4088
6073
  const {
4089
6074
  skills = [],
@@ -4096,7 +6081,8 @@ function createSkillMiddleware(params = {}) {
4096
6081
  name: "skillMiddleware",
4097
6082
  tools: [
4098
6083
  createLoadSkillsTool({ skills: readAll ? void 0 : skills }),
4099
- createLoadSkillContentTool()
6084
+ createLoadSkillContentTool(),
6085
+ createLoadSkillResourceTool()
4100
6086
  ],
4101
6087
  beforeAgent: async () => {
4102
6088
  try {
@@ -4116,7 +6102,8 @@ function createSkillMiddleware(params = {}) {
4116
6102
  }
4117
6103
  },
4118
6104
  wrapModelCall: (request, handler) => {
4119
- const skillsPrompt = latestSkills.map((skill) => `- **${skill.name}**: ${skill.description}`).join("\n");
6105
+ const skillsPrompt = latestSkills.map((skill) => `## ${skill.name}
6106
+ ${skill.description}`).join("\n");
4120
6107
  const skillsAddendum = `
4121
6108
 
4122
6109
  ${heading}
@@ -4135,9 +6122,9 @@ ${extraNote}`;
4135
6122
  }
4136
6123
 
4137
6124
  // src/deep_agent_new/middleware/fs.ts
4138
- import { createMiddleware as createMiddleware5, tool as tool33, ToolMessage } from "langchain";
6125
+ import { createMiddleware as createMiddleware5, tool as tool41, ToolMessage } from "langchain";
4139
6126
  import { Command, isCommand, getCurrentTaskInput } from "@langchain/langgraph";
4140
- import { z as z34 } from "zod/v3";
6127
+ import { z as z310 } from "zod/v3";
4141
6128
  import { withLangGraph } from "@langchain/langgraph/zod";
4142
6129
 
4143
6130
  // src/deep_agent_new/backends/utils.ts
@@ -4283,15 +6270,15 @@ function globSearchFiles(files, pattern, path5 = "/") {
4283
6270
  const effectivePattern = pattern;
4284
6271
  const matches = [];
4285
6272
  for (const [filePath, fileData] of Object.entries(filtered)) {
4286
- let relative3 = filePath.substring(normalizedPath.length);
4287
- if (relative3.startsWith("/")) {
4288
- relative3 = relative3.substring(1);
6273
+ let relative4 = filePath.substring(normalizedPath.length);
6274
+ if (relative4.startsWith("/")) {
6275
+ relative4 = relative4.substring(1);
4289
6276
  }
4290
- if (!relative3) {
6277
+ if (!relative4) {
4291
6278
  const parts = filePath.split("/");
4292
- relative3 = parts[parts.length - 1] || "";
6279
+ relative4 = parts[parts.length - 1] || "";
4293
6280
  }
4294
- if (micromatch.isMatch(relative3, effectivePattern, {
6281
+ if (micromatch.isMatch(relative4, effectivePattern, {
4295
6282
  dot: true,
4296
6283
  nobrace: false
4297
6284
  })) {
@@ -4445,9 +6432,9 @@ var StateBackend = class {
4445
6432
  if (!k.startsWith(normalizedPath)) {
4446
6433
  continue;
4447
6434
  }
4448
- const relative3 = k.substring(normalizedPath.length);
4449
- if (relative3.includes("/")) {
4450
- const subdirName = relative3.split("/")[0];
6435
+ const relative4 = k.substring(normalizedPath.length);
6436
+ if (relative4.includes("/")) {
6437
+ const subdirName = relative4.split("/")[0];
4451
6438
  subdirs.add(normalizedPath + subdirName + "/");
4452
6439
  continue;
4453
6440
  }
@@ -4576,10 +6563,10 @@ var StateBackend = class {
4576
6563
  };
4577
6564
 
4578
6565
  // src/deep_agent_new/middleware/fs.ts
4579
- var FileDataSchema = z34.object({
4580
- content: z34.array(z34.string()),
4581
- created_at: z34.string(),
4582
- modified_at: z34.string()
6566
+ var FileDataSchema = z310.object({
6567
+ content: z310.array(z310.string()),
6568
+ created_at: z310.string(),
6569
+ modified_at: z310.string()
4583
6570
  });
4584
6571
  function fileDataReducer(left, right) {
4585
6572
  if (left === void 0) {
@@ -4601,13 +6588,13 @@ function fileDataReducer(left, right) {
4601
6588
  }
4602
6589
  return result;
4603
6590
  }
4604
- var FilesystemStateSchema = z34.object({
6591
+ var FilesystemStateSchema = z310.object({
4605
6592
  files: withLangGraph(
4606
- z34.record(z34.string(), FileDataSchema).default({}),
6593
+ z310.record(z310.string(), FileDataSchema).default({}),
4607
6594
  {
4608
6595
  reducer: {
4609
6596
  fn: fileDataReducer,
4610
- schema: z34.record(z34.string(), FileDataSchema.nullable())
6597
+ schema: z310.record(z310.string(), FileDataSchema.nullable())
4611
6598
  }
4612
6599
  }
4613
6600
  )
@@ -4634,7 +6621,7 @@ var GLOB_TOOL_DESCRIPTION = "Find files matching a glob pattern (e.g., '**/*.py'
4634
6621
  var GREP_TOOL_DESCRIPTION = "Search for a regex pattern in files. Returns matching files and line numbers";
4635
6622
  function createLsTool(backend, options) {
4636
6623
  const { customDescription } = options;
4637
- return tool33(
6624
+ return tool41(
4638
6625
  async (input, config) => {
4639
6626
  const { runConfig } = config.configurable;
4640
6627
  const stateAndStore = {
@@ -4662,15 +6649,15 @@ function createLsTool(backend, options) {
4662
6649
  {
4663
6650
  name: "ls",
4664
6651
  description: customDescription || LS_TOOL_DESCRIPTION,
4665
- schema: z34.object({
4666
- path: z34.string().optional().default("/").describe("Directory path to list (default: /)")
6652
+ schema: z310.object({
6653
+ path: z310.string().optional().default("/").describe("Directory path to list (default: /)")
4667
6654
  })
4668
6655
  }
4669
6656
  );
4670
6657
  }
4671
6658
  function createReadFileTool(backend, options) {
4672
6659
  const { customDescription } = options;
4673
- return tool33(
6660
+ return tool41(
4674
6661
  async (input, config) => {
4675
6662
  const { runConfig } = config.configurable;
4676
6663
  const stateAndStore = {
@@ -4685,17 +6672,17 @@ function createReadFileTool(backend, options) {
4685
6672
  {
4686
6673
  name: "read_file",
4687
6674
  description: customDescription || READ_FILE_TOOL_DESCRIPTION,
4688
- schema: z34.object({
4689
- file_path: z34.string().describe("Absolute path to the file to read"),
4690
- offset: z34.number({ coerce: true }).optional().default(0).describe("Line offset to start reading from (0-indexed)"),
4691
- limit: z34.number({ coerce: true }).optional().default(2e3).describe("Maximum number of lines to read")
6675
+ schema: z310.object({
6676
+ file_path: z310.string().describe("Absolute path to the file to read"),
6677
+ offset: z310.number({ coerce: true }).optional().default(0).describe("Line offset to start reading from (0-indexed)"),
6678
+ limit: z310.number({ coerce: true }).optional().default(2e3).describe("Maximum number of lines to read")
4692
6679
  })
4693
6680
  }
4694
6681
  );
4695
6682
  }
4696
6683
  function createWriteFileTool(backend, options) {
4697
6684
  const { customDescription } = options;
4698
- return tool33(
6685
+ return tool41(
4699
6686
  async (input, config) => {
4700
6687
  const { runConfig } = config.configurable;
4701
6688
  const stateAndStore = {
@@ -4725,16 +6712,16 @@ function createWriteFileTool(backend, options) {
4725
6712
  {
4726
6713
  name: "write_file",
4727
6714
  description: customDescription || WRITE_FILE_TOOL_DESCRIPTION,
4728
- schema: z34.object({
4729
- file_path: z34.string().describe("Absolute path to the file to write"),
4730
- content: z34.string().describe("Content to write to the file")
6715
+ schema: z310.object({
6716
+ file_path: z310.string().describe("Absolute path to the file to write"),
6717
+ content: z310.string().describe("Content to write to the file")
4731
6718
  })
4732
6719
  }
4733
6720
  );
4734
6721
  }
4735
6722
  function createEditFileTool(backend, options) {
4736
6723
  const { customDescription } = options;
4737
- return tool33(
6724
+ return tool41(
4738
6725
  async (input, config) => {
4739
6726
  const { runConfig } = config.configurable;
4740
6727
  const stateAndStore = {
@@ -4769,18 +6756,18 @@ function createEditFileTool(backend, options) {
4769
6756
  {
4770
6757
  name: "edit_file",
4771
6758
  description: customDescription || EDIT_FILE_TOOL_DESCRIPTION,
4772
- schema: z34.object({
4773
- file_path: z34.string().describe("Absolute path to the file to edit"),
4774
- old_string: z34.string().describe("String to be replaced (must match exactly)"),
4775
- new_string: z34.string().describe("String to replace with"),
4776
- replace_all: z34.boolean().optional().default(false).describe("Whether to replace all occurrences")
6759
+ schema: z310.object({
6760
+ file_path: z310.string().describe("Absolute path to the file to edit"),
6761
+ old_string: z310.string().describe("String to be replaced (must match exactly)"),
6762
+ new_string: z310.string().describe("String to replace with"),
6763
+ replace_all: z310.boolean().optional().default(false).describe("Whether to replace all occurrences")
4777
6764
  })
4778
6765
  }
4779
6766
  );
4780
6767
  }
4781
6768
  function createGlobTool(backend, options) {
4782
6769
  const { customDescription } = options;
4783
- return tool33(
6770
+ return tool41(
4784
6771
  async (input, config) => {
4785
6772
  const { runConfig } = config.configurable;
4786
6773
  const stateAndStore = {
@@ -4799,16 +6786,16 @@ function createGlobTool(backend, options) {
4799
6786
  {
4800
6787
  name: "glob",
4801
6788
  description: customDescription || GLOB_TOOL_DESCRIPTION,
4802
- schema: z34.object({
4803
- pattern: z34.string().describe("Glob pattern (e.g., '*.py', '**/*.ts')"),
4804
- path: z34.string().optional().default("/").describe("Base path to search from (default: /)")
6789
+ schema: z310.object({
6790
+ pattern: z310.string().describe("Glob pattern (e.g., '*.py', '**/*.ts')"),
6791
+ path: z310.string().optional().default("/").describe("Base path to search from (default: /)")
4805
6792
  })
4806
6793
  }
4807
6794
  );
4808
6795
  }
4809
6796
  function createGrepTool(backend, options) {
4810
6797
  const { customDescription } = options;
4811
- return tool33(
6798
+ return tool41(
4812
6799
  async (input, config) => {
4813
6800
  const { runConfig } = config.configurable;
4814
6801
  const stateAndStore = {
@@ -4840,10 +6827,10 @@ ${currentFile}:`);
4840
6827
  {
4841
6828
  name: "grep",
4842
6829
  description: customDescription || GREP_TOOL_DESCRIPTION,
4843
- schema: z34.object({
4844
- pattern: z34.string().describe("Regex pattern to search for"),
4845
- path: z34.string().optional().default("/").describe("Base path to search from (default: /)"),
4846
- glob: z34.string().optional().nullable().describe("Optional glob pattern to filter files (e.g., '*.py')")
6830
+ schema: z310.object({
6831
+ pattern: z310.string().describe("Regex pattern to search for"),
6832
+ path: z310.string().optional().default("/").describe("Base path to search from (default: /)"),
6833
+ glob: z310.string().optional().nullable().describe("Optional glob pattern to filter files (e.g., '*.py')")
4847
6834
  })
4848
6835
  }
4849
6836
  );
@@ -4970,6 +6957,31 @@ ${systemPrompt}` : systemPrompt;
4970
6957
  });
4971
6958
  }
4972
6959
 
6960
+ // src/middlewares/metricsMiddleware.ts
6961
+ import { createMiddleware as createMiddleware6 } from "langchain";
6962
+ function createMetricsMiddleware(params) {
6963
+ const { serverKeys, serverDescriptions } = params;
6964
+ if (!serverKeys || serverKeys.length === 0) {
6965
+ return createMiddleware6({
6966
+ name: "metricsMiddleware",
6967
+ tools: []
6968
+ });
6969
+ }
6970
+ const toolParams = {
6971
+ serverKeys,
6972
+ serverDescriptions
6973
+ };
6974
+ return createMiddleware6({
6975
+ name: "metricsMiddleware",
6976
+ tools: [
6977
+ createListMetricsDataSourcesTool(toolParams),
6978
+ createQueryMetricsListTool(toolParams),
6979
+ createQueryMetricDefinitionTool(toolParams),
6980
+ createQuerySemanticMetricDataTool(toolParams)
6981
+ ]
6982
+ });
6983
+ }
6984
+
4973
6985
  // src/agent_lattice/builders/commonMiddleware.ts
4974
6986
  function createCommonMiddlewares(middlewareConfigs, filesystemBackend) {
4975
6987
  const middlewares = [];
@@ -5008,6 +7020,14 @@ function createCommonMiddlewares(middlewareConfigs, filesystemBackend) {
5008
7020
  case "skill":
5009
7021
  middlewares.push(createSkillMiddleware(config.config));
5010
7022
  break;
7023
+ case "metrics":
7024
+ {
7025
+ const metricsConfig = config.config;
7026
+ if (metricsConfig.serverKeys && metricsConfig.serverKeys.length > 0) {
7027
+ middlewares.push(createMetricsMiddleware(metricsConfig));
7028
+ }
7029
+ }
7030
+ break;
5011
7031
  }
5012
7032
  }
5013
7033
  return middlewares;
@@ -5051,9 +7071,9 @@ var ReActAgentGraphBuilder = class {
5051
7071
  */
5052
7072
  build(agentLattice, params) {
5053
7073
  const tools = params.tools.map((t) => {
5054
- const tool38 = getToolClient(t.key);
5055
- return tool38;
5056
- }).filter((tool38) => tool38 !== void 0);
7074
+ const tool46 = getToolClient(t.key);
7075
+ return tool46;
7076
+ }).filter((tool46) => tool46 !== void 0);
5057
7077
  const stateSchema2 = createReactAgentSchema(params.stateSchema);
5058
7078
  const middlewareConfigs = params.middleware || [];
5059
7079
  const filesystemBackend = this.createFilesystemBackendFactory(middlewareConfigs);
@@ -5079,11 +7099,11 @@ import {
5079
7099
  } from "langchain";
5080
7100
 
5081
7101
  // src/deep_agent_new/middleware/subagents.ts
5082
- import { z as z35 } from "zod/v3";
7102
+ import { z as z42 } from "zod/v3";
5083
7103
  import {
5084
- createMiddleware as createMiddleware6,
7104
+ createMiddleware as createMiddleware7,
5085
7105
  createAgent as createAgent2,
5086
- tool as tool34,
7106
+ tool as tool42,
5087
7107
  ToolMessage as ToolMessage2,
5088
7108
  humanInTheLoopMiddleware
5089
7109
  } from "langchain";
@@ -5727,7 +7747,7 @@ function createTaskTool(options) {
5727
7747
  generalPurposeAgent
5728
7748
  });
5729
7749
  const finalTaskDescription = taskDescription ? taskDescription : getTaskToolDescription(subagentDescriptions);
5730
- return tool34(
7750
+ return tool42(
5731
7751
  async (input, config) => {
5732
7752
  const { description, subagent_type } = input;
5733
7753
  try {
@@ -5770,9 +7790,9 @@ function createTaskTool(options) {
5770
7790
  {
5771
7791
  name: "task",
5772
7792
  description: finalTaskDescription,
5773
- schema: z35.object({
5774
- description: z35.string().describe("The task to execute with the selected agent"),
5775
- subagent_type: z35.string().describe(
7793
+ schema: z42.object({
7794
+ description: z42.string().describe("The task to execute with the selected agent"),
7795
+ subagent_type: z42.string().describe(
5776
7796
  `Name of the agent to use. Available: ${Object.keys(
5777
7797
  subagentGraphs
5778
7798
  ).join(", ")}`
@@ -5801,7 +7821,7 @@ function createSubAgentMiddleware(options) {
5801
7821
  generalPurposeAgent,
5802
7822
  taskDescription
5803
7823
  });
5804
- return createMiddleware6({
7824
+ return createMiddleware7({
5805
7825
  name: "subAgentMiddleware",
5806
7826
  tools: [taskTool],
5807
7827
  wrapModelCall: async (request, handler) => {
@@ -5822,14 +7842,14 @@ ${systemPrompt}` : systemPrompt;
5822
7842
 
5823
7843
  // src/deep_agent_new/middleware/patch_tool_calls.ts
5824
7844
  import {
5825
- createMiddleware as createMiddleware7,
7845
+ createMiddleware as createMiddleware8,
5826
7846
  ToolMessage as ToolMessage3,
5827
7847
  AIMessage as AIMessage2
5828
7848
  } from "langchain";
5829
7849
  import { RemoveMessage } from "@langchain/core/messages";
5830
7850
  import { REMOVE_ALL_MESSAGES } from "@langchain/langgraph";
5831
7851
  function createPatchToolCallsMiddleware() {
5832
- return createMiddleware7({
7852
+ return createMiddleware8({
5833
7853
  name: "patchToolCallsMiddleware",
5834
7854
  beforeAgent: async (state) => {
5835
7855
  const messages = state.messages;
@@ -5983,9 +8003,9 @@ var StoreBackend = class {
5983
8003
  if (!itemKey.startsWith(normalizedPath)) {
5984
8004
  continue;
5985
8005
  }
5986
- const relative3 = itemKey.substring(normalizedPath.length);
5987
- if (relative3.includes("/")) {
5988
- const subdirName = relative3.split("/")[0];
8006
+ const relative4 = itemKey.substring(normalizedPath.length);
8007
+ if (relative4.includes("/")) {
8008
+ const subdirName = relative4.split("/")[0];
5989
8009
  subdirs.add(normalizedPath + subdirName + "/");
5990
8010
  continue;
5991
8011
  }
@@ -6178,8 +8198,8 @@ var FilesystemBackend = class {
6178
8198
  throw new Error("Path traversal not allowed");
6179
8199
  }
6180
8200
  const full = path4.resolve(this.cwd, vpath.substring(1));
6181
- const relative3 = path4.relative(this.cwd, full);
6182
- if (relative3.startsWith("..") || path4.isAbsolute(relative3)) {
8201
+ const relative4 = path4.relative(this.cwd, full);
8202
+ if (relative4.startsWith("..") || path4.isAbsolute(relative4)) {
6183
8203
  throw new Error(`Path: ${full} outside root directory: ${this.cwd}`);
6184
8204
  }
6185
8205
  return full;
@@ -6514,9 +8534,9 @@ var FilesystemBackend = class {
6514
8534
  if (this.virtualMode) {
6515
8535
  try {
6516
8536
  const resolved = path4.resolve(ftext);
6517
- const relative3 = path4.relative(this.cwd, resolved);
6518
- if (relative3.startsWith("..")) continue;
6519
- const normalizedRelative = relative3.split(path4.sep).join("/");
8537
+ const relative4 = path4.relative(this.cwd, resolved);
8538
+ if (relative4.startsWith("..")) continue;
8539
+ const normalizedRelative = relative4.split(path4.sep).join("/");
6520
8540
  virtPath = "/" + normalizedRelative;
6521
8541
  } catch {
6522
8542
  continue;
@@ -6578,9 +8598,9 @@ var FilesystemBackend = class {
6578
8598
  let virtPath;
6579
8599
  if (this.virtualMode) {
6580
8600
  try {
6581
- const relative3 = path4.relative(this.cwd, fp);
6582
- if (relative3.startsWith("..")) continue;
6583
- const normalizedRelative = relative3.split(path4.sep).join("/");
8601
+ const relative4 = path4.relative(this.cwd, fp);
8602
+ if (relative4.startsWith("..")) continue;
8603
+ const normalizedRelative = relative4.split(path4.sep).join("/");
6584
8604
  virtPath = "/" + normalizedRelative;
6585
8605
  } catch {
6586
8606
  continue;
@@ -6863,9 +8883,9 @@ var MemoryBackend = class {
6863
8883
  if (!k.startsWith(normalizedPath)) {
6864
8884
  continue;
6865
8885
  }
6866
- const relative3 = k.substring(normalizedPath.length);
6867
- if (relative3.includes("/")) {
6868
- const subdirName = relative3.split("/")[0];
8886
+ const relative4 = k.substring(normalizedPath.length);
8887
+ if (relative4.includes("/")) {
8888
+ const subdirName = relative4.split("/")[0];
6869
8889
  subdirs.add(normalizedPath + subdirName + "/");
6870
8890
  continue;
6871
8891
  }
@@ -6961,8 +8981,8 @@ var MemoryBackend = class {
6961
8981
 
6962
8982
  // src/deep_agent_new/middleware/todos.ts
6963
8983
  import { Command as Command3 } from "@langchain/langgraph";
6964
- import { z as z36 } from "zod";
6965
- import { createMiddleware as createMiddleware8, tool as tool35, ToolMessage as ToolMessage4 } from "langchain";
8984
+ import { z as z43 } from "zod";
8985
+ import { createMiddleware as createMiddleware9, tool as tool43, ToolMessage as ToolMessage4 } from "langchain";
6966
8986
  var WRITE_TODOS_DESCRIPTION = `Use this tool to create and manage a structured task list for your current work session. This helps you track progress, organize complex tasks, and demonstrate thoroughness to the user.
6967
8987
  It also helps the user understand the progress of the task and overall progress of their requests.
6968
8988
  Only use this tool if you think it will be helpful in staying organized. If the user's request is trivial and takes less than 3 steps, it is better to NOT use this tool and just do the taks directly.
@@ -7189,14 +9209,14 @@ Writing todos takes time and tokens, use it when it is helpful for managing comp
7189
9209
  ## Important To-Do List Usage Notes to Remember
7190
9210
  - The \`write_todos\` tool should never be called multiple times in parallel.
7191
9211
  - Don't be afraid to revise the To-Do list as you go. New information may reveal new tasks that need to be done, or old tasks that are irrelevant.`;
7192
- var TodoStatus = z36.enum(["pending", "in_progress", "completed"]).describe("Status of the todo");
7193
- var TodoSchema = z36.object({
7194
- content: z36.string().describe("Content of the todo item"),
9212
+ var TodoStatus = z43.enum(["pending", "in_progress", "completed"]).describe("Status of the todo");
9213
+ var TodoSchema = z43.object({
9214
+ content: z43.string().describe("Content of the todo item"),
7195
9215
  status: TodoStatus
7196
9216
  });
7197
- var stateSchema = z36.object({ todos: z36.array(TodoSchema).default([]) });
9217
+ var stateSchema = z43.object({ todos: z43.array(TodoSchema).default([]) });
7198
9218
  function todoListMiddleware(options) {
7199
- const writeTodos = tool35(
9219
+ const writeTodos = tool43(
7200
9220
  ({ todos }, config) => {
7201
9221
  return new Command3({
7202
9222
  update: {
@@ -7213,12 +9233,12 @@ function todoListMiddleware(options) {
7213
9233
  {
7214
9234
  name: "write_todos",
7215
9235
  description: options?.toolDescription ?? WRITE_TODOS_DESCRIPTION,
7216
- schema: z36.object({
7217
- todos: z36.array(TodoSchema).describe("List of todo items to update")
9236
+ schema: z43.object({
9237
+ todos: z43.array(TodoSchema).describe("List of todo items to update")
7218
9238
  })
7219
9239
  }
7220
9240
  );
7221
- return createMiddleware8({
9241
+ return createMiddleware9({
7222
9242
  name: "todoListMiddleware",
7223
9243
  stateSchema,
7224
9244
  tools: [writeTodos],
@@ -7361,7 +9381,7 @@ var DeepAgentGraphBuilder = class {
7361
9381
  const tools = params.tools.map((t) => {
7362
9382
  const toolClient = getToolClient(t.key);
7363
9383
  return toolClient;
7364
- }).filter((tool38) => tool38 !== void 0);
9384
+ }).filter((tool46) => tool46 !== void 0);
7365
9385
  const subagents = params.subAgents.map((sa) => {
7366
9386
  if (sa.client) {
7367
9387
  return {
@@ -7399,7 +9419,7 @@ var DeepAgentGraphBuilder = class {
7399
9419
  };
7400
9420
 
7401
9421
  // src/agent_team/agent_team.ts
7402
- import { z as z39 } from "zod/v3";
9422
+ import { z as z46 } from "zod/v3";
7403
9423
  import { createAgent as createAgent5 } from "langchain";
7404
9424
 
7405
9425
  // src/agent_team/types.ts
@@ -7835,14 +9855,14 @@ var InMemoryMailboxStore = class {
7835
9855
  };
7836
9856
 
7837
9857
  // src/agent_team/middleware/team.ts
7838
- import { z as z38 } from "zod/v3";
7839
- import { createMiddleware as createMiddleware9, createAgent as createAgent4, tool as tool37, ToolMessage as ToolMessage6 } from "langchain";
9858
+ import { z as z45 } from "zod/v3";
9859
+ import { createMiddleware as createMiddleware10, createAgent as createAgent4, tool as tool45, ToolMessage as ToolMessage6 } from "langchain";
7840
9860
  import { Command as Command5, getCurrentTaskInput as getCurrentTaskInput3 } from "@langchain/langgraph";
7841
9861
  import { v4 as uuidv4 } from "uuid";
7842
9862
 
7843
9863
  // src/agent_team/middleware/teammate_tools.ts
7844
- import { z as z37 } from "zod/v3";
7845
- import { tool as tool36, ToolMessage as ToolMessage5 } from "langchain";
9864
+ import { z as z44 } from "zod/v3";
9865
+ import { tool as tool44, ToolMessage as ToolMessage5 } from "langchain";
7846
9866
  import { Command as Command4 } from "@langchain/langgraph";
7847
9867
 
7848
9868
  // src/agent_team/middleware/formatMessages.ts
@@ -7867,7 +9887,7 @@ ${meta}${body}`;
7867
9887
  // src/agent_team/middleware/teammate_tools.ts
7868
9888
  function createTeammateTools(options) {
7869
9889
  const { teamId, agentId, taskListStore, mailboxStore } = options;
7870
- const claimTaskTool = tool36(
9890
+ const claimTaskTool = tool44(
7871
9891
  async (input) => {
7872
9892
  const task = await taskListStore.claimTaskById(
7873
9893
  teamId,
@@ -7892,12 +9912,12 @@ function createTeammateTools(options) {
7892
9912
  {
7893
9913
  name: "claim_task",
7894
9914
  description: "Pick a task to work on by task_id. Use check_tasks first to see all tasks; then call this with the task_id you choose. The task's assignee is set to you and you should focus on that task until you complete_task or fail_task it.",
7895
- schema: z37.object({
7896
- task_id: z37.string().describe("ID of the task to claim (e.g. task-01). Use check_tasks to see IDs.")
9915
+ schema: z44.object({
9916
+ task_id: z44.string().describe("ID of the task to claim (e.g. task-01). Use check_tasks to see IDs.")
7897
9917
  })
7898
9918
  }
7899
9919
  );
7900
- const completeTaskTool = tool36(
9920
+ const completeTaskTool = tool44(
7901
9921
  async (input) => {
7902
9922
  const task = await taskListStore.completeTask(
7903
9923
  teamId,
@@ -7918,13 +9938,13 @@ function createTeammateTools(options) {
7918
9938
  {
7919
9939
  name: "complete_task",
7920
9940
  description: "Mark a claimed task as completed with a result summary. Call this after you have finished working on a task.",
7921
- schema: z37.object({
7922
- task_id: z37.string().describe("ID of the task to complete"),
7923
- result: z37.string().describe("Summary of the task result")
9941
+ schema: z44.object({
9942
+ task_id: z44.string().describe("ID of the task to complete"),
9943
+ result: z44.string().describe("Summary of the task result")
7924
9944
  })
7925
9945
  }
7926
9946
  );
7927
- const failTaskTool = tool36(
9947
+ const failTaskTool = tool44(
7928
9948
  async (input) => {
7929
9949
  const task = await taskListStore.failTask(
7930
9950
  teamId,
@@ -7945,13 +9965,13 @@ function createTeammateTools(options) {
7945
9965
  {
7946
9966
  name: "fail_task",
7947
9967
  description: "Mark a claimed task as failed with an error description. Call this if you cannot complete the task.",
7948
- schema: z37.object({
7949
- task_id: z37.string().describe("ID of the task to fail"),
7950
- error: z37.string().describe("Description of why the task failed")
9968
+ schema: z44.object({
9969
+ task_id: z44.string().describe("ID of the task to fail"),
9970
+ error: z44.string().describe("Description of why the task failed")
7951
9971
  })
7952
9972
  }
7953
9973
  );
7954
- const sendMessageTool = tool36(
9974
+ const sendMessageTool = tool44(
7955
9975
  async (input) => {
7956
9976
  await mailboxStore.sendMessage(
7957
9977
  teamId,
@@ -7965,11 +9985,11 @@ function createTeammateTools(options) {
7965
9985
  {
7966
9986
  name: "send_message",
7967
9987
  description: 'Send a message to the team lead or another teammate via the mailbox. Use "team_lead" to message the team lead. Use this to report discoveries, request guidance, or suggest new tasks.',
7968
- schema: z37.object({
7969
- to: z37.string().describe(
9988
+ schema: z44.object({
9989
+ to: z44.string().describe(
7970
9990
  'Recipient agent name (e.g. "team_lead" or a teammate name)'
7971
9991
  ),
7972
- content: z37.string().describe("Message content")
9992
+ content: z44.string().describe("Message content")
7973
9993
  })
7974
9994
  }
7975
9995
  );
@@ -7989,7 +10009,7 @@ function createTeammateTools(options) {
7989
10009
  read: msg.read
7990
10010
  }));
7991
10011
  };
7992
- const readMessagesTool = tool36(
10012
+ const readMessagesTool = tool44(
7993
10013
  async (input, config) => {
7994
10014
  const formatAndMarkAsRead = async (msgs2) => {
7995
10015
  for (const msg of msgs2) {
@@ -8048,10 +10068,10 @@ function createTeammateTools(options) {
8048
10068
  {
8049
10069
  name: "read_messages",
8050
10070
  description: "Read unread messages from the mailbox. Returns immediately if messages exist, otherwise waits for up to 3 minutes for new messages.",
8051
- schema: z37.object({})
10071
+ schema: z44.object({})
8052
10072
  }
8053
10073
  );
8054
- const checkTasksTool = tool36(
10074
+ const checkTasksTool = tool44(
8055
10075
  async () => {
8056
10076
  const tasks = await taskListStore.getAllTasks(teamId);
8057
10077
  return formatTaskSummary(tasks);
@@ -8059,10 +10079,10 @@ function createTeammateTools(options) {
8059
10079
  {
8060
10080
  name: "check_tasks",
8061
10081
  description: "Use this tool to get the current status of all tasks in a team. This is your primary way to monitor task progress.",
8062
- schema: z37.object({})
10082
+ schema: z44.object({})
8063
10083
  }
8064
10084
  );
8065
- const broadcastMessageTool = tool36(
10085
+ const broadcastMessageTool = tool44(
8066
10086
  async (input) => {
8067
10087
  const allAgents = await mailboxStore.getRegisteredAgents(teamId);
8068
10088
  const recipients = allAgents.filter((a) => a !== agentId);
@@ -8081,8 +10101,8 @@ function createTeammateTools(options) {
8081
10101
  {
8082
10102
  name: "broadcast_message",
8083
10103
  description: "Send a message to everyone in the team except yourself. Use this to share updates or information with all teammates and the team lead at once.",
8084
- schema: z37.object({
8085
- content: z37.string().describe("Message content to broadcast to others")
10104
+ schema: z44.object({
10105
+ content: z44.string().describe("Message content to broadcast to others")
8086
10106
  })
8087
10107
  }
8088
10108
  );
@@ -8305,7 +10325,7 @@ async function spawnTeammate(options) {
8305
10325
  function createTeamMiddleware(options) {
8306
10326
  const { teamConfig, taskListStore, mailboxStore } = options;
8307
10327
  const defaultModel = teamConfig.model ?? "claude-sonnet-4-5-20250929";
8308
- const createTeamTool = tool37(
10328
+ const createTeamTool = tool45(
8309
10329
  async (input, config) => {
8310
10330
  const state = getCurrentTaskInput3();
8311
10331
  if (state?.team?.teamId) {
@@ -8456,20 +10476,20 @@ After calling create_team, you MUST:
8456
10476
  2. When messages indicate task changes, call check_tasks to get full task status
8457
10477
  3. Continue until all tasks show "completed" or "failed"
8458
10478
  4. Do NOT assume tasks are done - always verify with check_tasks`,
8459
- schema: z38.object({
8460
- tasks: z38.array(
8461
- z38.object({
8462
- id: z38.string().describe("Task ID in format task-01, task-02, etc."),
8463
- title: z38.string().describe("Short task title"),
8464
- description: z38.string().describe("Detailed task description - what exactly needs to be done"),
8465
- dependencies: z38.array(z38.string()).optional().default([]).describe('Array of task IDs that must complete before this task (e.g. ["task-01"])')
10479
+ schema: z45.object({
10480
+ tasks: z45.array(
10481
+ z45.object({
10482
+ id: z45.string().describe("Task ID in format task-01, task-02, etc."),
10483
+ title: z45.string().describe("Short task title"),
10484
+ description: z45.string().describe("Detailed task description - what exactly needs to be done"),
10485
+ dependencies: z45.array(z45.string()).optional().default([]).describe('Array of task IDs that must complete before this task (e.g. ["task-01"])')
8466
10486
  })
8467
10487
  ).describe("List of tasks for teammates to work on. Each task needs unique ID (task-01, task-02, etc.)."),
8468
- teammates: z38.array(
8469
- z38.object({
8470
- name: z38.string().describe("Teammate name (must match a pre-configured teammate type)"),
8471
- role: z38.string().describe("Role category (e.g. researcher, writer, coder, reviewer)"),
8472
- description: z38.string().describe("What this teammate will focus on - specific instructions for their work")
10488
+ teammates: z45.array(
10489
+ z45.object({
10490
+ name: z45.string().describe("Teammate name (must match a pre-configured teammate type)"),
10491
+ role: z45.string().describe("Role category (e.g. researcher, writer, coder, reviewer)"),
10492
+ description: z45.string().describe("What this teammate will focus on - specific instructions for their work")
8473
10493
  })
8474
10494
  ).describe("Teammate agents to create. Each should have a clear role and focus.")
8475
10495
  })
@@ -8480,7 +10500,7 @@ After calling create_team, you MUST:
8480
10500
  if (state?.team?.teamId) return state.team.teamId;
8481
10501
  throw new Error("No team_id provided and no team in state. Call create_team first.");
8482
10502
  };
8483
- const addTasksTool = tool37(
10503
+ const addTasksTool = tool45(
8484
10504
  async (input, config) => {
8485
10505
  const teamId = resolveTeamId();
8486
10506
  const created = await taskListStore.addTasks(
@@ -8532,20 +10552,20 @@ IMPORTANT: Dependencies
8532
10552
 
8533
10553
  IMPORTANT: Assigning to a specific teammate
8534
10554
  - When you need a particular teammate to do the work, set assignee to that teammate's name (e.g. assignee: "researcher"). They can then claim or see the task as assigned to them.`,
8535
- schema: z38.object({
8536
- tasks: z38.array(
8537
- z38.object({
8538
- id: z38.string().describe("Task ID in format task-01, task-02, etc. Must be unique."),
8539
- title: z38.string().describe("Short task title"),
8540
- description: z38.string().describe("Detailed task description - what needs to be done"),
8541
- assignee: z38.string().optional().describe("Teammate name to assign this task to (use when you need that person to do the work)"),
8542
- dependencies: z38.array(z38.string()).optional().default([]).describe("Array of task IDs that must complete before this task")
10555
+ schema: z45.object({
10556
+ tasks: z45.array(
10557
+ z45.object({
10558
+ id: z45.string().describe("Task ID in format task-01, task-02, etc. Must be unique."),
10559
+ title: z45.string().describe("Short task title"),
10560
+ description: z45.string().describe("Detailed task description - what needs to be done"),
10561
+ assignee: z45.string().optional().describe("Teammate name to assign this task to (use when you need that person to do the work)"),
10562
+ dependencies: z45.array(z45.string()).optional().default([]).describe("Array of task IDs that must complete before this task")
8543
10563
  })
8544
10564
  ).describe("New tasks to add to the team")
8545
10565
  })
8546
10566
  }
8547
10567
  );
8548
- const assignTaskTool = tool37(
10568
+ const assignTaskTool = tool45(
8549
10569
  async (input, config) => {
8550
10570
  const teamId = resolveTeamId();
8551
10571
  const task = await taskListStore.updateTask(teamId, input.task_id, {
@@ -8567,13 +10587,13 @@ IMPORTANT: Assigning to a specific teammate
8567
10587
  {
8568
10588
  name: "assign_task",
8569
10589
  description: "Assign a task to a specific teammate. Use when you need to reassign work to a different teammate. Omit team_id to use the active team from state.",
8570
- schema: z38.object({
8571
- task_id: z38.string().describe("Task ID to assign"),
8572
- assignee: z38.string().describe("Teammate name to assign this task to")
10590
+ schema: z45.object({
10591
+ task_id: z45.string().describe("Task ID to assign"),
10592
+ assignee: z45.string().describe("Teammate name to assign this task to")
8573
10593
  })
8574
10594
  }
8575
10595
  );
8576
- const setTaskStatusTool = tool37(
10596
+ const setTaskStatusTool = tool45(
8577
10597
  async (input, config) => {
8578
10598
  const teamId = resolveTeamId();
8579
10599
  const task = await taskListStore.updateTask(teamId, input.task_id, {
@@ -8595,13 +10615,13 @@ IMPORTANT: Assigning to a specific teammate
8595
10615
  {
8596
10616
  name: "set_task_status",
8597
10617
  description: "Set a task's status. Use to reopen a task (set to pending), mark as failed, or correct status. Values: pending, claimed, in_progress, completed, failed. Omit team_id to use the active team from state.",
8598
- schema: z38.object({
8599
- task_id: z38.string().describe("Task ID to update"),
8600
- status: z38.enum(["pending", "claimed", "in_progress", "completed", "failed"]).describe("New status for the task")
10618
+ schema: z45.object({
10619
+ task_id: z45.string().describe("Task ID to update"),
10620
+ status: z45.enum(["pending", "claimed", "in_progress", "completed", "failed"]).describe("New status for the task")
8601
10621
  })
8602
10622
  }
8603
10623
  );
8604
- const setTaskDependenciesTool = tool37(
10624
+ const setTaskDependenciesTool = tool45(
8605
10625
  async (input, config) => {
8606
10626
  const teamId = resolveTeamId();
8607
10627
  const task = await taskListStore.updateTask(teamId, input.task_id, {
@@ -8623,13 +10643,13 @@ IMPORTANT: Assigning to a specific teammate
8623
10643
  {
8624
10644
  name: "set_task_dependencies",
8625
10645
  description: 'Set which task IDs must complete before this task can be claimed. Pass an array of task IDs (e.g. ["task-01", "task-02"]). Use to fix task order or add/remove dependencies. Omit team_id to use the active team from state.',
8626
- schema: z38.object({
8627
- task_id: z38.string().describe("Task ID to update"),
8628
- dependencies: z38.array(z38.string()).describe("Task IDs that must complete before this task can be claimed")
10646
+ schema: z45.object({
10647
+ task_id: z45.string().describe("Task ID to update"),
10648
+ dependencies: z45.array(z45.string()).describe("Task IDs that must complete before this task can be claimed")
8629
10649
  })
8630
10650
  }
8631
10651
  );
8632
- const checkTasksTool = tool37(
10652
+ const checkTasksTool = tool45(
8633
10653
  async (input, config) => {
8634
10654
  const teamId = resolveTeamId();
8635
10655
  const tasks = await taskListStore.getAllTasks(teamId);
@@ -8669,12 +10689,12 @@ Task Status Values:
8669
10689
  - in_progress: Teammate is actively working on this task
8670
10690
  - completed: Task finished successfully
8671
10691
  - failed: Task encountered an error`,
8672
- schema: z38.object({
8673
- team_id: z38.string().optional().describe("Team ID (omit to use active team)")
10692
+ schema: z45.object({
10693
+ team_id: z45.string().optional().describe("Team ID (omit to use active team)")
8674
10694
  })
8675
10695
  }
8676
10696
  );
8677
- const sendMessageTool = tool37(
10697
+ const sendMessageTool = tool45(
8678
10698
  async (input, config) => {
8679
10699
  const teamId = resolveTeamId();
8680
10700
  await mailboxStore.sendMessage(
@@ -8693,13 +10713,13 @@ Task Status Values:
8693
10713
  {
8694
10714
  name: "send_message",
8695
10715
  description: "Send a message to a specific teammate in the team. Omit team_id to use the active team from state.",
8696
- schema: z38.object({
8697
- to: z38.string().describe("Recipient teammate name"),
8698
- content: z38.string().describe("Message content")
10716
+ schema: z45.object({
10717
+ to: z45.string().describe("Recipient teammate name"),
10718
+ content: z45.string().describe("Message content")
8699
10719
  })
8700
10720
  }
8701
10721
  );
8702
- const readMessagesTool = tool37(
10722
+ const readMessagesTool = tool45(
8703
10723
  async (input, config) => {
8704
10724
  const teamId = resolveTeamId();
8705
10725
  const formatAndMarkAsRead = async (msgs2) => {
@@ -8781,12 +10801,12 @@ Task Status Values:
8781
10801
  {
8782
10802
  name: "read_messages",
8783
10803
  description: "Read unread messages from teammates. Returns immediately if messages exist, otherwise waits for up to 3 minutes for new messages.",
8784
- schema: z38.object({
8785
- team_id: z38.string().optional().describe("Team ID (omit to use active team)")
10804
+ schema: z45.object({
10805
+ team_id: z45.string().optional().describe("Team ID (omit to use active team)")
8786
10806
  })
8787
10807
  }
8788
10808
  );
8789
- const disbandTeamTool = tool37(
10809
+ const disbandTeamTool = tool45(
8790
10810
  async (input, config) => {
8791
10811
  const teamId = resolveTeamId();
8792
10812
  await mailboxStore.broadcastMessage(
@@ -8807,7 +10827,7 @@ Task Status Values:
8807
10827
  description: "Disband a team when all work is done. Before calling: (1) Call check_tasks to verify no tasks are still pending/in_progress; (2) if any are, discuss with the team via read_messages and broadcast_message/send_message whether to continue or stop/cancel them; (3) only after alignment (all tasks completed/failed or explicitly stopped), then call this tool. This will: 1) Send a shutdown message to all teammates, 2) Wait briefly for them to clean up, 3) Clear all tasks and messages. Omit team_id to use the active team from state."
8808
10828
  }
8809
10829
  );
8810
- const broadcastMessageTool = tool37(
10830
+ const broadcastMessageTool = tool45(
8811
10831
  async (input, config) => {
8812
10832
  const teamId = resolveTeamId();
8813
10833
  await mailboxStore.broadcastMessage(
@@ -8825,12 +10845,12 @@ Task Status Values:
8825
10845
  {
8826
10846
  name: "broadcast_message",
8827
10847
  description: "Send a message to all teammates at once. Use this to communicate with everyone in the team. Omit team_id to use the active team from state.",
8828
- schema: z38.object({
8829
- content: z38.string().describe("Message content to broadcast to all teammates")
10848
+ schema: z45.object({
10849
+ content: z45.string().describe("Message content to broadcast to all teammates")
8830
10850
  })
8831
10851
  }
8832
10852
  );
8833
- return createMiddleware9({
10853
+ return createMiddleware10({
8834
10854
  name: "teamMiddleware",
8835
10855
  tools: [
8836
10856
  createTeamTool,
@@ -8858,37 +10878,37 @@ ${TEAM_SYSTEM_PROMPT}` : TEAM_SYSTEM_PROMPT;
8858
10878
  }
8859
10879
 
8860
10880
  // src/agent_team/agent_team.ts
8861
- var TeammateInfoSchema = z39.object({
8862
- name: z39.string().describe("Teammate name"),
8863
- role: z39.string().describe("Role category (e.g. research, writing, review)"),
8864
- description: z39.string().describe("What this teammate focuses on")
10881
+ var TeammateInfoSchema = z46.object({
10882
+ name: z46.string().describe("Teammate name"),
10883
+ role: z46.string().describe("Role category (e.g. research, writing, review)"),
10884
+ description: z46.string().describe("What this teammate focuses on")
8865
10885
  });
8866
- var TeamTaskInfoSchema = z39.object({
8867
- id: z39.string(),
8868
- title: z39.string(),
8869
- description: z39.string(),
8870
- status: z39.string().optional()
10886
+ var TeamTaskInfoSchema = z46.object({
10887
+ id: z46.string(),
10888
+ title: z46.string(),
10889
+ description: z46.string(),
10890
+ status: z46.string().optional()
8871
10891
  });
8872
- var MailboxMessageSchema = z39.object({
8873
- id: z39.string().describe("Unique message identifier"),
8874
- from: z39.string().describe("Sender agent name"),
8875
- to: z39.string().describe("Recipient agent name"),
8876
- content: z39.string().describe("Message content"),
8877
- timestamp: z39.string().describe("ISO timestamp when the message was sent"),
8878
- type: z39.nativeEnum(MessageType).describe("Message type"),
8879
- read: z39.boolean().describe("Whether the recipient has read this message")
10892
+ var MailboxMessageSchema = z46.object({
10893
+ id: z46.string().describe("Unique message identifier"),
10894
+ from: z46.string().describe("Sender agent name"),
10895
+ to: z46.string().describe("Recipient agent name"),
10896
+ content: z46.string().describe("Message content"),
10897
+ timestamp: z46.string().describe("ISO timestamp when the message was sent"),
10898
+ type: z46.nativeEnum(MessageType).describe("Message type"),
10899
+ read: z46.boolean().describe("Whether the recipient has read this message")
8880
10900
  });
8881
- var TeamInfoSchema = z39.object({
8882
- teamId: z39.string().describe("Unique team identifier"),
8883
- teamLeadId: z39.string().default("team_lead").describe("Team lead agent ID"),
8884
- teammates: z39.array(TeammateInfoSchema).describe("Active teammates in this team"),
8885
- tasks: z39.array(TeamTaskInfoSchema).optional().describe("Initial tasks snapshot"),
8886
- createdAt: z39.string().optional().describe("ISO timestamp when team was created")
10901
+ var TeamInfoSchema = z46.object({
10902
+ teamId: z46.string().describe("Unique team identifier"),
10903
+ teamLeadId: z46.string().default("team_lead").describe("Team lead agent ID"),
10904
+ teammates: z46.array(TeammateInfoSchema).describe("Active teammates in this team"),
10905
+ tasks: z46.array(TeamTaskInfoSchema).optional().describe("Initial tasks snapshot"),
10906
+ createdAt: z46.string().optional().describe("ISO timestamp when team was created")
8887
10907
  });
8888
- var TEAM_STATE_SCHEMA = z39.object({
10908
+ var TEAM_STATE_SCHEMA = z46.object({
8889
10909
  team: TeamInfoSchema.optional().describe("Team info: teamId, teamLeadId, teammates, tasks. Set when create_team succeeds."),
8890
- tasks: z39.array(TeamTaskInfoSchema).optional().describe("Current tasks snapshot from check_tasks. Updated on each check."),
8891
- team_mailbox: z39.array(MailboxMessageSchema).optional().describe("All team mailbox messages for display")
10910
+ tasks: z46.array(TeamTaskInfoSchema).optional().describe("Current tasks snapshot from check_tasks. Updated on each check."),
10911
+ team_mailbox: z46.array(MailboxMessageSchema).optional().describe("All team mailbox messages for display")
8892
10912
  });
8893
10913
  var TEAM_LEAD_BASE_PROMPT = `You are a team lead that coordinates a team of specialized agents. In order to complete the objective that the user asks of you, you will need to:
8894
10914
 
@@ -8968,7 +10988,7 @@ var TeamAgentGraphBuilder = class {
8968
10988
  const tools = params.tools.map((t) => {
8969
10989
  const toolClient = getToolClient(t.key);
8970
10990
  return toolClient;
8971
- }).filter((tool38) => tool38 !== void 0);
10991
+ }).filter((tool46) => tool46 !== void 0);
8972
10992
  const teammates = params.subAgents.map((sa) => {
8973
10993
  const baseConfig = sa.config;
8974
10994
  return {
@@ -11645,10 +13665,10 @@ var McpLatticeManager = class _McpLatticeManager extends BaseLatticeManager {
11645
13665
  }
11646
13666
  const tools = await this.getAllTools();
11647
13667
  console.log(`[MCP] Registering ${tools.length} tools to Tool Lattice...`);
11648
- for (const tool38 of tools) {
11649
- const toolKey = prefix ? `${prefix}_${tool38.name}` : tool38.name;
11650
- tool38.name = toolKey;
11651
- toolLatticeManager.registerExistingTool(toolKey, tool38);
13668
+ for (const tool46 of tools) {
13669
+ const toolKey = prefix ? `${prefix}_${tool46.name}` : tool46.name;
13670
+ tool46.name = toolKey;
13671
+ toolLatticeManager.registerExistingTool(toolKey, tool46);
11652
13672
  console.log(`[MCP] Registered tool: ${toolKey}`);
11653
13673
  }
11654
13674
  console.log(`[MCP] Successfully registered ${tools.length} tools to Tool Lattice`);
@@ -11732,6 +13752,7 @@ export {
11732
13752
  ChunkBufferLatticeManager,
11733
13753
  CompositeBackend,
11734
13754
  ConsoleLoggerClient,
13755
+ CustomMetricsClient,
11735
13756
  DefaultScheduleClient,
11736
13757
  EMPTY_CONTENT_WARNING,
11737
13758
  EmbeddingsLatticeManager,
@@ -11743,7 +13764,10 @@ export {
11743
13764
  InMemoryDatabaseConfigStore,
11744
13765
  InMemoryMailboxStore,
11745
13766
  InMemoryTaskListStore,
13767
+ InMemoryTenantStore,
11746
13768
  InMemoryThreadStore,
13769
+ InMemoryUserStore,
13770
+ InMemoryUserTenantLinkStore,
11747
13771
  LINE_NUMBER_WIDTH,
11748
13772
  LoggerLatticeManager,
11749
13773
  MAX_LINE_LENGTH,
@@ -11754,14 +13778,17 @@ export {
11754
13778
  MemoryScheduleStorage,
11755
13779
  MemoryType,
11756
13780
  MessageType,
13781
+ MetricsServerManager,
11757
13782
  ModelLatticeManager,
11758
13783
  PinoLoggerClient,
11759
13784
  PostgresDatabase,
13785
+ PrometheusClient,
11760
13786
  Protocols,
11761
13787
  QueueLatticeManager,
11762
13788
  SandboxFilesystem,
11763
13789
  SandboxLatticeManager,
11764
13790
  ScheduleLatticeManager,
13791
+ SemanticMetricsClient,
11765
13792
  SkillLatticeManager,
11766
13793
  SqlDatabaseManager,
11767
13794
  StateBackend,
@@ -11781,9 +13808,16 @@ export {
11781
13808
  createAgentTeam,
11782
13809
  createFileData,
11783
13810
  createInfoSqlTool,
13811
+ createListMetricsDataSourcesTool,
13812
+ createListMetricsServersTool,
11784
13813
  createListTablesSqlTool,
11785
13814
  createQueryCheckerSqlTool,
13815
+ createQueryMetricDefinitionTool,
13816
+ createQueryMetricsListTool,
13817
+ createQuerySemanticMetricDataTool,
11786
13818
  createQuerySqlTool,
13819
+ createQueryTableDefinitionTool,
13820
+ createQueryTablesListTool,
11787
13821
  createTeamMiddleware,
11788
13822
  createTeammateTools,
11789
13823
  decrypt,
@@ -11829,6 +13863,7 @@ export {
11829
13863
  isValidSkillName,
11830
13864
  loggerLatticeManager,
11831
13865
  mcpManager,
13866
+ metricsServerManager,
11832
13867
  modelLatticeManager,
11833
13868
  normalizeSandboxName,
11834
13869
  parseCronExpression,