@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.d.mts +593 -2
- package/dist/index.d.ts +593 -2
- package/dist/index.js +2332 -282
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2374 -339
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
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,
|
|
511
|
+
registerExistingTool(key, tool46) {
|
|
512
512
|
const config = {
|
|
513
|
-
name:
|
|
514
|
-
description:
|
|
515
|
-
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:
|
|
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,
|
|
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
|
|
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
|
|
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
|
|
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:
|
|
1512
|
-
language:
|
|
1513
|
-
code:
|
|
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
|
|
1520
|
-
import { tool as
|
|
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
|
|
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:
|
|
1597
|
-
file_path:
|
|
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
|
|
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:
|
|
1622
|
-
uri:
|
|
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
|
|
1646
|
-
import { tool as
|
|
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
|
|
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:
|
|
1674
|
-
url:
|
|
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
|
|
1682
|
-
import { tool as
|
|
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
|
|
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:
|
|
1710
|
-
index:
|
|
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
|
|
1718
|
-
import { tool as
|
|
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
|
|
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:
|
|
3330
|
+
schema: z19.object({})
|
|
1744
3331
|
}
|
|
1745
3332
|
);
|
|
1746
3333
|
};
|
|
1747
3334
|
|
|
1748
3335
|
// src/tool_lattice/browser/browser_get_markdown.ts
|
|
1749
|
-
import
|
|
1750
|
-
import { tool as
|
|
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
|
|
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:
|
|
3362
|
+
schema: z20.object({})
|
|
1776
3363
|
}
|
|
1777
3364
|
);
|
|
1778
3365
|
};
|
|
1779
3366
|
|
|
1780
3367
|
// src/tool_lattice/browser/browser_evaluate.ts
|
|
1781
|
-
import
|
|
1782
|
-
import { tool as
|
|
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
|
|
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:
|
|
1810
|
-
script:
|
|
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
|
|
1818
|
-
import { tool as
|
|
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
|
|
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:
|
|
1884
|
-
name:
|
|
1885
|
-
selector:
|
|
1886
|
-
index:
|
|
1887
|
-
width:
|
|
1888
|
-
height:
|
|
1889
|
-
fullPage:
|
|
1890
|
-
highlight:
|
|
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
|
|
1898
|
-
import { tool as
|
|
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
|
|
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:
|
|
1926
|
-
amount:
|
|
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
|
|
1934
|
-
import { tool as
|
|
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
|
|
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:
|
|
1968
|
-
selector:
|
|
1969
|
-
index:
|
|
1970
|
-
value:
|
|
1971
|
-
clear:
|
|
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
|
|
1979
|
-
import { tool as
|
|
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
|
|
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:
|
|
2011
|
-
index:
|
|
2012
|
-
selector:
|
|
2013
|
-
value:
|
|
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
|
|
2021
|
-
import { tool as
|
|
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
|
|
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:
|
|
2051
|
-
index:
|
|
2052
|
-
selector:
|
|
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
|
|
2060
|
-
import { tool as
|
|
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
|
|
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:
|
|
3672
|
+
schema: z27.object({})
|
|
2086
3673
|
}
|
|
2087
3674
|
);
|
|
2088
3675
|
};
|
|
2089
3676
|
|
|
2090
3677
|
// src/tool_lattice/browser/browser_go_forward.ts
|
|
2091
|
-
import
|
|
2092
|
-
import { tool as
|
|
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
|
|
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:
|
|
3704
|
+
schema: z28.object({})
|
|
2118
3705
|
}
|
|
2119
3706
|
);
|
|
2120
3707
|
};
|
|
2121
3708
|
|
|
2122
3709
|
// src/tool_lattice/browser/browser_new_tab.ts
|
|
2123
|
-
import
|
|
2124
|
-
import { tool as
|
|
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
|
|
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:
|
|
2152
|
-
url:
|
|
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
|
|
2160
|
-
import { tool as
|
|
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
|
|
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:
|
|
3772
|
+
schema: z30.object({})
|
|
2186
3773
|
}
|
|
2187
3774
|
);
|
|
2188
3775
|
};
|
|
2189
3776
|
|
|
2190
3777
|
// src/tool_lattice/browser/browser_switch_tab.ts
|
|
2191
|
-
import
|
|
2192
|
-
import { tool as
|
|
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
|
|
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:
|
|
2220
|
-
index:
|
|
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
|
|
2228
|
-
import { tool as
|
|
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
|
|
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:
|
|
3840
|
+
schema: z32.object({})
|
|
2254
3841
|
}
|
|
2255
3842
|
);
|
|
2256
3843
|
};
|
|
2257
3844
|
|
|
2258
3845
|
// src/tool_lattice/browser/browser_close.ts
|
|
2259
|
-
import
|
|
2260
|
-
import { tool as
|
|
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
|
|
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:
|
|
3872
|
+
schema: z33.object({})
|
|
2286
3873
|
}
|
|
2287
3874
|
);
|
|
2288
3875
|
};
|
|
2289
3876
|
|
|
2290
3877
|
// src/tool_lattice/browser/browser_press_key.ts
|
|
2291
|
-
import
|
|
2292
|
-
import { tool as
|
|
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
|
|
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:
|
|
2320
|
-
key:
|
|
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
|
|
2368
|
-
import { tool as
|
|
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
|
|
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:
|
|
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
|
|
2400
|
-
import { tool as
|
|
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
|
|
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:
|
|
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
|
|
2432
|
-
import { tool as
|
|
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
|
|
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:
|
|
4044
|
+
schema: z37.object({})
|
|
2458
4045
|
}
|
|
2459
4046
|
);
|
|
2460
4047
|
};
|
|
2461
4048
|
|
|
2462
4049
|
// src/tool_lattice/browser/get_info.ts
|
|
2463
|
-
import
|
|
2464
|
-
import { tool as
|
|
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
|
|
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:
|
|
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
|
|
2645
|
-
const normalized =
|
|
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
|
|
3997
|
-
import { tool as
|
|
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
|
|
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:
|
|
5955
|
+
schema: z39.object({})
|
|
4025
5956
|
}
|
|
4026
5957
|
);
|
|
4027
5958
|
};
|
|
4028
5959
|
|
|
4029
5960
|
// src/tool_lattice/skill/load_skill_content.ts
|
|
4030
|
-
import
|
|
4031
|
-
import { tool as
|
|
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
|
|
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
|
-
|
|
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:
|
|
4078
|
-
skill_name:
|
|
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 = "
|
|
4086
|
-
var DEFAULT_EXTRA_NOTE =
|
|
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) =>
|
|
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
|
|
6125
|
+
import { createMiddleware as createMiddleware5, tool as tool41, ToolMessage } from "langchain";
|
|
4139
6126
|
import { Command, isCommand, getCurrentTaskInput } from "@langchain/langgraph";
|
|
4140
|
-
import { z as
|
|
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
|
|
4287
|
-
if (
|
|
4288
|
-
|
|
6273
|
+
let relative4 = filePath.substring(normalizedPath.length);
|
|
6274
|
+
if (relative4.startsWith("/")) {
|
|
6275
|
+
relative4 = relative4.substring(1);
|
|
4289
6276
|
}
|
|
4290
|
-
if (!
|
|
6277
|
+
if (!relative4) {
|
|
4291
6278
|
const parts = filePath.split("/");
|
|
4292
|
-
|
|
6279
|
+
relative4 = parts[parts.length - 1] || "";
|
|
4293
6280
|
}
|
|
4294
|
-
if (micromatch.isMatch(
|
|
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
|
|
4449
|
-
if (
|
|
4450
|
-
const subdirName =
|
|
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 =
|
|
4580
|
-
content:
|
|
4581
|
-
created_at:
|
|
4582
|
-
modified_at:
|
|
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 =
|
|
6591
|
+
var FilesystemStateSchema = z310.object({
|
|
4605
6592
|
files: withLangGraph(
|
|
4606
|
-
|
|
6593
|
+
z310.record(z310.string(), FileDataSchema).default({}),
|
|
4607
6594
|
{
|
|
4608
6595
|
reducer: {
|
|
4609
6596
|
fn: fileDataReducer,
|
|
4610
|
-
schema:
|
|
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
|
|
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:
|
|
4666
|
-
path:
|
|
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
|
|
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:
|
|
4689
|
-
file_path:
|
|
4690
|
-
offset:
|
|
4691
|
-
limit:
|
|
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
|
|
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:
|
|
4729
|
-
file_path:
|
|
4730
|
-
content:
|
|
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
|
|
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:
|
|
4773
|
-
file_path:
|
|
4774
|
-
old_string:
|
|
4775
|
-
new_string:
|
|
4776
|
-
replace_all:
|
|
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
|
|
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:
|
|
4803
|
-
pattern:
|
|
4804
|
-
path:
|
|
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
|
|
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:
|
|
4844
|
-
pattern:
|
|
4845
|
-
path:
|
|
4846
|
-
glob:
|
|
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
|
|
5055
|
-
return
|
|
5056
|
-
}).filter((
|
|
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
|
|
7102
|
+
import { z as z42 } from "zod/v3";
|
|
5083
7103
|
import {
|
|
5084
|
-
createMiddleware as
|
|
7104
|
+
createMiddleware as createMiddleware7,
|
|
5085
7105
|
createAgent as createAgent2,
|
|
5086
|
-
tool as
|
|
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
|
|
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:
|
|
5774
|
-
description:
|
|
5775
|
-
subagent_type:
|
|
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
|
|
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
|
|
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
|
|
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
|
|
5987
|
-
if (
|
|
5988
|
-
const subdirName =
|
|
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
|
|
6182
|
-
if (
|
|
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
|
|
6518
|
-
if (
|
|
6519
|
-
const normalizedRelative =
|
|
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
|
|
6582
|
-
if (
|
|
6583
|
-
const normalizedRelative =
|
|
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
|
|
6867
|
-
if (
|
|
6868
|
-
const subdirName =
|
|
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
|
|
6965
|
-
import { createMiddleware as
|
|
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 =
|
|
7193
|
-
var TodoSchema =
|
|
7194
|
-
content:
|
|
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 =
|
|
9217
|
+
var stateSchema = z43.object({ todos: z43.array(TodoSchema).default([]) });
|
|
7198
9218
|
function todoListMiddleware(options) {
|
|
7199
|
-
const writeTodos =
|
|
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:
|
|
7217
|
-
todos:
|
|
9236
|
+
schema: z43.object({
|
|
9237
|
+
todos: z43.array(TodoSchema).describe("List of todo items to update")
|
|
7218
9238
|
})
|
|
7219
9239
|
}
|
|
7220
9240
|
);
|
|
7221
|
-
return
|
|
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((
|
|
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
|
|
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
|
|
7839
|
-
import { createMiddleware as
|
|
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
|
|
7845
|
-
import { tool as
|
|
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 =
|
|
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:
|
|
7896
|
-
task_id:
|
|
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 =
|
|
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:
|
|
7922
|
-
task_id:
|
|
7923
|
-
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 =
|
|
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:
|
|
7949
|
-
task_id:
|
|
7950
|
-
error:
|
|
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 =
|
|
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:
|
|
7969
|
-
to:
|
|
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:
|
|
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 =
|
|
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:
|
|
10071
|
+
schema: z44.object({})
|
|
8052
10072
|
}
|
|
8053
10073
|
);
|
|
8054
|
-
const checkTasksTool =
|
|
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:
|
|
10082
|
+
schema: z44.object({})
|
|
8063
10083
|
}
|
|
8064
10084
|
);
|
|
8065
|
-
const broadcastMessageTool =
|
|
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:
|
|
8085
|
-
content:
|
|
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 =
|
|
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:
|
|
8460
|
-
tasks:
|
|
8461
|
-
|
|
8462
|
-
id:
|
|
8463
|
-
title:
|
|
8464
|
-
description:
|
|
8465
|
-
dependencies:
|
|
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:
|
|
8469
|
-
|
|
8470
|
-
name:
|
|
8471
|
-
role:
|
|
8472
|
-
description:
|
|
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 =
|
|
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:
|
|
8536
|
-
tasks:
|
|
8537
|
-
|
|
8538
|
-
id:
|
|
8539
|
-
title:
|
|
8540
|
-
description:
|
|
8541
|
-
assignee:
|
|
8542
|
-
dependencies:
|
|
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 =
|
|
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:
|
|
8571
|
-
task_id:
|
|
8572
|
-
assignee:
|
|
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 =
|
|
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:
|
|
8599
|
-
task_id:
|
|
8600
|
-
status:
|
|
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 =
|
|
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:
|
|
8627
|
-
task_id:
|
|
8628
|
-
dependencies:
|
|
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 =
|
|
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:
|
|
8673
|
-
team_id:
|
|
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 =
|
|
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:
|
|
8697
|
-
to:
|
|
8698
|
-
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 =
|
|
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:
|
|
8785
|
-
team_id:
|
|
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 =
|
|
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 =
|
|
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:
|
|
8829
|
-
content:
|
|
10848
|
+
schema: z45.object({
|
|
10849
|
+
content: z45.string().describe("Message content to broadcast to all teammates")
|
|
8830
10850
|
})
|
|
8831
10851
|
}
|
|
8832
10852
|
);
|
|
8833
|
-
return
|
|
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 =
|
|
8862
|
-
name:
|
|
8863
|
-
role:
|
|
8864
|
-
description:
|
|
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 =
|
|
8867
|
-
id:
|
|
8868
|
-
title:
|
|
8869
|
-
description:
|
|
8870
|
-
status:
|
|
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 =
|
|
8873
|
-
id:
|
|
8874
|
-
from:
|
|
8875
|
-
to:
|
|
8876
|
-
content:
|
|
8877
|
-
timestamp:
|
|
8878
|
-
type:
|
|
8879
|
-
read:
|
|
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 =
|
|
8882
|
-
teamId:
|
|
8883
|
-
teamLeadId:
|
|
8884
|
-
teammates:
|
|
8885
|
-
tasks:
|
|
8886
|
-
createdAt:
|
|
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 =
|
|
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:
|
|
8891
|
-
team_mailbox:
|
|
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((
|
|
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
|
|
11649
|
-
const toolKey = prefix ? `${prefix}_${
|
|
11650
|
-
|
|
11651
|
-
toolLatticeManager.registerExistingTool(toolKey,
|
|
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,
|