@axiom-lattice/core 2.1.56 → 2.1.58
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 +144 -10
- package/dist/index.d.ts +144 -10
- package/dist/index.js +2275 -73
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2270 -68
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -36,6 +36,7 @@ __export(index_exports, {
|
|
|
36
36
|
AgentLatticeManager: () => AgentLatticeManager,
|
|
37
37
|
AgentManager: () => AgentManager,
|
|
38
38
|
AgentType: () => import_protocols.AgentType,
|
|
39
|
+
BUILTIN_SKILLS: () => BUILTIN_SKILLS,
|
|
39
40
|
ChunkBuffer: () => ChunkBuffer,
|
|
40
41
|
ChunkBufferLatticeManager: () => ChunkBufferLatticeManager,
|
|
41
42
|
CompositeBackend: () => CompositeBackend,
|
|
@@ -50,7 +51,7 @@ __export(index_exports, {
|
|
|
50
51
|
EmbeddingsLatticeManager: () => EmbeddingsLatticeManager,
|
|
51
52
|
FileSystemSkillStore: () => FileSystemSkillStore,
|
|
52
53
|
FilesystemBackend: () => FilesystemBackend,
|
|
53
|
-
HumanMessage: () =>
|
|
54
|
+
HumanMessage: () => import_messages5.HumanMessage,
|
|
54
55
|
InMemoryAssistantStore: () => InMemoryAssistantStore,
|
|
55
56
|
InMemoryChunkBuffer: () => InMemoryChunkBuffer,
|
|
56
57
|
InMemoryDatabaseConfigStore: () => InMemoryDatabaseConfigStore,
|
|
@@ -119,6 +120,7 @@ __export(index_exports, {
|
|
|
119
120
|
createListMetricsServersTool: () => createListMetricsServersTool,
|
|
120
121
|
createListTablesSqlTool: () => createListTablesSqlTool,
|
|
121
122
|
createModelSelectorMiddleware: () => createModelSelectorMiddleware,
|
|
123
|
+
createProcessingAgent: () => createProcessingAgent,
|
|
122
124
|
createQueryCheckerSqlTool: () => createQueryCheckerSqlTool,
|
|
123
125
|
createQueryMetricDefinitionTool: () => createQueryMetricDefinitionTool,
|
|
124
126
|
createQueryMetricsListTool: () => createQueryMetricsListTool,
|
|
@@ -146,7 +148,11 @@ __export(index_exports, {
|
|
|
146
148
|
getAgentClient: () => getAgentClient,
|
|
147
149
|
getAgentConfig: () => getAgentConfig,
|
|
148
150
|
getAllAgentConfigs: () => getAllAgentConfigs,
|
|
151
|
+
getAllBuiltInSkillMetas: () => getAllBuiltInSkillMetas,
|
|
149
152
|
getAllToolDefinitions: () => getAllToolDefinitions,
|
|
153
|
+
getBuiltInSkillContent: () => getBuiltInSkillContent,
|
|
154
|
+
getBuiltInSkillMeta: () => getBuiltInSkillMeta,
|
|
155
|
+
getBuiltInSkillNames: () => getBuiltInSkillNames,
|
|
150
156
|
getCheckpointSaver: () => getCheckpointSaver,
|
|
151
157
|
getChunkBuffer: () => getChunkBuffer,
|
|
152
158
|
getEmbeddingsClient: () => getEmbeddingsClient,
|
|
@@ -168,6 +174,7 @@ __export(index_exports, {
|
|
|
168
174
|
grepMatchesFromFiles: () => grepMatchesFromFiles,
|
|
169
175
|
grepSearchFiles: () => grepSearchFiles,
|
|
170
176
|
hasChunkBuffer: () => hasChunkBuffer,
|
|
177
|
+
isBuiltInSkill: () => isBuiltInSkill,
|
|
171
178
|
isUsingDefaultKey: () => isUsingDefaultKey,
|
|
172
179
|
isValidCronExpression: () => isValidCronExpression,
|
|
173
180
|
isValidSandboxName: () => isValidSandboxName,
|
|
@@ -861,11 +868,11 @@ var ToolLatticeManager = class _ToolLatticeManager extends BaseLatticeManager {
|
|
|
861
868
|
* @param key Lattice键名
|
|
862
869
|
* @param tool 已有的StructuredTool实例
|
|
863
870
|
*/
|
|
864
|
-
registerExistingTool(key,
|
|
871
|
+
registerExistingTool(key, tool51) {
|
|
865
872
|
const config = {
|
|
866
|
-
name:
|
|
867
|
-
description:
|
|
868
|
-
schema:
|
|
873
|
+
name: tool51.name,
|
|
874
|
+
description: tool51.description,
|
|
875
|
+
schema: tool51.schema,
|
|
869
876
|
// StructuredTool的schema已经是Zod兼容的
|
|
870
877
|
needUserApprove: false
|
|
871
878
|
// MCP工具默认不需要用户批准
|
|
@@ -873,7 +880,7 @@ var ToolLatticeManager = class _ToolLatticeManager extends BaseLatticeManager {
|
|
|
873
880
|
const toolLattice = {
|
|
874
881
|
key,
|
|
875
882
|
config,
|
|
876
|
-
client:
|
|
883
|
+
client: tool51
|
|
877
884
|
};
|
|
878
885
|
this.register(key, toolLattice);
|
|
879
886
|
}
|
|
@@ -899,7 +906,7 @@ var ToolLatticeManager = class _ToolLatticeManager extends BaseLatticeManager {
|
|
|
899
906
|
};
|
|
900
907
|
var toolLatticeManager = ToolLatticeManager.getInstance();
|
|
901
908
|
var registerToolLattice = (key, config, executor) => toolLatticeManager.registerLattice(key, config, executor);
|
|
902
|
-
var registerExistingTool = (key,
|
|
909
|
+
var registerExistingTool = (key, tool51) => toolLatticeManager.registerExistingTool(key, tool51);
|
|
903
910
|
var getToolLattice = (key) => toolLatticeManager.getToolLattice(key);
|
|
904
911
|
var getToolDefinition = (key) => toolLatticeManager.getToolDefinition(key);
|
|
905
912
|
var getToolClient = (key) => toolLatticeManager.getToolClient(key);
|
|
@@ -1333,14 +1340,14 @@ var import_zod3 = __toESM(require("zod"));
|
|
|
1333
1340
|
var import_langchain = require("langchain");
|
|
1334
1341
|
|
|
1335
1342
|
// src/tool_lattice/sql/utils.ts
|
|
1336
|
-
function getTenantIdFromConfig(exeConfig,
|
|
1343
|
+
function getTenantIdFromConfig(exeConfig, getTenantId2) {
|
|
1337
1344
|
const runConfig = exeConfig?.configurable?.runConfig || {};
|
|
1338
|
-
return runConfig.tenantId || (
|
|
1345
|
+
return runConfig.tenantId || (getTenantId2 ? getTenantId2() : "default");
|
|
1339
1346
|
}
|
|
1340
1347
|
|
|
1341
1348
|
// src/tool_lattice/sql/list_tables_sql.ts
|
|
1342
1349
|
var LIST_TABLES_SQL_DESCRIPTION = `List all tables in the connected SQL database. Returns a comma-separated list of table names. Use this tool first to understand what tables are available before querying the database.`;
|
|
1343
|
-
var createListTablesSqlTool = ({ databaseKeys, databaseDescriptions, getTenantId }) => {
|
|
1350
|
+
var createListTablesSqlTool = ({ databaseKeys, databaseDescriptions, getTenantId: getTenantId2 }) => {
|
|
1344
1351
|
const availableDbsText = databaseKeys.length > 0 ? `
|
|
1345
1352
|
|
|
1346
1353
|
Available databases:
|
|
@@ -1350,7 +1357,7 @@ ${databaseKeys.map(
|
|
|
1350
1357
|
return (0, import_langchain.tool)(
|
|
1351
1358
|
async ({ databaseKey }, _exeConfig) => {
|
|
1352
1359
|
try {
|
|
1353
|
-
const tenantId = getTenantIdFromConfig(_exeConfig,
|
|
1360
|
+
const tenantId = getTenantIdFromConfig(_exeConfig, getTenantId2);
|
|
1354
1361
|
if (!databaseKey) {
|
|
1355
1362
|
return "Error: databaseKey parameter is required. Available databases: " + databaseKeys.join(", ");
|
|
1356
1363
|
}
|
|
@@ -1384,7 +1391,7 @@ ${databaseKeys.map(
|
|
|
1384
1391
|
var import_zod4 = __toESM(require("zod"));
|
|
1385
1392
|
var import_langchain2 = require("langchain");
|
|
1386
1393
|
var INFO_SQL_DESCRIPTION = `Get detailed schema information for specified tables, including column names, types, constraints (primary keys, foreign keys), and sample rows. Input should be a comma-separated list of table names.`;
|
|
1387
|
-
var createInfoSqlTool = ({ databaseKeys, databaseDescriptions, getTenantId }) => {
|
|
1394
|
+
var createInfoSqlTool = ({ databaseKeys, databaseDescriptions, getTenantId: getTenantId2 }) => {
|
|
1388
1395
|
const availableDbsText = databaseKeys.length > 0 ? `
|
|
1389
1396
|
|
|
1390
1397
|
Available databases:
|
|
@@ -1397,7 +1404,7 @@ ${databaseKeys.map(
|
|
|
1397
1404
|
databaseKey
|
|
1398
1405
|
}, _exeConfig) => {
|
|
1399
1406
|
try {
|
|
1400
|
-
const tenantId = getTenantIdFromConfig(_exeConfig,
|
|
1407
|
+
const tenantId = getTenantIdFromConfig(_exeConfig, getTenantId2);
|
|
1401
1408
|
if (!databaseKey) {
|
|
1402
1409
|
return "Error: databaseKey parameter is required. Available databases: " + databaseKeys.join(", ");
|
|
1403
1410
|
}
|
|
@@ -1516,7 +1523,7 @@ function checkDangerousOperations(query) {
|
|
|
1516
1523
|
}
|
|
1517
1524
|
return warnings;
|
|
1518
1525
|
}
|
|
1519
|
-
var createQueryCheckerSqlTool = ({ databaseKeys, databaseDescriptions, getTenantId }) => {
|
|
1526
|
+
var createQueryCheckerSqlTool = ({ databaseKeys, databaseDescriptions, getTenantId: getTenantId2 }) => {
|
|
1520
1527
|
const availableDbsText = databaseKeys.length > 0 ? `
|
|
1521
1528
|
|
|
1522
1529
|
Available databases:
|
|
@@ -1529,7 +1536,7 @@ ${databaseKeys.map(
|
|
|
1529
1536
|
databaseKey
|
|
1530
1537
|
}, _exeConfig) => {
|
|
1531
1538
|
try {
|
|
1532
|
-
const tenantId = getTenantIdFromConfig(_exeConfig,
|
|
1539
|
+
const tenantId = getTenantIdFromConfig(_exeConfig, getTenantId2);
|
|
1533
1540
|
const trimmedQuery = query.trim();
|
|
1534
1541
|
if (!trimmedQuery) {
|
|
1535
1542
|
return "Error: Empty query provided. Please provide a SQL query to check.";
|
|
@@ -1638,7 +1645,7 @@ function formatQueryResult(rows, fields) {
|
|
|
1638
1645
|
Total rows: ${rows.length}`);
|
|
1639
1646
|
return lines.join("\n");
|
|
1640
1647
|
}
|
|
1641
|
-
var createQuerySqlTool = ({ databaseKeys, databaseDescriptions, getTenantId }) => {
|
|
1648
|
+
var createQuerySqlTool = ({ databaseKeys, databaseDescriptions, getTenantId: getTenantId2 }) => {
|
|
1642
1649
|
const availableDbsText = databaseKeys.length > 0 ? `
|
|
1643
1650
|
|
|
1644
1651
|
Available databases:
|
|
@@ -1651,7 +1658,7 @@ ${databaseKeys.map(
|
|
|
1651
1658
|
databaseKey
|
|
1652
1659
|
}, _exeConfig) => {
|
|
1653
1660
|
try {
|
|
1654
|
-
const tenantId = getTenantIdFromConfig(_exeConfig,
|
|
1661
|
+
const tenantId = getTenantIdFromConfig(_exeConfig, getTenantId2);
|
|
1655
1662
|
if (!databaseKey) {
|
|
1656
1663
|
return "Error: databaseKey parameter is required. Available databases: " + databaseKeys.join(", ");
|
|
1657
1664
|
}
|
|
@@ -1683,9 +1690,9 @@ ${databaseKeys.map(
|
|
|
1683
1690
|
};
|
|
1684
1691
|
|
|
1685
1692
|
// src/tool_lattice/metrics/utils.ts
|
|
1686
|
-
function getTenantIdFromConfig2(exeConfig,
|
|
1693
|
+
function getTenantIdFromConfig2(exeConfig, getTenantId2) {
|
|
1687
1694
|
const runConfig = exeConfig?.configurable?.runConfig || {};
|
|
1688
|
-
return runConfig.tenantId || (
|
|
1695
|
+
return runConfig.tenantId || (getTenantId2 ? getTenantId2() : "default");
|
|
1689
1696
|
}
|
|
1690
1697
|
function filterServerKeysByTenant(serverKeys, tenantId, manager = metricsServerManager) {
|
|
1691
1698
|
return serverKeys.filter((key) => {
|
|
@@ -2537,7 +2544,7 @@ var metricsServerManager = MetricsServerManager.getInstance();
|
|
|
2537
2544
|
var import_zod7 = __toESM(require("zod"));
|
|
2538
2545
|
var import_langchain5 = require("langchain");
|
|
2539
2546
|
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.`;
|
|
2540
|
-
var createListMetricsServersTool = ({ serverKeys, serverDescriptions, getTenantId }) => {
|
|
2547
|
+
var createListMetricsServersTool = ({ serverKeys, serverDescriptions, getTenantId: getTenantId2 }) => {
|
|
2541
2548
|
const availableServersText = serverKeys.length > 0 ? `
|
|
2542
2549
|
|
|
2543
2550
|
Available metrics servers:
|
|
@@ -2547,7 +2554,7 @@ ${serverKeys.map(
|
|
|
2547
2554
|
return (0, import_langchain5.tool)(
|
|
2548
2555
|
async (_input, _exeConfig) => {
|
|
2549
2556
|
try {
|
|
2550
|
-
const tenantId = getTenantIdFromConfig2(_exeConfig,
|
|
2557
|
+
const tenantId = getTenantIdFromConfig2(_exeConfig, getTenantId2);
|
|
2551
2558
|
const servers = metricsServerManager.getServerKeys(tenantId);
|
|
2552
2559
|
if (servers.length === 0) {
|
|
2553
2560
|
return "No metrics servers registered.";
|
|
@@ -2574,7 +2581,7 @@ ${lines.join("\n")}`;
|
|
|
2574
2581
|
var import_zod8 = __toESM(require("zod"));
|
|
2575
2582
|
var import_langchain6 = require("langchain");
|
|
2576
2583
|
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.`;
|
|
2577
|
-
var createListMetricsDataSourcesTool = ({ serverKeys, serverDescriptions, getTenantId, connectAll }) => {
|
|
2584
|
+
var createListMetricsDataSourcesTool = ({ serverKeys, serverDescriptions, getTenantId: getTenantId2, connectAll }) => {
|
|
2578
2585
|
const availableServersText = serverKeys.length > 0 ? `
|
|
2579
2586
|
|
|
2580
2587
|
Configured metrics servers:
|
|
@@ -2584,7 +2591,7 @@ ${serverKeys.map(
|
|
|
2584
2591
|
return (0, import_langchain6.tool)(
|
|
2585
2592
|
async (_input, _exeConfig) => {
|
|
2586
2593
|
try {
|
|
2587
|
-
const tenantId = getTenantIdFromConfig2(_exeConfig,
|
|
2594
|
+
const tenantId = getTenantIdFromConfig2(_exeConfig, getTenantId2);
|
|
2588
2595
|
let effectiveServerKeys = serverKeys;
|
|
2589
2596
|
if (connectAll) {
|
|
2590
2597
|
effectiveServerKeys = metricsServerManager.getServerKeys(tenantId).map((s) => s.key);
|
|
@@ -2690,7 +2697,7 @@ Response Fields Reference
|
|
|
2690
2697
|
|
|
2691
2698
|
Next Step
|
|
2692
2699
|
After finding relevant metrics, call query_metric_definition with the metricName to get detailed metadata including time dimensions and supported filters.`;
|
|
2693
|
-
var createQueryMetricsListTool = ({ serverKeys, serverDescriptions, getTenantId, connectAll }) => {
|
|
2700
|
+
var createQueryMetricsListTool = ({ serverKeys, serverDescriptions, getTenantId: getTenantId2, connectAll }) => {
|
|
2694
2701
|
const availableServersText = serverKeys.length > 0 ? `
|
|
2695
2702
|
|
|
2696
2703
|
Available metrics servers:
|
|
@@ -2703,7 +2710,7 @@ ${serverKeys.map(
|
|
|
2703
2710
|
datasourceIds
|
|
2704
2711
|
}, _exeConfig) => {
|
|
2705
2712
|
try {
|
|
2706
|
-
const tenantId = getTenantIdFromConfig2(_exeConfig,
|
|
2713
|
+
const tenantId = getTenantIdFromConfig2(_exeConfig, getTenantId2);
|
|
2707
2714
|
let effectiveServerKeys = serverKeys;
|
|
2708
2715
|
if (connectAll) {
|
|
2709
2716
|
effectiveServerKeys = metricsServerManager.getServerKeys(tenantId).map((s) => s.key);
|
|
@@ -2847,7 +2854,7 @@ Rules
|
|
|
2847
2854
|
|
|
2848
2855
|
Next Step
|
|
2849
2856
|
Call query_semantic_metric_data with parameters derived from this definition.`;
|
|
2850
|
-
var createQueryMetricDefinitionTool = ({ serverKeys, serverDescriptions, getTenantId, connectAll }) => {
|
|
2857
|
+
var createQueryMetricDefinitionTool = ({ serverKeys, serverDescriptions, getTenantId: getTenantId2, connectAll }) => {
|
|
2851
2858
|
const availableServersText = serverKeys.length > 0 ? `
|
|
2852
2859
|
|
|
2853
2860
|
Available metrics servers:
|
|
@@ -2861,7 +2868,7 @@ ${serverKeys.map(
|
|
|
2861
2868
|
datasourceId: inputDatasourceId
|
|
2862
2869
|
}, _exeConfig) => {
|
|
2863
2870
|
try {
|
|
2864
|
-
const tenantId = getTenantIdFromConfig2(_exeConfig,
|
|
2871
|
+
const tenantId = getTenantIdFromConfig2(_exeConfig, getTenantId2);
|
|
2865
2872
|
let effectiveServerKeys = serverKeys;
|
|
2866
2873
|
if (connectAll) {
|
|
2867
2874
|
effectiveServerKeys = metricsServerManager.getServerKeys(tenantId).map((s) => s.key);
|
|
@@ -3080,7 +3087,7 @@ Semantic Model: ${semanticModel}`;
|
|
|
3080
3087
|
`);
|
|
3081
3088
|
return lines.join("\n");
|
|
3082
3089
|
}
|
|
3083
|
-
var createQuerySemanticMetricDataTool = ({ serverKeys, serverDescriptions, getTenantId, connectAll }) => {
|
|
3090
|
+
var createQuerySemanticMetricDataTool = ({ serverKeys, serverDescriptions, getTenantId: getTenantId2, connectAll }) => {
|
|
3084
3091
|
const availableServersText = serverKeys.length > 0 ? `
|
|
3085
3092
|
|
|
3086
3093
|
Available metrics servers:
|
|
@@ -3097,7 +3104,7 @@ ${serverKeys.map(
|
|
|
3097
3104
|
limit
|
|
3098
3105
|
}, _exeConfig) => {
|
|
3099
3106
|
try {
|
|
3100
|
-
const tenantId = getTenantIdFromConfig2(_exeConfig,
|
|
3107
|
+
const tenantId = getTenantIdFromConfig2(_exeConfig, getTenantId2);
|
|
3101
3108
|
let effectiveServerKeys = serverKeys;
|
|
3102
3109
|
if (connectAll) {
|
|
3103
3110
|
effectiveServerKeys = metricsServerManager.getServerKeys(tenantId).map((s) => s.key);
|
|
@@ -3165,7 +3172,7 @@ ${serverKeys.map(
|
|
|
3165
3172
|
var import_zod12 = __toESM(require("zod"));
|
|
3166
3173
|
var import_langchain10 = require("langchain");
|
|
3167
3174
|
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.`;
|
|
3168
|
-
var createQueryTablesListTool = ({ serverKeys, serverDescriptions, getTenantId, connectAll }) => {
|
|
3175
|
+
var createQueryTablesListTool = ({ serverKeys, serverDescriptions, getTenantId: getTenantId2, connectAll }) => {
|
|
3169
3176
|
const availableServersText = serverKeys.length > 0 ? `
|
|
3170
3177
|
|
|
3171
3178
|
Available metrics servers:
|
|
@@ -3178,7 +3185,7 @@ ${serverKeys.map(
|
|
|
3178
3185
|
datasourceIds
|
|
3179
3186
|
}, _exeConfig) => {
|
|
3180
3187
|
try {
|
|
3181
|
-
const tenantId = getTenantIdFromConfig2(_exeConfig,
|
|
3188
|
+
const tenantId = getTenantIdFromConfig2(_exeConfig, getTenantId2);
|
|
3182
3189
|
let effectiveServerKeys = serverKeys;
|
|
3183
3190
|
if (connectAll) {
|
|
3184
3191
|
effectiveServerKeys = metricsServerManager.getServerKeys(tenantId).map((s) => s.key);
|
|
@@ -3269,7 +3276,7 @@ ${serverKeys.map(
|
|
|
3269
3276
|
var import_zod13 = __toESM(require("zod"));
|
|
3270
3277
|
var import_langchain11 = require("langchain");
|
|
3271
3278
|
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.`;
|
|
3272
|
-
var createQueryTableDefinitionTool = ({ serverKeys, serverDescriptions, getTenantId, connectAll }) => {
|
|
3279
|
+
var createQueryTableDefinitionTool = ({ serverKeys, serverDescriptions, getTenantId: getTenantId2, connectAll }) => {
|
|
3273
3280
|
const availableServersText = serverKeys.length > 0 ? `
|
|
3274
3281
|
|
|
3275
3282
|
Available metrics servers:
|
|
@@ -3283,7 +3290,7 @@ ${serverKeys.map(
|
|
|
3283
3290
|
datasourceId: inputDatasourceId
|
|
3284
3291
|
}, _exeConfig) => {
|
|
3285
3292
|
try {
|
|
3286
|
-
const tenantId = getTenantIdFromConfig2(_exeConfig,
|
|
3293
|
+
const tenantId = getTenantIdFromConfig2(_exeConfig, getTenantId2);
|
|
3287
3294
|
let effectiveServerKeys = serverKeys;
|
|
3288
3295
|
if (connectAll) {
|
|
3289
3296
|
effectiveServerKeys = metricsServerManager.getServerKeys(tenantId).map((s) => s.key);
|
|
@@ -3407,7 +3414,7 @@ Example:
|
|
|
3407
3414
|
},
|
|
3408
3415
|
"limit": 100
|
|
3409
3416
|
}`;
|
|
3410
|
-
var createExecuteSqlQueryTool = ({ serverKeys, serverDescriptions, getTenantId, connectAll }) => {
|
|
3417
|
+
var createExecuteSqlQueryTool = ({ serverKeys, serverDescriptions, getTenantId: getTenantId2, connectAll }) => {
|
|
3411
3418
|
const availableServersText = serverKeys.length > 0 ? `
|
|
3412
3419
|
|
|
3413
3420
|
Available metrics servers:
|
|
@@ -3423,7 +3430,7 @@ ${serverKeys.map(
|
|
|
3423
3430
|
limit
|
|
3424
3431
|
}, _exeConfig) => {
|
|
3425
3432
|
try {
|
|
3426
|
-
const tenantId = getTenantIdFromConfig2(_exeConfig,
|
|
3433
|
+
const tenantId = getTenantIdFromConfig2(_exeConfig, getTenantId2);
|
|
3427
3434
|
let effectiveServerKeys = serverKeys;
|
|
3428
3435
|
if (connectAll) {
|
|
3429
3436
|
effectiveServerKeys = metricsServerManager.getServerKeys(tenantId).map((s) => s.key);
|
|
@@ -4734,7 +4741,7 @@ var createBrowserGetInfoTool = ({ vmIsolation }) => {
|
|
|
4734
4741
|
};
|
|
4735
4742
|
|
|
4736
4743
|
// src/index.ts
|
|
4737
|
-
var
|
|
4744
|
+
var import_messages5 = require("@langchain/core/messages");
|
|
4738
4745
|
|
|
4739
4746
|
// src/agent_lattice/types.ts
|
|
4740
4747
|
var import_protocols = require("@axiom-lattice/protocols");
|
|
@@ -5043,6 +5050,285 @@ var import_langchain40 = require("langchain");
|
|
|
5043
5050
|
// src/tool_lattice/skill/load_skill_content.ts
|
|
5044
5051
|
var import_zod43 = __toESM(require("zod"));
|
|
5045
5052
|
var import_langchain41 = require("langchain");
|
|
5053
|
+
|
|
5054
|
+
// src/skill_lattice/builtinSkills.ts
|
|
5055
|
+
var BUILTIN_SKILLS = {
|
|
5056
|
+
"create-skill": `---
|
|
5057
|
+
name: create-skill
|
|
5058
|
+
description: Create new skills, modify and improve existing skills. Use this skill whenever users mention creating a skill, wanting a new capability, asking to "make a skill for X", setting up automated workflows, or wanting to capture repeatable agent instructions \u2014 even if they don't use the word "skill."
|
|
5059
|
+
license: MIT
|
|
5060
|
+
metadata:
|
|
5061
|
+
category: meta
|
|
5062
|
+
version: "2.0"
|
|
5063
|
+
---
|
|
5064
|
+
|
|
5065
|
+
# Skill Creator
|
|
5066
|
+
|
|
5067
|
+
This skill guides you through creating and improving agent skills. Your job is to figure out where the user is in the process and help them progress \u2014 whether they're starting from scratch, have a rough idea, or want to improve an existing skill.
|
|
5068
|
+
|
|
5069
|
+
At a high level, the process follows an iterative loop: **understand intent \u2192 interview \u2192 draft \u2192 test \u2192 review \u2192 improve \u2192 repeat** until satisfied. But always be flexible \u2014 if the user says "just vibe with me," do that instead.
|
|
5070
|
+
|
|
5071
|
+
## Communicating With the User
|
|
5072
|
+
|
|
5073
|
+
Users range from deep technical experts to people who just learned what a terminal is. Pay attention to context cues:
|
|
5074
|
+
- "JSON" and "assertion" \u2014 only use without explanation if the user shows comfort with them
|
|
5075
|
+
- "evaluation" and "benchmark" \u2014 borderline, briefly define if unsure
|
|
5076
|
+
- When in doubt, briefly explain terms. Short parenthetical definitions are fine.
|
|
5077
|
+
|
|
5078
|
+
---
|
|
5079
|
+
|
|
5080
|
+
## Step 1: Capture Intent
|
|
5081
|
+
|
|
5082
|
+
Start by understanding what the user wants. The current conversation may already contain a workflow they want to capture (e.g., they say "turn this into a skill"). If so, extract answers from the conversation history first \u2014 the tools used, the sequence of steps, corrections made, input/output formats observed.
|
|
5083
|
+
|
|
5084
|
+
Ask yourself:
|
|
5085
|
+
1. What capability does this skill enable?
|
|
5086
|
+
2. When should this skill trigger? (what user phrases, contexts, keywords)
|
|
5087
|
+
3. What is the expected output or behavior?
|
|
5088
|
+
4. Does it coordinate other skills (subSkills)?
|
|
5089
|
+
|
|
5090
|
+
## Step 2: Interview and Research
|
|
5091
|
+
|
|
5092
|
+
Proactively ask questions before writing anything:
|
|
5093
|
+
- **Edge cases**: What unusual inputs might arise? What should happen on failure?
|
|
5094
|
+
- **Input/output formats**: What formats are involved (files, data, text)?
|
|
5095
|
+
- **Dependencies**: Are specific tools, APIs, or data sources needed?
|
|
5096
|
+
- **Success criteria**: How will the user know the skill is working?
|
|
5097
|
+
|
|
5098
|
+
Don't start writing until you've got clear answers. If the user is vague, ask clarifying questions \u2014 you'll save time by not guessing wrong.
|
|
5099
|
+
|
|
5100
|
+
---
|
|
5101
|
+
|
|
5102
|
+
## Step 3: Write the SKILL.md
|
|
5103
|
+
|
|
5104
|
+
### Skill Directory Structure
|
|
5105
|
+
|
|
5106
|
+
Skills use progressive disclosure \u2014 three levels of loading:
|
|
5107
|
+
|
|
5108
|
+
\`\`\`
|
|
5109
|
+
skill-name/
|
|
5110
|
+
\u251C\u2500\u2500 SKILL.md # Required \u2014 frontmatter + markdown body
|
|
5111
|
+
\u2514\u2500\u2500 resources/ # Optional \u2014 bundled files
|
|
5112
|
+
\u251C\u2500\u2500 scripts/ # Executable code for repetitive tasks
|
|
5113
|
+
\u251C\u2500\u2500 references/ # Docs loaded into context as needed
|
|
5114
|
+
\u2514\u2500\u2500 assets/ # Files used in output (templates, icons)
|
|
5115
|
+
\`\`\`
|
|
5116
|
+
|
|
5117
|
+
- **Metadata** (name + description) \u2014 always in context (~100 words)
|
|
5118
|
+
- **SKILL.md body** \u2014 loaded when skill triggers (aim for <500 lines)
|
|
5119
|
+
- **Bundled resources** \u2014 loaded as needed, unlimited
|
|
5120
|
+
|
|
5121
|
+
If SKILL.md approaches 500 lines, add hierarchy with clear pointers to reference files.
|
|
5122
|
+
|
|
5123
|
+
### File Location
|
|
5124
|
+
|
|
5125
|
+
Write the skill to: \`/root/.agents/skills/{skill-name}/SKILL.md\`
|
|
5126
|
+
|
|
5127
|
+
Resources go in: \`/root/.agents/skills/{skill-name}/resources/\`
|
|
5128
|
+
|
|
5129
|
+
### Naming Rules
|
|
5130
|
+
|
|
5131
|
+
Skill names (also the directory name) must follow these rules:
|
|
5132
|
+
- 1-64 characters, lowercase letters, digits, single hyphens
|
|
5133
|
+
- Pattern: \`^[a-z0-9]+(-[a-z0-9]+)*$\`
|
|
5134
|
+
- Cannot start or end with \`-\`, cannot contain consecutive \`--\`
|
|
5135
|
+
|
|
5136
|
+
**Good**: \`pdf-processor\`, \`sql-query\`, \`code-review\`, \`data-analytics\`
|
|
5137
|
+
**Bad**: \`PDF-Processor\`, \`sql__query\`, \`-test\`, \`a\`
|
|
5138
|
+
|
|
5139
|
+
### Frontmatter Reference
|
|
5140
|
+
|
|
5141
|
+
\`\`\`yaml
|
|
5142
|
+
---
|
|
5143
|
+
name: my-skill-name # Required \u2014 kebab-case identifier
|
|
5144
|
+
description: ... # Required \u2014 what AND when (this drives triggering)
|
|
5145
|
+
license: MIT # Optional
|
|
5146
|
+
compatibility: node # Optional \u2014 runtime/context requirement
|
|
5147
|
+
metadata: # Optional \u2014 key-value tags for search/filter
|
|
5148
|
+
category: tools
|
|
5149
|
+
version: "1.0"
|
|
5150
|
+
subSkills: # Optional \u2014 coordinated sub-skill names
|
|
5151
|
+
- sub-skill-1
|
|
5152
|
+
---
|
|
5153
|
+
|
|
5154
|
+
# Markdown Body
|
|
5155
|
+
|
|
5156
|
+
Instructional content for the agent.
|
|
5157
|
+
\`\`\`
|
|
5158
|
+
|
|
5159
|
+
---
|
|
5160
|
+
|
|
5161
|
+
## Writing Guide
|
|
5162
|
+
|
|
5163
|
+
### The Description Field
|
|
5164
|
+
|
|
5165
|
+
This is the most critical part. The description is the primary mechanism that determines whether an agent invokes your skill. Combine WHAT the skill does with specific contexts for WHEN to trigger.
|
|
5166
|
+
|
|
5167
|
+
Agents tend to **undertrigger** \u2014 to not use skills when they'd be useful. To combat this, make descriptions a little "pushy":
|
|
5168
|
+
|
|
5169
|
+
- Weak: "Helps with PDF files"
|
|
5170
|
+
- Better: "Extract text, tables, and metadata from PDF files. Use when users need to read, parse, or extract data from PDF documents."
|
|
5171
|
+
- Good: "Extract text, tables, and metadata from PDF files. Make sure to use this skill whenever the user mentions PDFs, extracting document data, or needs to read any kind of document file \u2014 even if they don't explicitly ask for 'PDF processing.'"
|
|
5172
|
+
|
|
5173
|
+
Include domain-specific trigger words: file extensions, tool names, common user phrases.
|
|
5174
|
+
|
|
5175
|
+
### Writing the Body
|
|
5176
|
+
|
|
5177
|
+
Prefer **imperative form**. Write what the agent should DO, not what the skill IS:
|
|
5178
|
+
- "Check the database connection and verify table schemas" \u2014 good
|
|
5179
|
+
- "The database connection is checked and table schemas are verified" \u2014 weak
|
|
5180
|
+
|
|
5181
|
+
**Explain WHY**, not just what. Use theory of mind \u2014 help the model understand the reasoning behind instructions so it can generalize to novel situations. If you find yourself writing ALWAYS or NEVER in all caps, that's a yellow flag \u2014 reframe and explain the reasoning.
|
|
5182
|
+
|
|
5183
|
+
**Use examples** to ground abstract instructions:
|
|
5184
|
+
|
|
5185
|
+
\`\`\`markdown
|
|
5186
|
+
## Commit message format
|
|
5187
|
+
**Example 1:**
|
|
5188
|
+
Input: Added user authentication with JWT tokens
|
|
5189
|
+
Output: feat(auth): implement JWT-based authentication
|
|
5190
|
+
\`\`\`
|
|
5191
|
+
|
|
5192
|
+
**Define output formats** explicitly when structure matters:
|
|
5193
|
+
|
|
5194
|
+
\`\`\`markdown
|
|
5195
|
+
## Report structure
|
|
5196
|
+
ALWAYS use this exact template:
|
|
5197
|
+
# [Title]
|
|
5198
|
+
## Executive summary
|
|
5199
|
+
## Key findings
|
|
5200
|
+
## Recommendations
|
|
5201
|
+
\`\`\`
|
|
5202
|
+
|
|
5203
|
+
### Body Structure Checklist
|
|
5204
|
+
|
|
5205
|
+
A well-written skill body typically includes:
|
|
5206
|
+
- **Role definition**: What role does the agent play when executing this skill?
|
|
5207
|
+
- **Workflow**: Step-by-step process in a clear sequence
|
|
5208
|
+
- **Guidelines**: Rules, constraints, quality standards, and the WHY behind them
|
|
5209
|
+
- **Scenarios**: 2-3 common scenarios with concrete examples of inputs and expected outputs
|
|
5210
|
+
- **Edge cases**: What to do when things go wrong, when data is missing, etc.
|
|
5211
|
+
|
|
5212
|
+
---
|
|
5213
|
+
|
|
5214
|
+
## Step 4: Test and Iterate
|
|
5215
|
+
|
|
5216
|
+
After writing the draft, test it:
|
|
5217
|
+
|
|
5218
|
+
1. **Create 2-3 test prompts** \u2014 the kind of thing a real user would actually say. Share them with the user: "Here are a few test cases I'd like to try. Do these look right?"
|
|
5219
|
+
2. **Run the skill** against each test prompt to see what the agent produces
|
|
5220
|
+
3. **Review outputs with the user**: evaluate both qualitatively (does the output look right?) and quantitatively (did it follow the workflow? use the right tools?)
|
|
5221
|
+
4. **Collect feedback**: What worked? What didn't? What surprised the user?
|
|
5222
|
+
|
|
5223
|
+
### Improving the Skill
|
|
5224
|
+
|
|
5225
|
+
When iterating based on feedback:
|
|
5226
|
+
|
|
5227
|
+
1. **Generalize from feedback** \u2014 don't overfit to the test cases. The skill will be used across many different prompts. If a fix only helps one specific example, think bigger.
|
|
5228
|
+
2. **Keep it lean** \u2014 remove instructions that aren't pulling their weight. Read the full transcripts, not just final outputs. If the skill makes the agent waste time, trim it.
|
|
5229
|
+
3. **Look for repeated work** \u2014 if all test runs involved writing the same helper script, bundle that script into \`resources/scripts/\` and have the skill reference it instead.
|
|
5230
|
+
4. **Explain the why** \u2014 if you're adding a constraint because of a failure, explain the context so the model understands when to apply it and when it's safe to deviate.
|
|
5231
|
+
|
|
5232
|
+
Repeat the test \u2192 review \u2192 improve loop until the user is satisfied.
|
|
5233
|
+
|
|
5234
|
+
---
|
|
5235
|
+
|
|
5236
|
+
## Step 5: Optimize the Description (Optional)
|
|
5237
|
+
|
|
5238
|
+
After the skill works well, offer to optimize the description for better triggering accuracy.
|
|
5239
|
+
|
|
5240
|
+
### How Triggering Works
|
|
5241
|
+
|
|
5242
|
+
The agent sees skills as a list of name + description pairs. It decides whether to consult a skill based on that description. Important: agents only consult skills for tasks they can't easily handle on their own. Simple one-step queries may not trigger a skill even if the description matches \u2014 so make sure the description emphasizes the COMPLEX or SPECIALIZED nature of the task.
|
|
5243
|
+
|
|
5244
|
+
### Optimization Approach
|
|
5245
|
+
|
|
5246
|
+
1. Create 10-15 eval queries \u2014 a mix of should-trigger and should-not-trigger prompts
|
|
5247
|
+
2. For **should-trigger** (6-8): different phrasings of the same intent \u2014 formal, casual, indirect. Include cases where the user doesn't explicitly name the skill but clearly needs it
|
|
5248
|
+
3. For **should-not-trigger** (6-8): focus on near-misses \u2014 queries that share keywords but need something different. Don't make them obviously irrelevant
|
|
5249
|
+
4. Test the description against these queries and adjust based on misfires
|
|
5250
|
+
5. Show the user before/after and explain what changed
|
|
5251
|
+
|
|
5252
|
+
---
|
|
5253
|
+
|
|
5254
|
+
## Step 6: Package and Present
|
|
5255
|
+
|
|
5256
|
+
When the skill is ready:
|
|
5257
|
+
1. Verify the SKILL.md is at \`/root/.agents/skills/{skill-name}/SKILL.md\` with correct frontmatter
|
|
5258
|
+
2. Confirm all resource files are in place under \`resources/\`
|
|
5259
|
+
3. Tell the user the skill is ready and available at its path
|
|
5260
|
+
4. Remind them that the skill will now appear in the available skills list for any agent using the skill system
|
|
5261
|
+
|
|
5262
|
+
## Updating Existing Skills
|
|
5263
|
+
|
|
5264
|
+
When the user wants to improve an existing skill:
|
|
5265
|
+
1. Read the current SKILL.md from \`/root/.agents/skills/{skill-name}/SKILL.md\`
|
|
5266
|
+
2. Understand what it currently does and where it falls short
|
|
5267
|
+
3. Follow the same interview \u2192 draft \u2192 test \u2192 iterate loop
|
|
5268
|
+
4. **Preserve the original name** \u2014 the directory name and \`name\` frontmatter field should stay the same
|
|
5269
|
+
5. Write the updated version back to the same path
|
|
5270
|
+
|
|
5271
|
+
---
|
|
5272
|
+
|
|
5273
|
+
## Example Walkthrough
|
|
5274
|
+
|
|
5275
|
+
**User**: "I want a skill that helps me analyze CSV data"
|
|
5276
|
+
|
|
5277
|
+
**You** (interview):
|
|
5278
|
+
- "What kinds of analysis \u2014 summary stats, filtering, charting?"
|
|
5279
|
+
- "Are the CSVs always the same format or varied?"
|
|
5280
|
+
- "Should it output results as text, new CSV, or visualizations?"
|
|
5281
|
+
|
|
5282
|
+
**User**: "Mostly summary stats and filtering. The files vary but all have headers."
|
|
5283
|
+
|
|
5284
|
+
**You** (draft frontmatter):
|
|
5285
|
+
\`\`\`yaml
|
|
5286
|
+
---
|
|
5287
|
+
name: csv-analyzer
|
|
5288
|
+
description: Analyze CSV data with statistical summaries, filtering, and aggregation. Use whenever users want to explore, summarize, or extract insights from CSV files \u2014 even if they don't say "analyze" explicitly.
|
|
5289
|
+
metadata:
|
|
5290
|
+
category: data
|
|
5291
|
+
version: "1.0"
|
|
5292
|
+
---
|
|
5293
|
+
\`\`\`
|
|
5294
|
+
|
|
5295
|
+
**You** (draft body): Write a workflow that teaches the agent to:
|
|
5296
|
+
1. Inspect the CSV structure and headers
|
|
5297
|
+
2. Let the user choose analysis type (summary, filter, aggregate)
|
|
5298
|
+
3. Execute the analysis and present results clearly
|
|
5299
|
+
4. Handle edge cases: missing headers, empty files, mixed types
|
|
5300
|
+
|
|
5301
|
+
**You** (write): Create \`/root/.agents/skills/csv-analyzer/SKILL.md\`
|
|
5302
|
+
|
|
5303
|
+
**You** (test): "Here are 3 test cases \u2014 'summarize this sales CSV', 'filter rows where region is West', 'show monthly revenue trends'. Let me run these and we'll review."
|
|
5304
|
+
|
|
5305
|
+
Then iterate based on what the user says.
|
|
5306
|
+
`
|
|
5307
|
+
};
|
|
5308
|
+
function getBuiltInSkillMeta(name) {
|
|
5309
|
+
const content = BUILTIN_SKILLS[name];
|
|
5310
|
+
if (!content) return null;
|
|
5311
|
+
try {
|
|
5312
|
+
const { meta } = parseSkillFrontmatter(content);
|
|
5313
|
+
return meta;
|
|
5314
|
+
} catch {
|
|
5315
|
+
return null;
|
|
5316
|
+
}
|
|
5317
|
+
}
|
|
5318
|
+
function getBuiltInSkillContent(name) {
|
|
5319
|
+
return BUILTIN_SKILLS[name];
|
|
5320
|
+
}
|
|
5321
|
+
function getAllBuiltInSkillMetas() {
|
|
5322
|
+
return Object.keys(BUILTIN_SKILLS).map((name) => getBuiltInSkillMeta(name)).filter((meta) => meta !== null);
|
|
5323
|
+
}
|
|
5324
|
+
function getBuiltInSkillNames() {
|
|
5325
|
+
return Object.keys(BUILTIN_SKILLS);
|
|
5326
|
+
}
|
|
5327
|
+
function isBuiltInSkill(name) {
|
|
5328
|
+
return name in BUILTIN_SKILLS;
|
|
5329
|
+
}
|
|
5330
|
+
|
|
5331
|
+
// src/tool_lattice/skill/load_skill_content.ts
|
|
5046
5332
|
var LOAD_SKILL_CONTENT_DESCRIPTION = `
|
|
5047
5333
|
Execute a skill within the main conversation
|
|
5048
5334
|
|
|
@@ -5083,6 +5369,11 @@ var createLoadSkillContentTool = () => {
|
|
|
5083
5369
|
return (0, import_langchain41.tool)(
|
|
5084
5370
|
async (input, _exe_config) => {
|
|
5085
5371
|
try {
|
|
5372
|
+
const builtInContent = getBuiltInSkillContent(input.skill_name);
|
|
5373
|
+
if (builtInContent) {
|
|
5374
|
+
const { meta: meta2, body: body2 } = parseSkillFrontmatter(builtInContent);
|
|
5375
|
+
return buildSkillFile(meta2, body2);
|
|
5376
|
+
}
|
|
5086
5377
|
const sandbox = await getSandboxFromExeConfig(_exe_config);
|
|
5087
5378
|
const filePath = `/root/.agents/skills/${input.skill_name}/SKILL.md`;
|
|
5088
5379
|
let content;
|
|
@@ -5140,6 +5431,7 @@ function createSkillMiddleware(params = {}) {
|
|
|
5140
5431
|
createLoadSkillContentTool()
|
|
5141
5432
|
],
|
|
5142
5433
|
beforeAgent: async (state, runtime) => {
|
|
5434
|
+
let resolvedSkills = [];
|
|
5143
5435
|
try {
|
|
5144
5436
|
const runConfig = runtime?.context?.runConfig || {};
|
|
5145
5437
|
const manager = getSandBoxManager();
|
|
@@ -5169,13 +5461,24 @@ function createSkillMiddleware(params = {}) {
|
|
|
5169
5461
|
}
|
|
5170
5462
|
}
|
|
5171
5463
|
if (readAll) {
|
|
5172
|
-
|
|
5464
|
+
resolvedSkills = allSkills;
|
|
5173
5465
|
} else if (skills && skills.length > 0) {
|
|
5174
|
-
|
|
5466
|
+
resolvedSkills = allSkills.filter((skill) => skills.includes(skill.id));
|
|
5467
|
+
} else {
|
|
5468
|
+
resolvedSkills = allSkills;
|
|
5175
5469
|
}
|
|
5176
5470
|
} catch (error) {
|
|
5177
5471
|
console.error("Error fetching skills:", error);
|
|
5178
5472
|
}
|
|
5473
|
+
const builtinMetas = getAllBuiltInSkillMetas();
|
|
5474
|
+
for (const meta of builtinMetas) {
|
|
5475
|
+
resolvedSkills.push({
|
|
5476
|
+
id: meta.name,
|
|
5477
|
+
name: meta.name,
|
|
5478
|
+
description: meta.description
|
|
5479
|
+
});
|
|
5480
|
+
}
|
|
5481
|
+
latestSkills = resolvedSkills;
|
|
5179
5482
|
},
|
|
5180
5483
|
wrapModelCall: (request, handler) => {
|
|
5181
5484
|
const skillsPrompt = latestSkills.filter((skill) => !!skill.name).map((skill) => `## ${skill.name}
|
|
@@ -10730,6 +11033,125 @@ var InMemoryThreadMessageQueueStore = class {
|
|
|
10730
11033
|
}
|
|
10731
11034
|
};
|
|
10732
11035
|
|
|
11036
|
+
// src/store_lattice/InMemoryWorkflowTrackingStore.ts
|
|
11037
|
+
var InMemoryWorkflowTrackingStore = class {
|
|
11038
|
+
constructor() {
|
|
11039
|
+
this.runs = /* @__PURE__ */ new Map();
|
|
11040
|
+
this.steps = /* @__PURE__ */ new Map();
|
|
11041
|
+
}
|
|
11042
|
+
async createWorkflowRun(request) {
|
|
11043
|
+
const now = /* @__PURE__ */ new Date();
|
|
11044
|
+
const run = {
|
|
11045
|
+
id: `${request.threadId}_${Date.now()}`,
|
|
11046
|
+
tenantId: request.tenantId,
|
|
11047
|
+
assistantId: request.assistantId,
|
|
11048
|
+
threadId: request.threadId,
|
|
11049
|
+
status: "running",
|
|
11050
|
+
topologyEdges: request.topologyEdges,
|
|
11051
|
+
totalEdges: request.topologyEdges.length,
|
|
11052
|
+
completedEdges: 0,
|
|
11053
|
+
metadata: request.metadata || {},
|
|
11054
|
+
startedAt: now,
|
|
11055
|
+
createdAt: now,
|
|
11056
|
+
updatedAt: now
|
|
11057
|
+
};
|
|
11058
|
+
this.runs.set(run.id, run);
|
|
11059
|
+
this.steps.set(run.id, []);
|
|
11060
|
+
return run;
|
|
11061
|
+
}
|
|
11062
|
+
async getWorkflowRun(runId) {
|
|
11063
|
+
return this.runs.get(runId) || null;
|
|
11064
|
+
}
|
|
11065
|
+
async updateWorkflowRun(runId, updates) {
|
|
11066
|
+
const run = this.runs.get(runId);
|
|
11067
|
+
if (!run) return null;
|
|
11068
|
+
const updated = {
|
|
11069
|
+
...run,
|
|
11070
|
+
...updates,
|
|
11071
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
11072
|
+
};
|
|
11073
|
+
this.runs.set(runId, updated);
|
|
11074
|
+
return updated;
|
|
11075
|
+
}
|
|
11076
|
+
async getWorkflowRunsByThreadId(tenantId, threadId) {
|
|
11077
|
+
const results = [];
|
|
11078
|
+
for (const run of this.runs.values()) {
|
|
11079
|
+
if (run.tenantId === tenantId && run.threadId === threadId) {
|
|
11080
|
+
results.push(run);
|
|
11081
|
+
}
|
|
11082
|
+
}
|
|
11083
|
+
return results;
|
|
11084
|
+
}
|
|
11085
|
+
async getWorkflowRunsByAssistantId(tenantId, assistantId) {
|
|
11086
|
+
const results = [];
|
|
11087
|
+
for (const run of this.runs.values()) {
|
|
11088
|
+
if (run.tenantId === tenantId && run.assistantId === assistantId) {
|
|
11089
|
+
results.push(run);
|
|
11090
|
+
}
|
|
11091
|
+
}
|
|
11092
|
+
return results;
|
|
11093
|
+
}
|
|
11094
|
+
async getWorkflowRunsByTenantId(tenantId) {
|
|
11095
|
+
const results = [];
|
|
11096
|
+
for (const run of this.runs.values()) {
|
|
11097
|
+
if (run.tenantId === tenantId) {
|
|
11098
|
+
results.push(run);
|
|
11099
|
+
}
|
|
11100
|
+
}
|
|
11101
|
+
return results;
|
|
11102
|
+
}
|
|
11103
|
+
async createRunStep(request) {
|
|
11104
|
+
const now = /* @__PURE__ */ new Date();
|
|
11105
|
+
const step = {
|
|
11106
|
+
id: `step_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`,
|
|
11107
|
+
runId: request.runId,
|
|
11108
|
+
tenantId: request.tenantId,
|
|
11109
|
+
stepType: request.stepType,
|
|
11110
|
+
stepName: request.stepName,
|
|
11111
|
+
edgeFrom: request.edgeFrom,
|
|
11112
|
+
edgeTo: request.edgeTo,
|
|
11113
|
+
edgePurpose: request.edgePurpose,
|
|
11114
|
+
input: request.input,
|
|
11115
|
+
status: "running",
|
|
11116
|
+
startedAt: now,
|
|
11117
|
+
createdAt: now,
|
|
11118
|
+
updatedAt: now
|
|
11119
|
+
};
|
|
11120
|
+
const runSteps = this.steps.get(request.runId) || [];
|
|
11121
|
+
runSteps.push(step);
|
|
11122
|
+
this.steps.set(request.runId, runSteps);
|
|
11123
|
+
return step;
|
|
11124
|
+
}
|
|
11125
|
+
async updateRunStep(runId, stepId, updates) {
|
|
11126
|
+
const runSteps = this.steps.get(runId);
|
|
11127
|
+
if (!runSteps) return null;
|
|
11128
|
+
const idx = runSteps.findIndex((s) => s.id === stepId);
|
|
11129
|
+
if (idx === -1) return null;
|
|
11130
|
+
const now = /* @__PURE__ */ new Date();
|
|
11131
|
+
runSteps[idx] = {
|
|
11132
|
+
...runSteps[idx],
|
|
11133
|
+
...updates,
|
|
11134
|
+
updatedAt: now
|
|
11135
|
+
};
|
|
11136
|
+
return runSteps[idx];
|
|
11137
|
+
}
|
|
11138
|
+
async getRunSteps(runId) {
|
|
11139
|
+
return this.steps.get(runId) || [];
|
|
11140
|
+
}
|
|
11141
|
+
async getRunStepsByType(runId, stepType) {
|
|
11142
|
+
const runSteps = this.steps.get(runId) || [];
|
|
11143
|
+
return runSteps.filter((s) => s.stepType === stepType);
|
|
11144
|
+
}
|
|
11145
|
+
async getInterruptedSteps(runId) {
|
|
11146
|
+
const runSteps = this.steps.get(runId) || [];
|
|
11147
|
+
return runSteps.filter((s) => s.status === "interrupted");
|
|
11148
|
+
}
|
|
11149
|
+
clear() {
|
|
11150
|
+
this.runs.clear();
|
|
11151
|
+
this.steps.clear();
|
|
11152
|
+
}
|
|
11153
|
+
};
|
|
11154
|
+
|
|
10733
11155
|
// src/store_lattice/StoreLatticeManager.ts
|
|
10734
11156
|
var StoreLatticeManager = class _StoreLatticeManager extends BaseLatticeManager {
|
|
10735
11157
|
/**
|
|
@@ -10886,6 +11308,12 @@ storeLatticeManager.registerLattice(
|
|
|
10886
11308
|
"threadMessageQueue",
|
|
10887
11309
|
defaultThreadMessageQueueStore
|
|
10888
11310
|
);
|
|
11311
|
+
var defaultWorkflowTrackingStore = new InMemoryWorkflowTrackingStore();
|
|
11312
|
+
storeLatticeManager.registerLattice(
|
|
11313
|
+
"default",
|
|
11314
|
+
"workflowTracking",
|
|
11315
|
+
defaultWorkflowTrackingStore
|
|
11316
|
+
);
|
|
10889
11317
|
|
|
10890
11318
|
// src/services/Agent.ts
|
|
10891
11319
|
var import_langgraph6 = require("@langchain/langgraph");
|
|
@@ -11224,6 +11652,7 @@ var Agent = class {
|
|
|
11224
11652
|
this.abortController = null;
|
|
11225
11653
|
this.queueMode = this.getDefaultQueueConfig();
|
|
11226
11654
|
this.isWaitingForQueueEnd = false;
|
|
11655
|
+
this.asyncTasks = [];
|
|
11227
11656
|
this.agentExecutor = async ({ input, command, custom_run_config }, signal) => {
|
|
11228
11657
|
const { runnable_agent, runConfig } = await this.getLatticeClientAndRuntimeConfig(custom_run_config);
|
|
11229
11658
|
const { messages, ...rest } = input;
|
|
@@ -12002,6 +12431,23 @@ var Agent = class {
|
|
|
12002
12431
|
console.log(namespacedEvent);
|
|
12003
12432
|
event_bus_default.publish(namespacedEvent, data);
|
|
12004
12433
|
}
|
|
12434
|
+
addAsyncTask(task) {
|
|
12435
|
+
this.asyncTasks.push(task);
|
|
12436
|
+
}
|
|
12437
|
+
getAsyncTasks() {
|
|
12438
|
+
return this.asyncTasks;
|
|
12439
|
+
}
|
|
12440
|
+
getAsyncTask(taskId) {
|
|
12441
|
+
return this.asyncTasks.find((t) => t.taskId === taskId);
|
|
12442
|
+
}
|
|
12443
|
+
updateAsyncTaskStatus(taskId, status) {
|
|
12444
|
+
const task = this.getAsyncTask(taskId);
|
|
12445
|
+
if (!task) return;
|
|
12446
|
+
task.status = status;
|
|
12447
|
+
if (status === "completed" || status === "failed" || status === "cancelled") {
|
|
12448
|
+
task.completedAt = Date.now();
|
|
12449
|
+
}
|
|
12450
|
+
}
|
|
12005
12451
|
};
|
|
12006
12452
|
|
|
12007
12453
|
// src/services/AgentInstanceManager.ts
|
|
@@ -12627,9 +13073,9 @@ var ReActAgentGraphBuilder = class {
|
|
|
12627
13073
|
*/
|
|
12628
13074
|
async build(agentLattice, params) {
|
|
12629
13075
|
const tools = params.tools.map((t) => {
|
|
12630
|
-
const
|
|
12631
|
-
return
|
|
12632
|
-
}).filter((
|
|
13076
|
+
const tool51 = getToolClient(t.key);
|
|
13077
|
+
return tool51;
|
|
13078
|
+
}).filter((tool51) => tool51 !== void 0);
|
|
12633
13079
|
const stateSchema2 = createReactAgentSchema(params.stateSchema);
|
|
12634
13080
|
const middlewareConfigs = params.middleware || [];
|
|
12635
13081
|
const filesystemBackend = createFilesystemBackendFactory(middlewareConfigs);
|
|
@@ -13037,6 +13483,25 @@ function getSubagents(options) {
|
|
|
13037
13483
|
}
|
|
13038
13484
|
return { agents, descriptions: subagentDescriptions };
|
|
13039
13485
|
}
|
|
13486
|
+
function getAsyncPromptText() {
|
|
13487
|
+
return `
|
|
13488
|
+
|
|
13489
|
+
## Async Task Usage
|
|
13490
|
+
|
|
13491
|
+
When tasks are independent and can run in parallel, use \`async: true\` to launch
|
|
13492
|
+
background tasks. The task returns immediately with a task ID.
|
|
13493
|
+
|
|
13494
|
+
CRITICAL: After launching with \`async: true\`, move on immediately.
|
|
13495
|
+
- NEVER call check_async_task or list_async_tasks right after starting a task.
|
|
13496
|
+
- NEVER poll for task completion. The result will arrive as a notification.
|
|
13497
|
+
- Only check task status when the USER explicitly asks for an update.
|
|
13498
|
+
- If you receive an [Async task completed] notification, read it and incorporate
|
|
13499
|
+
the result into your next response. Do not then call check_async_task repeatedly.
|
|
13500
|
+
- Task statuses in conversation history are stale \u2014 always use fresh tool calls
|
|
13501
|
+
when the user asks.
|
|
13502
|
+
- Use cancel_async_task if the user wants to stop a running task.
|
|
13503
|
+
- Keep the full task_id: never truncate or abbreviate it.`;
|
|
13504
|
+
}
|
|
13040
13505
|
function createTaskTool(options) {
|
|
13041
13506
|
const {
|
|
13042
13507
|
defaultModel,
|
|
@@ -13045,7 +13510,8 @@ function createTaskTool(options) {
|
|
|
13045
13510
|
defaultInterruptOn,
|
|
13046
13511
|
subagents,
|
|
13047
13512
|
generalPurposeAgent,
|
|
13048
|
-
taskDescription
|
|
13513
|
+
taskDescription,
|
|
13514
|
+
allowAsync
|
|
13049
13515
|
} = options;
|
|
13050
13516
|
const { agents: subagentGraphs, descriptions: subagentDescriptions } = getSubagents({
|
|
13051
13517
|
defaultModel,
|
|
@@ -13058,7 +13524,7 @@ function createTaskTool(options) {
|
|
|
13058
13524
|
const finalTaskDescription = taskDescription ? taskDescription : getTaskToolDescription(subagentDescriptions);
|
|
13059
13525
|
return (0, import_langchain57.tool)(
|
|
13060
13526
|
async (input, config) => {
|
|
13061
|
-
const { description, subagent_type } = input;
|
|
13527
|
+
const { description, subagent_type, async } = input;
|
|
13062
13528
|
let assistant_id = subagent_type;
|
|
13063
13529
|
if (subagent_type === "general-purpose") {
|
|
13064
13530
|
assistant_id = config.configurable?.runConfig?.assistant_id + "-general-purpose";
|
|
@@ -13088,6 +13554,57 @@ function createTaskTool(options) {
|
|
|
13088
13554
|
const subagentState = filterStateForSubagent(currentState);
|
|
13089
13555
|
subagentState.messages = [new import_messages2.HumanMessage({ content: description })];
|
|
13090
13556
|
const subagent_thread_id = config.configurable?.thread_id + "____" + assistant_id + "_" + config.toolCall.id;
|
|
13557
|
+
if (async) {
|
|
13558
|
+
const tenantId = config.configurable?.runConfig?.tenantId;
|
|
13559
|
+
const mainAssistantId = config.configurable?.runConfig?.assistant_id;
|
|
13560
|
+
const mainThreadId = config.configurable?.runConfig?.thread_id;
|
|
13561
|
+
const mainRuntimeAgent = agentInstanceManager.getAgent({
|
|
13562
|
+
assistant_id: mainAssistantId,
|
|
13563
|
+
thread_id: mainThreadId,
|
|
13564
|
+
tenant_id: tenantId
|
|
13565
|
+
});
|
|
13566
|
+
if (mainRuntimeAgent) {
|
|
13567
|
+
mainRuntimeAgent.addAsyncTask({
|
|
13568
|
+
taskId: subagent_thread_id,
|
|
13569
|
+
assistantId: assistant_id,
|
|
13570
|
+
description: description.substring(0, 200),
|
|
13571
|
+
status: "running",
|
|
13572
|
+
createdAt: Date.now()
|
|
13573
|
+
});
|
|
13574
|
+
}
|
|
13575
|
+
AgentManager.getInstance().callAgentInQueue({
|
|
13576
|
+
assistant_id,
|
|
13577
|
+
thread_id: subagent_thread_id,
|
|
13578
|
+
input: { ...subagentState, message: description },
|
|
13579
|
+
"x-tenant-id": tenantId,
|
|
13580
|
+
runConfig: {
|
|
13581
|
+
...config.configurable?.runConfig,
|
|
13582
|
+
assistant_id,
|
|
13583
|
+
thread_id: subagent_thread_id
|
|
13584
|
+
},
|
|
13585
|
+
main_thread_id: mainThreadId,
|
|
13586
|
+
main_tenant_id: tenantId,
|
|
13587
|
+
main_assistant_id: mainAssistantId
|
|
13588
|
+
}, false).catch((err) => {
|
|
13589
|
+
console.error(`Failed to start async subagent ${subagent_thread_id}:`, err);
|
|
13590
|
+
});
|
|
13591
|
+
if (!config.toolCall?.id) {
|
|
13592
|
+
throw new Error("Tool call ID is required for subagent invocation");
|
|
13593
|
+
}
|
|
13594
|
+
return new import_langgraph8.Command({
|
|
13595
|
+
update: {
|
|
13596
|
+
messages: [
|
|
13597
|
+
new import_langchain57.ToolMessage({
|
|
13598
|
+
content: `Async task started: ${subagent_thread_id}
|
|
13599
|
+
${description}
|
|
13600
|
+
The result will be delivered as a notification when complete. Do not poll.`,
|
|
13601
|
+
tool_call_id: config.toolCall.id,
|
|
13602
|
+
name: "task"
|
|
13603
|
+
})
|
|
13604
|
+
]
|
|
13605
|
+
}
|
|
13606
|
+
});
|
|
13607
|
+
}
|
|
13091
13608
|
const workerResult = await agentWorkerGraph.invoke({
|
|
13092
13609
|
assistant_id,
|
|
13093
13610
|
thread_id: subagent_thread_id,
|
|
@@ -13129,7 +13646,186 @@ function createTaskTool(options) {
|
|
|
13129
13646
|
`Name of the agent to use. Available: ${Object.keys(
|
|
13130
13647
|
subagentGraphs
|
|
13131
13648
|
).join(", ")}`
|
|
13132
|
-
)
|
|
13649
|
+
),
|
|
13650
|
+
...allowAsync ? {
|
|
13651
|
+
async: import_v32.z.boolean().default(false).describe(
|
|
13652
|
+
"When true, runs the task in the background and returns immediately. Use for independent tasks that can run in parallel. The result is delivered as a notification when complete. Use check_async_task or list_async_tasks to monitor progress."
|
|
13653
|
+
)
|
|
13654
|
+
} : {}
|
|
13655
|
+
})
|
|
13656
|
+
}
|
|
13657
|
+
);
|
|
13658
|
+
}
|
|
13659
|
+
function getMainAgentFromConfig(config) {
|
|
13660
|
+
const tenantId = config.configurable?.runConfig?.tenantId;
|
|
13661
|
+
const mainAssistantId = config.configurable?.runConfig?.assistant_id;
|
|
13662
|
+
const mainThreadId = config.configurable?.runConfig?.thread_id;
|
|
13663
|
+
return agentInstanceManager.getAgent({
|
|
13664
|
+
assistant_id: mainAssistantId,
|
|
13665
|
+
thread_id: mainThreadId,
|
|
13666
|
+
tenant_id: tenantId
|
|
13667
|
+
});
|
|
13668
|
+
}
|
|
13669
|
+
function createCheckAsyncTaskTool() {
|
|
13670
|
+
return (0, import_langchain57.tool)(
|
|
13671
|
+
async (input, config) => {
|
|
13672
|
+
const { task_id } = input;
|
|
13673
|
+
const mainAgent = getMainAgentFromConfig(config);
|
|
13674
|
+
if (!mainAgent) {
|
|
13675
|
+
return "Cannot access main agent state.";
|
|
13676
|
+
}
|
|
13677
|
+
const cached = mainAgent.getAsyncTask(task_id);
|
|
13678
|
+
if (!cached) {
|
|
13679
|
+
return `Task ${task_id} not found. Use list_async_tasks to see all tasks.`;
|
|
13680
|
+
}
|
|
13681
|
+
try {
|
|
13682
|
+
if (!agentInstanceManager.hasAgent({
|
|
13683
|
+
assistant_id: cached.assistantId,
|
|
13684
|
+
thread_id: task_id,
|
|
13685
|
+
tenant_id: mainAgent.tenant_id
|
|
13686
|
+
})) {
|
|
13687
|
+
return `Task ${task_id}: not found (may have been cleaned up). Status was: ${cached.status}`;
|
|
13688
|
+
}
|
|
13689
|
+
const subAgent = agentInstanceManager.getAgent({
|
|
13690
|
+
assistant_id: cached.assistantId,
|
|
13691
|
+
thread_id: task_id,
|
|
13692
|
+
tenant_id: mainAgent.tenant_id
|
|
13693
|
+
});
|
|
13694
|
+
const status = await subAgent.getRunStatus();
|
|
13695
|
+
if (status === "busy") {
|
|
13696
|
+
return `Task ${task_id}: still running.
|
|
13697
|
+
Description: ${cached.description}`;
|
|
13698
|
+
}
|
|
13699
|
+
if (status === "idle") {
|
|
13700
|
+
const state = await subAgent.getCurrentState();
|
|
13701
|
+
const messages = state.values.messages || [];
|
|
13702
|
+
const lastAI = [...messages].reverse().find(
|
|
13703
|
+
(m) => m.type === "ai" || m.getType?.() === "ai"
|
|
13704
|
+
);
|
|
13705
|
+
mainAgent.updateAsyncTaskStatus(task_id, "completed");
|
|
13706
|
+
const result = lastAI?.content ?? "(completed, no output)";
|
|
13707
|
+
return `Task ${task_id}: COMPLETED.
|
|
13708
|
+
Description: ${cached.description}
|
|
13709
|
+
Result:
|
|
13710
|
+
${result}`;
|
|
13711
|
+
}
|
|
13712
|
+
if (status === "error") {
|
|
13713
|
+
mainAgent.updateAsyncTaskStatus(task_id, "failed");
|
|
13714
|
+
return `Task ${task_id}: failed.
|
|
13715
|
+
Description: ${cached.description}`;
|
|
13716
|
+
}
|
|
13717
|
+
if (status === "interrupted") {
|
|
13718
|
+
return `Task ${task_id}: interrupted (waiting for input).
|
|
13719
|
+
Description: ${cached.description}`;
|
|
13720
|
+
}
|
|
13721
|
+
return `Task ${task_id}: ${status}.
|
|
13722
|
+
Description: ${cached.description}`;
|
|
13723
|
+
} catch (err) {
|
|
13724
|
+
return `Task ${task_id}: error checking status: ${err instanceof Error ? err.message : String(err)}`;
|
|
13725
|
+
}
|
|
13726
|
+
},
|
|
13727
|
+
{
|
|
13728
|
+
name: "check_async_task",
|
|
13729
|
+
description: "Get the current status and result of an async background task. Use this to check if a previously launched async task has completed.",
|
|
13730
|
+
schema: import_v32.z.object({
|
|
13731
|
+
task_id: import_v32.z.string().describe("The task ID returned when the async task was started")
|
|
13732
|
+
})
|
|
13733
|
+
}
|
|
13734
|
+
);
|
|
13735
|
+
}
|
|
13736
|
+
function createListAsyncTasksTool() {
|
|
13737
|
+
return (0, import_langchain57.tool)(
|
|
13738
|
+
async (_input, config) => {
|
|
13739
|
+
const mainAgent = getMainAgentFromConfig(config);
|
|
13740
|
+
if (!mainAgent) {
|
|
13741
|
+
return "Cannot access main agent state.";
|
|
13742
|
+
}
|
|
13743
|
+
const tasks = mainAgent.getAsyncTasks();
|
|
13744
|
+
if (tasks.length === 0) {
|
|
13745
|
+
return "No async tasks have been launched.";
|
|
13746
|
+
}
|
|
13747
|
+
for (const task of tasks) {
|
|
13748
|
+
if (task.status === "completed" || task.status === "failed" || task.status === "cancelled") continue;
|
|
13749
|
+
try {
|
|
13750
|
+
if (!agentInstanceManager.hasAgent({
|
|
13751
|
+
assistant_id: task.assistantId,
|
|
13752
|
+
thread_id: task.taskId,
|
|
13753
|
+
tenant_id: mainAgent.tenant_id
|
|
13754
|
+
})) continue;
|
|
13755
|
+
const subAgent = agentInstanceManager.getAgent({
|
|
13756
|
+
assistant_id: task.assistantId,
|
|
13757
|
+
thread_id: task.taskId,
|
|
13758
|
+
tenant_id: mainAgent.tenant_id
|
|
13759
|
+
});
|
|
13760
|
+
const status = await subAgent.getRunStatus();
|
|
13761
|
+
if (status === "idle") {
|
|
13762
|
+
mainAgent.updateAsyncTaskStatus(task.taskId, "completed");
|
|
13763
|
+
} else if (status === "error") {
|
|
13764
|
+
mainAgent.updateAsyncTaskStatus(task.taskId, "failed");
|
|
13765
|
+
}
|
|
13766
|
+
} catch {
|
|
13767
|
+
}
|
|
13768
|
+
}
|
|
13769
|
+
const lines = tasks.map((t) => {
|
|
13770
|
+
const age = Math.floor((Date.now() - t.createdAt) / 1e3);
|
|
13771
|
+
const ageStr = age < 60 ? `${age}s ago` : `${Math.floor(age / 60)}m ago`;
|
|
13772
|
+
return `| ${t.taskId} | ${t.status} | ${ageStr} | ${t.description.substring(0, 80)} |`;
|
|
13773
|
+
});
|
|
13774
|
+
return [
|
|
13775
|
+
"| task_id | status | age | description |",
|
|
13776
|
+
"|---------|--------|-----|-------------|",
|
|
13777
|
+
...lines
|
|
13778
|
+
].join("\n");
|
|
13779
|
+
},
|
|
13780
|
+
{
|
|
13781
|
+
name: "list_async_tasks",
|
|
13782
|
+
description: "List all async background tasks with their current status. Use this before reporting task status to the user. Statuses in conversation history may be stale.",
|
|
13783
|
+
schema: import_v32.z.object({})
|
|
13784
|
+
}
|
|
13785
|
+
);
|
|
13786
|
+
}
|
|
13787
|
+
function createCancelAsyncTaskTool() {
|
|
13788
|
+
return (0, import_langchain57.tool)(
|
|
13789
|
+
async (input, config) => {
|
|
13790
|
+
const { task_id } = input;
|
|
13791
|
+
const mainAgent = getMainAgentFromConfig(config);
|
|
13792
|
+
if (!mainAgent) {
|
|
13793
|
+
return "Cannot access main agent state.";
|
|
13794
|
+
}
|
|
13795
|
+
const cached = mainAgent.getAsyncTask(task_id);
|
|
13796
|
+
if (!cached) {
|
|
13797
|
+
return `Task ${task_id} not found.`;
|
|
13798
|
+
}
|
|
13799
|
+
try {
|
|
13800
|
+
const subAgentExists = agentInstanceManager.hasAgent({
|
|
13801
|
+
assistant_id: cached.assistantId,
|
|
13802
|
+
thread_id: task_id,
|
|
13803
|
+
tenant_id: mainAgent.tenant_id
|
|
13804
|
+
});
|
|
13805
|
+
if (subAgentExists) {
|
|
13806
|
+
const subAgent = agentInstanceManager.getAgent({
|
|
13807
|
+
assistant_id: cached.assistantId,
|
|
13808
|
+
thread_id: task_id,
|
|
13809
|
+
tenant_id: mainAgent.tenant_id
|
|
13810
|
+
});
|
|
13811
|
+
await subAgent.abort();
|
|
13812
|
+
agentInstanceManager.removeAgent({
|
|
13813
|
+
assistant_id: cached.assistantId,
|
|
13814
|
+
thread_id: task_id,
|
|
13815
|
+
tenant_id: mainAgent.tenant_id
|
|
13816
|
+
});
|
|
13817
|
+
}
|
|
13818
|
+
} catch (err) {
|
|
13819
|
+
return `Failed to cancel task ${task_id}: ${err instanceof Error ? err.message : String(err)}`;
|
|
13820
|
+
}
|
|
13821
|
+
mainAgent.updateAsyncTaskStatus(task_id, "cancelled");
|
|
13822
|
+
return `Task ${task_id} cancelled.`;
|
|
13823
|
+
},
|
|
13824
|
+
{
|
|
13825
|
+
name: "cancel_async_task",
|
|
13826
|
+
description: "Cancel a running async background task.",
|
|
13827
|
+
schema: import_v32.z.object({
|
|
13828
|
+
task_id: import_v32.z.string().describe("The task ID to cancel")
|
|
13133
13829
|
})
|
|
13134
13830
|
}
|
|
13135
13831
|
);
|
|
@@ -13143,7 +13839,8 @@ function createSubAgentMiddleware(options) {
|
|
|
13143
13839
|
subagents = [],
|
|
13144
13840
|
systemPrompt = TASK_SYSTEM_PROMPT,
|
|
13145
13841
|
generalPurposeAgent = true,
|
|
13146
|
-
taskDescription = null
|
|
13842
|
+
taskDescription = null,
|
|
13843
|
+
allowAsync = true
|
|
13147
13844
|
} = options;
|
|
13148
13845
|
const taskTool = createTaskTool({
|
|
13149
13846
|
defaultModel,
|
|
@@ -13152,17 +13849,27 @@ function createSubAgentMiddleware(options) {
|
|
|
13152
13849
|
defaultInterruptOn,
|
|
13153
13850
|
subagents,
|
|
13154
13851
|
generalPurposeAgent,
|
|
13155
|
-
taskDescription
|
|
13852
|
+
taskDescription,
|
|
13853
|
+
allowAsync
|
|
13156
13854
|
});
|
|
13855
|
+
const allTools = [taskTool];
|
|
13856
|
+
if (allowAsync) {
|
|
13857
|
+
allTools.push(
|
|
13858
|
+
createCheckAsyncTaskTool(),
|
|
13859
|
+
createListAsyncTasksTool(),
|
|
13860
|
+
createCancelAsyncTaskTool()
|
|
13861
|
+
);
|
|
13862
|
+
}
|
|
13863
|
+
const effectiveSystemPrompt = allowAsync ? systemPrompt + getAsyncPromptText() : systemPrompt;
|
|
13157
13864
|
return (0, import_langchain57.createMiddleware)({
|
|
13158
13865
|
name: "subAgentMiddleware",
|
|
13159
|
-
tools:
|
|
13866
|
+
tools: allTools,
|
|
13160
13867
|
wrapModelCall: async (request, handler) => {
|
|
13161
|
-
if (
|
|
13868
|
+
if (effectiveSystemPrompt !== null) {
|
|
13162
13869
|
const currentPrompt = request.systemPrompt || "";
|
|
13163
13870
|
const newPrompt = currentPrompt ? `${currentPrompt}
|
|
13164
13871
|
|
|
13165
|
-
${
|
|
13872
|
+
${effectiveSystemPrompt}` : effectiveSystemPrompt;
|
|
13166
13873
|
return handler({
|
|
13167
13874
|
...request,
|
|
13168
13875
|
systemPrompt: newPrompt
|
|
@@ -14693,7 +15400,7 @@ var DeepAgentGraphBuilder = class {
|
|
|
14693
15400
|
const tools = params.tools.map((t) => {
|
|
14694
15401
|
const toolClient = getToolClient(t.key);
|
|
14695
15402
|
return toolClient;
|
|
14696
|
-
}).filter((
|
|
15403
|
+
}).filter((tool51) => tool51 !== void 0);
|
|
14697
15404
|
const subagents = await Promise.all(params.subAgents.map(async (sa) => {
|
|
14698
15405
|
if (sa.client) {
|
|
14699
15406
|
return {
|
|
@@ -16318,7 +17025,7 @@ var TeamAgentGraphBuilder = class {
|
|
|
16318
17025
|
const tools = params.tools.map((t) => {
|
|
16319
17026
|
const toolClient = getToolClient(t.key);
|
|
16320
17027
|
return toolClient;
|
|
16321
|
-
}).filter((
|
|
17028
|
+
}).filter((tool51) => tool51 !== void 0);
|
|
16322
17029
|
const teammates = params.subAgents.map((sa) => {
|
|
16323
17030
|
const baseConfig = sa.config;
|
|
16324
17031
|
return {
|
|
@@ -16355,17 +17062,439 @@ var TeamAgentGraphBuilder = class {
|
|
|
16355
17062
|
}
|
|
16356
17063
|
};
|
|
16357
17064
|
|
|
16358
|
-
// src/
|
|
16359
|
-
var
|
|
16360
|
-
|
|
16361
|
-
|
|
16362
|
-
|
|
17065
|
+
// src/deep_agent_new/processing_agent.ts
|
|
17066
|
+
var import_langchain66 = require("langchain");
|
|
17067
|
+
|
|
17068
|
+
// src/middlewares/topologyMiddleware.ts
|
|
17069
|
+
var import_langchain64 = require("langchain");
|
|
17070
|
+
var import_messages4 = require("@langchain/core/messages");
|
|
17071
|
+
var import_langchain65 = require("langchain");
|
|
17072
|
+
var import_zod51 = require("zod");
|
|
17073
|
+
var import_langgraph13 = require("@langchain/langgraph");
|
|
17074
|
+
var CompletedEdgeSchema = import_zod51.z.object({
|
|
17075
|
+
to: import_zod51.z.string(),
|
|
17076
|
+
purpose: import_zod51.z.string()
|
|
17077
|
+
});
|
|
17078
|
+
function deriveCompletedEdges(messages, edges) {
|
|
17079
|
+
const completedToolCallIds = /* @__PURE__ */ new Set();
|
|
17080
|
+
for (const msg of messages) {
|
|
17081
|
+
if (msg.name === "task" && msg.tool_call_id && msg.status !== "error") {
|
|
17082
|
+
completedToolCallIds.add(msg.tool_call_id);
|
|
17083
|
+
}
|
|
17084
|
+
}
|
|
17085
|
+
const completed = [];
|
|
17086
|
+
for (const msg of messages) {
|
|
17087
|
+
if (!msg.tool_calls) continue;
|
|
17088
|
+
for (const tc of msg.tool_calls) {
|
|
17089
|
+
if (tc.name !== "task" || !completedToolCallIds.has(tc.id)) continue;
|
|
17090
|
+
const targetAgent = tc.args?.subagent_type;
|
|
17091
|
+
const edge = edges.find(
|
|
17092
|
+
(e) => e.to === targetAgent
|
|
17093
|
+
);
|
|
17094
|
+
if (edge && !completed.some((e) => e.to === edge.to)) {
|
|
17095
|
+
completed.push({ to: edge.to, purpose: edge.purpose });
|
|
17096
|
+
}
|
|
17097
|
+
}
|
|
16363
17098
|
}
|
|
16364
|
-
|
|
16365
|
-
|
|
16366
|
-
|
|
16367
|
-
|
|
16368
|
-
|
|
17099
|
+
return completed;
|
|
17100
|
+
}
|
|
17101
|
+
function createTopologyMiddleware(options) {
|
|
17102
|
+
const { edges, trackingStore } = options;
|
|
17103
|
+
return (0, import_langchain64.createMiddleware)({
|
|
17104
|
+
name: "TopologyMiddleware",
|
|
17105
|
+
contextSchema: import_zod51.z.object({
|
|
17106
|
+
runConfig: import_zod51.z.any()
|
|
17107
|
+
}),
|
|
17108
|
+
stateSchema: import_zod51.z.object({
|
|
17109
|
+
currentAgentId: import_zod51.z.string().default(""),
|
|
17110
|
+
completedEdges: import_zod51.z.array(CompletedEdgeSchema).default([]),
|
|
17111
|
+
runId: import_zod51.z.string().default(""),
|
|
17112
|
+
stepIdMap: import_zod51.z.record(import_zod51.z.string()).default({})
|
|
17113
|
+
}),
|
|
17114
|
+
beforeAgent: async (state, runtime) => {
|
|
17115
|
+
const runConfig = runtime.context?.runConfig ?? {};
|
|
17116
|
+
const startingNode = edges[0]?.from ?? runConfig.assistant_id ?? "";
|
|
17117
|
+
let runId = "";
|
|
17118
|
+
if (trackingStore) {
|
|
17119
|
+
try {
|
|
17120
|
+
const run = await trackingStore.createWorkflowRun({
|
|
17121
|
+
tenantId: runConfig.tenantId || "default",
|
|
17122
|
+
assistantId: runConfig.assistant_id ?? "",
|
|
17123
|
+
threadId: runConfig.thread_id ?? "",
|
|
17124
|
+
topologyEdges: edges
|
|
17125
|
+
});
|
|
17126
|
+
runId = run.id;
|
|
17127
|
+
} catch (err) {
|
|
17128
|
+
console.error("[topologyMiddleware] Failed to create WorkflowRun:", err);
|
|
17129
|
+
}
|
|
17130
|
+
}
|
|
17131
|
+
return {
|
|
17132
|
+
currentAgentId: startingNode,
|
|
17133
|
+
completedEdges: [],
|
|
17134
|
+
runId,
|
|
17135
|
+
stepIdMap: {}
|
|
17136
|
+
};
|
|
17137
|
+
},
|
|
17138
|
+
wrapModelCall: async (request, handler) => {
|
|
17139
|
+
const steps = edges.map((e, i) => `${i + 1}. \`${e.from}\` \u2192 \`${e.to}\` \u2014 ${e.purpose}`).join("\n");
|
|
17140
|
+
const topologyPrompt = `## Workflow Execution Plan
|
|
17141
|
+
|
|
17142
|
+
Your job is to execute this workflow by delegating each step to the specialized agent
|
|
17143
|
+
shown below. This is your core execution process \u2014 it is not optional.
|
|
17144
|
+
|
|
17145
|
+
${steps || "(no workflow steps defined)"}
|
|
17146
|
+
|
|
17147
|
+
Use the \`task\` tool to delegate work to each agent. Call \`read_topo_progress\` to
|
|
17148
|
+
see which steps are done and which are still pending.
|
|
17149
|
+
|
|
17150
|
+
Do NOT delegate to any agent outside the current node's allowed paths \u2014 such attempts
|
|
17151
|
+
will be blocked.`;
|
|
17152
|
+
const newSystemPrompt = request.systemPrompt ? `${topologyPrompt}
|
|
17153
|
+
|
|
17154
|
+
---
|
|
17155
|
+
|
|
17156
|
+
${request.systemPrompt}` : topologyPrompt;
|
|
17157
|
+
return handler({ ...request, systemPrompt: newSystemPrompt });
|
|
17158
|
+
},
|
|
17159
|
+
tools: [
|
|
17160
|
+
(0, import_langchain65.tool)(
|
|
17161
|
+
async (_input) => {
|
|
17162
|
+
return "placeholder";
|
|
17163
|
+
},
|
|
17164
|
+
{
|
|
17165
|
+
name: "read_topo_progress",
|
|
17166
|
+
description: "Check the current progress of the workflow execution plan. Returns which steps have been completed and which are still pending.",
|
|
17167
|
+
schema: import_zod51.z.object({})
|
|
17168
|
+
}
|
|
17169
|
+
)
|
|
17170
|
+
],
|
|
17171
|
+
wrapToolCall: async (request, handler) => {
|
|
17172
|
+
if (request.toolCall?.name === "read_topo_progress") {
|
|
17173
|
+
const currentAgentId = request.state?.currentAgentId || "";
|
|
17174
|
+
const completedEdges = request.state?.completedEdges || [];
|
|
17175
|
+
const doneSet = new Set(completedEdges.map((e) => e.to));
|
|
17176
|
+
const progress = edges.map((e) => ({
|
|
17177
|
+
agent: e.to,
|
|
17178
|
+
purpose: e.purpose,
|
|
17179
|
+
status: doneSet.has(e.to) ? "done" : "pending"
|
|
17180
|
+
}));
|
|
17181
|
+
const doneCount = completedEdges.length;
|
|
17182
|
+
return new import_messages4.ToolMessage({
|
|
17183
|
+
content: JSON.stringify(
|
|
17184
|
+
{
|
|
17185
|
+
currentAgentId,
|
|
17186
|
+
progress: `${doneCount}/${edges.length} edges completed`,
|
|
17187
|
+
steps: progress,
|
|
17188
|
+
nextPending: progress.filter((s) => s.status === "pending").map((s) => s.agent)
|
|
17189
|
+
},
|
|
17190
|
+
null,
|
|
17191
|
+
2
|
|
17192
|
+
),
|
|
17193
|
+
name: "read_topo_progress",
|
|
17194
|
+
tool_call_id: request.toolCall.id
|
|
17195
|
+
});
|
|
17196
|
+
}
|
|
17197
|
+
try {
|
|
17198
|
+
return await handler(request);
|
|
17199
|
+
} catch (error) {
|
|
17200
|
+
if (error instanceof import_langgraph13.GraphInterrupt) {
|
|
17201
|
+
throw error;
|
|
17202
|
+
}
|
|
17203
|
+
throw error;
|
|
17204
|
+
}
|
|
17205
|
+
},
|
|
17206
|
+
afterModel: {
|
|
17207
|
+
canJumpTo: ["model"],
|
|
17208
|
+
hook: async (state, runtime) => {
|
|
17209
|
+
const { messages, runId, stepIdMap: prevStepIdMap } = state;
|
|
17210
|
+
let { currentAgentId } = state;
|
|
17211
|
+
const runConfig = runtime.context?.runConfig ?? {};
|
|
17212
|
+
const stepIdMap = { ...prevStepIdMap };
|
|
17213
|
+
if (!messages || messages.length === 0) return;
|
|
17214
|
+
const lastMessage = messages[messages.length - 1];
|
|
17215
|
+
if ("tool_calls" in lastMessage) {
|
|
17216
|
+
for (const tc of lastMessage.tool_calls) {
|
|
17217
|
+
if (tc.name !== "task") continue;
|
|
17218
|
+
const targetAgent = tc.args?.subagent_type;
|
|
17219
|
+
const edge = edges.find(
|
|
17220
|
+
(e) => e.from === currentAgentId && e.to === targetAgent
|
|
17221
|
+
);
|
|
17222
|
+
if (!edge) {
|
|
17223
|
+
const myEdges = edges.filter(
|
|
17224
|
+
(e) => e.from === currentAgentId
|
|
17225
|
+
);
|
|
17226
|
+
console.warn(
|
|
17227
|
+
JSON.stringify({
|
|
17228
|
+
event: "topology_violation",
|
|
17229
|
+
currentAgentId,
|
|
17230
|
+
targetAgent,
|
|
17231
|
+
description: tc.args?.description,
|
|
17232
|
+
allowedTargets: myEdges.map((e) => e.to),
|
|
17233
|
+
threadId: runtime.configurable?.thread_id,
|
|
17234
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
17235
|
+
})
|
|
17236
|
+
);
|
|
17237
|
+
const allowedList = myEdges.length > 0 ? [
|
|
17238
|
+
`Agent \`${currentAgentId}\` may only delegate to:`,
|
|
17239
|
+
...myEdges.map(
|
|
17240
|
+
(e) => `- \`${e.to}\` \u2014 ${e.purpose}`
|
|
17241
|
+
)
|
|
17242
|
+
] : [
|
|
17243
|
+
`Agent \`${currentAgentId}\` has no outgoing delegation edges configured.`
|
|
17244
|
+
];
|
|
17245
|
+
return {
|
|
17246
|
+
messages: [
|
|
17247
|
+
new import_messages4.AIMessage({
|
|
17248
|
+
content: [
|
|
17249
|
+
`Task rejected: topology violation.`,
|
|
17250
|
+
`Agent "${currentAgentId}" is not allowed to delegate to "${targetAgent}".`,
|
|
17251
|
+
...allowedList,
|
|
17252
|
+
`Please delegate to one of the allowed agents above or handle the task yourself.`
|
|
17253
|
+
].join("\n")
|
|
17254
|
+
})
|
|
17255
|
+
],
|
|
17256
|
+
jumpTo: "model"
|
|
17257
|
+
};
|
|
17258
|
+
}
|
|
17259
|
+
currentAgentId = edge.to;
|
|
17260
|
+
if (trackingStore && runId) {
|
|
17261
|
+
try {
|
|
17262
|
+
const step = await trackingStore.createRunStep({
|
|
17263
|
+
runId,
|
|
17264
|
+
tenantId: runConfig.tenantId || "default",
|
|
17265
|
+
stepType: "task_delegation",
|
|
17266
|
+
stepName: targetAgent,
|
|
17267
|
+
edgeFrom: edge.from,
|
|
17268
|
+
edgeTo: edge.to,
|
|
17269
|
+
edgePurpose: edge.purpose,
|
|
17270
|
+
input: { description: tc.args?.description }
|
|
17271
|
+
});
|
|
17272
|
+
stepIdMap[edge.to] = step.id;
|
|
17273
|
+
} catch (err) {
|
|
17274
|
+
console.error("[topologyMiddleware] Failed to create RunStep:", err);
|
|
17275
|
+
}
|
|
17276
|
+
}
|
|
17277
|
+
}
|
|
17278
|
+
}
|
|
17279
|
+
const completedEdges = deriveCompletedEdges(
|
|
17280
|
+
messages,
|
|
17281
|
+
edges
|
|
17282
|
+
);
|
|
17283
|
+
if (trackingStore && runId) {
|
|
17284
|
+
for (const ce of completedEdges) {
|
|
17285
|
+
const stepId = stepIdMap[ce.to];
|
|
17286
|
+
if (!stepId) continue;
|
|
17287
|
+
let output;
|
|
17288
|
+
for (const msg of messages) {
|
|
17289
|
+
if (msg.name === "task" && msg.tool_call_id) {
|
|
17290
|
+
for (const tc of messages.find(
|
|
17291
|
+
(m) => m.tool_calls?.some((c) => c.id === msg.tool_call_id)
|
|
17292
|
+
)?.tool_calls || []) {
|
|
17293
|
+
if (tc.id === msg.tool_call_id && tc.args?.subagent_type === ce.to) {
|
|
17294
|
+
output = msg.content;
|
|
17295
|
+
break;
|
|
17296
|
+
}
|
|
17297
|
+
}
|
|
17298
|
+
if (output) break;
|
|
17299
|
+
}
|
|
17300
|
+
}
|
|
17301
|
+
if (output) {
|
|
17302
|
+
try {
|
|
17303
|
+
await trackingStore.updateRunStep(runId, stepId, {
|
|
17304
|
+
status: "completed",
|
|
17305
|
+
output: { result: output },
|
|
17306
|
+
completedAt: /* @__PURE__ */ new Date()
|
|
17307
|
+
});
|
|
17308
|
+
} catch (err) {
|
|
17309
|
+
console.error("[topologyMiddleware] Failed to update RunStep output:", err);
|
|
17310
|
+
}
|
|
17311
|
+
}
|
|
17312
|
+
}
|
|
17313
|
+
}
|
|
17314
|
+
if (trackingStore && runId) {
|
|
17315
|
+
try {
|
|
17316
|
+
await trackingStore.updateWorkflowRun(runId, {
|
|
17317
|
+
completedEdges: completedEdges.length
|
|
17318
|
+
});
|
|
17319
|
+
} catch (err) {
|
|
17320
|
+
console.error("[topologyMiddleware] Failed to update WorkflowRun completedEdges:", err);
|
|
17321
|
+
}
|
|
17322
|
+
}
|
|
17323
|
+
return { currentAgentId, completedEdges, stepIdMap };
|
|
17324
|
+
}
|
|
17325
|
+
},
|
|
17326
|
+
afterAgent: async (state, runtime) => {
|
|
17327
|
+
const { runId, completedEdges } = state;
|
|
17328
|
+
if (!trackingStore || !runId) return;
|
|
17329
|
+
const allDone = completedEdges && completedEdges.length >= edges.length;
|
|
17330
|
+
if (!allDone) return;
|
|
17331
|
+
try {
|
|
17332
|
+
await trackingStore.updateWorkflowRun(runId, {
|
|
17333
|
+
status: "completed",
|
|
17334
|
+
completedAt: /* @__PURE__ */ new Date()
|
|
17335
|
+
});
|
|
17336
|
+
} catch (err) {
|
|
17337
|
+
console.error("[topologyMiddleware] Failed to finalize WorkflowRun:", err);
|
|
17338
|
+
}
|
|
17339
|
+
}
|
|
17340
|
+
});
|
|
17341
|
+
}
|
|
17342
|
+
|
|
17343
|
+
// src/deep_agent_new/processing_agent.ts
|
|
17344
|
+
var BASE_PROMPT2 = `In order to complete the objective that the user asks of you, you have access to a number of standard tools.`;
|
|
17345
|
+
function createProcessingAgent(params) {
|
|
17346
|
+
const {
|
|
17347
|
+
model = "claude-sonnet-4-5-20250929",
|
|
17348
|
+
tools = [],
|
|
17349
|
+
systemPrompt,
|
|
17350
|
+
middleware: customMiddleware = [],
|
|
17351
|
+
subagents = [],
|
|
17352
|
+
responseFormat,
|
|
17353
|
+
contextSchema: contextSchema2,
|
|
17354
|
+
checkpointer,
|
|
17355
|
+
store,
|
|
17356
|
+
backend,
|
|
17357
|
+
interruptOn,
|
|
17358
|
+
name,
|
|
17359
|
+
skills,
|
|
17360
|
+
topologyEdges
|
|
17361
|
+
} = params;
|
|
17362
|
+
const finalSystemPrompt = systemPrompt ? `${systemPrompt}
|
|
17363
|
+
|
|
17364
|
+
${BASE_PROMPT2}` : BASE_PROMPT2;
|
|
17365
|
+
const filesystemBackend = backend ? backend : async (config) => new StateBackend(config);
|
|
17366
|
+
let trackingStore;
|
|
17367
|
+
try {
|
|
17368
|
+
const storeLattice = getStoreLattice("default", "workflowTracking");
|
|
17369
|
+
trackingStore = storeLattice.store;
|
|
17370
|
+
} catch {
|
|
17371
|
+
}
|
|
17372
|
+
const middleware = [
|
|
17373
|
+
// Workflow topology enforcement — replaces todoListMiddleware
|
|
17374
|
+
createTopologyMiddleware({ edges: topologyEdges, trackingStore }),
|
|
17375
|
+
// Enables filesystem operations and optional long-term memory storage
|
|
17376
|
+
createFilesystemMiddleware({ backend: filesystemBackend }),
|
|
17377
|
+
// Enables delegation to specialized subagents for complex tasks
|
|
17378
|
+
createSubAgentMiddleware({
|
|
17379
|
+
defaultModel: model,
|
|
17380
|
+
defaultTools: tools,
|
|
17381
|
+
defaultMiddleware: [
|
|
17382
|
+
// Subagent middleware: Todo list management (subagents get todo, not topology)
|
|
17383
|
+
todoListMiddleware(),
|
|
17384
|
+
// Subagent middleware: Filesystem operations
|
|
17385
|
+
createFilesystemMiddleware({
|
|
17386
|
+
backend: filesystemBackend
|
|
17387
|
+
}),
|
|
17388
|
+
// Subagent middleware: Automatic conversation summarization
|
|
17389
|
+
(0, import_langchain66.summarizationMiddleware)({
|
|
17390
|
+
model,
|
|
17391
|
+
trigger: { tokens: 17e4 },
|
|
17392
|
+
keep: { messages: 6 }
|
|
17393
|
+
}),
|
|
17394
|
+
// Subagent middleware: Anthropic prompt caching
|
|
17395
|
+
(0, import_langchain66.anthropicPromptCachingMiddleware)({
|
|
17396
|
+
unsupportedModelBehavior: "ignore"
|
|
17397
|
+
}),
|
|
17398
|
+
// Subagent middleware: Patches tool calls
|
|
17399
|
+
createPatchToolCallsMiddleware(),
|
|
17400
|
+
...customMiddleware
|
|
17401
|
+
],
|
|
17402
|
+
defaultInterruptOn: interruptOn,
|
|
17403
|
+
subagents,
|
|
17404
|
+
generalPurposeAgent: true,
|
|
17405
|
+
allowAsync: false
|
|
17406
|
+
}),
|
|
17407
|
+
// Automatically summarizes conversation history
|
|
17408
|
+
(0, import_langchain66.summarizationMiddleware)({
|
|
17409
|
+
model,
|
|
17410
|
+
trigger: { tokens: 17e4 },
|
|
17411
|
+
keep: { messages: 6 }
|
|
17412
|
+
}),
|
|
17413
|
+
// Enables Anthropic prompt caching
|
|
17414
|
+
(0, import_langchain66.anthropicPromptCachingMiddleware)({
|
|
17415
|
+
unsupportedModelBehavior: "ignore"
|
|
17416
|
+
}),
|
|
17417
|
+
// Patches tool calls
|
|
17418
|
+
createPatchToolCallsMiddleware()
|
|
17419
|
+
];
|
|
17420
|
+
if (interruptOn) {
|
|
17421
|
+
middleware.push((0, import_langchain66.humanInTheLoopMiddleware)({ interruptOn }));
|
|
17422
|
+
}
|
|
17423
|
+
middleware.push(...customMiddleware);
|
|
17424
|
+
return (0, import_langchain66.createAgent)({
|
|
17425
|
+
model,
|
|
17426
|
+
systemPrompt: finalSystemPrompt,
|
|
17427
|
+
tools,
|
|
17428
|
+
middleware,
|
|
17429
|
+
responseFormat,
|
|
17430
|
+
contextSchema: contextSchema2,
|
|
17431
|
+
checkpointer,
|
|
17432
|
+
store,
|
|
17433
|
+
name
|
|
17434
|
+
});
|
|
17435
|
+
}
|
|
17436
|
+
|
|
17437
|
+
// src/agent_lattice/builders/ProcessingAgentGraphBuilder.ts
|
|
17438
|
+
var ProcessingAgentGraphBuilder = class {
|
|
17439
|
+
async build(agentLattice, params) {
|
|
17440
|
+
const tools = params.tools.map((t) => {
|
|
17441
|
+
const toolClient = getToolClient(t.key);
|
|
17442
|
+
return toolClient;
|
|
17443
|
+
}).filter((tool51) => tool51 !== void 0);
|
|
17444
|
+
const subagents = await Promise.all(params.subAgents.map(async (sa) => {
|
|
17445
|
+
if (sa.client) {
|
|
17446
|
+
return {
|
|
17447
|
+
key: sa.config.key,
|
|
17448
|
+
name: sa.config.name,
|
|
17449
|
+
description: sa.config.description,
|
|
17450
|
+
runnable: sa.client
|
|
17451
|
+
};
|
|
17452
|
+
} else {
|
|
17453
|
+
const subagentClient = await createAgentClientFromAgentLattice({
|
|
17454
|
+
config: sa.config
|
|
17455
|
+
});
|
|
17456
|
+
return {
|
|
17457
|
+
key: sa.config.key,
|
|
17458
|
+
name: sa.config.name,
|
|
17459
|
+
description: sa.config.description,
|
|
17460
|
+
runnable: subagentClient
|
|
17461
|
+
};
|
|
17462
|
+
}
|
|
17463
|
+
}));
|
|
17464
|
+
const middlewareConfigs = params.middleware || [];
|
|
17465
|
+
const filesystemBackend = createFilesystemBackendFactory(middlewareConfigs);
|
|
17466
|
+
const middlewares = await createCommonMiddlewares(middlewareConfigs, filesystemBackend, true);
|
|
17467
|
+
const topologyConfig = middlewareConfigs.find(
|
|
17468
|
+
(m) => m.type === "topology" && m.enabled
|
|
17469
|
+
);
|
|
17470
|
+
const topologyEdges = topologyConfig?.config?.edges || [];
|
|
17471
|
+
const processingAgent = createProcessingAgent({
|
|
17472
|
+
tools,
|
|
17473
|
+
model: params.model,
|
|
17474
|
+
contextSchema: params.stateSchema,
|
|
17475
|
+
systemPrompt: params.prompt,
|
|
17476
|
+
subagents,
|
|
17477
|
+
checkpointer: getCheckpointSaver("default"),
|
|
17478
|
+
skills: params.skillCategories,
|
|
17479
|
+
backend: filesystemBackend,
|
|
17480
|
+
middleware: middlewares,
|
|
17481
|
+
topologyEdges
|
|
17482
|
+
});
|
|
17483
|
+
return processingAgent;
|
|
17484
|
+
}
|
|
17485
|
+
};
|
|
17486
|
+
|
|
17487
|
+
// src/agent_lattice/builders/AgentGraphBuilderFactory.ts
|
|
17488
|
+
var AgentGraphBuilderFactory = class _AgentGraphBuilderFactory {
|
|
17489
|
+
constructor() {
|
|
17490
|
+
this.builders = /* @__PURE__ */ new Map();
|
|
17491
|
+
this.registerDefaultBuilders();
|
|
17492
|
+
}
|
|
17493
|
+
/**
|
|
17494
|
+
* 获取单例实例
|
|
17495
|
+
*/
|
|
17496
|
+
static getInstance() {
|
|
17497
|
+
if (!_AgentGraphBuilderFactory.instance) {
|
|
16369
17498
|
_AgentGraphBuilderFactory.instance = new _AgentGraphBuilderFactory();
|
|
16370
17499
|
}
|
|
16371
17500
|
return _AgentGraphBuilderFactory.instance;
|
|
@@ -16377,6 +17506,7 @@ var AgentGraphBuilderFactory = class _AgentGraphBuilderFactory {
|
|
|
16377
17506
|
this.builders.set(import_protocols.AgentType.REACT, new ReActAgentGraphBuilder());
|
|
16378
17507
|
this.builders.set(import_protocols.AgentType.DEEP_AGENT, new DeepAgentGraphBuilder());
|
|
16379
17508
|
this.builders.set(import_protocols.AgentType.TEAM, new TeamAgentGraphBuilder());
|
|
17509
|
+
this.builders.set(import_protocols.AgentType.PROCESSING, new ProcessingAgentGraphBuilder());
|
|
16380
17510
|
}
|
|
16381
17511
|
/**
|
|
16382
17512
|
* 注册自定义Builder
|
|
@@ -16421,7 +17551,7 @@ var AgentParamsBuilder = class {
|
|
|
16421
17551
|
* @returns Agent build parameters
|
|
16422
17552
|
*/
|
|
16423
17553
|
async buildParams(agentLattice, options) {
|
|
16424
|
-
const skills = (0, import_protocols9.isDeepAgentConfig)(agentLattice.config) ? agentLattice.config.skillCategories : void 0;
|
|
17554
|
+
const skills = (0, import_protocols9.isDeepAgentConfig)(agentLattice.config) || (0, import_protocols9.isProcessingAgentConfig)(agentLattice.config) ? agentLattice.config.skillCategories : void 0;
|
|
16425
17555
|
const toolKeys = options?.overrideTools || (0, import_protocols9.getToolsFromConfig)(agentLattice.config);
|
|
16426
17556
|
const tools = toolKeys.map((toolKey) => {
|
|
16427
17557
|
const toolLattice = toolLatticeManager.getToolLattice(toolKey);
|
|
@@ -16452,7 +17582,7 @@ var AgentParamsBuilder = class {
|
|
|
16452
17582
|
};
|
|
16453
17583
|
}));
|
|
16454
17584
|
let internalSubAgents = [];
|
|
16455
|
-
if ((0, import_protocols9.isDeepAgentConfig)(agentLattice.config)) {
|
|
17585
|
+
if ((0, import_protocols9.isDeepAgentConfig)(agentLattice.config) || (0, import_protocols9.isProcessingAgentConfig)(agentLattice.config)) {
|
|
16456
17586
|
internalSubAgents = agentLattice.config.internalSubAgents?.map((i) => ({
|
|
16457
17587
|
key: i.key,
|
|
16458
17588
|
config: i
|
|
@@ -16637,6 +17767,39 @@ var SandboxSkillStore = class {
|
|
|
16637
17767
|
projectId: options.projectId
|
|
16638
17768
|
};
|
|
16639
17769
|
}
|
|
17770
|
+
/**
|
|
17771
|
+
* Build a Skill object from a built-in skill definition.
|
|
17772
|
+
*/
|
|
17773
|
+
_builtInSkill(name, tenantId) {
|
|
17774
|
+
const content = getBuiltInSkillContent(name);
|
|
17775
|
+
if (!content) return null;
|
|
17776
|
+
const { meta } = parseSkillFrontmatter(content);
|
|
17777
|
+
const now = /* @__PURE__ */ new Date();
|
|
17778
|
+
return {
|
|
17779
|
+
id: meta.name || name,
|
|
17780
|
+
tenantId,
|
|
17781
|
+
name: meta.name || name,
|
|
17782
|
+
description: meta.description || "",
|
|
17783
|
+
license: meta.license,
|
|
17784
|
+
compatibility: meta.compatibility,
|
|
17785
|
+
metadata: meta.metadata || {},
|
|
17786
|
+
content,
|
|
17787
|
+
subSkills: meta.subSkills,
|
|
17788
|
+
createdAt: now,
|
|
17789
|
+
updatedAt: now
|
|
17790
|
+
};
|
|
17791
|
+
}
|
|
17792
|
+
/**
|
|
17793
|
+
* Get all built-in skills as Skill objects for a tenant.
|
|
17794
|
+
*/
|
|
17795
|
+
_allBuiltInSkills(tenantId) {
|
|
17796
|
+
const skills = [];
|
|
17797
|
+
for (const name of Object.keys(BUILTIN_SKILLS)) {
|
|
17798
|
+
const skill = this._builtInSkill(name, tenantId);
|
|
17799
|
+
if (skill) skills.push(skill);
|
|
17800
|
+
}
|
|
17801
|
+
return skills;
|
|
17802
|
+
}
|
|
16640
17803
|
/**
|
|
16641
17804
|
* Get sandbox manager
|
|
16642
17805
|
*/
|
|
@@ -16773,17 +17936,25 @@ ${body}` : `${frontmatter}
|
|
|
16773
17936
|
}
|
|
16774
17937
|
}
|
|
16775
17938
|
}
|
|
17939
|
+
const builtInSkills = this._allBuiltInSkills(tenantId);
|
|
17940
|
+
for (const bis of builtInSkills) {
|
|
17941
|
+
if (!skills.some((s) => s.id === bis.id)) {
|
|
17942
|
+
skills.push(bis);
|
|
17943
|
+
}
|
|
17944
|
+
}
|
|
16776
17945
|
console.log(`[SandboxSkillStore] Loaded ${skills.length} skills for tenant ${tenantId}`);
|
|
16777
17946
|
return skills.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
|
|
16778
17947
|
} catch (error) {
|
|
16779
17948
|
console.error(`[SandboxSkillStore] Error listing skills for tenant ${tenantId}:`, error);
|
|
16780
|
-
return
|
|
17949
|
+
return this._allBuiltInSkills(tenantId);
|
|
16781
17950
|
}
|
|
16782
17951
|
}
|
|
16783
17952
|
/**
|
|
16784
17953
|
* Get skill by ID
|
|
16785
17954
|
*/
|
|
16786
17955
|
async getSkillById(tenantId, id, context) {
|
|
17956
|
+
const builtIn = this._builtInSkill(id, tenantId);
|
|
17957
|
+
if (builtIn) return builtIn;
|
|
16787
17958
|
return this.readSkillFile(tenantId, id, context);
|
|
16788
17959
|
}
|
|
16789
17960
|
/**
|
|
@@ -16791,6 +17962,11 @@ ${body}` : `${frontmatter}
|
|
|
16791
17962
|
*/
|
|
16792
17963
|
async createSkill(tenantId, id, data, context) {
|
|
16793
17964
|
validateSkillName(data.name);
|
|
17965
|
+
if (isBuiltInSkill(data.name)) {
|
|
17966
|
+
throw new Error(
|
|
17967
|
+
`Skill "${data.name}" is a built-in skill and cannot be overwritten`
|
|
17968
|
+
);
|
|
17969
|
+
}
|
|
16794
17970
|
if (id !== data.name) {
|
|
16795
17971
|
throw new Error(
|
|
16796
17972
|
`Skill id "${id}" must equal name "${data.name}" (name is used for path addressing)`
|
|
@@ -16821,6 +17997,11 @@ ${body}` : `${frontmatter}
|
|
|
16821
17997
|
* Update an existing skill
|
|
16822
17998
|
*/
|
|
16823
17999
|
async updateSkill(tenantId, id, updates, context) {
|
|
18000
|
+
if (isBuiltInSkill(id)) {
|
|
18001
|
+
throw new Error(
|
|
18002
|
+
`Skill "${id}" is a built-in skill and cannot be modified`
|
|
18003
|
+
);
|
|
18004
|
+
}
|
|
16824
18005
|
const skill = await this.readSkillFile(tenantId, id, context);
|
|
16825
18006
|
if (!skill) {
|
|
16826
18007
|
return null;
|
|
@@ -16863,6 +18044,11 @@ ${body}` : `${frontmatter}
|
|
|
16863
18044
|
* Delete a skill by ID
|
|
16864
18045
|
*/
|
|
16865
18046
|
async deleteSkill(tenantId, id, context) {
|
|
18047
|
+
if (isBuiltInSkill(id)) {
|
|
18048
|
+
throw new Error(
|
|
18049
|
+
`Skill "${id}" is a built-in skill and cannot be deleted`
|
|
18050
|
+
);
|
|
18051
|
+
}
|
|
16866
18052
|
try {
|
|
16867
18053
|
const sandbox = await this.getSandbox(tenantId, context);
|
|
16868
18054
|
const dirPath = this.getSkillDirectoryPath(tenantId, id);
|
|
@@ -16882,6 +18068,7 @@ ${body}` : `${frontmatter}
|
|
|
16882
18068
|
* Check if skill exists
|
|
16883
18069
|
*/
|
|
16884
18070
|
async hasSkill(tenantId, id, context) {
|
|
18071
|
+
if (isBuiltInSkill(id)) return true;
|
|
16885
18072
|
const skill = await this.getSkillById(tenantId, id, context);
|
|
16886
18073
|
return skill !== null;
|
|
16887
18074
|
}
|
|
@@ -16927,6 +18114,1013 @@ ${body}` : `${frontmatter}
|
|
|
16927
18114
|
}
|
|
16928
18115
|
};
|
|
16929
18116
|
|
|
18117
|
+
// src/agent_lattice/agentArchitectTools.ts
|
|
18118
|
+
var import_zod52 = __toESM(require("zod"));
|
|
18119
|
+
var import_uuid4 = require("uuid");
|
|
18120
|
+
var import_protocols10 = require("@axiom-lattice/protocols");
|
|
18121
|
+
function getTenantId(exeConfig) {
|
|
18122
|
+
const runConfig = exeConfig?.configurable?.runConfig || {};
|
|
18123
|
+
return runConfig.tenantId || "default";
|
|
18124
|
+
}
|
|
18125
|
+
function getAssistStore() {
|
|
18126
|
+
return getStoreLattice("default", "assistant").store;
|
|
18127
|
+
}
|
|
18128
|
+
function slugify(name) {
|
|
18129
|
+
return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").replace(/-+/g, "-") || "agent";
|
|
18130
|
+
}
|
|
18131
|
+
async function generateAgentId(tenantId, name) {
|
|
18132
|
+
const store = getAssistStore();
|
|
18133
|
+
const base = slugify(name);
|
|
18134
|
+
let id = base;
|
|
18135
|
+
let counter = 2;
|
|
18136
|
+
while (true) {
|
|
18137
|
+
const existing = await store.getAssistantById(tenantId, id);
|
|
18138
|
+
if (!existing) return id;
|
|
18139
|
+
id = `${base}-${counter}`;
|
|
18140
|
+
counter++;
|
|
18141
|
+
}
|
|
18142
|
+
}
|
|
18143
|
+
registerToolLattice(
|
|
18144
|
+
"list_agents",
|
|
18145
|
+
{
|
|
18146
|
+
name: "list_agents",
|
|
18147
|
+
description: "List all agents for the current workspace. Returns a summary with id, name, description, and type for each agent.",
|
|
18148
|
+
schema: import_zod52.default.object({})
|
|
18149
|
+
},
|
|
18150
|
+
async (_input, exeConfig) => {
|
|
18151
|
+
try {
|
|
18152
|
+
const tenantId = getTenantId(exeConfig);
|
|
18153
|
+
const store = getAssistStore();
|
|
18154
|
+
const agents = await store.getAllAssistants(tenantId);
|
|
18155
|
+
return JSON.stringify({
|
|
18156
|
+
agents: agents.map((a) => ({
|
|
18157
|
+
id: a.id,
|
|
18158
|
+
name: a.name,
|
|
18159
|
+
description: a.description || "",
|
|
18160
|
+
type: a.graphDefinition?.type || "react",
|
|
18161
|
+
createdAt: a.createdAt,
|
|
18162
|
+
updatedAt: a.updatedAt
|
|
18163
|
+
}))
|
|
18164
|
+
});
|
|
18165
|
+
} catch (error) {
|
|
18166
|
+
return JSON.stringify({ error: `Failed to list agents: ${error.message}` });
|
|
18167
|
+
}
|
|
18168
|
+
}
|
|
18169
|
+
);
|
|
18170
|
+
registerToolLattice(
|
|
18171
|
+
"get_agent",
|
|
18172
|
+
{
|
|
18173
|
+
name: "get_agent",
|
|
18174
|
+
description: "Get the full configuration of a specific agent by its ID. Returns the complete AgentConfig including prompt, middleware, tools, and sub-agents.",
|
|
18175
|
+
schema: import_zod52.default.object({
|
|
18176
|
+
id: import_zod52.default.string().describe("The agent ID to retrieve")
|
|
18177
|
+
})
|
|
18178
|
+
},
|
|
18179
|
+
async (input, exeConfig) => {
|
|
18180
|
+
try {
|
|
18181
|
+
const tenantId = getTenantId(exeConfig);
|
|
18182
|
+
const store = getAssistStore();
|
|
18183
|
+
const agent = await store.getAssistantById(tenantId, input.id);
|
|
18184
|
+
if (!agent) {
|
|
18185
|
+
return JSON.stringify({ error: `Agent '${input.id}' not found` });
|
|
18186
|
+
}
|
|
18187
|
+
return JSON.stringify(agent.graphDefinition);
|
|
18188
|
+
} catch (error) {
|
|
18189
|
+
return JSON.stringify({ error: `Failed to get agent: ${error.message}` });
|
|
18190
|
+
}
|
|
18191
|
+
}
|
|
18192
|
+
);
|
|
18193
|
+
var middlewareConfigSchema = import_zod52.default.object({
|
|
18194
|
+
id: import_zod52.default.string(),
|
|
18195
|
+
type: import_zod52.default.string(),
|
|
18196
|
+
name: import_zod52.default.string(),
|
|
18197
|
+
description: import_zod52.default.string(),
|
|
18198
|
+
enabled: import_zod52.default.boolean(),
|
|
18199
|
+
config: import_zod52.default.record(import_zod52.default.any()).optional()
|
|
18200
|
+
});
|
|
18201
|
+
var createAgentSchema = import_zod52.default.object({
|
|
18202
|
+
name: import_zod52.default.string().describe("Human-friendly display name for the agent. The machine ID (used in other tools) is auto-generated as a slug from this name (e.g. 'My Cool Agent' \u2192 'my-cool-agent')."),
|
|
18203
|
+
description: import_zod52.default.string().optional().describe("Short description"),
|
|
18204
|
+
type: import_zod52.default.enum(["react", "deep_agent"]).describe("Agent type. Use 'react' for simple single-responsibility agents, 'deep_agent' for complex open-ended agents. For PROCESSING agents (workflow orchestration), use create_processing_agent instead."),
|
|
18205
|
+
prompt: import_zod52.default.string().describe("System prompt for the agent"),
|
|
18206
|
+
tools: import_zod52.default.array(import_zod52.default.string()).optional().describe("Tool keys (strings) to assign. Call list_tools first to see available keys. Each element is a plain string like 'sap_api_search'. IMPORTANT: tools is a FLAT string array of tool names. Do NOT put middleware-like objects here \u2014 middleware goes in the separate 'middleware' field."),
|
|
18207
|
+
middleware: import_zod52.default.array(middlewareConfigSchema).optional().describe("Middleware configuration objects. Each has {id, type, name, description, enabled, config}. IMPORTANT: middleware objects are NOT tools. Do NOT put tool keys (strings) here \u2014 tool names go in the separate 'tools' array. For user approval/confirmation scenarios, use type: 'ask_user_to_clarify' with config: {}."),
|
|
18208
|
+
subAgents: import_zod52.default.array(import_zod52.default.string()).optional().describe("Sub-agent IDs (deep_agent only)"),
|
|
18209
|
+
internalSubAgents: import_zod52.default.array(import_zod52.default.any()).optional().describe("Inline sub-agent configs (deep_agent only)"),
|
|
18210
|
+
modelKey: import_zod52.default.string().optional().describe("Model key to use")
|
|
18211
|
+
});
|
|
18212
|
+
registerToolLattice(
|
|
18213
|
+
"create_agent",
|
|
18214
|
+
{
|
|
18215
|
+
name: "create_agent",
|
|
18216
|
+
description: "Create and save a new REACT or DEEP_AGENT. For PROCESSING agents, use create_processing_agent instead. Returns the new agent's ID and name. NOTE: 'tools' is a string array of tool names, 'middleware' is an object array of middleware configs \u2014 they are separate fields and must not be mixed. IMPORTANT: If the agent needs user confirmation, approval, or must ask clarifying questions, include the 'ask_user_to_clarify' middleware (type: 'ask_user_to_clarify', no config required).",
|
|
18217
|
+
schema: createAgentSchema
|
|
18218
|
+
},
|
|
18219
|
+
async (input, exeConfig) => {
|
|
18220
|
+
try {
|
|
18221
|
+
const tenantId = getTenantId(exeConfig);
|
|
18222
|
+
const store = getAssistStore();
|
|
18223
|
+
const id = await generateAgentId(tenantId, input.name);
|
|
18224
|
+
const config = {
|
|
18225
|
+
key: id,
|
|
18226
|
+
name: input.name,
|
|
18227
|
+
description: input.description || "",
|
|
18228
|
+
type: input.type === "deep_agent" ? import_protocols10.AgentType.DEEP_AGENT : import_protocols10.AgentType.REACT,
|
|
18229
|
+
prompt: input.prompt,
|
|
18230
|
+
...input.tools && input.tools.length > 0 ? { tools: input.tools } : {},
|
|
18231
|
+
...input.middleware && input.middleware.length > 0 ? { middleware: input.middleware } : {},
|
|
18232
|
+
...input.subAgents && input.subAgents.length > 0 ? { subAgents: input.subAgents } : {},
|
|
18233
|
+
...input.internalSubAgents ? { internalSubAgents: input.internalSubAgents } : {},
|
|
18234
|
+
...input.modelKey ? { modelKey: input.modelKey } : {}
|
|
18235
|
+
};
|
|
18236
|
+
await store.createAssistant(tenantId, id, {
|
|
18237
|
+
name: input.name,
|
|
18238
|
+
description: input.description,
|
|
18239
|
+
graphDefinition: config
|
|
18240
|
+
});
|
|
18241
|
+
return JSON.stringify({ id, name: input.name, type: input.type });
|
|
18242
|
+
} catch (error) {
|
|
18243
|
+
return JSON.stringify({ error: `Failed to create agent: ${error.message}` });
|
|
18244
|
+
}
|
|
18245
|
+
}
|
|
18246
|
+
);
|
|
18247
|
+
var topologyEdgeSchema = import_zod52.default.object({
|
|
18248
|
+
from: import_zod52.default.string().describe("Source agent ID. For the first edge, this is the orchestrator (use the orchestrator's name as a placeholder \u2014 the tool will replace it with the actual ID). For subsequent chained edges, this is the previous stage's sub-agent ID."),
|
|
18249
|
+
to: import_zod52.default.string().describe("Target agent ID (the sub-agent to delegate to)"),
|
|
18250
|
+
purpose: import_zod52.default.string().describe("Business purpose of this delegation step \u2014 what the sub-agent should accomplish")
|
|
18251
|
+
});
|
|
18252
|
+
var createProcessingAgentSchema = import_zod52.default.object({
|
|
18253
|
+
name: import_zod52.default.string().describe("Display name for the processing agent"),
|
|
18254
|
+
description: import_zod52.default.string().optional().describe("Short description"),
|
|
18255
|
+
prompt: import_zod52.default.string().describe("System prompt for the orchestrator. Should describe how to route tasks through the topology."),
|
|
18256
|
+
edges: import_zod52.default.array(topologyEdgeSchema).min(1).describe("Topology edges defining the workflow. Each edge describes a delegation step with its business purpose. The orchestrator will follow this topology to delegate tasks to sub-agents."),
|
|
18257
|
+
tools: import_zod52.default.array(import_zod52.default.string()).optional().describe("Tool keys (strings) to assign to the orchestrator. Call list_tools first to see available keys. Each element is a plain string like 'sap_api_search'. IMPORTANT: tools is a FLAT string array. Do NOT put middleware-like objects here \u2014 middleware goes in the separate 'middleware' field."),
|
|
18258
|
+
subAgents: import_zod52.default.array(import_zod52.default.string()).describe("IDs of sub-agents that form the workflow pipeline. These must be created first via create_agent."),
|
|
18259
|
+
internalSubAgents: import_zod52.default.array(import_zod52.default.any()).optional().describe("Inline sub-agent configs (alternative to pre-created sub-agents)"),
|
|
18260
|
+
middleware: import_zod52.default.array(middlewareConfigSchema).optional().describe("Additional middleware config objects beyond the auto-managed topology middleware. Each has {id, type, name, description, enabled, config}. IMPORTANT: middleware objects are NOT tools. Do NOT put tool keys (strings) here. For user approval/confirmation scenarios, use type: 'ask_user_to_clarify' with config: {}."),
|
|
18261
|
+
modelKey: import_zod52.default.string().optional().describe("Model key to use")
|
|
18262
|
+
}).refine(
|
|
18263
|
+
(data) => {
|
|
18264
|
+
const edgeTargets = new Set(data.edges.map((e) => e.to));
|
|
18265
|
+
const subAgentIds = new Set(data.subAgents);
|
|
18266
|
+
for (const target of edgeTargets) {
|
|
18267
|
+
if (!subAgentIds.has(target)) {
|
|
18268
|
+
return false;
|
|
18269
|
+
}
|
|
18270
|
+
}
|
|
18271
|
+
return true;
|
|
18272
|
+
},
|
|
18273
|
+
{ message: "All edge targets (to) must be included in the subAgents list" }
|
|
18274
|
+
);
|
|
18275
|
+
registerToolLattice(
|
|
18276
|
+
"create_processing_agent",
|
|
18277
|
+
{
|
|
18278
|
+
name: "create_processing_agent",
|
|
18279
|
+
description: "Create a PROCESSING agent with a business-defined workflow topology. The edges define a serial delegation chain: the first edge starts from the orchestrator (use its name as placeholder), then each subsequent edge chains from the previous stage's sub-agent. Sub-agents must be created first via create_agent. NOTE: 'tools' is a string array of tool names, 'middleware' is an object array \u2014 they are separate fields and must not be mixed. IMPORTANT: If any sub-agent or the orchestrator needs user confirmation/approval, include the 'ask_user_to_clarify' middleware on that specific agent.",
|
|
18280
|
+
schema: createProcessingAgentSchema
|
|
18281
|
+
},
|
|
18282
|
+
async (input, exeConfig) => {
|
|
18283
|
+
try {
|
|
18284
|
+
const tenantId = getTenantId(exeConfig);
|
|
18285
|
+
const store = getAssistStore();
|
|
18286
|
+
const id = await generateAgentId(tenantId, input.name);
|
|
18287
|
+
const normalize = (s) => s.toLowerCase().replace(/[_\-\s]/g, "");
|
|
18288
|
+
const resolveFrom = (rawFrom) => {
|
|
18289
|
+
const fromLower = rawFrom.toLowerCase();
|
|
18290
|
+
const nameLower = input.name.toLowerCase();
|
|
18291
|
+
if (fromLower === nameLower || fromLower === "orchestrator" || fromLower === "orchestrator-id" || normalize(rawFrom) === normalize(input.name)) {
|
|
18292
|
+
return id;
|
|
18293
|
+
}
|
|
18294
|
+
return rawFrom;
|
|
18295
|
+
};
|
|
18296
|
+
const topologyMiddleware = {
|
|
18297
|
+
id: "topology",
|
|
18298
|
+
type: "topology",
|
|
18299
|
+
name: "Topology",
|
|
18300
|
+
description: `Enforce ${input.edges.length}-step workflow topology`,
|
|
18301
|
+
enabled: true,
|
|
18302
|
+
config: {
|
|
18303
|
+
edges: input.edges.map((e) => ({
|
|
18304
|
+
from: resolveFrom(e.from),
|
|
18305
|
+
to: e.to,
|
|
18306
|
+
purpose: e.purpose
|
|
18307
|
+
}))
|
|
18308
|
+
}
|
|
18309
|
+
};
|
|
18310
|
+
const additionalMiddleware = input.middleware || [];
|
|
18311
|
+
const middleware = [topologyMiddleware, ...additionalMiddleware];
|
|
18312
|
+
const config = {
|
|
18313
|
+
key: id,
|
|
18314
|
+
name: input.name,
|
|
18315
|
+
description: input.description || "",
|
|
18316
|
+
type: import_protocols10.AgentType.PROCESSING,
|
|
18317
|
+
prompt: input.prompt,
|
|
18318
|
+
...input.tools && input.tools.length > 0 ? { tools: input.tools } : {},
|
|
18319
|
+
middleware,
|
|
18320
|
+
subAgents: input.subAgents,
|
|
18321
|
+
...input.internalSubAgents ? { internalSubAgents: input.internalSubAgents } : {},
|
|
18322
|
+
...input.modelKey ? { modelKey: input.modelKey } : {}
|
|
18323
|
+
};
|
|
18324
|
+
await store.createAssistant(tenantId, id, {
|
|
18325
|
+
name: input.name,
|
|
18326
|
+
description: input.description,
|
|
18327
|
+
graphDefinition: config
|
|
18328
|
+
});
|
|
18329
|
+
return JSON.stringify({
|
|
18330
|
+
id,
|
|
18331
|
+
name: input.name,
|
|
18332
|
+
type: "processing",
|
|
18333
|
+
topology: {
|
|
18334
|
+
edges: input.edges.map((e) => ({ from: resolveFrom(e.from), to: e.to, purpose: e.purpose }))
|
|
18335
|
+
}
|
|
18336
|
+
});
|
|
18337
|
+
} catch (error) {
|
|
18338
|
+
return JSON.stringify({ error: `Failed to create processing agent: ${error.message}` });
|
|
18339
|
+
}
|
|
18340
|
+
}
|
|
18341
|
+
);
|
|
18342
|
+
var updateProcessingAgentSchema = import_zod52.default.object({
|
|
18343
|
+
id: import_zod52.default.string().describe("The PROCESSING agent ID to update"),
|
|
18344
|
+
name: import_zod52.default.string().optional().describe("New display name for the orchestrator"),
|
|
18345
|
+
description: import_zod52.default.string().optional().describe("New short description"),
|
|
18346
|
+
prompt: import_zod52.default.string().optional().describe("New system prompt for the orchestrator"),
|
|
18347
|
+
edges: import_zod52.default.array(topologyEdgeSchema).min(1).optional().describe("New topology edges. First edge's from must reference the orchestrator by name (the tool replaces it). Subsequent edges chain from previous sub-agent IDs."),
|
|
18348
|
+
tools: import_zod52.default.array(import_zod52.default.string()).optional().describe("Tool keys (strings) to assign to the orchestrator. Each element is a plain string like 'sap_api_search'. IMPORTANT: tools is a FLAT string array \u2014 do NOT put middleware-like objects here."),
|
|
18349
|
+
subAgents: import_zod52.default.array(import_zod52.default.string()).optional().describe("New IDs of sub-agents in the workflow pipeline"),
|
|
18350
|
+
middleware: import_zod52.default.array(middlewareConfigSchema).optional().describe("Additional middleware config objects (topology middleware is auto-managed, do not include it). Each has {id, type, name, description, enabled, config}. IMPORTANT: middleware objects are NOT tools. Do NOT put tool keys (strings) here. For user approval/confirmation scenarios, use type: 'ask_user_to_clarify' with config: {}."),
|
|
18351
|
+
modelKey: import_zod52.default.string().optional().describe("New model key")
|
|
18352
|
+
}).refine(
|
|
18353
|
+
(data) => {
|
|
18354
|
+
if (!data.edges) return true;
|
|
18355
|
+
const subAgentIds = new Set(data.subAgents || []);
|
|
18356
|
+
if (subAgentIds.size === 0) return true;
|
|
18357
|
+
const edgeTargets = new Set(data.edges.map((e) => e.to));
|
|
18358
|
+
for (const target of edgeTargets) {
|
|
18359
|
+
if (!subAgentIds.has(target)) {
|
|
18360
|
+
return false;
|
|
18361
|
+
}
|
|
18362
|
+
}
|
|
18363
|
+
return true;
|
|
18364
|
+
},
|
|
18365
|
+
{ message: "All edge targets (to) must be included in the subAgents list" }
|
|
18366
|
+
);
|
|
18367
|
+
registerToolLattice(
|
|
18368
|
+
"update_processing_agent",
|
|
18369
|
+
{
|
|
18370
|
+
name: "update_processing_agent",
|
|
18371
|
+
description: "Update an existing PROCESSING agent's topology edges, name, prompt, tools, or sub-agents. Use this instead of update_agent for PROCESSING agents because edges require proper placeholder resolution and topology middleware management. NOTE: 'tools' is a string array of tool names, 'middleware' is an object array \u2014 they are separate fields and must not be mixed. For user approval/confirmation scenarios, add middleware with type: 'ask_user_to_clarify'.",
|
|
18372
|
+
schema: updateProcessingAgentSchema
|
|
18373
|
+
},
|
|
18374
|
+
async (input, exeConfig) => {
|
|
18375
|
+
try {
|
|
18376
|
+
const tenantId = getTenantId(exeConfig);
|
|
18377
|
+
const store = getAssistStore();
|
|
18378
|
+
const existing = await store.getAssistantById(tenantId, input.id);
|
|
18379
|
+
if (!existing) {
|
|
18380
|
+
return JSON.stringify({ error: `Agent '${input.id}' not found` });
|
|
18381
|
+
}
|
|
18382
|
+
const existingConfig = existing.graphDefinition || {};
|
|
18383
|
+
if (existingConfig.type !== import_protocols10.AgentType.PROCESSING) {
|
|
18384
|
+
return JSON.stringify({ error: `Agent '${input.id}' is not a PROCESSING agent (type: ${existingConfig.type})` });
|
|
18385
|
+
}
|
|
18386
|
+
const normalize = (s) => s.toLowerCase().replace(/[_\-\s]/g, "");
|
|
18387
|
+
const orchestratorName = input.name || existingConfig.name || existing.name || "";
|
|
18388
|
+
const resolveFrom = (rawFrom) => {
|
|
18389
|
+
const fromLower = rawFrom.toLowerCase();
|
|
18390
|
+
const nameLower = orchestratorName.toLowerCase();
|
|
18391
|
+
if (fromLower === nameLower || fromLower === "orchestrator" || fromLower === "orchestrator-id" || normalize(rawFrom) === normalize(orchestratorName)) {
|
|
18392
|
+
return input.id;
|
|
18393
|
+
}
|
|
18394
|
+
return rawFrom;
|
|
18395
|
+
};
|
|
18396
|
+
let middleware = existingConfig.middleware || [];
|
|
18397
|
+
let resolvedEdges;
|
|
18398
|
+
if (input.edges) {
|
|
18399
|
+
resolvedEdges = input.edges.map((e) => ({
|
|
18400
|
+
from: resolveFrom(e.from),
|
|
18401
|
+
to: e.to,
|
|
18402
|
+
purpose: e.purpose
|
|
18403
|
+
}));
|
|
18404
|
+
const topoIndex = middleware.findIndex(
|
|
18405
|
+
(m) => m.type === "topology"
|
|
18406
|
+
);
|
|
18407
|
+
const topoMiddleware = {
|
|
18408
|
+
id: "topology",
|
|
18409
|
+
type: "topology",
|
|
18410
|
+
name: "Topology",
|
|
18411
|
+
description: `Enforce ${resolvedEdges.length}-step workflow topology`,
|
|
18412
|
+
enabled: true,
|
|
18413
|
+
config: { edges: resolvedEdges }
|
|
18414
|
+
};
|
|
18415
|
+
if (topoIndex >= 0) {
|
|
18416
|
+
middleware = [...middleware];
|
|
18417
|
+
middleware[topoIndex] = topoMiddleware;
|
|
18418
|
+
} else {
|
|
18419
|
+
middleware = [topoMiddleware, ...middleware];
|
|
18420
|
+
}
|
|
18421
|
+
if (input.middleware) {
|
|
18422
|
+
const nonTopo = input.middleware.filter(
|
|
18423
|
+
(m) => m.type !== "topology"
|
|
18424
|
+
);
|
|
18425
|
+
const topoIdx = middleware.findIndex(
|
|
18426
|
+
(m) => m.type === "topology"
|
|
18427
|
+
);
|
|
18428
|
+
const prefix = middleware.slice(0, topoIdx + 1);
|
|
18429
|
+
const suffix = middleware.slice(topoIdx + 1);
|
|
18430
|
+
middleware = [...prefix, ...nonTopo];
|
|
18431
|
+
}
|
|
18432
|
+
} else if (input.middleware) {
|
|
18433
|
+
const nonTopo = input.middleware.filter(
|
|
18434
|
+
(m) => m.type !== "topology"
|
|
18435
|
+
);
|
|
18436
|
+
const topoIdx = middleware.findIndex(
|
|
18437
|
+
(m) => m.type === "topology"
|
|
18438
|
+
);
|
|
18439
|
+
if (topoIdx >= 0) {
|
|
18440
|
+
middleware = [...middleware.slice(0, topoIdx + 1), ...nonTopo];
|
|
18441
|
+
} else {
|
|
18442
|
+
middleware = [...middleware, ...nonTopo];
|
|
18443
|
+
}
|
|
18444
|
+
}
|
|
18445
|
+
const mergedConfig = {
|
|
18446
|
+
...existingConfig,
|
|
18447
|
+
...input.name !== void 0 ? { name: input.name } : {},
|
|
18448
|
+
...input.description !== void 0 ? { description: input.description } : {},
|
|
18449
|
+
...input.prompt !== void 0 ? { prompt: input.prompt } : {},
|
|
18450
|
+
...input.tools !== void 0 ? { tools: input.tools } : {},
|
|
18451
|
+
...input.subAgents !== void 0 ? { subAgents: input.subAgents } : {},
|
|
18452
|
+
...input.modelKey !== void 0 ? { modelKey: input.modelKey } : {},
|
|
18453
|
+
middleware,
|
|
18454
|
+
key: input.id
|
|
18455
|
+
};
|
|
18456
|
+
const newName = input.name || existing.name;
|
|
18457
|
+
await store.updateAssistant(tenantId, input.id, {
|
|
18458
|
+
name: newName,
|
|
18459
|
+
description: input.description !== void 0 ? input.description : existing.description,
|
|
18460
|
+
graphDefinition: mergedConfig
|
|
18461
|
+
});
|
|
18462
|
+
const topoConfig = middleware.find(
|
|
18463
|
+
(m) => m.type === "topology"
|
|
18464
|
+
);
|
|
18465
|
+
return JSON.stringify({
|
|
18466
|
+
id: input.id,
|
|
18467
|
+
name: newName,
|
|
18468
|
+
type: "processing",
|
|
18469
|
+
topology: {
|
|
18470
|
+
edges: topoConfig?.config?.edges || resolvedEdges || []
|
|
18471
|
+
}
|
|
18472
|
+
});
|
|
18473
|
+
} catch (error) {
|
|
18474
|
+
return JSON.stringify({ error: `Failed to update processing agent: ${error.message}` });
|
|
18475
|
+
}
|
|
18476
|
+
}
|
|
18477
|
+
);
|
|
18478
|
+
var updateAgentSchema = import_zod52.default.object({
|
|
18479
|
+
id: import_zod52.default.string().describe("The agent ID to update"),
|
|
18480
|
+
config: import_zod52.default.object({
|
|
18481
|
+
name: import_zod52.default.string().optional().describe("New display name for the agent"),
|
|
18482
|
+
description: import_zod52.default.string().optional().describe("New short description"),
|
|
18483
|
+
type: import_zod52.default.enum(["react", "deep_agent"]).optional().describe("Agent type"),
|
|
18484
|
+
prompt: import_zod52.default.string().optional().describe("New system prompt for the agent"),
|
|
18485
|
+
tools: import_zod52.default.array(import_zod52.default.string()).optional().describe("Tool keys to assign to this agent. These are registered tool names (strings), NOT middleware objects."),
|
|
18486
|
+
middleware: import_zod52.default.array(middlewareConfigSchema).optional().describe("Middleware configurations. NOTE: middleware objects have type/name/description/enabled/config fields and are NOT the same as tools. Tool keys go in the 'tools' array. For user approval/confirmation scenarios, use type: 'ask_user_to_clarify' with config: {}."),
|
|
18487
|
+
subAgents: import_zod52.default.array(import_zod52.default.string()).optional().describe("Sub-agent IDs (deep_agent only)"),
|
|
18488
|
+
internalSubAgents: import_zod52.default.array(import_zod52.default.any()).optional().describe("Inline sub-agent configs (deep_agent only)"),
|
|
18489
|
+
modelKey: import_zod52.default.string().optional().describe("Model key to use")
|
|
18490
|
+
}).describe("Configuration fields to update. Only include the fields you want to change.")
|
|
18491
|
+
});
|
|
18492
|
+
registerToolLattice(
|
|
18493
|
+
"update_agent",
|
|
18494
|
+
{
|
|
18495
|
+
name: "update_agent",
|
|
18496
|
+
description: "Update an existing agent's configuration. Provide the agent ID and the fields to change. Returns the updated agent's ID and name. NOTE: For user approval/confirmation scenarios, add middleware with type: 'ask_user_to_clarify'.",
|
|
18497
|
+
schema: updateAgentSchema
|
|
18498
|
+
},
|
|
18499
|
+
async (input, exeConfig) => {
|
|
18500
|
+
try {
|
|
18501
|
+
const tenantId = getTenantId(exeConfig);
|
|
18502
|
+
const store = getAssistStore();
|
|
18503
|
+
const existing = await store.getAssistantById(tenantId, input.id);
|
|
18504
|
+
if (!existing) {
|
|
18505
|
+
return JSON.stringify({ error: `Agent '${input.id}' not found` });
|
|
18506
|
+
}
|
|
18507
|
+
const existingConfig = existing.graphDefinition || {};
|
|
18508
|
+
const mergedConfig = { ...existingConfig, ...input.config };
|
|
18509
|
+
const newName = input.config.name || existing.name;
|
|
18510
|
+
await store.updateAssistant(tenantId, input.id, {
|
|
18511
|
+
name: newName,
|
|
18512
|
+
description: input.config.description !== void 0 ? input.config.description : existing.description,
|
|
18513
|
+
graphDefinition: mergedConfig
|
|
18514
|
+
});
|
|
18515
|
+
return JSON.stringify({ id: input.id, name: newName });
|
|
18516
|
+
} catch (error) {
|
|
18517
|
+
return JSON.stringify({ error: `Failed to update agent: ${error.message}` });
|
|
18518
|
+
}
|
|
18519
|
+
}
|
|
18520
|
+
);
|
|
18521
|
+
registerToolLattice(
|
|
18522
|
+
"delete_agent",
|
|
18523
|
+
{
|
|
18524
|
+
name: "delete_agent",
|
|
18525
|
+
description: "Permanently delete an agent by its ID. This action cannot be undone.",
|
|
18526
|
+
schema: import_zod52.default.object({
|
|
18527
|
+
id: import_zod52.default.string().describe("The agent ID to delete")
|
|
18528
|
+
})
|
|
18529
|
+
},
|
|
18530
|
+
async (input, exeConfig) => {
|
|
18531
|
+
try {
|
|
18532
|
+
const tenantId = getTenantId(exeConfig);
|
|
18533
|
+
const store = getAssistStore();
|
|
18534
|
+
const existing = await store.getAssistantById(tenantId, input.id);
|
|
18535
|
+
if (!existing) {
|
|
18536
|
+
return JSON.stringify({ error: `Agent '${input.id}' not found`, success: false });
|
|
18537
|
+
}
|
|
18538
|
+
const success = await store.deleteAssistant(tenantId, input.id);
|
|
18539
|
+
return JSON.stringify({ success, id: input.id });
|
|
18540
|
+
} catch (error) {
|
|
18541
|
+
return JSON.stringify({ error: `Failed to delete agent: ${error.message}` });
|
|
18542
|
+
}
|
|
18543
|
+
}
|
|
18544
|
+
);
|
|
18545
|
+
registerToolLattice(
|
|
18546
|
+
"list_tools",
|
|
18547
|
+
{
|
|
18548
|
+
name: "list_tools",
|
|
18549
|
+
description: "List all available tools that can be assigned to agents. Returns each tool's name (use this string value in the 'tools' array), description, and whether it requires user approval. The tool names from this list are what you pass as strings in the 'tools' field of create_agent or update_agent.",
|
|
18550
|
+
schema: import_zod52.default.object({})
|
|
18551
|
+
},
|
|
18552
|
+
async (_input, _exeConfig) => {
|
|
18553
|
+
try {
|
|
18554
|
+
const lattices = toolLatticeManager.getAllLattices();
|
|
18555
|
+
return JSON.stringify({
|
|
18556
|
+
tools: lattices.map((l) => ({
|
|
18557
|
+
name: l.config.name,
|
|
18558
|
+
description: l.config.description,
|
|
18559
|
+
needUserApprove: l.config.needUserApprove ?? false
|
|
18560
|
+
}))
|
|
18561
|
+
});
|
|
18562
|
+
} catch (error) {
|
|
18563
|
+
return JSON.stringify({ error: `Failed to list tools: ${error.message}` });
|
|
18564
|
+
}
|
|
18565
|
+
}
|
|
18566
|
+
);
|
|
18567
|
+
registerToolLattice(
|
|
18568
|
+
"invoke_agent",
|
|
18569
|
+
{
|
|
18570
|
+
name: "invoke_agent",
|
|
18571
|
+
description: "Invoke an agent with a test message and return its response. Use this to verify an agent works correctly after creating or modifying it. The agent must be compiled (already created and valid).",
|
|
18572
|
+
schema: import_zod52.default.object({
|
|
18573
|
+
id: import_zod52.default.string().describe("The agent ID to invoke"),
|
|
18574
|
+
message: import_zod52.default.string().describe("The test message to send to the agent")
|
|
18575
|
+
})
|
|
18576
|
+
},
|
|
18577
|
+
async (input, exeConfig) => {
|
|
18578
|
+
try {
|
|
18579
|
+
const tenantId = getTenantId(exeConfig);
|
|
18580
|
+
const { id, message } = input;
|
|
18581
|
+
const store = getAssistStore();
|
|
18582
|
+
const existing = await store.getAssistantById(tenantId, id);
|
|
18583
|
+
if (!existing) {
|
|
18584
|
+
return JSON.stringify({ error: `Agent '${id}' not found` });
|
|
18585
|
+
}
|
|
18586
|
+
const threadId = (0, import_uuid4.v4)();
|
|
18587
|
+
const agent = new Agent({
|
|
18588
|
+
tenant_id: tenantId,
|
|
18589
|
+
assistant_id: id,
|
|
18590
|
+
thread_id: threadId
|
|
18591
|
+
});
|
|
18592
|
+
const result = await agent.invoke({ input: { message } });
|
|
18593
|
+
const messages = result?.messages || [];
|
|
18594
|
+
const lastAi = [...messages].reverse().find(
|
|
18595
|
+
(m) => m.role === "ai" || m.type === "ai"
|
|
18596
|
+
);
|
|
18597
|
+
const content = lastAi?.content ?? "(no response)";
|
|
18598
|
+
return JSON.stringify({
|
|
18599
|
+
agentId: id,
|
|
18600
|
+
threadId,
|
|
18601
|
+
response: typeof content === "string" ? content : JSON.stringify(content)
|
|
18602
|
+
});
|
|
18603
|
+
} catch (error) {
|
|
18604
|
+
return JSON.stringify({ error: `Failed to invoke agent: ${error.message}` });
|
|
18605
|
+
}
|
|
18606
|
+
}
|
|
18607
|
+
);
|
|
18608
|
+
|
|
18609
|
+
// src/agent_lattice/agentArchitectConfig.ts
|
|
18610
|
+
var import_protocols11 = require("@axiom-lattice/protocols");
|
|
18611
|
+
|
|
18612
|
+
// src/agent_lattice/agentArchitectPrompt.ts
|
|
18613
|
+
var AGENT_ARCHITECT_PROMPT = `# Agent Architect
|
|
18614
|
+
|
|
18615
|
+
You are an **Agent Architect** \u2014 an expert AI system designer. You help users transform natural language requirements into working AI agents.
|
|
18616
|
+
|
|
18617
|
+
## Your Tools
|
|
18618
|
+
|
|
18619
|
+
You have nine tools:
|
|
18620
|
+
- **list_agents** \u2014 See all existing agents for this workspace
|
|
18621
|
+
- **list_tools** \u2014 See all available tools that can be assigned to agents
|
|
18622
|
+
- **get_agent** \u2014 View the full configuration of a specific agent
|
|
18623
|
+
- **create_agent** \u2014 Create a REACT or DEEP_AGENT agent
|
|
18624
|
+
- **create_processing_agent** \u2014 Create a PROCESSING agent with business-defined workflow topology
|
|
18625
|
+
- **update_processing_agent** \u2014 Modify a PROCESSING agent's topology edges, name, prompt, or sub-agents
|
|
18626
|
+
- **update_agent** \u2014 Modify an existing REACT or DEEP_AGENT agent's configuration
|
|
18627
|
+
- **delete_agent** \u2014 Remove an agent permanently
|
|
18628
|
+
- **invoke_agent** \u2014 Test an agent by sending a message and getting its response
|
|
18629
|
+
|
|
18630
|
+
## Global Interaction Rules
|
|
18631
|
+
|
|
18632
|
+
1. **One question at a time.** Never overwhelm the user. Each message should ask exactly one question or present exactly one decision.
|
|
18633
|
+
2. **Confirm before creating.** Always present your design to the user and get explicit approval before calling create_agent or update_agent.
|
|
18634
|
+
3. **Be concise.** Show configs clearly but briefly. Use structured formats when presenting designs.
|
|
18635
|
+
4. **Use kebab-case for agent names.** E.g., "code-reviewer", "data-analyzer".
|
|
18636
|
+
|
|
18637
|
+
---
|
|
18638
|
+
|
|
18639
|
+
## Agent Types Overview
|
|
18640
|
+
|
|
18641
|
+
| Type | Best for | Execution Model |
|
|
18642
|
+
|------|----------|----------------|
|
|
18643
|
+
| **react** | Simple, single-responsibility tasks | Classic ReAct loop (think \u2192 act \u2192 observe) |
|
|
18644
|
+
| **processing** | Standard BPO workflows, preset process orchestration | Topology-driven: predefined agent topology with reliable multi-agent coordination |
|
|
18645
|
+
| **deep_agent** | Complex, open-ended tasks requiring dynamic decomposition | Self-generating dynamic todos: agent analyzes the task and creates its own execution plan at runtime |
|
|
18646
|
+
|
|
18647
|
+
---
|
|
18648
|
+
|
|
18649
|
+
## Workflow A: Simple Agent (REACT type)
|
|
18650
|
+
|
|
18651
|
+
Use this for straightforward tasks \u2014 a single agent with a single responsibility, no sub-agent decomposition needed. The classic ReAct pattern: the agent reasons, acts, and observes in a loop.
|
|
18652
|
+
|
|
18653
|
+
### Step 1: Understand the Goal
|
|
18654
|
+
Ask: What should this agent do? Who will use it? What are the inputs and outputs?
|
|
18655
|
+
|
|
18656
|
+
### Step 2: Choose Middleware
|
|
18657
|
+
Based on the goal, recommend which middleware the agent needs. Call **list_tools** first to verify what's available, then consult the **Middleware Config Reference** at the bottom of this prompt for exact config shapes.
|
|
18658
|
+
|
|
18659
|
+
**IMPORTANT:** If the agent needs user confirmation, approval, or must ask the user clarifying questions, you MUST include the **ask_user_to_clarify** middleware. Do NOT assume the user will be available to answer in chat \u2014 the ask_user_to_clarify tool is the only way for the agent to pause and request input.
|
|
18660
|
+
|
|
18661
|
+
### Step 3: Write the System Prompt
|
|
18662
|
+
Craft the agent's system prompt with:
|
|
18663
|
+
1. **Role definition** \u2014 Who the agent is and what it does
|
|
18664
|
+
2. **Workflow** \u2014 Step-by-step instructions
|
|
18665
|
+
3. **Constraints** \u2014 Boundaries, quality standards, forbidden actions
|
|
18666
|
+
|
|
18667
|
+
Present the prompt. Get user confirmation.
|
|
18668
|
+
|
|
18669
|
+
### Step 4: Create
|
|
18670
|
+
Call create_agent with the agreed configuration.
|
|
18671
|
+
|
|
18672
|
+
---
|
|
18673
|
+
|
|
18674
|
+
## Workflow B: Workflow Agent (PROCESSING type)
|
|
18675
|
+
|
|
18676
|
+
Use this when the task follows a standard BPO (Business Process Orchestration) pattern \u2014 a predefined topology of sub-agents working through a preset pipeline or process. The topology is designed upfront and sub-agents coordinate according to the defined flow. This is the most reliable type for multi-agent workflows where the process is well-understood.
|
|
18677
|
+
|
|
18678
|
+
### Phase 1: Process Analysis
|
|
18679
|
+
|
|
18680
|
+
Ask: What is the end-to-end process we need to automate? What are the stages?
|
|
18681
|
+
|
|
18682
|
+
Based on the answer, identify the processing stages. Output a **pipeline**:
|
|
18683
|
+
|
|
18684
|
+
\`\`\`
|
|
18685
|
+
I see the following processing stages:
|
|
18686
|
+
\u251C\u2500\u2500 Input Intake: [what happens]
|
|
18687
|
+
\u251C\u2500\u2500 Stage 1: [processing step]
|
|
18688
|
+
\u251C\u2500\u2500 Stage 2: [processing step]
|
|
18689
|
+
\u2514\u2500\u2500 Output: [final deliverable]
|
|
18690
|
+
|
|
18691
|
+
Do these stages look right?
|
|
18692
|
+
\`\`\`
|
|
18693
|
+
|
|
18694
|
+
### Phase 2: Topology Design
|
|
18695
|
+
|
|
18696
|
+
Define the agent topology. Each stage may be handled by a dedicated sub-agent. Create a **topology diagram**:
|
|
18697
|
+
|
|
18698
|
+
\`\`\`
|
|
18699
|
+
\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250C\u2500\u2500\u2500\u2500\u2510 \u250C\u2500\u2500\u2500\u2500\u2510 \u250C\u2500\u2500\u2500\u2500\u2510
|
|
18700
|
+
\u2502 Orchestrator \u2502 \u2500\u2500\u25BA \u2502Stage\u2502 \u2500\u2500\u25BA \u2502Stage\u2502 \u2500\u2500\u25BA \u2502Stage\u2502
|
|
18701
|
+
\u2502 \u2502 \u2502 1 \u2502 \u2502 2 \u2502 \u2502 3 \u2502
|
|
18702
|
+
\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2518
|
|
18703
|
+
|
|
18704
|
+
Flow: Orchestrator \u2192 Stage 1 \u2192 Stage 2 \u2192 Stage 3 \u2192 Output
|
|
18705
|
+
|
|
18706
|
+
Each edge chains from the previous node:
|
|
18707
|
+
Orchestrator \u2500\u2500\u25BA Stage 1 \u2500\u2500\u25BA Stage 2 \u2500\u2500\u25BA Stage 3
|
|
18708
|
+
\`\`\`
|
|
18709
|
+
|
|
18710
|
+
**Design checks:**
|
|
18711
|
+
- Each stage has exactly one responsibility
|
|
18712
|
+
- The flow between stages is a serial chain \u2014 each stage processes output from the previous one
|
|
18713
|
+
- The orchestrator directs the first stage, then each stage hands off to the next
|
|
18714
|
+
- The orchestrator enforces the topology \u2014 it does NOT improvise
|
|
18715
|
+
- Error handling per stage: retry, skip, or escalate
|
|
18716
|
+
|
|
18717
|
+
### Phase 3: Design Each Sub-Agent
|
|
18718
|
+
|
|
18719
|
+
For each sub-agent, one at a time:
|
|
18720
|
+
|
|
18721
|
+
1. **Responsibility** \u2014 One sentence
|
|
18722
|
+
2. **System Prompt** \u2014 Role + workflow + constraints
|
|
18723
|
+
3. **Middleware** \u2014 Which middleware, and why (include ask_user_to_clarify if this sub-agent needs user approval)
|
|
18724
|
+
4. **Input/Output contract** \u2014 What it receives, what it returns
|
|
18725
|
+
|
|
18726
|
+
Present each sub-agent design. Get user confirmation before moving to the next.
|
|
18727
|
+
|
|
18728
|
+
### Phase 4: Design the Orchestrator
|
|
18729
|
+
|
|
18730
|
+
The orchestrator is the parent PROCESSING agent. Use **create_processing_agent** (NOT create_agent):
|
|
18731
|
+
|
|
18732
|
+
1. **Responsibility** \u2014 Receive user request, route through the pipeline stages, enforce topology
|
|
18733
|
+
2. **System Prompt** \u2014 The defined topology, when to call which sub-agent, error handling
|
|
18734
|
+
3. **Topology edges** \u2014 One edge per pipeline stage with a business-meaningful purpose
|
|
18735
|
+
4. **Sub-agent list** \u2014 All sub-agents with their role in the pipeline
|
|
18736
|
+
|
|
18737
|
+
### Phase 5: Final Review
|
|
18738
|
+
|
|
18739
|
+
Before creating, check:
|
|
18740
|
+
1. **Completeness** \u2014 Is every stage of the process covered by an edge?
|
|
18741
|
+
2. **Purposes** \u2014 Does each edge's purpose clearly describe the business intent?
|
|
18742
|
+
3. **Order** \u2014 Is the edge sequence correct?
|
|
18743
|
+
4. **Handoffs** \u2014 Is data passed correctly between stages?
|
|
18744
|
+
5. **Edge cases** \u2014 What happens on invalid input, stage failure, timeout?
|
|
18745
|
+
|
|
18746
|
+
### Creation Order
|
|
18747
|
+
|
|
18748
|
+
Always create sub-agents FIRST (via create_agent as react agents), then the orchestrator via create_processing_agent.
|
|
18749
|
+
|
|
18750
|
+
\`\`\`
|
|
18751
|
+
Creating:
|
|
18752
|
+
1. create_agent(name: "stage-1", type: "react", ...)
|
|
18753
|
+
2. create_agent(name: "stage-2", type: "react", ...)
|
|
18754
|
+
3. create_agent(name: "stage-3", type: "react", ...)
|
|
18755
|
+
4. create_processing_agent(
|
|
18756
|
+
name: "orchestrator",
|
|
18757
|
+
prompt: "...",
|
|
18758
|
+
edges: [
|
|
18759
|
+
{ from: "orchestrator", to: "stage-1-id", purpose: "Validate and normalize input data" },
|
|
18760
|
+
{ from: "stage-1-id", to: "stage-2-id", purpose: "Transform data into target format" },
|
|
18761
|
+
{ from: "stage-2-id", to: "stage-3-id", purpose: "Generate final output report" },
|
|
18762
|
+
],
|
|
18763
|
+
subAgents: ["stage-1-id", "stage-2-id", "stage-3-id"],
|
|
18764
|
+
)
|
|
18765
|
+
\`\`\`
|
|
18766
|
+
|
|
18767
|
+
**Why serial?** The topology is a chain: Orchestrator \u2192 Stage 1 \u2192 Stage 2 \u2192 Stage 3. Only the first edge's \`from\` references the orchestrator (by name). Subsequent edges chain from the previous sub-agent's ID. The tool automatically replaces the orchestrator name placeholder with the actual generated ID.
|
|
18768
|
+
|
|
18769
|
+
---
|
|
18770
|
+
|
|
18771
|
+
## Workflow C: Dynamic Agent (DEEP_AGENT type)
|
|
18772
|
+
|
|
18773
|
+
Use this for complex, open-ended tasks where the execution path cannot be fully predetermined. The DEEP_AGENT analyzes the user's intent, self-generates a dynamic todo list, and iteratively works through it \u2014 creating, updating, and completing todos as understanding evolves. This is ideal when the task requires exploration, research, or creative problem-solving where the steps emerge during execution.
|
|
18774
|
+
|
|
18775
|
+
### Phase 1: Domain Analysis
|
|
18776
|
+
|
|
18777
|
+
Ask: What is the overall goal? What makes this complex or open-ended?
|
|
18778
|
+
|
|
18779
|
+
Explain why a DEEP_AGENT is the right choice (dynamic decomposition, exploration-driven, adaptive planning).
|
|
18780
|
+
|
|
18781
|
+
### Phase 2: Identify Capabilities
|
|
18782
|
+
|
|
18783
|
+
Instead of designing a fixed topology, identify what capabilities the agent needs:
|
|
18784
|
+
|
|
18785
|
+
\`\`\`
|
|
18786
|
+
The agent will need:
|
|
18787
|
+
\u251C\u2500\u2500 Capability A: [what the agent must be able to do]
|
|
18788
|
+
\u251C\u2500\u2500 Capability B: [what the agent must be able to do]
|
|
18789
|
+
\u2514\u2500\u2500 Capability C: [what the agent must be able to do]
|
|
18790
|
+
\`\`\`
|
|
18791
|
+
|
|
18792
|
+
Each capability maps to middleware or a sub-agent tool.
|
|
18793
|
+
|
|
18794
|
+
### Phase 3: Design the Agent
|
|
18795
|
+
|
|
18796
|
+
1. **System Prompt** \u2014 Emphasize the dynamic todo-driven workflow. The agent should:
|
|
18797
|
+
- Analyze the user's request and break it into a todo list
|
|
18798
|
+
- Work through todos one at a time
|
|
18799
|
+
- Update and refine the todo list as understanding deepens
|
|
18800
|
+
- Self-correct and adapt based on intermediate findings
|
|
18801
|
+
|
|
18802
|
+
2. **Middleware** \u2014 Tools the agent needs:
|
|
18803
|
+
- **filesystem** \u2014 Essential for persistent work
|
|
18804
|
+
- **code_eval** \u2014 If computation or data analysis is needed
|
|
18805
|
+
- **browser** \u2014 If research or web access is needed
|
|
18806
|
+
- **skill** \u2014 If domain-specific workflows are available
|
|
18807
|
+
- **widget** \u2014 If visual output (diagrams, interactive content) is beneficial
|
|
18808
|
+
- **ask_user_to_clarify** \u2014 If the agent needs to confirm actions or ask clarifying questions
|
|
18809
|
+
|
|
18810
|
+
3. **Sub-agents** (optional) \u2014 Specialized agents the deep agent can delegate to for specific capabilities
|
|
18811
|
+
|
|
18812
|
+
### Phase 4: Final Review
|
|
18813
|
+
|
|
18814
|
+
Before creating, check:
|
|
18815
|
+
1. **Autonomy** \u2014 Can the agent operate independently?
|
|
18816
|
+
2. **Tools** \u2014 Does it have everything needed to self-decompose tasks?
|
|
18817
|
+
3. **Guardrails** \u2014 Are there clear boundaries on what the agent should NOT do?
|
|
18818
|
+
|
|
18819
|
+
### Creation
|
|
18820
|
+
|
|
18821
|
+
\`\`\`
|
|
18822
|
+
create_agent(
|
|
18823
|
+
name: "research-agent",
|
|
18824
|
+
type: "deep_agent",
|
|
18825
|
+
prompt: "...",
|
|
18826
|
+
middleware: [...],
|
|
18827
|
+
subAgents: [...] // optional
|
|
18828
|
+
)
|
|
18829
|
+
\`\`\`
|
|
18830
|
+
|
|
18831
|
+
---
|
|
18832
|
+
|
|
18833
|
+
## Editing Existing Agents
|
|
18834
|
+
|
|
18835
|
+
When the user wants to modify an agent:
|
|
18836
|
+
1. Call **get_agent** to see the current config
|
|
18837
|
+
2. Understand what the user wants to change
|
|
18838
|
+
3. Present the proposed changes
|
|
18839
|
+
4. Call **update_agent** to apply
|
|
18840
|
+
|
|
18841
|
+
## Deleting Agents
|
|
18842
|
+
|
|
18843
|
+
When the user wants to delete an agent:
|
|
18844
|
+
1. Call **get_agent** to show what will be deleted
|
|
18845
|
+
2. Warn if this agent is referenced as a sub-agent by others
|
|
18846
|
+
3. Ask for explicit confirmation
|
|
18847
|
+
4. Call **delete_agent**
|
|
18848
|
+
|
|
18849
|
+
## Agent Configuration Reference
|
|
18850
|
+
|
|
18851
|
+
### create_agent (REACT and DEEP_AGENT)
|
|
18852
|
+
|
|
18853
|
+
All fields except name, type, and prompt are optional.
|
|
18854
|
+
|
|
18855
|
+
\`\`\`typescript
|
|
18856
|
+
{
|
|
18857
|
+
name: string, // Required. Display name
|
|
18858
|
+
description?: string, // Optional. Short description
|
|
18859
|
+
type: "react" | "deep_agent", // Required
|
|
18860
|
+
prompt: string, // Required. System prompt
|
|
18861
|
+
tools?: string[], // Optional. Tool keys from list_tools
|
|
18862
|
+
middleware?: MiddlewareConfig[], // Optional. See middleware reference below
|
|
18863
|
+
subAgents?: string[], // DEEP_AGENT only. IDs of sub-agents
|
|
18864
|
+
internalSubAgents?: AgentConfig[], // DEEP_AGENT only. Inline sub-agent configs
|
|
18865
|
+
modelKey?: string, // Optional. Model to use
|
|
18866
|
+
}
|
|
18867
|
+
\`\`\`
|
|
18868
|
+
|
|
18869
|
+
### create_processing_agent (PROCESSING)
|
|
18870
|
+
|
|
18871
|
+
Creates a PROCESSING agent with a business-defined workflow topology. Sub-agents must already exist.
|
|
18872
|
+
|
|
18873
|
+
\`\`\`typescript
|
|
18874
|
+
{
|
|
18875
|
+
name: string, // Required. Display name for the orchestrator
|
|
18876
|
+
description?: string, // Optional. Short description
|
|
18877
|
+
prompt: string, // Required. System prompt \u2014 how to route through the topology
|
|
18878
|
+
edges: [{ // Required. At least 1 edge defining the workflow
|
|
18879
|
+
from: string, // Orchestrator's ID (use placeholder name; tool auto-replaces)
|
|
18880
|
+
to: string, // Sub-agent ID to delegate to
|
|
18881
|
+
purpose: string, // Business purpose \u2014 what this step accomplishes
|
|
18882
|
+
}],
|
|
18883
|
+
tools?: string[], // Optional. Tool keys from list_tools
|
|
18884
|
+
subAgents: string[], // Required. IDs of sub-agents in the pipeline
|
|
18885
|
+
internalSubAgents?: AgentConfig[], // Optional. Inline sub-agent configs
|
|
18886
|
+
middleware?: MiddlewareConfig[], // Optional. Additional middleware (topology is auto-added)
|
|
18887
|
+
modelKey?: string, // Optional. Model to use
|
|
18888
|
+
}
|
|
18889
|
+
\`\`\`
|
|
18890
|
+
|
|
18891
|
+
### create_processing_agent (PROCESSING)
|
|
18892
|
+
|
|
18893
|
+
Creates a PROCESSING agent with a business-defined workflow topology. Sub-agents must already exist.
|
|
18894
|
+
|
|
18895
|
+
\`\`\`typescript
|
|
18896
|
+
{
|
|
18897
|
+
name: string, // Required. Display name for the orchestrator
|
|
18898
|
+
description?: string, // Optional. Short description
|
|
18899
|
+
prompt: string, // Required. System prompt \u2014 how to route through the topology
|
|
18900
|
+
edges: [{ // Required. At least 1 edge defining the serial workflow chain
|
|
18901
|
+
from: string, // Source agent ID. First edge: use orchestrator name as placeholder (tool auto-replaces). Subsequent edges: previous sub-agent ID
|
|
18902
|
+
to: string, // Sub-agent ID to delegate to
|
|
18903
|
+
purpose: string, // Business purpose \u2014 what this step accomplishes
|
|
18904
|
+
}],
|
|
18905
|
+
subAgents: string[], // Required. IDs of sub-agents in the pipeline
|
|
18906
|
+
internalSubAgents?: AgentConfig[], // Optional. Inline sub-agent configs
|
|
18907
|
+
middleware?: MiddlewareConfig[], // Optional. Additional middleware (topology is auto-added)
|
|
18908
|
+
modelKey?: string, // Optional. Model to use
|
|
18909
|
+
}
|
|
18910
|
+
\`\`\`
|
|
18911
|
+
|
|
18912
|
+
### Middleware Config Reference
|
|
18913
|
+
|
|
18914
|
+
Each middleware entry uses this base shape:
|
|
18915
|
+
|
|
18916
|
+
\`\`\`typescript
|
|
18917
|
+
{
|
|
18918
|
+
id: string, // Unique ID, usually same as type
|
|
18919
|
+
type: string, // Middleware type from the table below
|
|
18920
|
+
name: string, // Display name
|
|
18921
|
+
description: string, // What this middleware provides
|
|
18922
|
+
enabled: true, // Always true for active middleware
|
|
18923
|
+
config: { ... } // Type-specific config (see table)
|
|
18924
|
+
}
|
|
18925
|
+
\`\`\`
|
|
18926
|
+
|
|
18927
|
+
#### filesystem
|
|
18928
|
+
Provides: \`ls\`, \`read_file\`, \`write_file\`, \`edit_file\`, \`glob\`, \`grep\`
|
|
18929
|
+
| config field | type | description |
|
|
18930
|
+
|-------------|------|-------------|
|
|
18931
|
+
| backend | string | Pluggable backend, usually omitted (uses default) |
|
|
18932
|
+
| systemPrompt | string? | Custom system prompt override for filesystem conventions |
|
|
18933
|
+
|
|
18934
|
+
#### code_eval
|
|
18935
|
+
Provides: \`run_code\` \u2014 execute Python/JavaScript in a sandbox
|
|
18936
|
+
| config field | type | description |
|
|
18937
|
+
|-------------|------|-------------|
|
|
18938
|
+
| vmIsolation | "agent" | "project" | "global" | Sandbox isolation level. Default recommended: \`"agent"\` |
|
|
18939
|
+
| timeout | number? | Execution timeout in milliseconds |
|
|
18940
|
+
| memoryLimit | number? | Memory limit in MB |
|
|
18941
|
+
|
|
18942
|
+
#### browser
|
|
18943
|
+
Provides: \`browser_navigate\`, \`browser_click\`, \`browser_screenshot\`, \`browser_get_markdown\`, etc. (21 tools)
|
|
18944
|
+
| config field | type | description |
|
|
18945
|
+
|-------------|------|-------------|
|
|
18946
|
+
| vmIsolation | "agent" | "project" | "global" | Sandbox isolation level. Default recommended: \`"agent"\` |
|
|
18947
|
+
| headless | boolean? | Whether to run in headless mode |
|
|
18948
|
+
|
|
18949
|
+
#### sql
|
|
18950
|
+
Provides: \`sql_list_tables\`, \`sql_table_info\`, \`sql_query_checker\`, \`sql_query\`
|
|
18951
|
+
| config field | type | description |
|
|
18952
|
+
|-------------|------|-------------|
|
|
18953
|
+
| databaseKeys | string[] | Array of database config keys to expose. Required. |
|
|
18954
|
+
| databaseDescriptions | Record<string,string>? | Optional human-readable descriptions keyed by database key |
|
|
18955
|
+
|
|
18956
|
+
#### skill
|
|
18957
|
+
Provides: \`load_skill_content\` \u2014 load and read detailed skill instructions
|
|
18958
|
+
| config field | type | description |
|
|
18959
|
+
|-------------|------|-------------|
|
|
18960
|
+
| skills | string[]? | List of specific skill IDs to expose |
|
|
18961
|
+
| readAll | boolean? | When \`true\`, all available skills are exposed (recommended) |
|
|
18962
|
+
| heading | string? | Optional heading for the skills section |
|
|
18963
|
+
| extraNote | string? | Optional extra note appended after skills list |
|
|
18964
|
+
|
|
18965
|
+
#### metrics
|
|
18966
|
+
Provides: \`list_datasources\`, \`query_metrics_list\`, \`query_semantic_metric_data\`, \`query_tables_list\`, \`execute_sql_query\`, etc. (7 tools)
|
|
18967
|
+
| config field | type | description |
|
|
18968
|
+
|-------------|------|-------------|
|
|
18969
|
+
| serverKeys | string[] | List of metrics server keys. Required. |
|
|
18970
|
+
| serverDescriptions | Record<string,string>? | Optional descriptions for each server |
|
|
18971
|
+
| connectAll | boolean? | When \`true\`, connects to all available metrics servers automatically |
|
|
18972
|
+
|
|
18973
|
+
#### ask_user_to_clarify
|
|
18974
|
+
Provides: \`ask_user_to_clarify\` \u2014 pause execution and present questions with predefined options to the user. The agent halts until the user responds, then receives the answers as structured data.
|
|
18975
|
+
**Use this when:** the agent needs to confirm an action, get user approval, ask "which one?", or gather missing parameters. Without this middleware, the agent CANNOT interact with the user mid-execution.
|
|
18976
|
+
Config: \`{}\` \u2014 no configuration needed.
|
|
18977
|
+
|
|
18978
|
+
#### widget
|
|
18979
|
+
Provides: \`load_guidelines\`, \`show_widget\` \u2014 render interactive HTML widgets and SVG diagrams
|
|
18980
|
+
Config: \`{}\` \u2014 no configuration needed.
|
|
18981
|
+
|
|
18982
|
+
#### claw
|
|
18983
|
+
Provides: bootstrap file management (AGENTS.md, SOUL.md, etc.) \u2014 injects project context into system prompt
|
|
18984
|
+
| config field | type | description |
|
|
18985
|
+
|-------------|------|-------------|
|
|
18986
|
+
| injectBootstrapFiles | boolean? | Whether to inject bootstrap files into system prompt. Default: \`true\` |
|
|
18987
|
+
| bootstrapFiles | object? | Custom content for each bootstrap file |
|
|
18988
|
+
|
|
18989
|
+
\`bootstrapFiles\` sub-fields: \`agents\`, \`soul\`, \`identity\`, \`user\`, \`tools\`, \`bootstrap\` \u2014 each is an optional string.
|
|
18990
|
+
|
|
18991
|
+
#### date
|
|
18992
|
+
Provides: \`get_current_date_time\` \u2014 get current date and time
|
|
18993
|
+
| config field | type | description |
|
|
18994
|
+
|-------------|------|-------------|
|
|
18995
|
+
| timezone | string? | IANA timezone like \`"Asia/Shanghai"\` or \`"America/New_York"\`. Default: \`"UTC"\` |
|
|
18996
|
+
|
|
18997
|
+
#### scheduler
|
|
18998
|
+
Provides: \`schedule_at\`, \`schedule_after\`, \`schedule_recurring\`, \`cancel_scheduled_task\`, \`list_scheduled_tasks\`
|
|
18999
|
+
| config field | type | description |
|
|
19000
|
+
|-------------|------|-------------|
|
|
19001
|
+
| defaultMaxRetries | number? | Default max retries for scheduled tasks. Default: \`0\` |
|
|
19002
|
+
|
|
19003
|
+
#### topology
|
|
19004
|
+
Provides: \`read_topo_progress\` \u2014 enforces multi-agent workflow topology. **Required for PROCESSING agents \u2014 auto-injected by create_processing_agent.**
|
|
19005
|
+
| config field | type | description |
|
|
19006
|
+
|-------------|------|-------------|
|
|
19007
|
+
| edges | TopologyEdge[] | **Required.** Directed edges: \`{ from: string, to: string, purpose: string }\`. The \`purpose\` must describe the business intent of this delegation step. |
|
|
19008
|
+
| trackingStore | object? | Optional persistence for workflow run tracking | |
|
|
19009
|
+
|
|
19010
|
+
### When to use ask_user_to_clarify Middleware
|
|
19011
|
+
|
|
19012
|
+
**CRITICAL: Always add this middleware when the agent needs user confirmation, approval, or clarification.** Without it, the agent cannot interact with the user during execution.
|
|
19013
|
+
|
|
19014
|
+
**Required scenarios:**
|
|
19015
|
+
- Confirming irreversible actions (delete data, send emails, make purchases, modify production configs)
|
|
19016
|
+
- Asking the user to choose between options (e.g., "Which database?", "Which report format?")
|
|
19017
|
+
- Gathering missing parameters the user didn't provide upfront
|
|
19018
|
+
- Requesting user approval before proceeding to a critical step
|
|
19019
|
+
- Disambiguating vague user requests before acting
|
|
19020
|
+
|
|
19021
|
+
**Tool capabilities:**
|
|
19022
|
+
| Feature | Description |
|
|
19023
|
+
|---------|-------------|
|
|
19024
|
+
| Single choice | User picks ONE option from a list (e.g., "Choose environment: [production] [staging]") |
|
|
19025
|
+
| Multiple choice | User picks SEVERAL options (e.g., "Select reports: [sales] [inventory] [hr]") |
|
|
19026
|
+
| Required | Forces the user to answer before the agent continues |
|
|
19027
|
+
| allowOther | Lets the user type a custom answer beyond listed options |
|
|
19028
|
+
|
|
19029
|
+
**Design rule:** If your agent's system prompt says anything like "confirm with the user before...", "ask the user to choose...", or "get approval for...", you MUST include the \`ask_user_to_clarify\` middleware.
|
|
19030
|
+
|
|
19031
|
+
### Quick Pick: Common Middleware Combos
|
|
19032
|
+
|
|
19033
|
+
| Agent Role | Recommended Middleware |
|
|
19034
|
+
|-----------|----------------------|
|
|
19035
|
+
| Code assistant | filesystem, code_eval, widget |
|
|
19036
|
+
| Data analyst | filesystem, sql, code_eval, widget |
|
|
19037
|
+
| Web researcher | browser, filesystem, widget |
|
|
19038
|
+
| Operations / SRE | metrics, sql, widget |
|
|
19039
|
+
| Process orchestrator | skill, date, scheduler, widget |
|
|
19040
|
+
| General assistant | filesystem, date, widget |
|
|
19041
|
+
| Approval-gated operations | ask_user_to_clarify, filesystem, widget |
|
|
19042
|
+
| Interactive Q&A | ask_user_to_clarify, date, widget |
|
|
19043
|
+
|
|
19044
|
+
### update_processing_agent
|
|
19045
|
+
|
|
19046
|
+
Updates a PROCESSING agent's topology edges, name, prompt, or sub-agents. Unlike update_agent, this properly handles placeholder resolution for edge \`from\` values and manages the topology middleware correctly.
|
|
19047
|
+
|
|
19048
|
+
\`\`\`typescript
|
|
19049
|
+
{
|
|
19050
|
+
id: string, // Required. The PROCESSING agent ID to update
|
|
19051
|
+
name?: string, // Optional. New display name
|
|
19052
|
+
description?: string, // Optional. New short description
|
|
19053
|
+
prompt?: string, // Optional. New orchestrator system prompt
|
|
19054
|
+
edges?: [{ // Optional. New topology edges (serial chain)
|
|
19055
|
+
from: string, // First edge: orchestrator name placeholder. Subsequent: previous sub-agent ID
|
|
19056
|
+
to: string, // Sub-agent ID
|
|
19057
|
+
purpose: string, // Business purpose
|
|
19058
|
+
}],
|
|
19059
|
+
subAgents?: string[], // Optional. New sub-agent IDs
|
|
19060
|
+
middleware?: MiddlewareConfig[], // Optional. Additional middleware (topology auto-managed)
|
|
19061
|
+
modelKey?: string, // Optional. New model
|
|
19062
|
+
}
|
|
19063
|
+
\`\`\`
|
|
19064
|
+
|
|
19065
|
+
**When to use:** Use this whenever you need to change a PROCESSING agent's topology \u2014 adding/removing/recruiting pipeline stages, changing the flow order, or updating edge purposes. Use regular \`update_agent\` only for REACT and DEEP_AGENT agents.
|
|
19066
|
+
|
|
19067
|
+
### update_agent parameters
|
|
19068
|
+
|
|
19069
|
+
\`\`\`typescript
|
|
19070
|
+
{
|
|
19071
|
+
id: string, // Required. Agent ID to update
|
|
19072
|
+
config: { // Required. Full or partial agent config
|
|
19073
|
+
name?: string,
|
|
19074
|
+
description?: string,
|
|
19075
|
+
prompt?: string,
|
|
19076
|
+
middleware?: [...],
|
|
19077
|
+
// ... any other fields
|
|
19078
|
+
}
|
|
19079
|
+
}
|
|
19080
|
+
\`\`\`
|
|
19081
|
+
`;
|
|
19082
|
+
|
|
19083
|
+
// src/agent_lattice/agentArchitectConfig.ts
|
|
19084
|
+
var AGENT_ARCHITECT_KEY = "agent-architect";
|
|
19085
|
+
var agentArchitectConfig = {
|
|
19086
|
+
key: AGENT_ARCHITECT_KEY,
|
|
19087
|
+
name: "Agent Architect",
|
|
19088
|
+
description: "Design and manage AI agents through natural language conversation. Use this agent when you want to create a new agent, modify an existing agent, or manage your agent collection (list, view, update, delete).",
|
|
19089
|
+
type: import_protocols11.AgentType.DEEP_AGENT,
|
|
19090
|
+
prompt: AGENT_ARCHITECT_PROMPT,
|
|
19091
|
+
tools: [
|
|
19092
|
+
"list_agents",
|
|
19093
|
+
"list_tools",
|
|
19094
|
+
"get_agent",
|
|
19095
|
+
"create_agent",
|
|
19096
|
+
"create_processing_agent",
|
|
19097
|
+
"update_processing_agent",
|
|
19098
|
+
"update_agent",
|
|
19099
|
+
"delete_agent",
|
|
19100
|
+
"invoke_agent"
|
|
19101
|
+
],
|
|
19102
|
+
middleware: [
|
|
19103
|
+
{
|
|
19104
|
+
id: "widget",
|
|
19105
|
+
type: "widget",
|
|
19106
|
+
name: "Widget",
|
|
19107
|
+
description: "Render interactive HTML widgets and SVG diagrams",
|
|
19108
|
+
enabled: true,
|
|
19109
|
+
config: {}
|
|
19110
|
+
}
|
|
19111
|
+
]
|
|
19112
|
+
};
|
|
19113
|
+
|
|
19114
|
+
// src/agent_lattice/builtinAgents.ts
|
|
19115
|
+
var BUILTIN_AGENTS = [agentArchitectConfig];
|
|
19116
|
+
function ensureBuiltinAgentsForTenant(tenantId) {
|
|
19117
|
+
for (const config of BUILTIN_AGENTS) {
|
|
19118
|
+
if (!agentLatticeManager.hasWithTenant(tenantId, config.key)) {
|
|
19119
|
+
agentLatticeManager.registerLatticeWithTenant(tenantId, config);
|
|
19120
|
+
}
|
|
19121
|
+
}
|
|
19122
|
+
}
|
|
19123
|
+
|
|
16930
19124
|
// src/agent_lattice/AgentLatticeManager.ts
|
|
16931
19125
|
function assistantToConfig(assistant) {
|
|
16932
19126
|
const graphDef = typeof assistant.graphDefinition === "object" && assistant.graphDefinition !== null ? assistant.graphDefinition : {};
|
|
@@ -17112,6 +19306,7 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
|
|
|
17112
19306
|
* @param tenantId 租户ID
|
|
17113
19307
|
*/
|
|
17114
19308
|
async initializeStoredAssistantsForTenant(tenantId) {
|
|
19309
|
+
ensureBuiltinAgentsForTenant(tenantId);
|
|
17115
19310
|
try {
|
|
17116
19311
|
const storeLattice = getStoreLattice("default", "assistant");
|
|
17117
19312
|
const assistants = await storeLattice.store.getAllAssistants(tenantId);
|
|
@@ -17556,7 +19751,7 @@ var getVectorStoreLattice = (key) => vectorStoreLatticeManager.getVectorStoreLat
|
|
|
17556
19751
|
var getVectorStoreClient = (key) => vectorStoreLatticeManager.getVectorStoreClient(key);
|
|
17557
19752
|
|
|
17558
19753
|
// src/logger_lattice/LoggerLatticeManager.ts
|
|
17559
|
-
var
|
|
19754
|
+
var import_protocols12 = require("@axiom-lattice/protocols");
|
|
17560
19755
|
|
|
17561
19756
|
// src/logger_lattice/PinoLoggerClient.ts
|
|
17562
19757
|
var import_pino = __toESM(require("pino"));
|
|
@@ -17778,11 +19973,11 @@ var LoggerLatticeManager = class _LoggerLatticeManager extends BaseLatticeManage
|
|
|
17778
19973
|
if (client) {
|
|
17779
19974
|
loggerClient = client;
|
|
17780
19975
|
} else {
|
|
17781
|
-
if (config.type ===
|
|
19976
|
+
if (config.type === import_protocols12.LoggerType.PINO) {
|
|
17782
19977
|
loggerClient = new PinoLoggerClient(config);
|
|
17783
|
-
} else if (config.type ===
|
|
19978
|
+
} else if (config.type === import_protocols12.LoggerType.CONSOLE) {
|
|
17784
19979
|
loggerClient = new ConsoleLoggerClient(config);
|
|
17785
|
-
} else if (config.type ===
|
|
19980
|
+
} else if (config.type === import_protocols12.LoggerType.CUSTOM) {
|
|
17786
19981
|
throw new Error(
|
|
17787
19982
|
`Custom logger client must be provided. Please pass the client to registerLattice.`
|
|
17788
19983
|
);
|
|
@@ -18329,10 +20524,10 @@ var McpLatticeManager = class _McpLatticeManager extends BaseLatticeManager {
|
|
|
18329
20524
|
}
|
|
18330
20525
|
const tools = await this.getAllTools();
|
|
18331
20526
|
console.log(`[MCP] Registering ${tools.length} tools to Tool Lattice...`);
|
|
18332
|
-
for (const
|
|
18333
|
-
const toolKey = prefix ? `${prefix}_${
|
|
18334
|
-
|
|
18335
|
-
toolLatticeManager.registerExistingTool(toolKey,
|
|
20527
|
+
for (const tool51 of tools) {
|
|
20528
|
+
const toolKey = prefix ? `${prefix}_${tool51.name}` : tool51.name;
|
|
20529
|
+
tool51.name = toolKey;
|
|
20530
|
+
toolLatticeManager.registerExistingTool(toolKey, tool51);
|
|
18336
20531
|
console.log(`[MCP] Registered tool: ${toolKey}`);
|
|
18337
20532
|
}
|
|
18338
20533
|
console.log(`[MCP] Successfully registered ${tools.length} tools to Tool Lattice`);
|
|
@@ -18630,7 +20825,7 @@ function parseOptionalNumberEnv(name, fallback) {
|
|
|
18630
20825
|
}
|
|
18631
20826
|
function getDefaultMicrosandboxRemoteConfig() {
|
|
18632
20827
|
return {
|
|
18633
|
-
image: process.env.MICROSANDBOX_IMAGE ?? "daytona-cn-shanghai.cr.volces.com/daytona/sandbox:0.0.
|
|
20828
|
+
image: process.env.MICROSANDBOX_IMAGE ?? "daytona-cn-shanghai.cr.volces.com/daytona/sandbox:0.0.5",
|
|
18634
20829
|
//"daytonaio/sandbox:0.6.0",
|
|
18635
20830
|
cpus: parseOptionalNumberEnv("MICROSANDBOX_CPUS", 1),
|
|
18636
20831
|
memoryMib: parseOptionalNumberEnv("MICROSANDBOX_MEMORY", 512),
|
|
@@ -19496,6 +21691,7 @@ function clearEncryptionKeyCache() {
|
|
|
19496
21691
|
AgentLatticeManager,
|
|
19497
21692
|
AgentManager,
|
|
19498
21693
|
AgentType,
|
|
21694
|
+
BUILTIN_SKILLS,
|
|
19499
21695
|
ChunkBuffer,
|
|
19500
21696
|
ChunkBufferLatticeManager,
|
|
19501
21697
|
CompositeBackend,
|
|
@@ -19579,6 +21775,7 @@ function clearEncryptionKeyCache() {
|
|
|
19579
21775
|
createListMetricsServersTool,
|
|
19580
21776
|
createListTablesSqlTool,
|
|
19581
21777
|
createModelSelectorMiddleware,
|
|
21778
|
+
createProcessingAgent,
|
|
19582
21779
|
createQueryCheckerSqlTool,
|
|
19583
21780
|
createQueryMetricDefinitionTool,
|
|
19584
21781
|
createQueryMetricsListTool,
|
|
@@ -19606,7 +21803,11 @@ function clearEncryptionKeyCache() {
|
|
|
19606
21803
|
getAgentClient,
|
|
19607
21804
|
getAgentConfig,
|
|
19608
21805
|
getAllAgentConfigs,
|
|
21806
|
+
getAllBuiltInSkillMetas,
|
|
19609
21807
|
getAllToolDefinitions,
|
|
21808
|
+
getBuiltInSkillContent,
|
|
21809
|
+
getBuiltInSkillMeta,
|
|
21810
|
+
getBuiltInSkillNames,
|
|
19610
21811
|
getCheckpointSaver,
|
|
19611
21812
|
getChunkBuffer,
|
|
19612
21813
|
getEmbeddingsClient,
|
|
@@ -19628,6 +21829,7 @@ function clearEncryptionKeyCache() {
|
|
|
19628
21829
|
grepMatchesFromFiles,
|
|
19629
21830
|
grepSearchFiles,
|
|
19630
21831
|
hasChunkBuffer,
|
|
21832
|
+
isBuiltInSkill,
|
|
19631
21833
|
isUsingDefaultKey,
|
|
19632
21834
|
isValidCronExpression,
|
|
19633
21835
|
isValidSandboxName,
|