@axiom-lattice/core 2.1.79 → 2.1.81
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/chunk-C5HUS7YV.mjs +331 -0
- package/dist/chunk-C5HUS7YV.mjs.map +1 -0
- package/dist/chunk-SGRFQY3E.mjs +1140 -0
- package/dist/chunk-SGRFQY3E.mjs.map +1 -0
- package/dist/compile-4RFYHUBE.mjs +11 -0
- package/dist/compile-4RFYHUBE.mjs.map +1 -0
- package/dist/index.d.mts +306 -8
- package/dist/index.d.ts +306 -8
- package/dist/index.js +3261 -1026
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1609 -916
- package/dist/index.mjs.map +1 -1
- package/dist/memory_lattice-E66HTTVV.mjs +13 -0
- package/dist/memory_lattice-E66HTTVV.mjs.map +1 -0
- package/package.json +4 -2
package/dist/index.mjs
CHANGED
|
@@ -1,245 +1,28 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
* @param key 项目键名(不含前缀)
|
|
27
|
-
* @param item 项目实例
|
|
28
|
-
*/
|
|
29
|
-
registerWithTenant(tenantId, key, item) {
|
|
30
|
-
const fullKey = this.getFullKey(tenantId, key);
|
|
31
|
-
if (_BaseLatticeManager.registry.has(fullKey)) {
|
|
32
|
-
throw new Error(`\u9879\u76EE "${fullKey}" \u5DF2\u7ECF\u5B58\u5728\uFF0C\u65E0\u6CD5\u91CD\u590D\u6CE8\u518C`);
|
|
33
|
-
}
|
|
34
|
-
_BaseLatticeManager.registry.set(fullKey, item);
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* 带租户的获取指定项目(同步)
|
|
38
|
-
* @param tenantId 租户ID
|
|
39
|
-
* @param key 项目键名(不含前缀)
|
|
40
|
-
*/
|
|
41
|
-
getWithTenant(tenantId, key) {
|
|
42
|
-
const fullKey = this.getFullKey(tenantId, key);
|
|
43
|
-
return _BaseLatticeManager.registry.get(fullKey);
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* 带租户的获取指定项目(异步,支持从store回退加载)
|
|
47
|
-
* 如果内存中不存在且子类实现了loadItemFromStore,则尝试从store加载
|
|
48
|
-
* @param tenantId 租户ID
|
|
49
|
-
* @param key 项目键名(不含前缀)
|
|
50
|
-
* @returns 项目实例,如果未找到则返回undefined
|
|
51
|
-
*/
|
|
52
|
-
async getOrLoadWithTenant(tenantId, key) {
|
|
53
|
-
const item = this.getWithTenant(tenantId, key);
|
|
54
|
-
if (item !== void 0) {
|
|
55
|
-
return item;
|
|
56
|
-
}
|
|
57
|
-
if (this.loadItemFromStore) {
|
|
58
|
-
const loadedItem = await this.loadItemFromStore(tenantId, key);
|
|
59
|
-
if (loadedItem !== void 0) {
|
|
60
|
-
this.registerWithTenant(tenantId, key, loadedItem);
|
|
61
|
-
return loadedItem;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
return void 0;
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* 带租户的检查项目是否存在(同步)
|
|
68
|
-
* @param tenantId 租户ID
|
|
69
|
-
* @param key 项目键名(不含前缀)
|
|
70
|
-
*/
|
|
71
|
-
hasWithTenant(tenantId, key) {
|
|
72
|
-
const fullKey = this.getFullKey(tenantId, key);
|
|
73
|
-
return _BaseLatticeManager.registry.has(fullKey);
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* 带租户的检查项目是否存在(异步,支持从store回退加载)
|
|
77
|
-
* 如果内存中不存在且子类实现了loadItemFromStore,则尝试从store加载
|
|
78
|
-
* @param tenantId 租户ID
|
|
79
|
-
* @param key 项目键名(不含前缀)
|
|
80
|
-
* @returns 如果存在或能从store加载则返回true
|
|
81
|
-
*/
|
|
82
|
-
async hasOrLoadWithTenant(tenantId, key) {
|
|
83
|
-
if (this.hasWithTenant(tenantId, key)) {
|
|
84
|
-
return true;
|
|
85
|
-
}
|
|
86
|
-
if (this.loadItemFromStore) {
|
|
87
|
-
const loadedItem = await this.loadItemFromStore(tenantId, key);
|
|
88
|
-
if (loadedItem !== void 0) {
|
|
89
|
-
this.registerWithTenant(tenantId, key, loadedItem);
|
|
90
|
-
return true;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
return false;
|
|
94
|
-
}
|
|
95
|
-
/**
|
|
96
|
-
* 带租户的移除项目
|
|
97
|
-
* @param tenantId 租户ID
|
|
98
|
-
* @param key 项目键名(不含前缀)
|
|
99
|
-
*/
|
|
100
|
-
removeWithTenant(tenantId, key) {
|
|
101
|
-
const fullKey = this.getFullKey(tenantId, key);
|
|
102
|
-
return _BaseLatticeManager.registry.delete(fullKey);
|
|
103
|
-
}
|
|
104
|
-
/**
|
|
105
|
-
* 获取指定租户的所有项目
|
|
106
|
-
* @param tenantId 租户ID
|
|
107
|
-
*/
|
|
108
|
-
getAllByTenant(tenantId) {
|
|
109
|
-
const prefix = `${this.getLatticeType()}:${tenantId}:`;
|
|
110
|
-
const result = [];
|
|
111
|
-
for (const [key, value] of _BaseLatticeManager.registry.entries()) {
|
|
112
|
-
if (key.startsWith(prefix)) {
|
|
113
|
-
result.push(value);
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
return result;
|
|
117
|
-
}
|
|
118
|
-
/**
|
|
119
|
-
* 清空指定租户的所有项目
|
|
120
|
-
* @param tenantId 租户ID
|
|
121
|
-
*/
|
|
122
|
-
clearByTenant(tenantId) {
|
|
123
|
-
const prefix = `${this.getLatticeType()}:${tenantId}:`;
|
|
124
|
-
const keysToDelete = [];
|
|
125
|
-
for (const key of _BaseLatticeManager.registry.keys()) {
|
|
126
|
-
if (key.startsWith(prefix)) {
|
|
127
|
-
keysToDelete.push(key);
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
for (const key of keysToDelete) {
|
|
131
|
-
_BaseLatticeManager.registry.delete(key);
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
// ========== 向后兼容的旧API(使用 default 租户) ==========
|
|
135
|
-
/**
|
|
136
|
-
* 注册项目(向后兼容,使用 "default" 租户)
|
|
137
|
-
* @deprecated Use registerWithTenant(tenantId, key, item) instead
|
|
138
|
-
* @param key 项目键名(不含前缀)
|
|
139
|
-
* @param item 项目实例
|
|
140
|
-
*/
|
|
141
|
-
register(key, item) {
|
|
142
|
-
this.registerWithTenant("default", key, item);
|
|
143
|
-
}
|
|
144
|
-
/**
|
|
145
|
-
* 获取指定项目(向后兼容,使用 "default" 租户)
|
|
146
|
-
* @deprecated Use getWithTenant(tenantId, key) instead
|
|
147
|
-
* @param key 项目键名(不含前缀)
|
|
148
|
-
*/
|
|
149
|
-
get(key) {
|
|
150
|
-
return this.getWithTenant("default", key);
|
|
151
|
-
}
|
|
152
|
-
/**
|
|
153
|
-
* 获取所有当前类型的项目(向后兼容,包含所有租户)
|
|
154
|
-
*/
|
|
155
|
-
getAll() {
|
|
156
|
-
const prefix = `${this.getLatticeType()}:`;
|
|
157
|
-
const result = [];
|
|
158
|
-
for (const [key, value] of _BaseLatticeManager.registry.entries()) {
|
|
159
|
-
if (key.startsWith(prefix)) {
|
|
160
|
-
result.push(value);
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
return result;
|
|
164
|
-
}
|
|
165
|
-
/**
|
|
166
|
-
* 检查项目是否存在(向后兼容,使用 "default" 租户)
|
|
167
|
-
* @deprecated Use hasWithTenant(tenantId, key) instead
|
|
168
|
-
* @param key 项目键名(不含前缀)
|
|
169
|
-
*/
|
|
170
|
-
has(key) {
|
|
171
|
-
return this.hasWithTenant("default", key);
|
|
172
|
-
}
|
|
173
|
-
/**
|
|
174
|
-
* 移除项目(向后兼容,使用 "default" 租户)
|
|
175
|
-
* @deprecated Use removeWithTenant(tenantId, key) instead
|
|
176
|
-
* @param key 项目键名(不含前缀)
|
|
177
|
-
*/
|
|
178
|
-
remove(key) {
|
|
179
|
-
return this.removeWithTenant("default", key);
|
|
180
|
-
}
|
|
181
|
-
/**
|
|
182
|
-
* 清空当前类型的所有项目(向后兼容,包含所有租户)
|
|
183
|
-
*/
|
|
184
|
-
clear() {
|
|
185
|
-
const prefix = `${this.getLatticeType()}:`;
|
|
186
|
-
const keysToDelete = [];
|
|
187
|
-
for (const key of _BaseLatticeManager.registry.keys()) {
|
|
188
|
-
if (key.startsWith(prefix)) {
|
|
189
|
-
keysToDelete.push(key);
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
for (const key of keysToDelete) {
|
|
193
|
-
_BaseLatticeManager.registry.delete(key);
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
/**
|
|
197
|
-
* 获取当前类型的项目数量(向后兼容,包含所有租户)
|
|
198
|
-
*/
|
|
199
|
-
count() {
|
|
200
|
-
const prefix = `${this.getLatticeType()}:`;
|
|
201
|
-
let count = 0;
|
|
202
|
-
for (const key of _BaseLatticeManager.registry.keys()) {
|
|
203
|
-
if (key.startsWith(prefix)) {
|
|
204
|
-
count++;
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
return count;
|
|
208
|
-
}
|
|
209
|
-
/**
|
|
210
|
-
* 获取当前类型的项目键名列表(向后兼容,包含所有租户)
|
|
211
|
-
* 返回格式: {tenantId}:{key}
|
|
212
|
-
*/
|
|
213
|
-
keys() {
|
|
214
|
-
const prefix = `${this.getLatticeType()}:`;
|
|
215
|
-
const prefixLength = prefix.length;
|
|
216
|
-
const result = [];
|
|
217
|
-
for (const key of _BaseLatticeManager.registry.keys()) {
|
|
218
|
-
if (key.startsWith(prefix)) {
|
|
219
|
-
result.push(key.substring(prefixLength));
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
return result;
|
|
223
|
-
}
|
|
224
|
-
/**
|
|
225
|
-
* 获取当前类型的项目键名列表(仅指定租户,不含租户前缀)
|
|
226
|
-
* @param tenantId 租户ID
|
|
227
|
-
*/
|
|
228
|
-
keysByTenant(tenantId) {
|
|
229
|
-
const prefix = `${this.getLatticeType()}:${tenantId}:`;
|
|
230
|
-
const prefixLength = prefix.length;
|
|
231
|
-
const result = [];
|
|
232
|
-
for (const key of _BaseLatticeManager.registry.keys()) {
|
|
233
|
-
if (key.startsWith(prefix)) {
|
|
234
|
-
result.push(key.substring(prefixLength));
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
return result;
|
|
238
|
-
}
|
|
239
|
-
};
|
|
240
|
-
// 全局统一的Lattice注册表
|
|
241
|
-
_BaseLatticeManager.registry = /* @__PURE__ */ new Map();
|
|
242
|
-
var BaseLatticeManager = _BaseLatticeManager;
|
|
1
|
+
import {
|
|
2
|
+
BaseLatticeManager,
|
|
3
|
+
MemoryLatticeManager,
|
|
4
|
+
MemoryType,
|
|
5
|
+
getCheckpointSaver,
|
|
6
|
+
registerCheckpointSaver
|
|
7
|
+
} from "./chunk-C5HUS7YV.mjs";
|
|
8
|
+
import {
|
|
9
|
+
buildInput,
|
|
10
|
+
buildStateAnnotation,
|
|
11
|
+
compileInternal,
|
|
12
|
+
compileWorkflow,
|
|
13
|
+
createAgentNode,
|
|
14
|
+
createMapNode,
|
|
15
|
+
createNodeHandler,
|
|
16
|
+
extractOutput,
|
|
17
|
+
invokeWithRetry,
|
|
18
|
+
parallelLimit,
|
|
19
|
+
parseYaml,
|
|
20
|
+
renderTemplate,
|
|
21
|
+
resolvePath,
|
|
22
|
+
toJsonSchema,
|
|
23
|
+
toSafeStateExpr,
|
|
24
|
+
validateDSL
|
|
25
|
+
} from "./chunk-SGRFQY3E.mjs";
|
|
243
26
|
|
|
244
27
|
// src/model_lattice/ModelLattice.ts
|
|
245
28
|
import { ChatDeepSeek } from "@langchain/deepseek";
|
|
@@ -364,9 +147,11 @@ var ModelLattice = class extends BaseChatModel {
|
|
|
364
147
|
maxRetries: config.maxRetries || 2,
|
|
365
148
|
apiKey: config.apiKey || process.env[config.apiKeyEnvName || "SILICONCLOUD_API_KEY"],
|
|
366
149
|
configuration: {
|
|
367
|
-
baseURL: "https://api.siliconflow.cn/v1"
|
|
150
|
+
baseURL: config.baseURL || "https://api.siliconflow.cn/v1"
|
|
368
151
|
},
|
|
369
|
-
streaming: config.streaming
|
|
152
|
+
streaming: config.streaming,
|
|
153
|
+
modelKwargs: config.modelKwargs,
|
|
154
|
+
...config.extra || {}
|
|
370
155
|
});
|
|
371
156
|
} else if (config.provider === "volcengine") {
|
|
372
157
|
return new ChatOpenAI({
|
|
@@ -648,11 +433,11 @@ var ToolLatticeManager = class _ToolLatticeManager extends BaseLatticeManager {
|
|
|
648
433
|
* @param key Lattice键名
|
|
649
434
|
* @param tool 已有的StructuredTool实例
|
|
650
435
|
*/
|
|
651
|
-
registerExistingTool(key,
|
|
436
|
+
registerExistingTool(key, tool52) {
|
|
652
437
|
const config = {
|
|
653
|
-
name:
|
|
654
|
-
description:
|
|
655
|
-
schema:
|
|
438
|
+
name: tool52.name,
|
|
439
|
+
description: tool52.description,
|
|
440
|
+
schema: tool52.schema,
|
|
656
441
|
// StructuredTool的schema已经是Zod兼容的
|
|
657
442
|
needUserApprove: false
|
|
658
443
|
// MCP工具默认不需要用户批准
|
|
@@ -660,7 +445,7 @@ var ToolLatticeManager = class _ToolLatticeManager extends BaseLatticeManager {
|
|
|
660
445
|
const toolLattice = {
|
|
661
446
|
key,
|
|
662
447
|
config,
|
|
663
|
-
client:
|
|
448
|
+
client: tool52
|
|
664
449
|
};
|
|
665
450
|
this.register(key, toolLattice);
|
|
666
451
|
}
|
|
@@ -686,7 +471,7 @@ var ToolLatticeManager = class _ToolLatticeManager extends BaseLatticeManager {
|
|
|
686
471
|
};
|
|
687
472
|
var toolLatticeManager = ToolLatticeManager.getInstance();
|
|
688
473
|
var registerToolLattice = (key, config, executor) => toolLatticeManager.registerLattice(key, config, executor);
|
|
689
|
-
var registerExistingTool = (key,
|
|
474
|
+
var registerExistingTool = (key, tool52) => toolLatticeManager.registerExistingTool(key, tool52);
|
|
690
475
|
var getToolLattice = (key) => toolLatticeManager.getToolLattice(key);
|
|
691
476
|
var getToolDefinition = (key) => toolLatticeManager.getToolDefinition(key);
|
|
692
477
|
var getToolClient = (key) => toolLatticeManager.getToolClient(key);
|
|
@@ -953,6 +738,7 @@ var InMemoryAssistantStore = class {
|
|
|
953
738
|
name: data.name,
|
|
954
739
|
description: data.description,
|
|
955
740
|
graphDefinition: data.graphDefinition,
|
|
741
|
+
ownerUserId: data.ownerUserId,
|
|
956
742
|
createdAt: now,
|
|
957
743
|
updatedAt: now
|
|
958
744
|
};
|
|
@@ -999,6 +785,17 @@ var InMemoryAssistantStore = class {
|
|
|
999
785
|
}
|
|
1000
786
|
return tenantAssistants.has(id);
|
|
1001
787
|
}
|
|
788
|
+
/**
|
|
789
|
+
* Get assistant by owner user ID
|
|
790
|
+
*/
|
|
791
|
+
async getByOwner(tenantId, userId) {
|
|
792
|
+
const tenantAssistants = this.assistants.get(tenantId);
|
|
793
|
+
if (!tenantAssistants) return null;
|
|
794
|
+
for (const assistant of tenantAssistants.values()) {
|
|
795
|
+
if (assistant.ownerUserId === userId) return assistant;
|
|
796
|
+
}
|
|
797
|
+
return null;
|
|
798
|
+
}
|
|
1002
799
|
/**
|
|
1003
800
|
* Clear all assistants for a tenant (useful for testing)
|
|
1004
801
|
*/
|
|
@@ -2231,7 +2028,7 @@ var InMemoryThreadMessageQueueStore = class {
|
|
|
2231
2028
|
return this.messages.get(threadId);
|
|
2232
2029
|
}
|
|
2233
2030
|
async addMessage(params) {
|
|
2234
|
-
const { threadId, tenantId, assistantId, content, type = "human", priority = 0, command, custom_run_config, id } = params;
|
|
2031
|
+
const { threadId, tenantId, assistantId, workspaceId, projectId, content, type = "human", priority = 0, command, custom_run_config, id } = params;
|
|
2235
2032
|
const threadMessages = this.getMessagesForThread(threadId);
|
|
2236
2033
|
const message = {
|
|
2237
2034
|
id: id || this.generateId(),
|
|
@@ -2242,6 +2039,8 @@ var InMemoryThreadMessageQueueStore = class {
|
|
|
2242
2039
|
status: "pending",
|
|
2243
2040
|
tenantId,
|
|
2244
2041
|
assistantId,
|
|
2042
|
+
workspaceId,
|
|
2043
|
+
projectId,
|
|
2245
2044
|
priority,
|
|
2246
2045
|
command,
|
|
2247
2046
|
custom_run_config
|
|
@@ -2250,7 +2049,7 @@ var InMemoryThreadMessageQueueStore = class {
|
|
|
2250
2049
|
return message;
|
|
2251
2050
|
}
|
|
2252
2051
|
async addMessageAtHead(params) {
|
|
2253
|
-
const { threadId, tenantId, assistantId, content, type = "system", id, command, custom_run_config } = params;
|
|
2052
|
+
const { threadId, tenantId, assistantId, workspaceId, projectId, content, type = "system", id, command, custom_run_config } = params;
|
|
2254
2053
|
const threadMessages = this.getMessagesForThread(threadId);
|
|
2255
2054
|
let resolvedTenantId = tenantId || "default";
|
|
2256
2055
|
let resolvedAssistantId = assistantId || "";
|
|
@@ -2268,6 +2067,8 @@ var InMemoryThreadMessageQueueStore = class {
|
|
|
2268
2067
|
status: "pending",
|
|
2269
2068
|
tenantId: resolvedTenantId,
|
|
2270
2069
|
assistantId: resolvedAssistantId,
|
|
2070
|
+
workspaceId,
|
|
2071
|
+
projectId,
|
|
2271
2072
|
priority: 100,
|
|
2272
2073
|
// High priority for head messages (STEER/Command)
|
|
2273
2074
|
command,
|
|
@@ -2299,7 +2100,9 @@ var InMemoryThreadMessageQueueStore = class {
|
|
|
2299
2100
|
result.push({
|
|
2300
2101
|
tenantId: firstMessage.tenantId || "default",
|
|
2301
2102
|
assistantId: firstMessage.assistantId || "",
|
|
2302
|
-
threadId
|
|
2103
|
+
threadId,
|
|
2104
|
+
workspaceId: firstMessage.workspaceId || void 0,
|
|
2105
|
+
projectId: firstMessage.projectId || void 0
|
|
2303
2106
|
});
|
|
2304
2107
|
}
|
|
2305
2108
|
}
|
|
@@ -2422,6 +2225,7 @@ var InMemoryWorkflowTrackingStore = class {
|
|
|
2422
2225
|
tenantId: request.tenantId,
|
|
2423
2226
|
stepType: request.stepType,
|
|
2424
2227
|
stepName: request.stepName,
|
|
2228
|
+
threadId: request.threadId,
|
|
2425
2229
|
edgeFrom: request.edgeFrom,
|
|
2426
2230
|
edgeTo: request.edgeTo,
|
|
2427
2231
|
edgePurpose: request.edgePurpose,
|
|
@@ -2436,6 +2240,19 @@ var InMemoryWorkflowTrackingStore = class {
|
|
|
2436
2240
|
this.steps.set(request.runId, runSteps);
|
|
2437
2241
|
return step;
|
|
2438
2242
|
}
|
|
2243
|
+
async upsertRunStep(request) {
|
|
2244
|
+
const runSteps = this.steps.get(request.runId) || [];
|
|
2245
|
+
const existing = runSteps.find(
|
|
2246
|
+
(s) => s.stepType === request.stepType && s.stepName === request.stepName
|
|
2247
|
+
);
|
|
2248
|
+
if (existing) {
|
|
2249
|
+
if (!existing.threadId && request.threadId) {
|
|
2250
|
+
existing.threadId = request.threadId;
|
|
2251
|
+
}
|
|
2252
|
+
return existing;
|
|
2253
|
+
}
|
|
2254
|
+
return this.createRunStep(request);
|
|
2255
|
+
}
|
|
2439
2256
|
async updateRunStep(runId, stepId, updates) {
|
|
2440
2257
|
const runSteps = this.steps.get(runId);
|
|
2441
2258
|
if (!runSteps) return null;
|
|
@@ -2492,6 +2309,11 @@ var InMemoryChannelInstallationStore = class {
|
|
|
2492
2309
|
(inst) => inst.tenantId === tenantId && (!channel || inst.channel === channel)
|
|
2493
2310
|
);
|
|
2494
2311
|
}
|
|
2312
|
+
async getAllInstallations(channel) {
|
|
2313
|
+
return Array.from(this.installations.values()).filter(
|
|
2314
|
+
(inst) => !channel || inst.channel === channel
|
|
2315
|
+
);
|
|
2316
|
+
}
|
|
2495
2317
|
/**
|
|
2496
2318
|
* Creates a new channel installation for a tenant.
|
|
2497
2319
|
*
|
|
@@ -2768,6 +2590,107 @@ var InMemoryA2AApiKeyStore = class {
|
|
|
2768
2590
|
}
|
|
2769
2591
|
};
|
|
2770
2592
|
|
|
2593
|
+
// src/store_lattice/InMemoryTaskStore.ts
|
|
2594
|
+
import { v4 as uuidv4 } from "uuid";
|
|
2595
|
+
var InMemoryTaskStore = class {
|
|
2596
|
+
constructor() {
|
|
2597
|
+
this.tasks = /* @__PURE__ */ new Map();
|
|
2598
|
+
}
|
|
2599
|
+
/**
|
|
2600
|
+
* Create a new task
|
|
2601
|
+
*/
|
|
2602
|
+
async create(params) {
|
|
2603
|
+
if (!this.tasks.has(params.tenantId)) {
|
|
2604
|
+
this.tasks.set(params.tenantId, /* @__PURE__ */ new Map());
|
|
2605
|
+
}
|
|
2606
|
+
const now = /* @__PURE__ */ new Date();
|
|
2607
|
+
const task = {
|
|
2608
|
+
id: uuidv4(),
|
|
2609
|
+
tenantId: params.tenantId,
|
|
2610
|
+
ownerType: params.ownerType,
|
|
2611
|
+
ownerId: params.ownerId,
|
|
2612
|
+
title: params.title,
|
|
2613
|
+
description: params.description,
|
|
2614
|
+
status: params.status || "pending",
|
|
2615
|
+
priority: params.priority || "medium",
|
|
2616
|
+
dueDate: params.dueDate,
|
|
2617
|
+
metadata: params.metadata,
|
|
2618
|
+
parentId: params.parentId,
|
|
2619
|
+
sourceId: params.sourceId,
|
|
2620
|
+
context: params.context,
|
|
2621
|
+
createdAt: now,
|
|
2622
|
+
updatedAt: now
|
|
2623
|
+
};
|
|
2624
|
+
this.tasks.get(params.tenantId).set(task.id, task);
|
|
2625
|
+
return task;
|
|
2626
|
+
}
|
|
2627
|
+
/**
|
|
2628
|
+
* Get task by ID
|
|
2629
|
+
*/
|
|
2630
|
+
async getById(tenantId, id) {
|
|
2631
|
+
const tenantTasks = this.tasks.get(tenantId);
|
|
2632
|
+
if (!tenantTasks) return null;
|
|
2633
|
+
return tenantTasks.get(id) || null;
|
|
2634
|
+
}
|
|
2635
|
+
/**
|
|
2636
|
+
* List tasks matching filter criteria
|
|
2637
|
+
*/
|
|
2638
|
+
async list(filter2) {
|
|
2639
|
+
const tenantTasks = this.tasks.get(filter2.tenantId);
|
|
2640
|
+
if (!tenantTasks) return [];
|
|
2641
|
+
let results = Array.from(tenantTasks.values());
|
|
2642
|
+
if (filter2.ownerType) results = results.filter((t) => t.ownerType === filter2.ownerType);
|
|
2643
|
+
if (filter2.ownerId) results = results.filter((t) => t.ownerId === filter2.ownerId);
|
|
2644
|
+
if (filter2.status) results = results.filter((t) => t.status === filter2.status);
|
|
2645
|
+
if (filter2.priority) results = results.filter((t) => t.priority === filter2.priority);
|
|
2646
|
+
if (filter2.parentId) results = results.filter((t) => t.parentId === filter2.parentId);
|
|
2647
|
+
if (filter2.sourceId) results = results.filter((t) => t.sourceId === filter2.sourceId);
|
|
2648
|
+
if (filter2.metadata) {
|
|
2649
|
+
for (const [key, value] of Object.entries(filter2.metadata)) {
|
|
2650
|
+
results = results.filter((t) => t.metadata?.[key] === value);
|
|
2651
|
+
}
|
|
2652
|
+
}
|
|
2653
|
+
results.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
|
|
2654
|
+
const offset = filter2.offset || 0;
|
|
2655
|
+
const limit = filter2.limit || 100;
|
|
2656
|
+
return results.slice(offset, offset + limit);
|
|
2657
|
+
}
|
|
2658
|
+
/**
|
|
2659
|
+
* Update an existing task
|
|
2660
|
+
*/
|
|
2661
|
+
async update(tenantId, id, updates) {
|
|
2662
|
+
const tenantTasks = this.tasks.get(tenantId);
|
|
2663
|
+
if (!tenantTasks) return null;
|
|
2664
|
+
const existing = tenantTasks.get(id);
|
|
2665
|
+
if (!existing) return null;
|
|
2666
|
+
const updated = {
|
|
2667
|
+
...existing,
|
|
2668
|
+
...updates,
|
|
2669
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
2670
|
+
};
|
|
2671
|
+
tenantTasks.set(id, updated);
|
|
2672
|
+
return updated;
|
|
2673
|
+
}
|
|
2674
|
+
/**
|
|
2675
|
+
* Delete a task by ID
|
|
2676
|
+
*/
|
|
2677
|
+
async delete(tenantId, id) {
|
|
2678
|
+
const tenantTasks = this.tasks.get(tenantId);
|
|
2679
|
+
if (!tenantTasks) return false;
|
|
2680
|
+
return tenantTasks.delete(id);
|
|
2681
|
+
}
|
|
2682
|
+
/**
|
|
2683
|
+
* Clear all tasks for a tenant (useful for testing)
|
|
2684
|
+
*/
|
|
2685
|
+
clear(tenantId) {
|
|
2686
|
+
if (tenantId) {
|
|
2687
|
+
this.tasks.delete(tenantId);
|
|
2688
|
+
} else {
|
|
2689
|
+
this.tasks.clear();
|
|
2690
|
+
}
|
|
2691
|
+
}
|
|
2692
|
+
};
|
|
2693
|
+
|
|
2771
2694
|
// src/store_lattice/StoreLatticeManager.ts
|
|
2772
2695
|
var StoreLatticeManager = class _StoreLatticeManager extends BaseLatticeManager {
|
|
2773
2696
|
/**
|
|
@@ -2948,6 +2871,12 @@ storeLatticeManager.registerLattice(
|
|
|
2948
2871
|
"a2aApiKey",
|
|
2949
2872
|
defaultA2AApiKeyStore
|
|
2950
2873
|
);
|
|
2874
|
+
var defaultTaskStore = new InMemoryTaskStore();
|
|
2875
|
+
storeLatticeManager.registerLattice(
|
|
2876
|
+
"default",
|
|
2877
|
+
"task",
|
|
2878
|
+
defaultTaskStore
|
|
2879
|
+
);
|
|
2951
2880
|
|
|
2952
2881
|
// src/tool_lattice/manage_binding/index.ts
|
|
2953
2882
|
function getInstallationStore() {
|
|
@@ -2959,7 +2888,7 @@ var manageBindingSchema = z3.object({
|
|
|
2959
2888
|
channelInstallationId: z3.string().optional().describe("Channel installation ID (auto-detected if omitted and only one exists for this channel)"),
|
|
2960
2889
|
senderId: z3.string().optional().describe("Sender identifier (email address, Lark openId, Slack userId)"),
|
|
2961
2890
|
agentId: z3.string().optional().describe("Target agent ID to route messages to"),
|
|
2962
|
-
threadMode: z3.enum(["fixed", "per_conversation"]).optional().default("per_conversation").describe("Thread mode
|
|
2891
|
+
threadMode: z3.enum(["fixed", "per_conversation"]).optional().default("per_conversation").describe("Thread mode (ignored when channel adapter has its own thread strategy, e.g. Lark)"),
|
|
2963
2892
|
senderDisplayName: z3.string().optional().describe("Human-readable name for the sender")
|
|
2964
2893
|
});
|
|
2965
2894
|
registerToolLattice(
|
|
@@ -2968,9 +2897,13 @@ registerToolLattice(
|
|
|
2968
2897
|
name: "manage_binding",
|
|
2969
2898
|
description: `Manage sender-to-agent bindings for external channels (email, Lark, Slack).
|
|
2970
2899
|
|
|
2900
|
+
Bindings are OPTIONAL \u2014 if no binding exists for a sender, messages route to the installation's fallbackAgentId. Only create a binding when a specific sender needs a different agent.
|
|
2901
|
+
|
|
2902
|
+
Thread isolation is handled automatically by the channel adapter (e.g. Lark isolates by sender+date). threadMode is only used when the channel adapter does not have its own strategy.
|
|
2903
|
+
|
|
2971
2904
|
- list_installations: List available channel installations. Filter by channel type (optional). Use this first to discover available channelInstallationIds.
|
|
2972
|
-
- create: Bind a sender to an agent. Required: channel, senderId, agentId. Optional: threadMode
|
|
2973
|
-
- update: Update an existing binding. Required: channel, senderId. Optional: agentId, threadMode
|
|
2905
|
+
- create: Bind a sender to an agent. Required: channel, senderId, agentId. Optional: threadMode. channelInstallationId auto-detected if only one exists.
|
|
2906
|
+
- update: Update an existing binding. Required: channel, senderId. Optional: agentId, threadMode, senderDisplayName.
|
|
2974
2907
|
- delete: Remove a binding. Required: channel, senderId.
|
|
2975
2908
|
- list: List all bindings. Optional: channel, agentId, channelInstallationId.
|
|
2976
2909
|
|
|
@@ -2978,7 +2911,7 @@ A sender can only be bound to ONE agent per channel+installation combination.`,
|
|
|
2978
2911
|
schema: manageBindingSchema
|
|
2979
2912
|
},
|
|
2980
2913
|
async (input, config) => {
|
|
2981
|
-
const
|
|
2914
|
+
const registry3 = getBindingRegistry();
|
|
2982
2915
|
const runConfig = config?.configurable?.runConfig || {};
|
|
2983
2916
|
const tenantId = runConfig.tenantId || "default";
|
|
2984
2917
|
switch (input.action) {
|
|
@@ -3001,7 +2934,7 @@ A sender can only be bound to ONE agent per channel+installation combination.`,
|
|
|
3001
2934
|
error: `No channelInstallationId provided and unable to auto-detect. Use action=list_installations to find available installations for channel "${input.channel}".`
|
|
3002
2935
|
});
|
|
3003
2936
|
}
|
|
3004
|
-
const binding = await
|
|
2937
|
+
const binding = await registry3.create({
|
|
3005
2938
|
channel: input.channel,
|
|
3006
2939
|
channelInstallationId: installId,
|
|
3007
2940
|
tenantId,
|
|
@@ -3023,7 +2956,7 @@ A sender can only be bound to ONE agent per channel+installation combination.`,
|
|
|
3023
2956
|
error: `No channelInstallationId provided and unable to auto-detect. Use action=list_installations first.`
|
|
3024
2957
|
});
|
|
3025
2958
|
}
|
|
3026
|
-
const existing = await
|
|
2959
|
+
const existing = await registry3.resolve({
|
|
3027
2960
|
channel: input.channel,
|
|
3028
2961
|
senderId: input.senderId,
|
|
3029
2962
|
channelInstallationId: installId,
|
|
@@ -3032,7 +2965,7 @@ A sender can only be bound to ONE agent per channel+installation combination.`,
|
|
|
3032
2965
|
if (!existing) {
|
|
3033
2966
|
return JSON.stringify({ success: false, error: "Binding not found" });
|
|
3034
2967
|
}
|
|
3035
|
-
const updated = await
|
|
2968
|
+
const updated = await registry3.update(existing.id, {
|
|
3036
2969
|
agentId: input.agentId,
|
|
3037
2970
|
threadMode: input.threadMode,
|
|
3038
2971
|
senderDisplayName: input.senderDisplayName
|
|
@@ -3050,7 +2983,7 @@ A sender can only be bound to ONE agent per channel+installation combination.`,
|
|
|
3050
2983
|
error: `No channelInstallationId provided and unable to auto-detect.`
|
|
3051
2984
|
});
|
|
3052
2985
|
}
|
|
3053
|
-
const existing = await
|
|
2986
|
+
const existing = await registry3.resolve({
|
|
3054
2987
|
channel: input.channel,
|
|
3055
2988
|
senderId: input.senderId,
|
|
3056
2989
|
channelInstallationId: installId,
|
|
@@ -3059,11 +2992,11 @@ A sender can only be bound to ONE agent per channel+installation combination.`,
|
|
|
3059
2992
|
if (!existing) {
|
|
3060
2993
|
return JSON.stringify({ success: false, error: "Binding not found" });
|
|
3061
2994
|
}
|
|
3062
|
-
await
|
|
2995
|
+
await registry3.delete(existing.id);
|
|
3063
2996
|
return JSON.stringify({ success: true, message: "Binding deleted" });
|
|
3064
2997
|
}
|
|
3065
2998
|
case "list": {
|
|
3066
|
-
const bindings = await
|
|
2999
|
+
const bindings = await registry3.list({
|
|
3067
3000
|
channel: input.channel,
|
|
3068
3001
|
agentId: input.agentId,
|
|
3069
3002
|
tenantId,
|
|
@@ -7049,86 +6982,6 @@ import {
|
|
|
7049
6982
|
getSubAgentsFromConfig
|
|
7050
6983
|
} from "@axiom-lattice/protocols";
|
|
7051
6984
|
|
|
7052
|
-
// src/memory_lattice/DefaultMemorySaver.ts
|
|
7053
|
-
import { MemorySaver } from "@langchain/langgraph";
|
|
7054
|
-
|
|
7055
|
-
// src/memory_lattice/MemoryLatticeManager.ts
|
|
7056
|
-
import { MemoryType } from "@axiom-lattice/protocols";
|
|
7057
|
-
var _MemoryLatticeManager = class _MemoryLatticeManager extends BaseLatticeManager {
|
|
7058
|
-
/**
|
|
7059
|
-
* 私有构造函数,防止外部直接实例化
|
|
7060
|
-
*/
|
|
7061
|
-
constructor() {
|
|
7062
|
-
super();
|
|
7063
|
-
}
|
|
7064
|
-
/**
|
|
7065
|
-
* 获取单例实例
|
|
7066
|
-
*/
|
|
7067
|
-
static getInstance() {
|
|
7068
|
-
if (!_MemoryLatticeManager.instance) {
|
|
7069
|
-
_MemoryLatticeManager.instance = new _MemoryLatticeManager();
|
|
7070
|
-
}
|
|
7071
|
-
return _MemoryLatticeManager.instance;
|
|
7072
|
-
}
|
|
7073
|
-
/**
|
|
7074
|
-
* 获取Lattice类型
|
|
7075
|
-
*/
|
|
7076
|
-
getLatticeType() {
|
|
7077
|
-
return "memory";
|
|
7078
|
-
}
|
|
7079
|
-
/**
|
|
7080
|
-
* 注册检查点保存器
|
|
7081
|
-
* @param key 保存器键名
|
|
7082
|
-
* @param saver 检查点保存器实例
|
|
7083
|
-
*/
|
|
7084
|
-
registerCheckpointSaver(key, saver) {
|
|
7085
|
-
if (_MemoryLatticeManager.checkpointSavers.has(key)) {
|
|
7086
|
-
console.warn(`\u68C0\u67E5\u70B9\u4FDD\u5B58\u5668 "${key}" \u5DF2\u7ECF\u5B58\u5728\uFF0C\u5C06\u4F1A\u8986\u76D6\u65E7\u7684\u68C0\u67E5\u70B9\u4FDD\u5B58\u5668`);
|
|
7087
|
-
}
|
|
7088
|
-
_MemoryLatticeManager.checkpointSavers.set(key, saver);
|
|
7089
|
-
}
|
|
7090
|
-
/**
|
|
7091
|
-
* 获取检查点保存器
|
|
7092
|
-
* @param key 保存器键名
|
|
7093
|
-
*/
|
|
7094
|
-
getCheckpointSaver(key) {
|
|
7095
|
-
const saver = _MemoryLatticeManager.checkpointSavers.get(key);
|
|
7096
|
-
if (!saver) {
|
|
7097
|
-
throw new Error(`\u68C0\u67E5\u70B9\u4FDD\u5B58\u5668 "${key}" \u4E0D\u5B58\u5728`);
|
|
7098
|
-
}
|
|
7099
|
-
return saver;
|
|
7100
|
-
}
|
|
7101
|
-
/**
|
|
7102
|
-
* 获取所有已注册的检查点保存器键名
|
|
7103
|
-
*/
|
|
7104
|
-
getCheckpointSaverKeys() {
|
|
7105
|
-
return Array.from(_MemoryLatticeManager.checkpointSavers.keys());
|
|
7106
|
-
}
|
|
7107
|
-
/**
|
|
7108
|
-
* 检查检查点保存器是否存在
|
|
7109
|
-
* @param key 保存器键名
|
|
7110
|
-
*/
|
|
7111
|
-
hasCheckpointSaver(key) {
|
|
7112
|
-
return _MemoryLatticeManager.checkpointSavers.has(key);
|
|
7113
|
-
}
|
|
7114
|
-
/**
|
|
7115
|
-
* 移除检查点保存器
|
|
7116
|
-
* @param key 保存器键名
|
|
7117
|
-
*/
|
|
7118
|
-
removeCheckpointSaver(key) {
|
|
7119
|
-
return _MemoryLatticeManager.checkpointSavers.delete(key);
|
|
7120
|
-
}
|
|
7121
|
-
};
|
|
7122
|
-
// 检查点保存器注册表
|
|
7123
|
-
_MemoryLatticeManager.checkpointSavers = /* @__PURE__ */ new Map();
|
|
7124
|
-
var MemoryLatticeManager = _MemoryLatticeManager;
|
|
7125
|
-
var getCheckpointSaver = (key) => MemoryLatticeManager.getInstance().getCheckpointSaver(key);
|
|
7126
|
-
var registerCheckpointSaver = (key, saver) => MemoryLatticeManager.getInstance().registerCheckpointSaver(key, saver);
|
|
7127
|
-
|
|
7128
|
-
// src/memory_lattice/DefaultMemorySaver.ts
|
|
7129
|
-
var memory = new MemorySaver();
|
|
7130
|
-
registerCheckpointSaver("default", memory);
|
|
7131
|
-
|
|
7132
6985
|
// src/agent_lattice/builders/state.ts
|
|
7133
6986
|
import "@langchain/langgraph/zod";
|
|
7134
6987
|
import { MessagesZodState } from "@langchain/langgraph";
|
|
@@ -7606,25 +7459,253 @@ metadata:
|
|
|
7606
7459
|
**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."
|
|
7607
7460
|
|
|
7608
7461
|
Then iterate based on what the user says.
|
|
7609
|
-
|
|
7610
|
-
|
|
7611
|
-
|
|
7612
|
-
|
|
7613
|
-
|
|
7614
|
-
|
|
7615
|
-
|
|
7616
|
-
|
|
7617
|
-
|
|
7618
|
-
|
|
7619
|
-
|
|
7620
|
-
|
|
7621
|
-
|
|
7622
|
-
|
|
7623
|
-
|
|
7624
|
-
|
|
7625
|
-
|
|
7626
|
-
|
|
7627
|
-
|
|
7462
|
+
`,
|
|
7463
|
+
"create-workflow": `---
|
|
7464
|
+
name: create-workflow
|
|
7465
|
+
description: Design and build multi-step AI workflows using the YAML linear DSL. Use whenever users want to orchestrate agents in a pipeline with routing, parallelism, human-in-the-loop, or batch processing.
|
|
7466
|
+
license: MIT
|
|
7467
|
+
metadata:
|
|
7468
|
+
category: meta
|
|
7469
|
+
version: "5.0"
|
|
7470
|
+
---
|
|
7471
|
+
|
|
7472
|
+
# YAML Workflow Designer
|
|
7473
|
+
|
|
7474
|
+
Use the linear YAML DSL \u2014 steps execute top-to-bottom. Use \`parallel:\` for concurrency. No dependency graph thinking required.
|
|
7475
|
+
|
|
7476
|
+
## Core Model: Linear + Parallel
|
|
7477
|
+
|
|
7478
|
+
- **Linear** \u2014 steps execute in written order. No \`needs\`, no dependency declarations.
|
|
7479
|
+
- **parallel** \u2014 a block where all children run concurrently. Block completes when all children finish.
|
|
7480
|
+
- **if** \u2014 JS expression. Step runs only when truthy. Omit to always run.
|
|
7481
|
+
- **prompt** \u2014 agent instruction with **{{label}}** refs. **{{input}}** is the user message.
|
|
7482
|
+
- **output** \u2014 shorthand schema using **{ field: type }** notation.
|
|
7483
|
+
- **ask** \u2014 boolean. Injects user clarification middleware for human interaction.
|
|
7484
|
+
|
|
7485
|
+
## When to Use parallel vs map
|
|
7486
|
+
|
|
7487
|
+
This is the most important design decision. **They are fundamentally different:**
|
|
7488
|
+
|
|
7489
|
+
| | parallel | map |
|
|
7490
|
+
|---|---|---|
|
|
7491
|
+
| **Concern** | **Business parallelism** \u2014 reduce business processing time | **Data parallelism** \u2014 handle data volume |
|
|
7492
|
+
| **Tasks** | Each child does a **different** task | All items do the **same** task |
|
|
7493
|
+
| **Count** | Few (2-5), each hand-written | Dynamic, driven by source data |
|
|
7494
|
+
| **Input** | Independent prompts per child | Single \`each.prompt\` template, \`{{item}}\` for current element |
|
|
7495
|
+
| **if** | Per-child conditional | Whole block conditional |
|
|
7496
|
+
| **Example** | Legal review + Market analysis in parallel | Audit each line item in an invoice |
|
|
7497
|
+
|
|
7498
|
+
**Rule of thumb:** If you're writing the same prompt twice, you probably want \`map\`. If each branch has a unique purpose, use \`parallel\`.
|
|
7499
|
+
|
|
7500
|
+
## Step Format
|
|
7501
|
+
|
|
7502
|
+
### Agent Step
|
|
7503
|
+
|
|
7504
|
+
\`\`\`yaml
|
|
7505
|
+
- label:
|
|
7506
|
+
prompt: instruction with {{refs}}
|
|
7507
|
+
if: "expression"
|
|
7508
|
+
output: { field: type }
|
|
7509
|
+
ask: true
|
|
7510
|
+
\`\`\`
|
|
7511
|
+
|
|
7512
|
+
### Parallel Block
|
|
7513
|
+
|
|
7514
|
+
\`\`\`yaml
|
|
7515
|
+
- parallel:
|
|
7516
|
+
- child1:
|
|
7517
|
+
prompt: ...
|
|
7518
|
+
if: "expression"
|
|
7519
|
+
- child2:
|
|
7520
|
+
prompt: ...
|
|
7521
|
+
\`\`\`
|
|
7522
|
+
|
|
7523
|
+
Parallel children are agent steps only. No nested parallel or map inside parallel.
|
|
7524
|
+
|
|
7525
|
+
### Map Step
|
|
7526
|
+
|
|
7527
|
+
\`\`\`yaml
|
|
7528
|
+
- label:
|
|
7529
|
+
map:
|
|
7530
|
+
source: "extract.items"
|
|
7531
|
+
if: "extract.items.length > 0"
|
|
7532
|
+
each:
|
|
7533
|
+
prompt: Process {{item}}
|
|
7534
|
+
output: { result: string }
|
|
7535
|
+
batch: 50
|
|
7536
|
+
concurrency: 5
|
|
7537
|
+
\`\`\`
|
|
7538
|
+
|
|
7539
|
+
## Schema Shorthand
|
|
7540
|
+
|
|
7541
|
+
Write **{ field: type }** instead of JSON Schema:
|
|
7542
|
+
|
|
7543
|
+
| Shorthand | Meaning |
|
|
7544
|
+
|-----------|---------|
|
|
7545
|
+
| **field: string** | string property |
|
|
7546
|
+
| **field: number** | number property |
|
|
7547
|
+
| **field: boolean** | boolean property |
|
|
7548
|
+
| **field: string[]** | array of strings |
|
|
7549
|
+
| **field: number[]** | array of numbers |
|
|
7550
|
+
| **field: [{ a: string, b: number }]** | array of objects |
|
|
7551
|
+
| **field: { sub: string }** | nested object |
|
|
7552
|
+
|
|
7553
|
+
Use **block style** (each field on its own line). Flow style \`{ field: "type" }\` with quoted values also works.
|
|
7554
|
+
|
|
7555
|
+
## Template Syntax
|
|
7556
|
+
|
|
7557
|
+
| Syntax | Resolves to |
|
|
7558
|
+
|--------|------------|
|
|
7559
|
+
| \`{{input}}\` | Initial user message |
|
|
7560
|
+
| \`{{label}}\` | Full output of step |
|
|
7561
|
+
| \`{{label.field}}\` | Nested field access |
|
|
7562
|
+
| \`{{item}}\` | Current element in map iteration |
|
|
7563
|
+
|
|
7564
|
+
## Design Patterns
|
|
7565
|
+
|
|
7566
|
+
### Linear Pipeline
|
|
7567
|
+
|
|
7568
|
+
\`\`\`yaml
|
|
7569
|
+
steps:
|
|
7570
|
+
- extract:
|
|
7571
|
+
prompt: Extract data from {{input}}
|
|
7572
|
+
- transform:
|
|
7573
|
+
prompt: Transform {{extract}}
|
|
7574
|
+
- final:
|
|
7575
|
+
prompt: Combine raw {{extract}} with transformed {{transform}}
|
|
7576
|
+
\`\`\`
|
|
7577
|
+
|
|
7578
|
+
### Classify -> Route via Parallel + if
|
|
7579
|
+
|
|
7580
|
+
\`\`\`yaml
|
|
7581
|
+
steps:
|
|
7582
|
+
- classify:
|
|
7583
|
+
prompt: Classify intent from {{input}}
|
|
7584
|
+
output:
|
|
7585
|
+
intent: string
|
|
7586
|
+
urgency: number
|
|
7587
|
+
- parallel:
|
|
7588
|
+
- billing:
|
|
7589
|
+
if: "classify.intent == 'billing'"
|
|
7590
|
+
prompt: Handle billing: {{input}}
|
|
7591
|
+
ask: true
|
|
7592
|
+
- technical:
|
|
7593
|
+
if: "classify.intent == 'technical'"
|
|
7594
|
+
prompt: Handle technical: {{input}}
|
|
7595
|
+
- escalate:
|
|
7596
|
+
if: "classify.urgency >= 8"
|
|
7597
|
+
prompt: Urgent handling
|
|
7598
|
+
ask: true
|
|
7599
|
+
\`\`\`
|
|
7600
|
+
|
|
7601
|
+
### Parallel Processing
|
|
7602
|
+
|
|
7603
|
+
\`\`\`yaml
|
|
7604
|
+
steps:
|
|
7605
|
+
- gather:
|
|
7606
|
+
prompt: Gather data from {{input}}
|
|
7607
|
+
- parallel:
|
|
7608
|
+
- legal:
|
|
7609
|
+
prompt: Legal analysis of {{gather}}
|
|
7610
|
+
output:
|
|
7611
|
+
risk: string
|
|
7612
|
+
compliant: boolean
|
|
7613
|
+
- market:
|
|
7614
|
+
prompt: Market analysis of {{gather}}
|
|
7615
|
+
output:
|
|
7616
|
+
opportunity: string
|
|
7617
|
+
score: number
|
|
7618
|
+
- report:
|
|
7619
|
+
prompt: |
|
|
7620
|
+
Synthesize findings:
|
|
7621
|
+
Legal: {{legal}}
|
|
7622
|
+
Market: {{market}}
|
|
7623
|
+
\`\`\`
|
|
7624
|
+
|
|
7625
|
+
### Approval Flow with Human
|
|
7626
|
+
|
|
7627
|
+
\`\`\`yaml
|
|
7628
|
+
steps:
|
|
7629
|
+
- draft:
|
|
7630
|
+
prompt: Draft response to {{input}}
|
|
7631
|
+
- review:
|
|
7632
|
+
prompt: Present {{draft}} to user for approval
|
|
7633
|
+
output:
|
|
7634
|
+
approved: boolean
|
|
7635
|
+
comments: string
|
|
7636
|
+
ask: true
|
|
7637
|
+
- publish:
|
|
7638
|
+
if: "review.approved"
|
|
7639
|
+
prompt: Publish {{draft}}
|
|
7640
|
+
- revise:
|
|
7641
|
+
if: "!review.approved"
|
|
7642
|
+
prompt: Revise based on {{review.comments}}
|
|
7643
|
+
\`\`\`
|
|
7644
|
+
|
|
7645
|
+
### Map (Iteration)
|
|
7646
|
+
|
|
7647
|
+
\`\`\`yaml
|
|
7648
|
+
steps:
|
|
7649
|
+
- extract:
|
|
7650
|
+
prompt: Extract items from {{input}}
|
|
7651
|
+
output:
|
|
7652
|
+
items:
|
|
7653
|
+
- name: string
|
|
7654
|
+
- map_items:
|
|
7655
|
+
map:
|
|
7656
|
+
source: "extract.items"
|
|
7657
|
+
each:
|
|
7658
|
+
prompt: Audit {{item.name}}
|
|
7659
|
+
output:
|
|
7660
|
+
result: string
|
|
7661
|
+
- summary:
|
|
7662
|
+
prompt: Summarize findings: {{map_items}}
|
|
7663
|
+
\`\`\`
|
|
7664
|
+
|
|
7665
|
+
## Keep Business Logic in Agents
|
|
7666
|
+
|
|
7667
|
+
The DSL is for orchestration (what runs when). Business logic (validation, branching, error handling, user interaction) belongs inside agent prompts, not as workflow if conditions. An agent can validate, branch, and ask questions \u2014 all in one step.
|
|
7668
|
+
|
|
7669
|
+
**Rule:** if you have more if conditions than workflow phases, move logic into richer agent prompts.
|
|
7670
|
+
|
|
7671
|
+
## What You NEVER Write
|
|
7672
|
+
|
|
7673
|
+
- **needs** \u2014 not supported. Steps execute linearly. Use parallel for concurrency.
|
|
7674
|
+
- **edges** \u2014 auto-generated from step order and parallel structure
|
|
7675
|
+
- **nested parallel** \u2014 parallel children are flat agent steps only
|
|
7676
|
+
- **map inside parallel** \u2014 map is a top-level step only
|
|
7677
|
+
- **json schema** \u2014 use **{ field: type }** block style
|
|
7678
|
+
- do not use {{}} markers in if expressions
|
|
7679
|
+
- **workflow-level business logic** \u2014 decisions belong inside agent prompts
|
|
7680
|
+
|
|
7681
|
+
## Checklist
|
|
7682
|
+
|
|
7683
|
+
- Every step has a unique label
|
|
7684
|
+
- Steps execute top-to-bottom \u2014 no dependency thinking needed
|
|
7685
|
+
- \`{{label}}\` can reference ANY upstream step output
|
|
7686
|
+
- if uses plain JS, no {{}}
|
|
7687
|
+
- Schema uses block style shorthand
|
|
7688
|
+
- parallel children are flat agent steps
|
|
7689
|
+
- Business logic stays inside agent prompts
|
|
7690
|
+
- ask: true for human interaction`
|
|
7691
|
+
};
|
|
7692
|
+
function getBuiltInSkillMeta(name) {
|
|
7693
|
+
const content = BUILTIN_SKILLS[name];
|
|
7694
|
+
if (!content) return null;
|
|
7695
|
+
try {
|
|
7696
|
+
const { meta } = parseSkillFrontmatter(content);
|
|
7697
|
+
return meta;
|
|
7698
|
+
} catch {
|
|
7699
|
+
return null;
|
|
7700
|
+
}
|
|
7701
|
+
}
|
|
7702
|
+
function getBuiltInSkillContent(name) {
|
|
7703
|
+
return BUILTIN_SKILLS[name];
|
|
7704
|
+
}
|
|
7705
|
+
function getAllBuiltInSkillMetas() {
|
|
7706
|
+
return Object.keys(BUILTIN_SKILLS).map((name) => getBuiltInSkillMeta(name)).filter((meta) => meta !== null);
|
|
7707
|
+
}
|
|
7708
|
+
function getBuiltInSkillNames() {
|
|
7628
7709
|
return Object.keys(BUILTIN_SKILLS);
|
|
7629
7710
|
}
|
|
7630
7711
|
function isBuiltInSkill(name) {
|
|
@@ -10517,7 +10598,7 @@ ${currentSystemPrompt}` : dateContext;
|
|
|
10517
10598
|
// src/deep_agent_new/middleware/scheduler.ts
|
|
10518
10599
|
import { tool as tool45, createMiddleware as createMiddleware13 } from "langchain";
|
|
10519
10600
|
import { z as z48 } from "zod";
|
|
10520
|
-
import { v4 as
|
|
10601
|
+
import { v4 as uuidv42 } from "uuid";
|
|
10521
10602
|
import { ScheduledTaskStatus as ScheduledTaskStatus3, ScheduleExecutionType as ScheduleExecutionType3 } from "@axiom-lattice/protocols";
|
|
10522
10603
|
|
|
10523
10604
|
// src/schedule_lattice/ScheduleLatticeManager.ts
|
|
@@ -12162,7 +12243,6 @@ var Agent = class {
|
|
|
12162
12243
|
const runnable_agent = await getAgentClientAsync(this.tenant_id, this.assistant_id);
|
|
12163
12244
|
const agentLattice = agentLatticeManager.getAgentLatticeWithTenant(this.tenant_id, this.assistant_id);
|
|
12164
12245
|
const { messages, ...rest } = input;
|
|
12165
|
-
const lifecycleManager = this;
|
|
12166
12246
|
const runConfig = {
|
|
12167
12247
|
thread_id: this.thread_id,
|
|
12168
12248
|
"x-tenant-id": this.tenant_id,
|
|
@@ -12214,43 +12294,13 @@ var Agent = class {
|
|
|
12214
12294
|
}
|
|
12215
12295
|
);
|
|
12216
12296
|
try {
|
|
12217
|
-
|
|
12218
|
-
if (signal?.aborted) {
|
|
12219
|
-
await lifecycleManager.chunkBuffer.abortThread(lifecycleManager.thread_id);
|
|
12220
|
-
throw new Error("Agent execution was aborted");
|
|
12221
|
-
}
|
|
12222
|
-
let data;
|
|
12223
|
-
let chunkContent = "";
|
|
12224
|
-
if (chunk[0] === "updates") {
|
|
12225
|
-
const update = chunk[1];
|
|
12226
|
-
const values = Object.values(update);
|
|
12227
|
-
const messages2 = values[0]?.messages;
|
|
12228
|
-
if (messages2?.[0]?.tool_call_id) {
|
|
12229
|
-
data = messages2[0].toDict();
|
|
12230
|
-
}
|
|
12231
|
-
} else if (chunk[0] === "messages") {
|
|
12232
|
-
const messages2 = chunk[1];
|
|
12233
|
-
data = messages2?.[0]?.toDict();
|
|
12234
|
-
}
|
|
12235
|
-
if (chunk?.[1]?.__interrupt__) {
|
|
12236
|
-
const interruptData = chunk?.[1]?.__interrupt__[0];
|
|
12237
|
-
data = {
|
|
12238
|
-
type: "interrupt",
|
|
12239
|
-
id: interruptData.id,
|
|
12240
|
-
data: { content: interruptData.value }
|
|
12241
|
-
};
|
|
12242
|
-
}
|
|
12243
|
-
if (data) {
|
|
12244
|
-
lifecycleManager.addChunk(data);
|
|
12245
|
-
}
|
|
12246
|
-
}
|
|
12297
|
+
await this.consumeAgentStream(agentStream, signal);
|
|
12247
12298
|
} catch (error) {
|
|
12248
12299
|
console.error("Stream error:", error);
|
|
12249
|
-
await lifecycleManager.chunkBuffer.abortThread(lifecycleManager.thread_id);
|
|
12250
12300
|
throw error;
|
|
12251
12301
|
}
|
|
12252
12302
|
} catch (error) {
|
|
12253
|
-
await this.chunkBuffer.abortThread(
|
|
12303
|
+
await this.chunkBuffer.abortThread(this.thread_id);
|
|
12254
12304
|
throw error;
|
|
12255
12305
|
}
|
|
12256
12306
|
};
|
|
@@ -12531,8 +12581,8 @@ var Agent = class {
|
|
|
12531
12581
|
this.assistant_id = assistant_id;
|
|
12532
12582
|
this.thread_id = thread_id;
|
|
12533
12583
|
this.tenant_id = tenant_id;
|
|
12534
|
-
this.workspace_id = workspace_id;
|
|
12535
|
-
this.project_id = project_id;
|
|
12584
|
+
this.workspace_id = workspace_id || "default";
|
|
12585
|
+
this.project_id = project_id || "default";
|
|
12536
12586
|
this.custom_run_config = custom_run_config;
|
|
12537
12587
|
}
|
|
12538
12588
|
getHumanPendingContent(message) {
|
|
@@ -12626,10 +12676,132 @@ var Agent = class {
|
|
|
12626
12676
|
const inputMessage = { ...queueMessage, input };
|
|
12627
12677
|
return this.agentExecutor(inputMessage, signal);
|
|
12628
12678
|
}
|
|
12679
|
+
/**
|
|
12680
|
+
* Like {@link invoke} but returns the full LangGraph state (all annotations)
|
|
12681
|
+
* instead of only messages. Messages are serialized to dicts; other state
|
|
12682
|
+
* fields are returned as-is.
|
|
12683
|
+
*
|
|
12684
|
+
* @remarks
|
|
12685
|
+
* Only call this when you need the full state. Existing callers (gateway,
|
|
12686
|
+
* workflows) should keep using {@link invoke} which returns only messages
|
|
12687
|
+
* to avoid exposing internal annotation data.
|
|
12688
|
+
*/
|
|
12689
|
+
async invokeWithState(queueMessage, signal) {
|
|
12690
|
+
const messageId = v4();
|
|
12691
|
+
const input = {
|
|
12692
|
+
...queueMessage.input,
|
|
12693
|
+
messages: [new HumanMessage({ id: messageId, content: queueMessage.input.message })]
|
|
12694
|
+
};
|
|
12695
|
+
const inputMessage = { ...queueMessage, input };
|
|
12696
|
+
const { runnable_agent, runConfig } = await this.getLatticeClientAndRuntimeConfig(inputMessage.custom_run_config);
|
|
12697
|
+
const { messages, ...rest } = inputMessage.input;
|
|
12698
|
+
if (signal?.aborted) {
|
|
12699
|
+
throw new Error("Agent execution was aborted");
|
|
12700
|
+
}
|
|
12701
|
+
let result;
|
|
12702
|
+
result = await runnable_agent.invoke(
|
|
12703
|
+
inputMessage.command ? new Command2(inputMessage.command) : { ...rest, messages, "x-tenant-id": this.tenant_id },
|
|
12704
|
+
{
|
|
12705
|
+
context: { runConfig },
|
|
12706
|
+
configurable: {
|
|
12707
|
+
run_id: v4(),
|
|
12708
|
+
...runConfig,
|
|
12709
|
+
runConfig
|
|
12710
|
+
},
|
|
12711
|
+
recursionLimit: 200,
|
|
12712
|
+
signal
|
|
12713
|
+
}
|
|
12714
|
+
);
|
|
12715
|
+
if (signal?.aborted) {
|
|
12716
|
+
throw new Error("Agent execution was aborted");
|
|
12717
|
+
}
|
|
12718
|
+
const { messages: _rawMessages, ...restState } = result;
|
|
12719
|
+
const serializedMessages = result.messages.map((message) => {
|
|
12720
|
+
const { type, data } = message.toDict();
|
|
12721
|
+
return { ...data, role: type };
|
|
12722
|
+
});
|
|
12723
|
+
return { messages: serializedMessages, ...restState };
|
|
12724
|
+
}
|
|
12629
12725
|
async getPendingMessages() {
|
|
12630
12726
|
const store = this.getQueueStore();
|
|
12631
12727
|
return await store.getPendingMessages(this.thread_id);
|
|
12632
12728
|
}
|
|
12729
|
+
async consumeAgentStream(agentStream, signal) {
|
|
12730
|
+
for await (const chunk of agentStream) {
|
|
12731
|
+
if (signal?.aborted) {
|
|
12732
|
+
await this.chunkBuffer.abortThread(this.thread_id);
|
|
12733
|
+
throw new Error("Agent execution was aborted");
|
|
12734
|
+
}
|
|
12735
|
+
let data;
|
|
12736
|
+
if (chunk[0] === "updates") {
|
|
12737
|
+
const update = chunk[1];
|
|
12738
|
+
const values = Object.values(update);
|
|
12739
|
+
const messages = values[0]?.messages;
|
|
12740
|
+
if (messages?.[0]?.tool_call_id) {
|
|
12741
|
+
data = messages[0].toDict();
|
|
12742
|
+
}
|
|
12743
|
+
} else if (chunk[0] === "messages") {
|
|
12744
|
+
const messages = chunk[1];
|
|
12745
|
+
data = messages?.[0]?.toDict();
|
|
12746
|
+
}
|
|
12747
|
+
if (chunk?.[1]?.__interrupt__) {
|
|
12748
|
+
const interruptData = chunk?.[1]?.__interrupt__[0];
|
|
12749
|
+
data = {
|
|
12750
|
+
type: "interrupt",
|
|
12751
|
+
id: interruptData.id,
|
|
12752
|
+
data: { content: interruptData.value }
|
|
12753
|
+
};
|
|
12754
|
+
}
|
|
12755
|
+
if (data) {
|
|
12756
|
+
this.addChunk(data);
|
|
12757
|
+
}
|
|
12758
|
+
}
|
|
12759
|
+
}
|
|
12760
|
+
/**
|
|
12761
|
+
* Resume LangGraph execution from the last checkpoint.
|
|
12762
|
+
*
|
|
12763
|
+
* Streams with `null` input — this tells LangGraph to continue from
|
|
12764
|
+
* wherever it left off using the checkpointed state for this thread.
|
|
12765
|
+
* All output chunks are buffered via {@link addChunk}.
|
|
12766
|
+
*/
|
|
12767
|
+
async resumeGraphFromCheckpoint(signal) {
|
|
12768
|
+
const runnable_agent = await getAgentClientAsync(this.tenant_id, this.assistant_id);
|
|
12769
|
+
const agentLattice = agentLatticeManager.getAgentLatticeWithTenant(this.tenant_id, this.assistant_id);
|
|
12770
|
+
if (!runnable_agent) {
|
|
12771
|
+
throw new Error(`Agent ${this.assistant_id} not found`);
|
|
12772
|
+
}
|
|
12773
|
+
const runConfig = {
|
|
12774
|
+
thread_id: this.thread_id,
|
|
12775
|
+
"x-tenant-id": this.tenant_id,
|
|
12776
|
+
"x-workspace-id": this.workspace_id,
|
|
12777
|
+
"x-project-id": this.project_id,
|
|
12778
|
+
"x-thread-id": this.thread_id,
|
|
12779
|
+
"x-assistant-id": this.assistant_id,
|
|
12780
|
+
...agentLattice?.config?.runConfig || {},
|
|
12781
|
+
tenantId: this.tenant_id,
|
|
12782
|
+
workspaceId: this.workspace_id,
|
|
12783
|
+
projectId: this.project_id,
|
|
12784
|
+
...this.custom_run_config || {},
|
|
12785
|
+
assistant_id: this.assistant_id
|
|
12786
|
+
};
|
|
12787
|
+
const agentStream = await runnable_agent.stream(
|
|
12788
|
+
null,
|
|
12789
|
+
{
|
|
12790
|
+
context: {
|
|
12791
|
+
runConfig
|
|
12792
|
+
},
|
|
12793
|
+
configurable: {
|
|
12794
|
+
...runConfig,
|
|
12795
|
+
runConfig
|
|
12796
|
+
},
|
|
12797
|
+
streamMode: ["updates", "messages"],
|
|
12798
|
+
subgraphs: false,
|
|
12799
|
+
recursionLimit: 200,
|
|
12800
|
+
signal
|
|
12801
|
+
}
|
|
12802
|
+
);
|
|
12803
|
+
await this.consumeAgentStream(agentStream, signal);
|
|
12804
|
+
}
|
|
12633
12805
|
getQueueStore() {
|
|
12634
12806
|
if (!this.queueStore) {
|
|
12635
12807
|
try {
|
|
@@ -12759,6 +12931,8 @@ var Agent = class {
|
|
|
12759
12931
|
threadId: this.thread_id,
|
|
12760
12932
|
tenantId: this.tenant_id,
|
|
12761
12933
|
assistantId: this.assistant_id,
|
|
12934
|
+
workspaceId: this.workspace_id,
|
|
12935
|
+
projectId: this.project_id,
|
|
12762
12936
|
content,
|
|
12763
12937
|
type: pendingType,
|
|
12764
12938
|
command: queueMessage.command,
|
|
@@ -12775,6 +12949,8 @@ var Agent = class {
|
|
|
12775
12949
|
threadId: this.thread_id,
|
|
12776
12950
|
tenantId: this.tenant_id,
|
|
12777
12951
|
assistantId: this.assistant_id,
|
|
12952
|
+
workspaceId: this.workspace_id,
|
|
12953
|
+
projectId: this.project_id,
|
|
12778
12954
|
content,
|
|
12779
12955
|
type: pendingType,
|
|
12780
12956
|
command: queueMessage.command,
|
|
@@ -12848,6 +13024,8 @@ var Agent = class {
|
|
|
12848
13024
|
threadId: thread.threadId,
|
|
12849
13025
|
tenantId: thread.tenantId,
|
|
12850
13026
|
assistantId: thread.assistantId,
|
|
13027
|
+
workspaceId: this.workspace_id,
|
|
13028
|
+
projectId: this.project_id,
|
|
12851
13029
|
content: reminderContent,
|
|
12852
13030
|
type: "system"
|
|
12853
13031
|
});
|
|
@@ -12919,9 +13097,14 @@ var Agent = class {
|
|
|
12919
13097
|
/**
|
|
12920
13098
|
* Resume processing after a server restart.
|
|
12921
13099
|
*
|
|
12922
|
-
*
|
|
12923
|
-
*
|
|
12924
|
-
*
|
|
13100
|
+
* If the graph was mid-execution (BUSY) it resumes from the LangGraph
|
|
13101
|
+
* checkpoint without re-injecting the message — the message has already
|
|
13102
|
+
* been consumed and is in the graph state. Processing messages are removed
|
|
13103
|
+
* rather than replayed.
|
|
13104
|
+
*
|
|
13105
|
+
* Skips threads that are in `INTERRUPTED` state (the interruption was
|
|
13106
|
+
* intentional). IDLE threads simply clean up and restart the queue
|
|
13107
|
+
* processor for any remaining pending messages.
|
|
12925
13108
|
*
|
|
12926
13109
|
* Called during gateway startup to recover threads that were mid-execution
|
|
12927
13110
|
* when the server went down.
|
|
@@ -12939,9 +13122,32 @@ var Agent = class {
|
|
|
12939
13122
|
return;
|
|
12940
13123
|
}
|
|
12941
13124
|
const store = this.getQueueStore();
|
|
12942
|
-
|
|
12943
|
-
|
|
12944
|
-
|
|
13125
|
+
if (runStatus === "busy" /* BUSY */) {
|
|
13126
|
+
this.abortController = new AbortController();
|
|
13127
|
+
try {
|
|
13128
|
+
await this.resumeGraphFromCheckpoint(this.abortController.signal);
|
|
13129
|
+
const processingMessages = await store.getProcessingMessages(this.thread_id);
|
|
13130
|
+
for (const msg of processingMessages) {
|
|
13131
|
+
await store.removeMessage(msg.id);
|
|
13132
|
+
}
|
|
13133
|
+
if (processingMessages.length > 0) {
|
|
13134
|
+
console.log(`[Agent] Removed ${processingMessages.length} processing messages for thread ${this.thread_id}`);
|
|
13135
|
+
}
|
|
13136
|
+
} catch (error) {
|
|
13137
|
+
console.error(`[Agent] Failed to resume graph for thread ${this.thread_id}:`, error);
|
|
13138
|
+
await this.chunkBuffer.abortThread(this.thread_id);
|
|
13139
|
+
throw error;
|
|
13140
|
+
} finally {
|
|
13141
|
+
this.abortController = null;
|
|
13142
|
+
}
|
|
13143
|
+
} else {
|
|
13144
|
+
const processingMessages = await store.getProcessingMessages(this.thread_id);
|
|
13145
|
+
for (const msg of processingMessages) {
|
|
13146
|
+
await store.removeMessage(msg.id);
|
|
13147
|
+
}
|
|
13148
|
+
if (processingMessages.length > 0) {
|
|
13149
|
+
console.log(`[Agent] Removed ${processingMessages.length} processing messages for thread ${this.thread_id}`);
|
|
13150
|
+
}
|
|
12945
13151
|
}
|
|
12946
13152
|
await this.startQueueProcessorIfNeeded();
|
|
12947
13153
|
}
|
|
@@ -13132,7 +13338,7 @@ var AgentInstanceManager = class _AgentInstanceManager {
|
|
|
13132
13338
|
console.log(`[AgentInstanceManager] Found ${threadsWithPending.length} threads with pending messages, restoring...`);
|
|
13133
13339
|
for (const threadInfo of threadsWithPending) {
|
|
13134
13340
|
try {
|
|
13135
|
-
await this.restoreThread(threadInfo
|
|
13341
|
+
await this.restoreThread(threadInfo);
|
|
13136
13342
|
stats.restored++;
|
|
13137
13343
|
} catch (error) {
|
|
13138
13344
|
console.error(`[AgentInstanceManager] Failed to restore thread ${threadInfo.threadId}:`, error);
|
|
@@ -13150,16 +13356,14 @@ var AgentInstanceManager = class _AgentInstanceManager {
|
|
|
13150
13356
|
* Restore a single thread
|
|
13151
13357
|
* Delegates actual recovery logic to Agent.resumeTask()
|
|
13152
13358
|
*/
|
|
13153
|
-
async restoreThread(threadInfo
|
|
13154
|
-
const { tenantId, assistantId, threadId } = threadInfo;
|
|
13359
|
+
async restoreThread(threadInfo) {
|
|
13360
|
+
const { tenantId, assistantId, threadId, workspaceId, projectId } = threadInfo;
|
|
13155
13361
|
const threadParams = {
|
|
13156
13362
|
tenant_id: tenantId,
|
|
13157
13363
|
assistant_id: assistantId,
|
|
13158
13364
|
thread_id: threadId,
|
|
13159
|
-
workspace_id:
|
|
13160
|
-
|
|
13161
|
-
project_id: "default"
|
|
13162
|
-
// TODO: Get from thread store
|
|
13365
|
+
workspace_id: workspaceId,
|
|
13366
|
+
project_id: projectId
|
|
13163
13367
|
};
|
|
13164
13368
|
const agent = this.getAgent(threadParams);
|
|
13165
13369
|
await agent.resumeTask();
|
|
@@ -13250,7 +13454,7 @@ function createSchedulerMiddleware(options = {}) {
|
|
|
13250
13454
|
async (input, config) => {
|
|
13251
13455
|
const runConfig = getRunConfig(config);
|
|
13252
13456
|
const scheduleLattice = getScheduleLattice(SCHEDULE_LATTICE_KEY);
|
|
13253
|
-
const taskId =
|
|
13457
|
+
const taskId = uuidv42();
|
|
13254
13458
|
const executeAt = input.executeAt;
|
|
13255
13459
|
const success = await scheduleLattice.client.scheduleOnce(
|
|
13256
13460
|
taskId,
|
|
@@ -13285,7 +13489,7 @@ function createSchedulerMiddleware(options = {}) {
|
|
|
13285
13489
|
async (input, config) => {
|
|
13286
13490
|
const runConfig = getRunConfig(config);
|
|
13287
13491
|
const scheduleLattice = getScheduleLattice(SCHEDULE_LATTICE_KEY);
|
|
13288
|
-
const taskId =
|
|
13492
|
+
const taskId = uuidv42();
|
|
13289
13493
|
const executeAt = Date.now() + input.delayMs;
|
|
13290
13494
|
const success = await scheduleLattice.client.scheduleOnce(
|
|
13291
13495
|
taskId,
|
|
@@ -13320,7 +13524,7 @@ function createSchedulerMiddleware(options = {}) {
|
|
|
13320
13524
|
async (input, config) => {
|
|
13321
13525
|
const runConfig = getRunConfig(config);
|
|
13322
13526
|
const scheduleLattice = getScheduleLattice(SCHEDULE_LATTICE_KEY);
|
|
13323
|
-
const taskId =
|
|
13527
|
+
const taskId = uuidv42();
|
|
13324
13528
|
const success = await scheduleLattice.client.scheduleCron(
|
|
13325
13529
|
taskId,
|
|
13326
13530
|
AGENT_ADD_MESSAGE_TASK_TYPE,
|
|
@@ -13408,6 +13612,138 @@ function createSchedulerMiddleware(options = {}) {
|
|
|
13408
13612
|
});
|
|
13409
13613
|
}
|
|
13410
13614
|
|
|
13615
|
+
// src/middlewares/taskMiddleware.ts
|
|
13616
|
+
import { createMiddleware as createMiddleware14, tool as tool46 } from "langchain";
|
|
13617
|
+
import { z as z49 } from "zod";
|
|
13618
|
+
function getRunConfig2(config) {
|
|
13619
|
+
const c = config;
|
|
13620
|
+
return c?.configurable?.runConfig ?? {};
|
|
13621
|
+
}
|
|
13622
|
+
function getTaskStore() {
|
|
13623
|
+
return getStoreLattice("default", "task").store;
|
|
13624
|
+
}
|
|
13625
|
+
var manageTaskSchema = z49.object({
|
|
13626
|
+
action: z49.enum(["create", "list", "update", "delete", "complete"]).describe("\u64CD\u4F5C\u7C7B\u578B"),
|
|
13627
|
+
id: z49.string().optional().describe("\u4EFB\u52A1 ID (update/delete/complete \u5FC5\u586B)"),
|
|
13628
|
+
title: z49.string().optional().describe("\u4EFB\u52A1\u6807\u9898 (create \u5FC5\u586B)"),
|
|
13629
|
+
description: z49.string().optional().describe("\u4EFB\u52A1\u63CF\u8FF0"),
|
|
13630
|
+
priority: z49.enum(["low", "medium", "high"]).optional().describe("\u4F18\u5148\u7EA7"),
|
|
13631
|
+
status: z49.enum(["pending", "in_progress", "completed", "cancelled"]).optional().describe("\u72B6\u6001"),
|
|
13632
|
+
dueDate: z49.string().optional().describe("\u622A\u6B62\u65E5\u671F (ISO 8601)"),
|
|
13633
|
+
metadata: z49.record(z49.unknown()).optional().describe("\u7ED3\u6784\u5316\u5143\u6570\u636E (projectId, module \u7B49)"),
|
|
13634
|
+
parentId: z49.string().optional().describe("\u7236\u4EFB\u52A1 ID (\u5B50\u4EFB\u52A1\u5173\u8054)"),
|
|
13635
|
+
sourceId: z49.string().optional().describe("\u6765\u6E90\u4F1A\u8BDD/thread ID"),
|
|
13636
|
+
context: z49.record(z49.unknown()).optional().describe("\u9644\u52A0\u4E0A\u4E0B\u6587"),
|
|
13637
|
+
ownerType: z49.enum(["user", "agent"]).optional().describe("\u6240\u6709\u8005\u7C7B\u578B\uFF0C\u4E0D\u4F20\u9ED8\u8BA4\u4E3A user"),
|
|
13638
|
+
ownerId: z49.string().optional().describe("\u6240\u6709\u8005 ID\uFF0C\u4E0D\u4F20\u81EA\u52A8\u53D6\u5F53\u524D\u7528\u6237/Agent")
|
|
13639
|
+
});
|
|
13640
|
+
function createTaskMiddleware() {
|
|
13641
|
+
return createMiddleware14({
|
|
13642
|
+
name: "TaskMiddleware",
|
|
13643
|
+
contextSchema,
|
|
13644
|
+
wrapModelCall: async (request, handler) => {
|
|
13645
|
+
const taskPrompt = `## \u4EFB\u52A1\u7BA1\u7406\u80FD\u529B
|
|
13646
|
+
\u4F60\u53EF\u4EE5\u901A\u8FC7 manage_task \u5DE5\u5177\u7BA1\u7406\u6301\u4E45\u5316\u4EFB\u52A1\u3002ownerType \u548C ownerId \u7684\u9ED8\u8BA4\u884C\u4E3A\uFF1A
|
|
13647
|
+
- \u4E0D\u4F20\u53C2\u6570: \u9ED8\u8BA4\u4E3A\u5F53\u524D\u7528\u6237\u521B\u5EFA\u4EFB\u52A1 (ownerType="user", ownerId \u81EA\u52A8\u53D6\u5F53\u524D\u7528\u6237)
|
|
13648
|
+
- ownerType="agent": \u4E3A\u81EA\u5DF1\u521B\u5EFA\u6267\u884C\u5B50\u4EFB\u52A1 (ownerId \u81EA\u52A8\u53D6\u5F53\u524D Agent)
|
|
13649
|
+
- \u663E\u5F0F\u4F20 ownerId: \u4E3A\u6307\u5B9A agent/user \u521B\u5EFA\u4EFB\u52A1\uFF08\u62D3\u6251\u573A\u666F\uFF09`;
|
|
13650
|
+
return handler({
|
|
13651
|
+
...request,
|
|
13652
|
+
systemPrompt: taskPrompt + "\n\n" + (request.systemPrompt ?? "")
|
|
13653
|
+
});
|
|
13654
|
+
},
|
|
13655
|
+
tools: [
|
|
13656
|
+
tool46(
|
|
13657
|
+
async (input, config) => {
|
|
13658
|
+
const rc = getRunConfig2(config);
|
|
13659
|
+
const tenantId = rc.tenantId || "default";
|
|
13660
|
+
const ownerId = input.ownerId || (input.ownerType === "agent" ? rc.assistant_id : null) || rc.user_id;
|
|
13661
|
+
const store = getTaskStore();
|
|
13662
|
+
switch (input.action) {
|
|
13663
|
+
case "create": {
|
|
13664
|
+
if (!input.title) {
|
|
13665
|
+
return JSON.stringify({ success: false, error: "create requires title" });
|
|
13666
|
+
}
|
|
13667
|
+
const task = await store.create({
|
|
13668
|
+
tenantId,
|
|
13669
|
+
ownerType: input.ownerType || "user",
|
|
13670
|
+
ownerId,
|
|
13671
|
+
title: input.title,
|
|
13672
|
+
description: input.description,
|
|
13673
|
+
priority: input.priority || "medium",
|
|
13674
|
+
status: input.status || "pending",
|
|
13675
|
+
dueDate: input.dueDate,
|
|
13676
|
+
metadata: input.metadata,
|
|
13677
|
+
parentId: input.parentId,
|
|
13678
|
+
sourceId: input.sourceId,
|
|
13679
|
+
context: input.context
|
|
13680
|
+
});
|
|
13681
|
+
return JSON.stringify({ success: true, data: task });
|
|
13682
|
+
}
|
|
13683
|
+
case "list": {
|
|
13684
|
+
const tasks = await store.list({
|
|
13685
|
+
tenantId,
|
|
13686
|
+
ownerType: input.ownerType,
|
|
13687
|
+
ownerId: input.ownerId,
|
|
13688
|
+
status: input.status,
|
|
13689
|
+
priority: input.priority
|
|
13690
|
+
});
|
|
13691
|
+
return JSON.stringify({ success: true, data: tasks, count: tasks.length });
|
|
13692
|
+
}
|
|
13693
|
+
case "update": {
|
|
13694
|
+
if (!input.id) {
|
|
13695
|
+
return JSON.stringify({ success: false, error: "update requires id" });
|
|
13696
|
+
}
|
|
13697
|
+
const { action, ...updates } = input;
|
|
13698
|
+
const updated = await store.update(tenantId, input.id, updates);
|
|
13699
|
+
if (!updated) {
|
|
13700
|
+
return JSON.stringify({ success: false, error: "Task not found" });
|
|
13701
|
+
}
|
|
13702
|
+
return JSON.stringify({ success: true, data: updated });
|
|
13703
|
+
}
|
|
13704
|
+
case "delete": {
|
|
13705
|
+
if (!input.id) {
|
|
13706
|
+
return JSON.stringify({ success: false, error: "delete requires id" });
|
|
13707
|
+
}
|
|
13708
|
+
const deleted = await store.delete(tenantId, input.id);
|
|
13709
|
+
return JSON.stringify({ success: deleted, message: deleted ? "Task deleted" : "Task not found" });
|
|
13710
|
+
}
|
|
13711
|
+
case "complete": {
|
|
13712
|
+
if (!input.id) {
|
|
13713
|
+
return JSON.stringify({ success: false, error: "complete requires id" });
|
|
13714
|
+
}
|
|
13715
|
+
const updated = await store.update(tenantId, input.id, { status: "completed" });
|
|
13716
|
+
if (!updated) {
|
|
13717
|
+
return JSON.stringify({ success: false, error: "Task not found" });
|
|
13718
|
+
}
|
|
13719
|
+
return JSON.stringify({ success: true, data: updated });
|
|
13720
|
+
}
|
|
13721
|
+
default:
|
|
13722
|
+
return JSON.stringify({ success: false, error: `Unknown action: ${input.action}` });
|
|
13723
|
+
}
|
|
13724
|
+
},
|
|
13725
|
+
{
|
|
13726
|
+
name: "manage_task",
|
|
13727
|
+
description: `\u7BA1\u7406\u6301\u4E45\u5316\u4EFB\u52A1\u7CFB\u7EDF\u3002CRUD \u64CD\u4F5C\u7528\u6237\u548C Agent \u7684\u4EFB\u52A1\u3002
|
|
13728
|
+
|
|
13729
|
+
## ownerType \u548C ownerId \u7684\u9ED8\u8BA4\u903B\u8F91
|
|
13730
|
+
- \u4E0D\u4F20 ownerType \u548C ownerId: \u7CFB\u7EDF\u81EA\u52A8\u4E3A\u5F53\u524D\u7528\u6237\u521B\u5EFA\u4EFB\u52A1 (ownerType="user", ownerId \u53D6\u81EA\u5F53\u524D\u767B\u5F55\u7528\u6237)
|
|
13731
|
+
- \u4F20 ownerType="agent" \u4E0D\u4F20 ownerId: \u7CFB\u7EDF\u81EA\u52A8\u4E3A\u5F53\u524D Agent \u521B\u5EFA\u5B50\u4EFB\u52A1
|
|
13732
|
+
- \u663E\u5F0F\u4F20 ownerId: \u7CFB\u7EDF\u4F7F\u7528\u4F60\u6307\u5B9A\u7684 ID\uFF0C\u53EF\u8DE8 Agent \u6D3E\u53D1\u4EFB\u52A1\uFF08\u62D3\u6251\u573A\u666F\uFF09
|
|
13733
|
+
|
|
13734
|
+
## Actions
|
|
13735
|
+
- create: \u521B\u5EFA\u4EFB\u52A1 (title \u5FC5\u586B, priority/description/dueDate/metadata/parentId/context \u53EF\u9009)
|
|
13736
|
+
- list: \u5217\u51FA\u4EFB\u52A1\uFF0C\u53EF\u6309 ownerType/status/priority \u8FC7\u6EE4
|
|
13737
|
+
- update: \u66F4\u65B0\u4EFB\u52A1 (id \u5FC5\u586B\uFF0C\u53EA\u4F20\u8981\u6539\u7684\u5B57\u6BB5)
|
|
13738
|
+
- delete: \u5220\u9664\u4EFB\u52A1 (id \u5FC5\u586B)
|
|
13739
|
+
- complete: \u5FEB\u901F\u6807\u8BB0\u5B8C\u6210 (id \u5FC5\u586B)`,
|
|
13740
|
+
schema: manageTaskSchema
|
|
13741
|
+
}
|
|
13742
|
+
)
|
|
13743
|
+
]
|
|
13744
|
+
});
|
|
13745
|
+
}
|
|
13746
|
+
|
|
13411
13747
|
// src/agent_lattice/builders/CustomMiddlewareRegistry.ts
|
|
13412
13748
|
var CustomMiddlewareRegistry = class {
|
|
13413
13749
|
/**
|
|
@@ -13543,6 +13879,9 @@ async function createCommonMiddlewares(middlewareConfigs, filesystemBackend, fsI
|
|
|
13543
13879
|
case "scheduler":
|
|
13544
13880
|
middlewares.push(createSchedulerMiddleware(config.config));
|
|
13545
13881
|
break;
|
|
13882
|
+
case "task":
|
|
13883
|
+
middlewares.push(createTaskMiddleware());
|
|
13884
|
+
break;
|
|
13546
13885
|
case "custom":
|
|
13547
13886
|
{
|
|
13548
13887
|
const customConfig = config.config;
|
|
@@ -13750,9 +14089,9 @@ var ReActAgentGraphBuilder = class {
|
|
|
13750
14089
|
*/
|
|
13751
14090
|
async build(agentLattice, params) {
|
|
13752
14091
|
const tools = params.tools.map((t) => {
|
|
13753
|
-
const
|
|
13754
|
-
return
|
|
13755
|
-
}).filter((
|
|
14092
|
+
const tool52 = getToolClient(t.key);
|
|
14093
|
+
return tool52;
|
|
14094
|
+
}).filter((tool52) => tool52 !== void 0);
|
|
13756
14095
|
const stateSchema2 = createReactAgentSchema(params.stateSchema);
|
|
13757
14096
|
const middlewareConfigs = params.middleware || [];
|
|
13758
14097
|
const filesystemBackend = createFilesystemBackendFactory(middlewareConfigs);
|
|
@@ -13764,7 +14103,8 @@ var ReActAgentGraphBuilder = class {
|
|
|
13764
14103
|
name: agentLattice.config.name,
|
|
13765
14104
|
checkpointer: getCheckpointSaver("default"),
|
|
13766
14105
|
stateSchema: stateSchema2,
|
|
13767
|
-
middleware: middlewares
|
|
14106
|
+
middleware: middlewares,
|
|
14107
|
+
responseFormat: params.responseFormat
|
|
13768
14108
|
});
|
|
13769
14109
|
}
|
|
13770
14110
|
};
|
|
@@ -13778,11 +14118,11 @@ import {
|
|
|
13778
14118
|
} from "langchain";
|
|
13779
14119
|
|
|
13780
14120
|
// src/deep_agent_new/middleware/subagents.ts
|
|
13781
|
-
import { z as
|
|
14121
|
+
import { z as z50 } from "zod/v3";
|
|
13782
14122
|
import {
|
|
13783
|
-
createMiddleware as
|
|
14123
|
+
createMiddleware as createMiddleware15,
|
|
13784
14124
|
createAgent as createAgent2,
|
|
13785
|
-
tool as
|
|
14125
|
+
tool as tool47,
|
|
13786
14126
|
ToolMessage as ToolMessage4,
|
|
13787
14127
|
humanInTheLoopMiddleware
|
|
13788
14128
|
} from "langchain";
|
|
@@ -14215,7 +14555,7 @@ function createTaskTool(options) {
|
|
|
14215
14555
|
generalPurposeAgent
|
|
14216
14556
|
});
|
|
14217
14557
|
const finalTaskDescription = taskDescription ? taskDescription : getTaskToolDescription(subagentDescriptions);
|
|
14218
|
-
return
|
|
14558
|
+
return tool47(
|
|
14219
14559
|
async (input, config) => {
|
|
14220
14560
|
const { description, subagent_type, async } = input;
|
|
14221
14561
|
let assistant_id = subagent_type;
|
|
@@ -14249,12 +14589,16 @@ function createTaskTool(options) {
|
|
|
14249
14589
|
const subagent_thread_id = config.configurable?.thread_id + "____" + assistant_id + "_" + config.toolCall.id;
|
|
14250
14590
|
if (async) {
|
|
14251
14591
|
const tenantId = config.configurable?.runConfig?.tenantId;
|
|
14592
|
+
const workspaceId = config.configurable?.runConfig?.workspaceId;
|
|
14593
|
+
const projectId = config.configurable?.runConfig?.projectId;
|
|
14252
14594
|
const mainAssistantId = config.configurable?.runConfig?.assistant_id;
|
|
14253
14595
|
const mainThreadId = config.configurable?.runConfig?.thread_id;
|
|
14254
14596
|
const mainRuntimeAgent = agentInstanceManager.getAgent({
|
|
14255
14597
|
assistant_id: mainAssistantId,
|
|
14256
14598
|
thread_id: mainThreadId,
|
|
14257
|
-
tenant_id: tenantId
|
|
14599
|
+
tenant_id: tenantId,
|
|
14600
|
+
workspace_id: workspaceId,
|
|
14601
|
+
project_id: projectId
|
|
14258
14602
|
});
|
|
14259
14603
|
if (mainRuntimeAgent) {
|
|
14260
14604
|
mainRuntimeAgent.addAsyncTask({
|
|
@@ -14333,15 +14677,15 @@ The result will be delivered as a notification when complete. Do not poll.`,
|
|
|
14333
14677
|
{
|
|
14334
14678
|
name: "task",
|
|
14335
14679
|
description: finalTaskDescription,
|
|
14336
|
-
schema:
|
|
14337
|
-
description:
|
|
14338
|
-
subagent_type:
|
|
14680
|
+
schema: z50.object({
|
|
14681
|
+
description: z50.string().describe("The task to execute with the selected agent"),
|
|
14682
|
+
subagent_type: z50.string().describe(
|
|
14339
14683
|
`Name of the agent to use. Available: ${Object.keys(
|
|
14340
14684
|
subagentGraphs
|
|
14341
14685
|
).join(", ")}`
|
|
14342
14686
|
),
|
|
14343
14687
|
...allowAsync ? {
|
|
14344
|
-
async:
|
|
14688
|
+
async: z50.boolean().default(false).describe(
|
|
14345
14689
|
"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."
|
|
14346
14690
|
)
|
|
14347
14691
|
} : {}
|
|
@@ -14360,7 +14704,7 @@ function getMainAgentFromConfig(config) {
|
|
|
14360
14704
|
});
|
|
14361
14705
|
}
|
|
14362
14706
|
function createCheckAsyncTaskTool() {
|
|
14363
|
-
return
|
|
14707
|
+
return tool47(
|
|
14364
14708
|
async (input, config) => {
|
|
14365
14709
|
const { task_id } = input;
|
|
14366
14710
|
const mainAgent = getMainAgentFromConfig(config);
|
|
@@ -14420,14 +14764,14 @@ Description: ${cached.description}`;
|
|
|
14420
14764
|
{
|
|
14421
14765
|
name: "check_async_task",
|
|
14422
14766
|
description: "Get the current status and result of an async background task. Use this to check if a previously launched async task has completed.",
|
|
14423
|
-
schema:
|
|
14424
|
-
task_id:
|
|
14767
|
+
schema: z50.object({
|
|
14768
|
+
task_id: z50.string().describe("The task ID returned when the async task was started")
|
|
14425
14769
|
})
|
|
14426
14770
|
}
|
|
14427
14771
|
);
|
|
14428
14772
|
}
|
|
14429
14773
|
function createListAsyncTasksTool() {
|
|
14430
|
-
return
|
|
14774
|
+
return tool47(
|
|
14431
14775
|
async (_input, config) => {
|
|
14432
14776
|
const mainAgent = getMainAgentFromConfig(config);
|
|
14433
14777
|
if (!mainAgent) {
|
|
@@ -14473,12 +14817,12 @@ function createListAsyncTasksTool() {
|
|
|
14473
14817
|
{
|
|
14474
14818
|
name: "list_async_tasks",
|
|
14475
14819
|
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.",
|
|
14476
|
-
schema:
|
|
14820
|
+
schema: z50.object({})
|
|
14477
14821
|
}
|
|
14478
14822
|
);
|
|
14479
14823
|
}
|
|
14480
14824
|
function createCancelAsyncTaskTool() {
|
|
14481
|
-
return
|
|
14825
|
+
return tool47(
|
|
14482
14826
|
async (input, config) => {
|
|
14483
14827
|
const { task_id } = input;
|
|
14484
14828
|
const mainAgent = getMainAgentFromConfig(config);
|
|
@@ -14517,8 +14861,8 @@ function createCancelAsyncTaskTool() {
|
|
|
14517
14861
|
{
|
|
14518
14862
|
name: "cancel_async_task",
|
|
14519
14863
|
description: "Cancel a running async background task.",
|
|
14520
|
-
schema:
|
|
14521
|
-
task_id:
|
|
14864
|
+
schema: z50.object({
|
|
14865
|
+
task_id: z50.string().describe("The task ID to cancel")
|
|
14522
14866
|
})
|
|
14523
14867
|
}
|
|
14524
14868
|
);
|
|
@@ -14554,7 +14898,7 @@ function createSubAgentMiddleware(options) {
|
|
|
14554
14898
|
);
|
|
14555
14899
|
}
|
|
14556
14900
|
const effectiveSystemPrompt = allowAsync ? systemPrompt + getAsyncPromptText() : systemPrompt;
|
|
14557
|
-
return
|
|
14901
|
+
return createMiddleware15({
|
|
14558
14902
|
name: "subAgentMiddleware",
|
|
14559
14903
|
tools: allTools,
|
|
14560
14904
|
wrapModelCall: async (request, handler) => {
|
|
@@ -14575,14 +14919,12 @@ ${effectiveSystemPrompt}` : effectiveSystemPrompt;
|
|
|
14575
14919
|
|
|
14576
14920
|
// src/deep_agent_new/middleware/patch_tool_calls.ts
|
|
14577
14921
|
import {
|
|
14578
|
-
createMiddleware as
|
|
14922
|
+
createMiddleware as createMiddleware16,
|
|
14579
14923
|
ToolMessage as ToolMessage5,
|
|
14580
14924
|
AIMessage as AIMessage2
|
|
14581
14925
|
} from "langchain";
|
|
14582
|
-
import { RemoveMessage } from "@langchain/core/messages";
|
|
14583
|
-
import { REMOVE_ALL_MESSAGES } from "@langchain/langgraph";
|
|
14584
14926
|
function createPatchToolCallsMiddleware() {
|
|
14585
|
-
return
|
|
14927
|
+
return createMiddleware16({
|
|
14586
14928
|
name: "patchToolCallsMiddleware",
|
|
14587
14929
|
beforeAgent: async (state) => {
|
|
14588
14930
|
const messages = state.messages;
|
|
@@ -14611,11 +14953,12 @@ function createPatchToolCallsMiddleware() {
|
|
|
14611
14953
|
}
|
|
14612
14954
|
}
|
|
14613
14955
|
}
|
|
14956
|
+
if (patchedMessages.length === messages.length) {
|
|
14957
|
+
return;
|
|
14958
|
+
}
|
|
14614
14959
|
return {
|
|
14615
|
-
messages:
|
|
14616
|
-
|
|
14617
|
-
...patchedMessages
|
|
14618
|
-
]
|
|
14960
|
+
messages: patchedMessages.slice(messages.length)
|
|
14961
|
+
// only the new ToolMessage patches
|
|
14619
14962
|
};
|
|
14620
14963
|
}
|
|
14621
14964
|
});
|
|
@@ -15728,8 +16071,8 @@ var MemoryBackend = class {
|
|
|
15728
16071
|
|
|
15729
16072
|
// src/deep_agent_new/middleware/todos.ts
|
|
15730
16073
|
import { Command as Command4 } from "@langchain/langgraph";
|
|
15731
|
-
import { z as
|
|
15732
|
-
import { createMiddleware as
|
|
16074
|
+
import { z as z51 } from "zod";
|
|
16075
|
+
import { createMiddleware as createMiddleware17, tool as tool48, ToolMessage as ToolMessage6 } from "langchain";
|
|
15733
16076
|
var WRITE_TODOS_DESCRIPTION = `Use this tool to create and manage a structured task list for your current work session. This helps you track progress, organize complex tasks, and demonstrate thoroughness to the user.
|
|
15734
16077
|
It also helps the user understand the progress of the task and overall progress of their requests.
|
|
15735
16078
|
Only use this tool if you think it will be helpful in staying organized. If the user's request is trivial and takes less than 3 steps, it is better to NOT use this tool and just do the taks directly.
|
|
@@ -15956,14 +16299,14 @@ Writing todos takes time and tokens, use it when it is helpful for managing comp
|
|
|
15956
16299
|
## Important To-Do List Usage Notes to Remember
|
|
15957
16300
|
- The \`write_todos\` tool should never be called multiple times in parallel.
|
|
15958
16301
|
- Don't be afraid to revise the To-Do list as you go. New information may reveal new tasks that need to be done, or old tasks that are irrelevant.`;
|
|
15959
|
-
var TodoStatus =
|
|
15960
|
-
var TodoSchema =
|
|
15961
|
-
content:
|
|
16302
|
+
var TodoStatus = z51.enum(["pending", "in_progress", "completed"]).describe("Status of the todo");
|
|
16303
|
+
var TodoSchema = z51.object({
|
|
16304
|
+
content: z51.string().describe("Content of the todo item"),
|
|
15962
16305
|
status: TodoStatus
|
|
15963
16306
|
});
|
|
15964
|
-
var stateSchema =
|
|
16307
|
+
var stateSchema = z51.object({ todos: z51.array(TodoSchema).default([]) });
|
|
15965
16308
|
function todoListMiddleware(options) {
|
|
15966
|
-
const writeTodos =
|
|
16309
|
+
const writeTodos = tool48(
|
|
15967
16310
|
({ todos }, config) => {
|
|
15968
16311
|
return new Command4({
|
|
15969
16312
|
update: {
|
|
@@ -15980,12 +16323,12 @@ function todoListMiddleware(options) {
|
|
|
15980
16323
|
{
|
|
15981
16324
|
name: "write_todos",
|
|
15982
16325
|
description: options?.toolDescription ?? WRITE_TODOS_DESCRIPTION,
|
|
15983
|
-
schema:
|
|
15984
|
-
todos:
|
|
16326
|
+
schema: z51.object({
|
|
16327
|
+
todos: z51.array(TodoSchema).describe("List of todo items to update")
|
|
15985
16328
|
})
|
|
15986
16329
|
}
|
|
15987
16330
|
);
|
|
15988
|
-
return
|
|
16331
|
+
return createMiddleware17({
|
|
15989
16332
|
name: "todoListMiddleware",
|
|
15990
16333
|
stateSchema,
|
|
15991
16334
|
tools: [writeTodos],
|
|
@@ -16097,7 +16440,7 @@ var DeepAgentGraphBuilder = class {
|
|
|
16097
16440
|
const tools = params.tools.map((t) => {
|
|
16098
16441
|
const toolClient = getToolClient(t.key);
|
|
16099
16442
|
return toolClient;
|
|
16100
|
-
}).filter((
|
|
16443
|
+
}).filter((tool52) => tool52 !== void 0);
|
|
16101
16444
|
const subagents = await Promise.all(params.subAgents.map(async (sa) => {
|
|
16102
16445
|
if (sa.client) {
|
|
16103
16446
|
return {
|
|
@@ -16127,6 +16470,7 @@ var DeepAgentGraphBuilder = class {
|
|
|
16127
16470
|
contextSchema: params.stateSchema,
|
|
16128
16471
|
systemPrompt: params.prompt,
|
|
16129
16472
|
subagents,
|
|
16473
|
+
responseFormat: params.responseFormat,
|
|
16130
16474
|
checkpointer: getCheckpointSaver("default"),
|
|
16131
16475
|
skills: params.skillCategories,
|
|
16132
16476
|
backend: filesystemBackend,
|
|
@@ -16137,7 +16481,7 @@ var DeepAgentGraphBuilder = class {
|
|
|
16137
16481
|
};
|
|
16138
16482
|
|
|
16139
16483
|
// src/agent_team/agent_team.ts
|
|
16140
|
-
import { z as
|
|
16484
|
+
import { z as z54 } from "zod/v3";
|
|
16141
16485
|
import { createAgent as createAgent5 } from "langchain";
|
|
16142
16486
|
|
|
16143
16487
|
// src/agent_team/types.ts
|
|
@@ -16573,14 +16917,14 @@ var InMemoryMailboxStore = class {
|
|
|
16573
16917
|
};
|
|
16574
16918
|
|
|
16575
16919
|
// src/agent_team/middleware/team.ts
|
|
16576
|
-
import { z as
|
|
16577
|
-
import { createMiddleware as
|
|
16920
|
+
import { z as z53 } from "zod/v3";
|
|
16921
|
+
import { createMiddleware as createMiddleware18, createAgent as createAgent4, tool as tool50, ToolMessage as ToolMessage8 } from "langchain";
|
|
16578
16922
|
import { Command as Command6, getCurrentTaskInput as getCurrentTaskInput3 } from "@langchain/langgraph";
|
|
16579
|
-
import { v4 as
|
|
16923
|
+
import { v4 as uuidv43 } from "uuid";
|
|
16580
16924
|
|
|
16581
16925
|
// src/agent_team/middleware/teammate_tools.ts
|
|
16582
|
-
import { z as
|
|
16583
|
-
import { tool as
|
|
16926
|
+
import { z as z52 } from "zod/v3";
|
|
16927
|
+
import { tool as tool49, ToolMessage as ToolMessage7 } from "langchain";
|
|
16584
16928
|
import { Command as Command5 } from "@langchain/langgraph";
|
|
16585
16929
|
|
|
16586
16930
|
// src/agent_team/middleware/formatMessages.ts
|
|
@@ -16605,7 +16949,7 @@ ${meta}${body}`;
|
|
|
16605
16949
|
// src/agent_team/middleware/teammate_tools.ts
|
|
16606
16950
|
function createTeammateTools(options) {
|
|
16607
16951
|
const { teamId, agentId, taskListStore, mailboxStore } = options;
|
|
16608
|
-
const claimTaskTool =
|
|
16952
|
+
const claimTaskTool = tool49(
|
|
16609
16953
|
async (input) => {
|
|
16610
16954
|
const task = await taskListStore.claimTaskById(
|
|
16611
16955
|
teamId,
|
|
@@ -16630,12 +16974,12 @@ function createTeammateTools(options) {
|
|
|
16630
16974
|
{
|
|
16631
16975
|
name: "claim_task",
|
|
16632
16976
|
description: "Pick a task to work on by task_id. Use check_tasks first to see all tasks; then call this with the task_id you choose. The task's assignee is set to you and you should focus on that task until you complete_task or fail_task it.",
|
|
16633
|
-
schema:
|
|
16634
|
-
task_id:
|
|
16977
|
+
schema: z52.object({
|
|
16978
|
+
task_id: z52.string().describe("ID of the task to claim (e.g. task-01). Use check_tasks to see IDs.")
|
|
16635
16979
|
})
|
|
16636
16980
|
}
|
|
16637
16981
|
);
|
|
16638
|
-
const completeTaskTool =
|
|
16982
|
+
const completeTaskTool = tool49(
|
|
16639
16983
|
async (input) => {
|
|
16640
16984
|
const task = await taskListStore.completeTask(
|
|
16641
16985
|
teamId,
|
|
@@ -16656,13 +17000,13 @@ function createTeammateTools(options) {
|
|
|
16656
17000
|
{
|
|
16657
17001
|
name: "complete_task",
|
|
16658
17002
|
description: "Mark a claimed task as completed with a result summary. Call this after you have finished working on a task.",
|
|
16659
|
-
schema:
|
|
16660
|
-
task_id:
|
|
16661
|
-
result:
|
|
17003
|
+
schema: z52.object({
|
|
17004
|
+
task_id: z52.string().describe("ID of the task to complete"),
|
|
17005
|
+
result: z52.string().describe("Summary of the task result")
|
|
16662
17006
|
})
|
|
16663
17007
|
}
|
|
16664
17008
|
);
|
|
16665
|
-
const failTaskTool =
|
|
17009
|
+
const failTaskTool = tool49(
|
|
16666
17010
|
async (input) => {
|
|
16667
17011
|
const task = await taskListStore.failTask(
|
|
16668
17012
|
teamId,
|
|
@@ -16683,13 +17027,13 @@ function createTeammateTools(options) {
|
|
|
16683
17027
|
{
|
|
16684
17028
|
name: "fail_task",
|
|
16685
17029
|
description: "Mark a claimed task as failed with an error description. Call this if you cannot complete the task.",
|
|
16686
|
-
schema:
|
|
16687
|
-
task_id:
|
|
16688
|
-
error:
|
|
17030
|
+
schema: z52.object({
|
|
17031
|
+
task_id: z52.string().describe("ID of the task to fail"),
|
|
17032
|
+
error: z52.string().describe("Description of why the task failed")
|
|
16689
17033
|
})
|
|
16690
17034
|
}
|
|
16691
17035
|
);
|
|
16692
|
-
const sendMessageTool =
|
|
17036
|
+
const sendMessageTool = tool49(
|
|
16693
17037
|
async (input) => {
|
|
16694
17038
|
await mailboxStore.sendMessage(
|
|
16695
17039
|
teamId,
|
|
@@ -16703,11 +17047,11 @@ function createTeammateTools(options) {
|
|
|
16703
17047
|
{
|
|
16704
17048
|
name: "send_message",
|
|
16705
17049
|
description: 'Send a message to the team lead or another teammate via the mailbox. Use "team_lead" to message the team lead. Use this to report discoveries, request guidance, or suggest new tasks.',
|
|
16706
|
-
schema:
|
|
16707
|
-
to:
|
|
17050
|
+
schema: z52.object({
|
|
17051
|
+
to: z52.string().describe(
|
|
16708
17052
|
'Recipient agent name (e.g. "team_lead" or a teammate name)'
|
|
16709
17053
|
),
|
|
16710
|
-
content:
|
|
17054
|
+
content: z52.string().describe("Message content")
|
|
16711
17055
|
})
|
|
16712
17056
|
}
|
|
16713
17057
|
);
|
|
@@ -16727,7 +17071,7 @@ function createTeammateTools(options) {
|
|
|
16727
17071
|
read: msg.read
|
|
16728
17072
|
}));
|
|
16729
17073
|
};
|
|
16730
|
-
const readMessagesTool =
|
|
17074
|
+
const readMessagesTool = tool49(
|
|
16731
17075
|
async (input, config) => {
|
|
16732
17076
|
const formatAndMarkAsRead = async (msgs2) => {
|
|
16733
17077
|
for (const msg of msgs2) {
|
|
@@ -16786,10 +17130,10 @@ function createTeammateTools(options) {
|
|
|
16786
17130
|
{
|
|
16787
17131
|
name: "read_messages",
|
|
16788
17132
|
description: "Read unread messages from the mailbox. Returns immediately if messages exist, otherwise waits for up to 3 minutes for new messages.",
|
|
16789
|
-
schema:
|
|
17133
|
+
schema: z52.object({})
|
|
16790
17134
|
}
|
|
16791
17135
|
);
|
|
16792
|
-
const checkTasksTool =
|
|
17136
|
+
const checkTasksTool = tool49(
|
|
16793
17137
|
async () => {
|
|
16794
17138
|
const tasks = await taskListStore.getAllTasks(teamId);
|
|
16795
17139
|
return formatTaskSummary(tasks);
|
|
@@ -16797,10 +17141,10 @@ function createTeammateTools(options) {
|
|
|
16797
17141
|
{
|
|
16798
17142
|
name: "check_tasks",
|
|
16799
17143
|
description: "Use this tool to get the current status of all tasks in a team. This is your primary way to monitor task progress.",
|
|
16800
|
-
schema:
|
|
17144
|
+
schema: z52.object({})
|
|
16801
17145
|
}
|
|
16802
17146
|
);
|
|
16803
|
-
const broadcastMessageTool =
|
|
17147
|
+
const broadcastMessageTool = tool49(
|
|
16804
17148
|
async (input) => {
|
|
16805
17149
|
const allAgents = await mailboxStore.getRegisteredAgents(teamId);
|
|
16806
17150
|
const recipients = allAgents.filter((a) => a !== agentId);
|
|
@@ -16819,8 +17163,8 @@ function createTeammateTools(options) {
|
|
|
16819
17163
|
{
|
|
16820
17164
|
name: "broadcast_message",
|
|
16821
17165
|
description: "Send a message to everyone in the team except yourself. Use this to share updates or information with all teammates and the team lead at once.",
|
|
16822
|
-
schema:
|
|
16823
|
-
content:
|
|
17166
|
+
schema: z52.object({
|
|
17167
|
+
content: z52.string().describe("Message content to broadcast to others")
|
|
16824
17168
|
})
|
|
16825
17169
|
}
|
|
16826
17170
|
);
|
|
@@ -17054,7 +17398,7 @@ async function spawnTeammate(options) {
|
|
|
17054
17398
|
function createTeamMiddleware(options) {
|
|
17055
17399
|
const { teamConfig, taskListStore, mailboxStore, tenantId } = options;
|
|
17056
17400
|
const defaultModel = teamConfig.model ?? "claude-sonnet-4-5-20250929";
|
|
17057
|
-
const createTeamTool =
|
|
17401
|
+
const createTeamTool = tool50(
|
|
17058
17402
|
async (input, config) => {
|
|
17059
17403
|
const state = getCurrentTaskInput3();
|
|
17060
17404
|
if (state?.team?.teamId) {
|
|
@@ -17066,7 +17410,7 @@ function createTeamMiddleware(options) {
|
|
|
17066
17410
|
});
|
|
17067
17411
|
return msg;
|
|
17068
17412
|
}
|
|
17069
|
-
const teamId =
|
|
17413
|
+
const teamId = uuidv43();
|
|
17070
17414
|
const createdTasks = await taskListStore.addTasks(
|
|
17071
17415
|
teamId,
|
|
17072
17416
|
input.tasks.map((t) => ({
|
|
@@ -17209,20 +17553,20 @@ After calling create_team, you MUST:
|
|
|
17209
17553
|
2. When messages indicate task changes, call check_tasks to get full task status
|
|
17210
17554
|
3. Continue until all tasks show "completed" or "failed"
|
|
17211
17555
|
4. Do NOT assume tasks are done - always verify with check_tasks`,
|
|
17212
|
-
schema:
|
|
17213
|
-
tasks:
|
|
17214
|
-
|
|
17215
|
-
id:
|
|
17216
|
-
title:
|
|
17217
|
-
description:
|
|
17218
|
-
dependencies:
|
|
17556
|
+
schema: z53.object({
|
|
17557
|
+
tasks: z53.array(
|
|
17558
|
+
z53.object({
|
|
17559
|
+
id: z53.string().describe("Task ID in format task-01, task-02, etc."),
|
|
17560
|
+
title: z53.string().describe("Short task title"),
|
|
17561
|
+
description: z53.string().describe("Detailed task description - what exactly needs to be done"),
|
|
17562
|
+
dependencies: z53.array(z53.string()).optional().default([]).describe('Array of task IDs that must complete before this task (e.g. ["task-01"])')
|
|
17219
17563
|
})
|
|
17220
17564
|
).describe("List of tasks for teammates to work on. Each task needs unique ID (task-01, task-02, etc.)."),
|
|
17221
|
-
teammates:
|
|
17222
|
-
|
|
17223
|
-
name:
|
|
17224
|
-
role:
|
|
17225
|
-
description:
|
|
17565
|
+
teammates: z53.array(
|
|
17566
|
+
z53.object({
|
|
17567
|
+
name: z53.string().describe("Teammate name (must match a pre-configured teammate type)"),
|
|
17568
|
+
role: z53.string().describe("Role category (e.g. researcher, writer, coder, reviewer)"),
|
|
17569
|
+
description: z53.string().describe("What this teammate will focus on - specific instructions for their work")
|
|
17226
17570
|
})
|
|
17227
17571
|
).describe("Teammate agents to create. Each should have a clear role and focus.")
|
|
17228
17572
|
})
|
|
@@ -17233,7 +17577,7 @@ After calling create_team, you MUST:
|
|
|
17233
17577
|
if (state?.team?.teamId) return state.team.teamId;
|
|
17234
17578
|
throw new Error("No team_id provided and no team in state. Call create_team first.");
|
|
17235
17579
|
};
|
|
17236
|
-
const addTasksTool =
|
|
17580
|
+
const addTasksTool = tool50(
|
|
17237
17581
|
async (input, config) => {
|
|
17238
17582
|
const teamId = resolveTeamId();
|
|
17239
17583
|
const created = await taskListStore.addTasks(
|
|
@@ -17285,20 +17629,20 @@ IMPORTANT: Dependencies
|
|
|
17285
17629
|
|
|
17286
17630
|
IMPORTANT: Assigning to a specific teammate
|
|
17287
17631
|
- When you need a particular teammate to do the work, set assignee to that teammate's name (e.g. assignee: "researcher"). They can then claim or see the task as assigned to them.`,
|
|
17288
|
-
schema:
|
|
17289
|
-
tasks:
|
|
17290
|
-
|
|
17291
|
-
id:
|
|
17292
|
-
title:
|
|
17293
|
-
description:
|
|
17294
|
-
assignee:
|
|
17295
|
-
dependencies:
|
|
17632
|
+
schema: z53.object({
|
|
17633
|
+
tasks: z53.array(
|
|
17634
|
+
z53.object({
|
|
17635
|
+
id: z53.string().describe("Task ID in format task-01, task-02, etc. Must be unique."),
|
|
17636
|
+
title: z53.string().describe("Short task title"),
|
|
17637
|
+
description: z53.string().describe("Detailed task description - what needs to be done"),
|
|
17638
|
+
assignee: z53.string().optional().describe("Teammate name to assign this task to (use when you need that person to do the work)"),
|
|
17639
|
+
dependencies: z53.array(z53.string()).optional().default([]).describe("Array of task IDs that must complete before this task")
|
|
17296
17640
|
})
|
|
17297
17641
|
).describe("New tasks to add to the team")
|
|
17298
17642
|
})
|
|
17299
17643
|
}
|
|
17300
17644
|
);
|
|
17301
|
-
const assignTaskTool =
|
|
17645
|
+
const assignTaskTool = tool50(
|
|
17302
17646
|
async (input, config) => {
|
|
17303
17647
|
const teamId = resolveTeamId();
|
|
17304
17648
|
const task = await taskListStore.updateTask(teamId, input.task_id, {
|
|
@@ -17320,13 +17664,13 @@ IMPORTANT: Assigning to a specific teammate
|
|
|
17320
17664
|
{
|
|
17321
17665
|
name: "assign_task",
|
|
17322
17666
|
description: "Assign a task to a specific teammate. Use when you need to reassign work to a different teammate. Omit team_id to use the active team from state.",
|
|
17323
|
-
schema:
|
|
17324
|
-
task_id:
|
|
17325
|
-
assignee:
|
|
17667
|
+
schema: z53.object({
|
|
17668
|
+
task_id: z53.string().describe("Task ID to assign"),
|
|
17669
|
+
assignee: z53.string().describe("Teammate name to assign this task to")
|
|
17326
17670
|
})
|
|
17327
17671
|
}
|
|
17328
17672
|
);
|
|
17329
|
-
const setTaskStatusTool =
|
|
17673
|
+
const setTaskStatusTool = tool50(
|
|
17330
17674
|
async (input, config) => {
|
|
17331
17675
|
const teamId = resolveTeamId();
|
|
17332
17676
|
const task = await taskListStore.updateTask(teamId, input.task_id, {
|
|
@@ -17348,13 +17692,13 @@ IMPORTANT: Assigning to a specific teammate
|
|
|
17348
17692
|
{
|
|
17349
17693
|
name: "set_task_status",
|
|
17350
17694
|
description: "Set a task's status. Use to reopen a task (set to pending), mark as failed, or correct status. Values: pending, claimed, in_progress, completed, failed. Omit team_id to use the active team from state.",
|
|
17351
|
-
schema:
|
|
17352
|
-
task_id:
|
|
17353
|
-
status:
|
|
17695
|
+
schema: z53.object({
|
|
17696
|
+
task_id: z53.string().describe("Task ID to update"),
|
|
17697
|
+
status: z53.enum(["pending", "claimed", "in_progress", "completed", "failed"]).describe("New status for the task")
|
|
17354
17698
|
})
|
|
17355
17699
|
}
|
|
17356
17700
|
);
|
|
17357
|
-
const setTaskDependenciesTool =
|
|
17701
|
+
const setTaskDependenciesTool = tool50(
|
|
17358
17702
|
async (input, config) => {
|
|
17359
17703
|
const teamId = resolveTeamId();
|
|
17360
17704
|
const task = await taskListStore.updateTask(teamId, input.task_id, {
|
|
@@ -17376,13 +17720,13 @@ IMPORTANT: Assigning to a specific teammate
|
|
|
17376
17720
|
{
|
|
17377
17721
|
name: "set_task_dependencies",
|
|
17378
17722
|
description: 'Set which task IDs must complete before this task can be claimed. Pass an array of task IDs (e.g. ["task-01", "task-02"]). Use to fix task order or add/remove dependencies. Omit team_id to use the active team from state.',
|
|
17379
|
-
schema:
|
|
17380
|
-
task_id:
|
|
17381
|
-
dependencies:
|
|
17723
|
+
schema: z53.object({
|
|
17724
|
+
task_id: z53.string().describe("Task ID to update"),
|
|
17725
|
+
dependencies: z53.array(z53.string()).describe("Task IDs that must complete before this task can be claimed")
|
|
17382
17726
|
})
|
|
17383
17727
|
}
|
|
17384
17728
|
);
|
|
17385
|
-
const checkTasksTool =
|
|
17729
|
+
const checkTasksTool = tool50(
|
|
17386
17730
|
async (input, config) => {
|
|
17387
17731
|
const teamId = resolveTeamId();
|
|
17388
17732
|
const tasks = await taskListStore.getAllTasks(teamId);
|
|
@@ -17422,12 +17766,12 @@ Task Status Values:
|
|
|
17422
17766
|
- in_progress: Teammate is actively working on this task
|
|
17423
17767
|
- completed: Task finished successfully
|
|
17424
17768
|
- failed: Task encountered an error`,
|
|
17425
|
-
schema:
|
|
17426
|
-
team_id:
|
|
17769
|
+
schema: z53.object({
|
|
17770
|
+
team_id: z53.string().optional().describe("Team ID (omit to use active team)")
|
|
17427
17771
|
})
|
|
17428
17772
|
}
|
|
17429
17773
|
);
|
|
17430
|
-
const sendMessageTool =
|
|
17774
|
+
const sendMessageTool = tool50(
|
|
17431
17775
|
async (input, config) => {
|
|
17432
17776
|
const teamId = resolveTeamId();
|
|
17433
17777
|
await mailboxStore.sendMessage(
|
|
@@ -17446,13 +17790,13 @@ Task Status Values:
|
|
|
17446
17790
|
{
|
|
17447
17791
|
name: "send_message",
|
|
17448
17792
|
description: "Send a message to a specific teammate in the team. Omit team_id to use the active team from state.",
|
|
17449
|
-
schema:
|
|
17450
|
-
to:
|
|
17451
|
-
content:
|
|
17793
|
+
schema: z53.object({
|
|
17794
|
+
to: z53.string().describe("Recipient teammate name"),
|
|
17795
|
+
content: z53.string().describe("Message content")
|
|
17452
17796
|
})
|
|
17453
17797
|
}
|
|
17454
17798
|
);
|
|
17455
|
-
const readMessagesTool =
|
|
17799
|
+
const readMessagesTool = tool50(
|
|
17456
17800
|
async (input, config) => {
|
|
17457
17801
|
const teamId = resolveTeamId();
|
|
17458
17802
|
const formatAndMarkAsRead = async (msgs2) => {
|
|
@@ -17534,12 +17878,12 @@ Task Status Values:
|
|
|
17534
17878
|
{
|
|
17535
17879
|
name: "read_messages",
|
|
17536
17880
|
description: "Read unread messages from teammates. Returns immediately if messages exist, otherwise waits for up to 3 minutes for new messages.",
|
|
17537
|
-
schema:
|
|
17538
|
-
team_id:
|
|
17881
|
+
schema: z53.object({
|
|
17882
|
+
team_id: z53.string().optional().describe("Team ID (omit to use active team)")
|
|
17539
17883
|
})
|
|
17540
17884
|
}
|
|
17541
17885
|
);
|
|
17542
|
-
const disbandTeamTool =
|
|
17886
|
+
const disbandTeamTool = tool50(
|
|
17543
17887
|
async (input, config) => {
|
|
17544
17888
|
const teamId = resolveTeamId();
|
|
17545
17889
|
await mailboxStore.broadcastMessage(
|
|
@@ -17560,7 +17904,7 @@ Task Status Values:
|
|
|
17560
17904
|
description: "Disband a team when all work is done. Before calling: (1) Call check_tasks to verify no tasks are still pending/in_progress; (2) if any are, discuss with the team via read_messages and broadcast_message/send_message whether to continue or stop/cancel them; (3) only after alignment (all tasks completed/failed or explicitly stopped), then call this tool. This will: 1) Send a shutdown message to all teammates, 2) Wait briefly for them to clean up, 3) Clear all tasks and messages. Omit team_id to use the active team from state."
|
|
17561
17905
|
}
|
|
17562
17906
|
);
|
|
17563
|
-
const broadcastMessageTool =
|
|
17907
|
+
const broadcastMessageTool = tool50(
|
|
17564
17908
|
async (input, config) => {
|
|
17565
17909
|
const teamId = resolveTeamId();
|
|
17566
17910
|
await mailboxStore.broadcastMessage(
|
|
@@ -17578,12 +17922,12 @@ Task Status Values:
|
|
|
17578
17922
|
{
|
|
17579
17923
|
name: "broadcast_message",
|
|
17580
17924
|
description: "Send a message to all teammates at once. Use this to communicate with everyone in the team. Omit team_id to use the active team from state.",
|
|
17581
|
-
schema:
|
|
17582
|
-
content:
|
|
17925
|
+
schema: z53.object({
|
|
17926
|
+
content: z53.string().describe("Message content to broadcast to all teammates")
|
|
17583
17927
|
})
|
|
17584
17928
|
}
|
|
17585
17929
|
);
|
|
17586
|
-
return
|
|
17930
|
+
return createMiddleware18({
|
|
17587
17931
|
name: "teamMiddleware",
|
|
17588
17932
|
tools: [
|
|
17589
17933
|
createTeamTool,
|
|
@@ -17611,37 +17955,37 @@ ${TEAM_SYSTEM_PROMPT}` : TEAM_SYSTEM_PROMPT;
|
|
|
17611
17955
|
}
|
|
17612
17956
|
|
|
17613
17957
|
// src/agent_team/agent_team.ts
|
|
17614
|
-
var TeammateInfoSchema =
|
|
17615
|
-
name:
|
|
17616
|
-
role:
|
|
17617
|
-
description:
|
|
17958
|
+
var TeammateInfoSchema = z54.object({
|
|
17959
|
+
name: z54.string().describe("Teammate name"),
|
|
17960
|
+
role: z54.string().describe("Role category (e.g. research, writing, review)"),
|
|
17961
|
+
description: z54.string().describe("What this teammate focuses on")
|
|
17618
17962
|
});
|
|
17619
|
-
var TeamTaskInfoSchema =
|
|
17620
|
-
id:
|
|
17621
|
-
title:
|
|
17622
|
-
description:
|
|
17623
|
-
status:
|
|
17963
|
+
var TeamTaskInfoSchema = z54.object({
|
|
17964
|
+
id: z54.string(),
|
|
17965
|
+
title: z54.string(),
|
|
17966
|
+
description: z54.string(),
|
|
17967
|
+
status: z54.string().optional()
|
|
17624
17968
|
});
|
|
17625
|
-
var MailboxMessageSchema =
|
|
17626
|
-
id:
|
|
17627
|
-
from:
|
|
17628
|
-
to:
|
|
17629
|
-
content:
|
|
17630
|
-
timestamp:
|
|
17631
|
-
type:
|
|
17632
|
-
read:
|
|
17969
|
+
var MailboxMessageSchema = z54.object({
|
|
17970
|
+
id: z54.string().describe("Unique message identifier"),
|
|
17971
|
+
from: z54.string().describe("Sender agent name"),
|
|
17972
|
+
to: z54.string().describe("Recipient agent name"),
|
|
17973
|
+
content: z54.string().describe("Message content"),
|
|
17974
|
+
timestamp: z54.string().describe("ISO timestamp when the message was sent"),
|
|
17975
|
+
type: z54.nativeEnum(MessageType).describe("Message type"),
|
|
17976
|
+
read: z54.boolean().describe("Whether the recipient has read this message")
|
|
17633
17977
|
});
|
|
17634
|
-
var TeamInfoSchema =
|
|
17635
|
-
teamId:
|
|
17636
|
-
teamLeadId:
|
|
17637
|
-
teammates:
|
|
17638
|
-
tasks:
|
|
17639
|
-
createdAt:
|
|
17978
|
+
var TeamInfoSchema = z54.object({
|
|
17979
|
+
teamId: z54.string().describe("Unique team identifier"),
|
|
17980
|
+
teamLeadId: z54.string().default("team_lead").describe("Team lead agent ID"),
|
|
17981
|
+
teammates: z54.array(TeammateInfoSchema).describe("Active teammates in this team"),
|
|
17982
|
+
tasks: z54.array(TeamTaskInfoSchema).optional().describe("Initial tasks snapshot"),
|
|
17983
|
+
createdAt: z54.string().optional().describe("ISO timestamp when team was created")
|
|
17640
17984
|
});
|
|
17641
|
-
var TEAM_STATE_SCHEMA =
|
|
17985
|
+
var TEAM_STATE_SCHEMA = z54.object({
|
|
17642
17986
|
team: TeamInfoSchema.optional().describe("Team info: teamId, teamLeadId, teammates, tasks. Set when create_team succeeds."),
|
|
17643
|
-
tasks:
|
|
17644
|
-
team_mailbox:
|
|
17987
|
+
tasks: z54.array(TeamTaskInfoSchema).optional().describe("Current tasks snapshot from check_tasks. Updated on each check."),
|
|
17988
|
+
team_mailbox: z54.array(MailboxMessageSchema).optional().describe("All team mailbox messages for display")
|
|
17645
17989
|
});
|
|
17646
17990
|
var TEAM_LEAD_BASE_PROMPT = `You are a team lead that coordinates a team of specialized agents. In order to complete the objective that the user asks of you, you will need to:
|
|
17647
17991
|
|
|
@@ -17722,7 +18066,7 @@ var TeamAgentGraphBuilder = class {
|
|
|
17722
18066
|
const tools = params.tools.map((t) => {
|
|
17723
18067
|
const toolClient = getToolClient(t.key);
|
|
17724
18068
|
return toolClient;
|
|
17725
|
-
}).filter((
|
|
18069
|
+
}).filter((tool52) => tool52 !== void 0);
|
|
17726
18070
|
const teammates = params.subAgents.map((sa) => {
|
|
17727
18071
|
const baseConfig = sa.config;
|
|
17728
18072
|
return {
|
|
@@ -17768,14 +18112,14 @@ import {
|
|
|
17768
18112
|
} from "langchain";
|
|
17769
18113
|
|
|
17770
18114
|
// src/middlewares/topologyMiddleware.ts
|
|
17771
|
-
import { createMiddleware as
|
|
18115
|
+
import { createMiddleware as createMiddleware19 } from "langchain";
|
|
17772
18116
|
import { AIMessage as AIMessage3, ToolMessage as ToolMessage9 } from "@langchain/core/messages";
|
|
17773
|
-
import { tool as
|
|
17774
|
-
import { z as
|
|
18117
|
+
import { tool as tool51 } from "langchain";
|
|
18118
|
+
import { z as z55 } from "zod";
|
|
17775
18119
|
import { GraphInterrupt as GraphInterrupt4 } from "@langchain/langgraph";
|
|
17776
|
-
var CompletedEdgeSchema =
|
|
17777
|
-
to:
|
|
17778
|
-
purpose:
|
|
18120
|
+
var CompletedEdgeSchema = z55.object({
|
|
18121
|
+
to: z55.string(),
|
|
18122
|
+
purpose: z55.string()
|
|
17779
18123
|
});
|
|
17780
18124
|
function deriveCompletedEdges(messages, edges) {
|
|
17781
18125
|
const completedToolCallIds = /* @__PURE__ */ new Set();
|
|
@@ -17802,16 +18146,16 @@ function deriveCompletedEdges(messages, edges) {
|
|
|
17802
18146
|
}
|
|
17803
18147
|
function createTopologyMiddleware(options) {
|
|
17804
18148
|
const { edges, trackingStore } = options;
|
|
17805
|
-
return
|
|
18149
|
+
return createMiddleware19({
|
|
17806
18150
|
name: "TopologyMiddleware",
|
|
17807
|
-
contextSchema:
|
|
17808
|
-
runConfig:
|
|
18151
|
+
contextSchema: z55.object({
|
|
18152
|
+
runConfig: z55.any()
|
|
17809
18153
|
}),
|
|
17810
|
-
stateSchema:
|
|
17811
|
-
currentAgentId:
|
|
17812
|
-
completedEdges:
|
|
17813
|
-
runId:
|
|
17814
|
-
stepIdMap:
|
|
18154
|
+
stateSchema: z55.object({
|
|
18155
|
+
currentAgentId: z55.string().default(""),
|
|
18156
|
+
completedEdges: z55.array(CompletedEdgeSchema).default([]),
|
|
18157
|
+
runId: z55.string().default(""),
|
|
18158
|
+
stepIdMap: z55.record(z55.string()).default({})
|
|
17815
18159
|
}),
|
|
17816
18160
|
beforeAgent: async (state, runtime) => {
|
|
17817
18161
|
if (state.runId) {
|
|
@@ -17862,14 +18206,14 @@ ${request.systemPrompt}` : topologyPrompt;
|
|
|
17862
18206
|
return handler({ ...request, systemPrompt: newSystemPrompt });
|
|
17863
18207
|
},
|
|
17864
18208
|
tools: [
|
|
17865
|
-
|
|
18209
|
+
tool51(
|
|
17866
18210
|
async (_input) => {
|
|
17867
18211
|
return "placeholder";
|
|
17868
18212
|
},
|
|
17869
18213
|
{
|
|
17870
18214
|
name: "read_topo_progress",
|
|
17871
18215
|
description: "Check the current progress of the workflow execution plan. Returns which steps have been completed and which are still pending.",
|
|
17872
|
-
schema:
|
|
18216
|
+
schema: z55.object({})
|
|
17873
18217
|
}
|
|
17874
18218
|
)
|
|
17875
18219
|
],
|
|
@@ -18145,7 +18489,7 @@ var ProcessingAgentGraphBuilder = class {
|
|
|
18145
18489
|
const tools = params.tools.map((t) => {
|
|
18146
18490
|
const toolClient = getToolClient(t.key);
|
|
18147
18491
|
return toolClient;
|
|
18148
|
-
}).filter((
|
|
18492
|
+
}).filter((tool52) => tool52 !== void 0);
|
|
18149
18493
|
const subagents = await Promise.all(params.subAgents.map(async (sa) => {
|
|
18150
18494
|
if (sa.client) {
|
|
18151
18495
|
return {
|
|
@@ -18179,6 +18523,7 @@ var ProcessingAgentGraphBuilder = class {
|
|
|
18179
18523
|
contextSchema: params.stateSchema,
|
|
18180
18524
|
systemPrompt: params.prompt,
|
|
18181
18525
|
subagents,
|
|
18526
|
+
responseFormat: params.responseFormat,
|
|
18182
18527
|
checkpointer: getCheckpointSaver("default"),
|
|
18183
18528
|
skills: params.skillCategories,
|
|
18184
18529
|
backend: filesystemBackend,
|
|
@@ -18410,6 +18755,100 @@ function extractLastHumanMessage(messages) {
|
|
|
18410
18755
|
return "";
|
|
18411
18756
|
}
|
|
18412
18757
|
|
|
18758
|
+
// src/agent_lattice/builders/WorkflowAgentGraphBuilder.ts
|
|
18759
|
+
import { createAgent as createAgent7 } from "langchain";
|
|
18760
|
+
import { isWorkflowAgentConfig } from "@axiom-lattice/protocols";
|
|
18761
|
+
var DEFAULT_AGENT_PROMPT = "Complete the task accurately and concisely. Follow the instructions in the user's message.";
|
|
18762
|
+
var WorkflowAgentGraphBuilder = class {
|
|
18763
|
+
async build(agentLattice, params) {
|
|
18764
|
+
if (!isWorkflowAgentConfig(agentLattice.config)) {
|
|
18765
|
+
throw new Error(
|
|
18766
|
+
`WorkflowAgentGraphBuilder received wrong agent type: ${agentLattice.config.type}`
|
|
18767
|
+
);
|
|
18768
|
+
}
|
|
18769
|
+
const config = agentLattice.config;
|
|
18770
|
+
const yaml = config.workflowYaml;
|
|
18771
|
+
const tenantId = agentLattice.config.tenantId ?? "default";
|
|
18772
|
+
const checkpointer = getCheckpointSaver("default");
|
|
18773
|
+
const tools = params.tools.map((t) => t.executor).filter(Boolean);
|
|
18774
|
+
const middlewareConfigs = params.middleware || [];
|
|
18775
|
+
const middlewares = await createCommonMiddlewares(middlewareConfigs, void 0, false);
|
|
18776
|
+
const askMiddlewares = await createCommonMiddlewares([
|
|
18777
|
+
{
|
|
18778
|
+
id: "ask_user_to_clarify",
|
|
18779
|
+
type: "ask_user_to_clarify",
|
|
18780
|
+
name: "Ask User Clarify",
|
|
18781
|
+
description: "For workflow steps requiring user interaction",
|
|
18782
|
+
enabled: true,
|
|
18783
|
+
config: {}
|
|
18784
|
+
}
|
|
18785
|
+
], void 0, false);
|
|
18786
|
+
const noWrapMiddlewares = middlewares.filter((m) => !m.wrapModelCall);
|
|
18787
|
+
const noWrapAskMiddlewares = askMiddlewares.filter((m) => !m.wrapModelCall);
|
|
18788
|
+
console.log(`[WF BUILDER] building default agent | toolCount=${tools.length} | middlewareCount=${middlewares.length}`);
|
|
18789
|
+
const defaultAgent = createAgent7({
|
|
18790
|
+
model: params.model,
|
|
18791
|
+
tools,
|
|
18792
|
+
systemPrompt: params.prompt || DEFAULT_AGENT_PROMPT,
|
|
18793
|
+
checkpointer,
|
|
18794
|
+
middleware: middlewares
|
|
18795
|
+
});
|
|
18796
|
+
console.log(`[WF BUILDER] default agent built`);
|
|
18797
|
+
const agentCache = /* @__PURE__ */ new Map();
|
|
18798
|
+
const resolveAgent = async (ref, responseFormat, stepType) => {
|
|
18799
|
+
if (ref) {
|
|
18800
|
+
console.log(`[WF BUILDER] resolveAgent: looking up ref="${ref}"`);
|
|
18801
|
+
return await getAgentClientAsync(tenantId, ref);
|
|
18802
|
+
}
|
|
18803
|
+
const isAsk = stepType === "ask";
|
|
18804
|
+
if (responseFormat) {
|
|
18805
|
+
const key = (isAsk ? "ask:" : "agent:") + JSON.stringify(responseFormat);
|
|
18806
|
+
console.log(`[WF BUILDER] resolveAgent: cacheKey=${key.slice(0, 80)}... | cached=${agentCache.has(key)}`);
|
|
18807
|
+
if (!agentCache.has(key)) {
|
|
18808
|
+
console.log(`[WF BUILDER] creating ${isAsk ? "ask" : "agent"} with responseFormat`);
|
|
18809
|
+
const agent = createAgent7({
|
|
18810
|
+
model: params.model,
|
|
18811
|
+
tools,
|
|
18812
|
+
systemPrompt: params.prompt || DEFAULT_AGENT_PROMPT,
|
|
18813
|
+
checkpointer,
|
|
18814
|
+
middleware: isAsk ? noWrapAskMiddlewares : noWrapMiddlewares,
|
|
18815
|
+
responseFormat
|
|
18816
|
+
});
|
|
18817
|
+
agentCache.set(key, agent);
|
|
18818
|
+
}
|
|
18819
|
+
return agentCache.get(key);
|
|
18820
|
+
}
|
|
18821
|
+
if (isAsk) {
|
|
18822
|
+
const key = "ask:default";
|
|
18823
|
+
if (!agentCache.has(key)) {
|
|
18824
|
+
console.log(`[WF BUILDER] creating ask default agent`);
|
|
18825
|
+
const agent = createAgent7({
|
|
18826
|
+
model: params.model,
|
|
18827
|
+
tools,
|
|
18828
|
+
systemPrompt: params.prompt || DEFAULT_AGENT_PROMPT,
|
|
18829
|
+
checkpointer,
|
|
18830
|
+
middleware: askMiddlewares
|
|
18831
|
+
});
|
|
18832
|
+
agentCache.set(key, agent);
|
|
18833
|
+
}
|
|
18834
|
+
return agentCache.get(key);
|
|
18835
|
+
}
|
|
18836
|
+
console.log(`[WF BUILDER] resolveAgent: using defaultAgent`);
|
|
18837
|
+
return defaultAgent;
|
|
18838
|
+
};
|
|
18839
|
+
let trackingStore;
|
|
18840
|
+
try {
|
|
18841
|
+
const storeLattice = getStoreLattice("default", "workflowTracking");
|
|
18842
|
+
trackingStore = storeLattice.store;
|
|
18843
|
+
console.log(`[WF BUILDER] trackingStore registered`);
|
|
18844
|
+
} catch {
|
|
18845
|
+
console.warn(`[WF BUILDER] no trackingStore registered`);
|
|
18846
|
+
}
|
|
18847
|
+
const graph = compileWorkflow(yaml, resolveAgent, checkpointer, trackingStore);
|
|
18848
|
+
return graph;
|
|
18849
|
+
}
|
|
18850
|
+
};
|
|
18851
|
+
|
|
18413
18852
|
// src/agent_lattice/builders/AgentGraphBuilderFactory.ts
|
|
18414
18853
|
var AgentGraphBuilderFactory = class _AgentGraphBuilderFactory {
|
|
18415
18854
|
constructor() {
|
|
@@ -18434,6 +18873,7 @@ var AgentGraphBuilderFactory = class _AgentGraphBuilderFactory {
|
|
|
18434
18873
|
this.builders.set(AgentType.TEAM, new TeamAgentGraphBuilder());
|
|
18435
18874
|
this.builders.set(AgentType.PROCESSING, new ProcessingAgentGraphBuilder());
|
|
18436
18875
|
this.builders.set(AgentType.A2A_REMOTE, new RemoteAgentGraphBuilder());
|
|
18876
|
+
this.builders.set(AgentType.WORKFLOW, new WorkflowAgentGraphBuilder());
|
|
18437
18877
|
}
|
|
18438
18878
|
/**
|
|
18439
18879
|
* 注册自定义Builder
|
|
@@ -18526,6 +18966,7 @@ var AgentParamsBuilder = class {
|
|
|
18526
18966
|
subAgents: [...subAgents, ...internalSubAgents],
|
|
18527
18967
|
prompt: agentLattice.config.prompt,
|
|
18528
18968
|
stateSchema: agentLattice.config.schema,
|
|
18969
|
+
responseFormat: agentLattice.config.responseFormat,
|
|
18529
18970
|
skillCategories: skills,
|
|
18530
18971
|
middleware: agentLattice.config.middleware,
|
|
18531
18972
|
tenantId: agentLattice.config.tenantId
|
|
@@ -19108,8 +19549,65 @@ ${body}` : `${frontmatter}
|
|
|
19108
19549
|
}
|
|
19109
19550
|
};
|
|
19110
19551
|
|
|
19552
|
+
// src/store_lattice/InMemoryMenuStore.ts
|
|
19553
|
+
import { randomUUID as randomUUID3 } from "crypto";
|
|
19554
|
+
var InMemoryMenuStore = class {
|
|
19555
|
+
constructor() {
|
|
19556
|
+
this.items = /* @__PURE__ */ new Map();
|
|
19557
|
+
}
|
|
19558
|
+
async list(params) {
|
|
19559
|
+
const results = Array.from(this.items.values()).filter((item) => {
|
|
19560
|
+
if (item.tenantId !== params.tenantId) return false;
|
|
19561
|
+
if (params.menuTarget && item.menuTarget !== params.menuTarget) return false;
|
|
19562
|
+
if (!item.enabled) return false;
|
|
19563
|
+
return true;
|
|
19564
|
+
});
|
|
19565
|
+
results.sort((a, b) => a.sortOrder - b.sortOrder);
|
|
19566
|
+
return results;
|
|
19567
|
+
}
|
|
19568
|
+
async getById(id) {
|
|
19569
|
+
return this.items.get(id) || null;
|
|
19570
|
+
}
|
|
19571
|
+
async create(input) {
|
|
19572
|
+
const now = /* @__PURE__ */ new Date();
|
|
19573
|
+
const item = {
|
|
19574
|
+
id: randomUUID3(),
|
|
19575
|
+
tenantId: input.tenantId,
|
|
19576
|
+
menuTarget: input.menuTarget,
|
|
19577
|
+
group: input.group,
|
|
19578
|
+
name: input.name,
|
|
19579
|
+
icon: input.icon,
|
|
19580
|
+
sortOrder: input.sortOrder ?? 0,
|
|
19581
|
+
contentType: input.contentType,
|
|
19582
|
+
contentConfig: input.contentConfig,
|
|
19583
|
+
enabled: true,
|
|
19584
|
+
createdAt: now,
|
|
19585
|
+
updatedAt: now
|
|
19586
|
+
};
|
|
19587
|
+
this.items.set(item.id, item);
|
|
19588
|
+
return item;
|
|
19589
|
+
}
|
|
19590
|
+
async update(id, patch) {
|
|
19591
|
+
const existing = this.items.get(id);
|
|
19592
|
+
if (!existing) throw new Error(`MenuItem ${id} not found`);
|
|
19593
|
+
const updated = {
|
|
19594
|
+
...existing,
|
|
19595
|
+
...patch,
|
|
19596
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
19597
|
+
};
|
|
19598
|
+
this.items.set(id, updated);
|
|
19599
|
+
return updated;
|
|
19600
|
+
}
|
|
19601
|
+
async delete(id) {
|
|
19602
|
+
this.items.delete(id);
|
|
19603
|
+
}
|
|
19604
|
+
clear() {
|
|
19605
|
+
this.items.clear();
|
|
19606
|
+
}
|
|
19607
|
+
};
|
|
19608
|
+
|
|
19111
19609
|
// src/agent_lattice/agentArchitectTools.ts
|
|
19112
|
-
import
|
|
19610
|
+
import z56 from "zod";
|
|
19113
19611
|
import { v4 as v43 } from "uuid";
|
|
19114
19612
|
import { AgentType as AgentType3 } from "@axiom-lattice/protocols";
|
|
19115
19613
|
function getTenantId(exeConfig) {
|
|
@@ -19139,7 +19637,7 @@ registerToolLattice(
|
|
|
19139
19637
|
{
|
|
19140
19638
|
name: "list_agents",
|
|
19141
19639
|
description: "List all agents for the current workspace. Returns a summary with id, name, description, and type for each agent.",
|
|
19142
|
-
schema:
|
|
19640
|
+
schema: z56.object({})
|
|
19143
19641
|
},
|
|
19144
19642
|
async (_input, exeConfig) => {
|
|
19145
19643
|
try {
|
|
@@ -19166,8 +19664,8 @@ registerToolLattice(
|
|
|
19166
19664
|
{
|
|
19167
19665
|
name: "get_agent",
|
|
19168
19666
|
description: "Get the full configuration of a specific agent by its ID. Returns the complete AgentConfig including prompt, middleware, tools, and sub-agents.",
|
|
19169
|
-
schema:
|
|
19170
|
-
id:
|
|
19667
|
+
schema: z56.object({
|
|
19668
|
+
id: z56.string().describe("The agent ID to retrieve")
|
|
19171
19669
|
})
|
|
19172
19670
|
},
|
|
19173
19671
|
async (input, exeConfig) => {
|
|
@@ -19184,24 +19682,24 @@ registerToolLattice(
|
|
|
19184
19682
|
}
|
|
19185
19683
|
}
|
|
19186
19684
|
);
|
|
19187
|
-
var middlewareConfigSchema =
|
|
19188
|
-
id:
|
|
19189
|
-
type:
|
|
19190
|
-
name:
|
|
19191
|
-
description:
|
|
19192
|
-
enabled:
|
|
19193
|
-
config:
|
|
19685
|
+
var middlewareConfigSchema = z56.object({
|
|
19686
|
+
id: z56.string(),
|
|
19687
|
+
type: z56.string(),
|
|
19688
|
+
name: z56.string(),
|
|
19689
|
+
description: z56.string(),
|
|
19690
|
+
enabled: z56.boolean(),
|
|
19691
|
+
config: z56.record(z56.any()).optional()
|
|
19194
19692
|
});
|
|
19195
|
-
var createAgentSchema =
|
|
19196
|
-
name:
|
|
19197
|
-
description:
|
|
19198
|
-
type:
|
|
19199
|
-
prompt:
|
|
19200
|
-
tools:
|
|
19201
|
-
middleware:
|
|
19202
|
-
subAgents:
|
|
19203
|
-
internalSubAgents:
|
|
19204
|
-
modelKey:
|
|
19693
|
+
var createAgentSchema = z56.object({
|
|
19694
|
+
name: z56.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')."),
|
|
19695
|
+
description: z56.string().optional().describe("Short description"),
|
|
19696
|
+
type: z56.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."),
|
|
19697
|
+
prompt: z56.string().describe("System prompt for the agent"),
|
|
19698
|
+
tools: z56.array(z56.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."),
|
|
19699
|
+
middleware: z56.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: {}."),
|
|
19700
|
+
subAgents: z56.array(z56.string()).optional().describe("Sub-agent IDs (deep_agent only)"),
|
|
19701
|
+
internalSubAgents: z56.array(z56.any()).optional().describe("Inline sub-agent configs (deep_agent only)"),
|
|
19702
|
+
modelKey: z56.string().optional().describe("Model key to use")
|
|
19205
19703
|
});
|
|
19206
19704
|
registerToolLattice(
|
|
19207
19705
|
"create_agent",
|
|
@@ -19239,21 +19737,21 @@ registerToolLattice(
|
|
|
19239
19737
|
}
|
|
19240
19738
|
}
|
|
19241
19739
|
);
|
|
19242
|
-
var topologyEdgeSchema =
|
|
19243
|
-
from:
|
|
19244
|
-
to:
|
|
19245
|
-
purpose:
|
|
19740
|
+
var topologyEdgeSchema = z56.object({
|
|
19741
|
+
from: z56.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."),
|
|
19742
|
+
to: z56.string().describe("Target agent ID (the sub-agent to delegate to)"),
|
|
19743
|
+
purpose: z56.string().describe("Business purpose of this delegation step \u2014 what the sub-agent should accomplish")
|
|
19246
19744
|
});
|
|
19247
|
-
var createProcessingAgentSchema =
|
|
19248
|
-
name:
|
|
19249
|
-
description:
|
|
19250
|
-
prompt:
|
|
19251
|
-
edges:
|
|
19252
|
-
tools:
|
|
19253
|
-
subAgents:
|
|
19254
|
-
internalSubAgents:
|
|
19255
|
-
middleware:
|
|
19256
|
-
modelKey:
|
|
19745
|
+
var createProcessingAgentSchema = z56.object({
|
|
19746
|
+
name: z56.string().describe("Display name for the processing agent"),
|
|
19747
|
+
description: z56.string().optional().describe("Short description"),
|
|
19748
|
+
prompt: z56.string().describe("System prompt for the orchestrator. Should describe how to route tasks through the topology."),
|
|
19749
|
+
edges: z56.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."),
|
|
19750
|
+
tools: z56.array(z56.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."),
|
|
19751
|
+
subAgents: z56.array(z56.string()).describe("IDs of sub-agents that form the workflow pipeline. These must be created first via create_agent."),
|
|
19752
|
+
internalSubAgents: z56.array(z56.any()).optional().describe("Inline sub-agent configs (alternative to pre-created sub-agents)"),
|
|
19753
|
+
middleware: z56.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: {}."),
|
|
19754
|
+
modelKey: z56.string().optional().describe("Model key to use")
|
|
19257
19755
|
}).refine(
|
|
19258
19756
|
(data) => {
|
|
19259
19757
|
const edgeTargets = new Set(data.edges.map((e) => e.to));
|
|
@@ -19335,16 +19833,177 @@ registerToolLattice(
|
|
|
19335
19833
|
}
|
|
19336
19834
|
}
|
|
19337
19835
|
);
|
|
19338
|
-
var
|
|
19339
|
-
|
|
19340
|
-
|
|
19341
|
-
|
|
19342
|
-
|
|
19343
|
-
|
|
19344
|
-
|
|
19345
|
-
|
|
19346
|
-
|
|
19347
|
-
|
|
19836
|
+
var createWorkflowSchema = z56.object({
|
|
19837
|
+
name: z56.string().describe("Display name for the workflow agent"),
|
|
19838
|
+
description: z56.string().optional().describe("Short description"),
|
|
19839
|
+
skillLoaded: z56.literal(true).describe("MUST be true. Set after loading the 'create-workflow' skill."),
|
|
19840
|
+
yaml: z56.string().describe("The YAML workflow definition in linear DSL format (steps execute top-to-bottom, use parallel: for concurrency)"),
|
|
19841
|
+
tools: z56.array(z56.string()).optional().describe("Tool keys for the workflow agent"),
|
|
19842
|
+
middleware: z56.array(middlewareConfigSchema).optional().describe("Middleware configs"),
|
|
19843
|
+
modelKey: z56.string().optional().describe("Model key")
|
|
19844
|
+
});
|
|
19845
|
+
registerToolLattice(
|
|
19846
|
+
"create_workflow",
|
|
19847
|
+
{
|
|
19848
|
+
name: "create_workflow",
|
|
19849
|
+
description: "Create a WORKFLOW agent from YAML DSL. Load the 'create-workflow' skill first. Linear model \u2014 steps execute top-to-bottom. Use parallel: for concurrency. Data flows via {{label}} automatically. Business logic stays in agent prompts.",
|
|
19850
|
+
schema: createWorkflowSchema
|
|
19851
|
+
},
|
|
19852
|
+
async (input, exeConfig) => {
|
|
19853
|
+
try {
|
|
19854
|
+
const tenantId = getTenantId(exeConfig);
|
|
19855
|
+
const store = getAssistStore();
|
|
19856
|
+
const id = await generateAgentId(tenantId, input.name);
|
|
19857
|
+
try {
|
|
19858
|
+
const { compileWorkflow: compileWorkflow2 } = await import("./compile-4RFYHUBE.mjs");
|
|
19859
|
+
const { getCheckpointSaver: getCheckpointSaver2 } = await import("./memory_lattice-E66HTTVV.mjs");
|
|
19860
|
+
await compileWorkflow2(input.yaml, async () => ({ invoke: async () => ({}) }), getCheckpointSaver2("default"));
|
|
19861
|
+
} catch (e) {
|
|
19862
|
+
return JSON.stringify({ error: `DSL validation failed: ${e.message}` });
|
|
19863
|
+
}
|
|
19864
|
+
const config = {
|
|
19865
|
+
key: id,
|
|
19866
|
+
name: input.name,
|
|
19867
|
+
description: input.description || "",
|
|
19868
|
+
type: AgentType3.WORKFLOW,
|
|
19869
|
+
prompt: input.description || `Workflow: ${input.name}`,
|
|
19870
|
+
workflowYaml: input.yaml,
|
|
19871
|
+
...input.tools && input.tools.length > 0 ? { tools: input.tools } : {},
|
|
19872
|
+
...input.middleware && input.middleware.length > 0 ? { middleware: input.middleware } : {},
|
|
19873
|
+
...input.modelKey ? { modelKey: input.modelKey } : {}
|
|
19874
|
+
};
|
|
19875
|
+
await store.createAssistant(tenantId, id, {
|
|
19876
|
+
name: input.name,
|
|
19877
|
+
description: input.description,
|
|
19878
|
+
graphDefinition: config
|
|
19879
|
+
});
|
|
19880
|
+
eventBus.publish("assistant:created", { id, name: input.name, tenantId });
|
|
19881
|
+
return JSON.stringify({ id, name: input.name, type: "workflow" });
|
|
19882
|
+
} catch (error) {
|
|
19883
|
+
return JSON.stringify({ error: `Failed to create workflow: ${error.message}` });
|
|
19884
|
+
}
|
|
19885
|
+
}
|
|
19886
|
+
);
|
|
19887
|
+
registerToolLattice(
|
|
19888
|
+
"validate_workflow",
|
|
19889
|
+
{
|
|
19890
|
+
name: "validate_workflow",
|
|
19891
|
+
description: "Validate a workflow agent's DSL for correctness by compiling it.",
|
|
19892
|
+
schema: z56.object({
|
|
19893
|
+
id: z56.string().describe("The workflow agent ID to validate")
|
|
19894
|
+
})
|
|
19895
|
+
},
|
|
19896
|
+
async (input, exeConfig) => {
|
|
19897
|
+
try {
|
|
19898
|
+
const tenantId = getTenantId(exeConfig);
|
|
19899
|
+
const store = getAssistStore();
|
|
19900
|
+
const agent = await store.getAssistantById(tenantId, input.id);
|
|
19901
|
+
if (!agent) {
|
|
19902
|
+
return JSON.stringify({ error: `Agent '${input.id}' not found` });
|
|
19903
|
+
}
|
|
19904
|
+
const graphDef = agent.graphDefinition;
|
|
19905
|
+
if (!graphDef || graphDef.type !== AgentType3.WORKFLOW) {
|
|
19906
|
+
return JSON.stringify({ error: `Agent '${input.id}' is not a workflow agent` });
|
|
19907
|
+
}
|
|
19908
|
+
const yaml = graphDef.workflowYaml;
|
|
19909
|
+
if (!yaml) {
|
|
19910
|
+
return JSON.stringify({ error: `Agent '${input.id}' has no workflow DSL` });
|
|
19911
|
+
}
|
|
19912
|
+
try {
|
|
19913
|
+
const { compileWorkflow: compileWorkflow2 } = await import("./compile-4RFYHUBE.mjs");
|
|
19914
|
+
const { getCheckpointSaver: getCheckpointSaver2 } = await import("./memory_lattice-E66HTTVV.mjs");
|
|
19915
|
+
await compileWorkflow2(yaml, async () => ({ invoke: async () => ({}) }), getCheckpointSaver2("default"));
|
|
19916
|
+
} catch (e) {
|
|
19917
|
+
return JSON.stringify({
|
|
19918
|
+
agentId: input.id,
|
|
19919
|
+
valid: false,
|
|
19920
|
+
issues: [{ type: "error", message: e.message }]
|
|
19921
|
+
});
|
|
19922
|
+
}
|
|
19923
|
+
return JSON.stringify({ agentId: input.id, valid: true, issues: [] });
|
|
19924
|
+
} catch (error) {
|
|
19925
|
+
return JSON.stringify({ error: `Failed to validate workflow: ${error.message}` });
|
|
19926
|
+
}
|
|
19927
|
+
}
|
|
19928
|
+
);
|
|
19929
|
+
var updateWorkflowSchema = z56.object({
|
|
19930
|
+
id: z56.string().describe("The workflow agent ID to update"),
|
|
19931
|
+
name: z56.string().optional().describe("New display name"),
|
|
19932
|
+
description: z56.string().optional().describe("New description"),
|
|
19933
|
+
yaml: z56.string().optional().describe("Replacement YAML workflow DSL. Omit to keep existing."),
|
|
19934
|
+
tools: z56.array(z56.string()).optional().describe("Replacement tool keys"),
|
|
19935
|
+
middleware: z56.array(middlewareConfigSchema).optional().describe("Replacement middleware configs"),
|
|
19936
|
+
modelKey: z56.string().optional().describe("Replacement model key")
|
|
19937
|
+
});
|
|
19938
|
+
registerToolLattice(
|
|
19939
|
+
"update_workflow",
|
|
19940
|
+
{
|
|
19941
|
+
name: "update_workflow",
|
|
19942
|
+
description: "Update an existing workflow agent. Provide the agent ID and only the fields to change. Pass yaml string to replace the DSL, or omit to keep it.",
|
|
19943
|
+
schema: updateWorkflowSchema
|
|
19944
|
+
},
|
|
19945
|
+
async (input, exeConfig) => {
|
|
19946
|
+
console.log(`[update_workflow] CALLED id=${input.id} hasYaml=${input.yaml !== void 0}`);
|
|
19947
|
+
try {
|
|
19948
|
+
const tenantId = getTenantId(exeConfig);
|
|
19949
|
+
const store = getAssistStore();
|
|
19950
|
+
const existing = await store.getAssistantById(tenantId, input.id);
|
|
19951
|
+
if (!existing) {
|
|
19952
|
+
console.log(`[update_workflow] ERROR: agent not found: ${input.id}`);
|
|
19953
|
+
return JSON.stringify({ error: `Agent '${input.id}' not found` });
|
|
19954
|
+
}
|
|
19955
|
+
const existingConfig = existing.graphDefinition || {};
|
|
19956
|
+
if (existingConfig.type !== AgentType3.WORKFLOW) {
|
|
19957
|
+
console.log(`[update_workflow] ERROR: not a workflow agent: ${input.id}`);
|
|
19958
|
+
return JSON.stringify({ error: `Agent '${input.id}' is not a workflow agent` });
|
|
19959
|
+
}
|
|
19960
|
+
const mergedConfig = { ...existingConfig };
|
|
19961
|
+
if (input.name !== void 0) mergedConfig.name = input.name;
|
|
19962
|
+
if (input.description !== void 0) mergedConfig.description = input.description;
|
|
19963
|
+
if (input.yaml !== void 0) mergedConfig.workflowYaml = input.yaml;
|
|
19964
|
+
if (input.tools !== void 0) mergedConfig.tools = input.tools;
|
|
19965
|
+
if (input.middleware !== void 0) mergedConfig.middleware = input.middleware;
|
|
19966
|
+
if (input.modelKey !== void 0) mergedConfig.modelKey = input.modelKey;
|
|
19967
|
+
if (input.yaml !== void 0) {
|
|
19968
|
+
console.log(`[update_workflow] validating DSL: ${input.id}`);
|
|
19969
|
+
try {
|
|
19970
|
+
const { compileWorkflow: compileWorkflow2 } = await import("./compile-4RFYHUBE.mjs");
|
|
19971
|
+
const { getCheckpointSaver: getCheckpointSaver2 } = await import("./memory_lattice-E66HTTVV.mjs");
|
|
19972
|
+
await compileWorkflow2(input.yaml, async () => ({ invoke: async () => ({}) }), getCheckpointSaver2("default"));
|
|
19973
|
+
console.log(`[update_workflow] DSL validation passed: ${input.id}`);
|
|
19974
|
+
} catch (e) {
|
|
19975
|
+
console.log(`[update_workflow] DSL validation FAILED: ${input.id} - ${e.message}`);
|
|
19976
|
+
return JSON.stringify({
|
|
19977
|
+
error: `DSL validation failed: ${e.message}`,
|
|
19978
|
+
issues: [{ type: "error", message: e.message }]
|
|
19979
|
+
});
|
|
19980
|
+
}
|
|
19981
|
+
}
|
|
19982
|
+
const newName = input.name || existing.name;
|
|
19983
|
+
await store.updateAssistant(tenantId, input.id, {
|
|
19984
|
+
name: newName,
|
|
19985
|
+
description: input.description !== void 0 ? input.description : existing.description,
|
|
19986
|
+
graphDefinition: mergedConfig
|
|
19987
|
+
});
|
|
19988
|
+
eventBus.publish("assistant:updated", { id: input.id, name: newName, tenantId });
|
|
19989
|
+
console.log(`[update_workflow] SUCCESS: id=${input.id} name=${newName}`);
|
|
19990
|
+
return JSON.stringify({ id: input.id, name: newName, type: "workflow" });
|
|
19991
|
+
} catch (error) {
|
|
19992
|
+
console.log(`[update_workflow] EXCEPTION: ${error.message}`);
|
|
19993
|
+
return JSON.stringify({ error: `Failed to update workflow: ${error.message}` });
|
|
19994
|
+
}
|
|
19995
|
+
}
|
|
19996
|
+
);
|
|
19997
|
+
var updateProcessingAgentSchema = z56.object({
|
|
19998
|
+
id: z56.string().describe("The PROCESSING agent ID to update"),
|
|
19999
|
+
name: z56.string().optional().describe("New display name for the orchestrator"),
|
|
20000
|
+
description: z56.string().optional().describe("New short description"),
|
|
20001
|
+
prompt: z56.string().optional().describe("New system prompt for the orchestrator"),
|
|
20002
|
+
edges: z56.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."),
|
|
20003
|
+
tools: z56.array(z56.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."),
|
|
20004
|
+
subAgents: z56.array(z56.string()).optional().describe("New IDs of sub-agents in the workflow pipeline"),
|
|
20005
|
+
middleware: z56.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: {}."),
|
|
20006
|
+
modelKey: z56.string().optional().describe("New model key")
|
|
19348
20007
|
}).refine(
|
|
19349
20008
|
(data) => {
|
|
19350
20009
|
if (!data.edges) return true;
|
|
@@ -19472,18 +20131,18 @@ registerToolLattice(
|
|
|
19472
20131
|
}
|
|
19473
20132
|
}
|
|
19474
20133
|
);
|
|
19475
|
-
var updateAgentSchema =
|
|
19476
|
-
id:
|
|
19477
|
-
config:
|
|
19478
|
-
name:
|
|
19479
|
-
description:
|
|
19480
|
-
type:
|
|
19481
|
-
prompt:
|
|
19482
|
-
tools:
|
|
19483
|
-
middleware:
|
|
19484
|
-
subAgents:
|
|
19485
|
-
internalSubAgents:
|
|
19486
|
-
modelKey:
|
|
20134
|
+
var updateAgentSchema = z56.object({
|
|
20135
|
+
id: z56.string().describe("The agent ID to update"),
|
|
20136
|
+
config: z56.object({
|
|
20137
|
+
name: z56.string().optional().describe("New display name for the agent"),
|
|
20138
|
+
description: z56.string().optional().describe("New short description"),
|
|
20139
|
+
type: z56.enum(["react", "deep_agent"]).optional().describe("Agent type"),
|
|
20140
|
+
prompt: z56.string().optional().describe("New system prompt for the agent"),
|
|
20141
|
+
tools: z56.array(z56.string()).optional().describe("Tool keys to assign to this agent. These are registered tool names (strings), NOT middleware objects."),
|
|
20142
|
+
middleware: z56.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: {}."),
|
|
20143
|
+
subAgents: z56.array(z56.string()).optional().describe("Sub-agent IDs (deep_agent only)"),
|
|
20144
|
+
internalSubAgents: z56.array(z56.any()).optional().describe("Inline sub-agent configs (deep_agent only)"),
|
|
20145
|
+
modelKey: z56.string().optional().describe("Model key to use")
|
|
19487
20146
|
}).describe("Configuration fields to update. Only include the fields you want to change.")
|
|
19488
20147
|
});
|
|
19489
20148
|
registerToolLattice(
|
|
@@ -19521,8 +20180,8 @@ registerToolLattice(
|
|
|
19521
20180
|
{
|
|
19522
20181
|
name: "delete_agent",
|
|
19523
20182
|
description: "Permanently delete an agent by its ID. This action cannot be undone.",
|
|
19524
|
-
schema:
|
|
19525
|
-
id:
|
|
20183
|
+
schema: z56.object({
|
|
20184
|
+
id: z56.string().describe("The agent ID to delete")
|
|
19526
20185
|
})
|
|
19527
20186
|
},
|
|
19528
20187
|
async (input, exeConfig) => {
|
|
@@ -19548,7 +20207,7 @@ registerToolLattice(
|
|
|
19548
20207
|
{
|
|
19549
20208
|
name: "list_tools",
|
|
19550
20209
|
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.",
|
|
19551
|
-
schema:
|
|
20210
|
+
schema: z56.object({})
|
|
19552
20211
|
},
|
|
19553
20212
|
async (_input, _exeConfig) => {
|
|
19554
20213
|
try {
|
|
@@ -19570,9 +20229,9 @@ registerToolLattice(
|
|
|
19570
20229
|
{
|
|
19571
20230
|
name: "invoke_agent",
|
|
19572
20231
|
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).",
|
|
19573
|
-
schema:
|
|
19574
|
-
id:
|
|
19575
|
-
message:
|
|
20232
|
+
schema: z56.object({
|
|
20233
|
+
id: z56.string().describe("The agent ID to invoke"),
|
|
20234
|
+
message: z56.string().describe("The test message to send to the agent")
|
|
19576
20235
|
})
|
|
19577
20236
|
},
|
|
19578
20237
|
async (input, exeConfig) => {
|
|
@@ -19590,18 +20249,10 @@ registerToolLattice(
|
|
|
19590
20249
|
assistant_id: id,
|
|
19591
20250
|
thread_id: threadId
|
|
19592
20251
|
});
|
|
19593
|
-
const result = await agent.
|
|
19594
|
-
|
|
19595
|
-
const lastAi = [...messages].reverse().find(
|
|
19596
|
-
(m) => m.role === "ai" || m.type === "ai"
|
|
19597
|
-
);
|
|
19598
|
-
const content = lastAi?.content ?? "(no response)";
|
|
19599
|
-
return JSON.stringify({
|
|
19600
|
-
agentId: id,
|
|
19601
|
-
threadId,
|
|
19602
|
-
response: typeof content === "string" ? content : JSON.stringify(content)
|
|
19603
|
-
});
|
|
20252
|
+
const result = await agent.invokeWithState({ input: { message } });
|
|
20253
|
+
return JSON.stringify({ agentId: id, threadId, result });
|
|
19604
20254
|
} catch (error) {
|
|
20255
|
+
console.error(`[invoke_agent] FAILED for agent="${input.id}":`, error.stack || error.message);
|
|
19605
20256
|
return JSON.stringify({ error: `Failed to invoke agent: ${error.message}` });
|
|
19606
20257
|
}
|
|
19607
20258
|
}
|
|
@@ -19625,12 +20276,12 @@ Every agent interaction follows this cycle. You MUST NOT skip any phase:
|
|
|
19625
20276
|
|-------|-------------|-------------------|
|
|
19626
20277
|
| **1. DESIGN** | Understand requirements, choose agent type, design config (prompt, middleware, sub-agents), create topology/architecture diagram | Present the design clearly. Use \`show_widget\` for visual diagrams. |
|
|
19627
20278
|
| **2. CONFIRM** | User reviews and approves the design | **MUST explicitly ask for approval.** Say: "Does this design look good? Shall I create it?" NEVER create or update anything without clear user confirmation. |
|
|
19628
|
-
| **3. BUILD** | Call \`create_agent\`, \`
|
|
20279
|
+
| **3. BUILD** | Call \`create_agent\`, \`create_workflow\`, or \`update_agent\` / \`update_workflow\` | Only after confirmation. Report the result (ID, name). |
|
|
19629
20280
|
| **4. TEST** | Verify the agent works correctly | You may ask the user if they want you to test. If yes, delegate to the **Agent Reviewer** sub-agent. Do NOT test until the user confirms. |
|
|
19630
20281
|
|
|
19631
20282
|
**CRITICAL RULES:**
|
|
19632
20283
|
- **NEVER build before confirming.** Design \u2192 ask \u2192 wait for "yes" \u2192 only then build.
|
|
19633
|
-
- **Edit, don't re-create.** After an agent exists, modifying it ALWAYS means \`update_agent\` or \`
|
|
20284
|
+
- **Edit, don't re-create.** After an agent exists, modifying it ALWAYS means \`update_agent\` or \`update_workflow\` \u2014 NEVER \`create_agent\` or \`create_workflow\` again. If you just created an agent and the user wants to change something, use the update tool for that agent.
|
|
19634
20285
|
- **NEVER test proactively.** You may ask if the user wants to test \u2014 but do NOT invoke the Reviewer until they say yes. Never test yourself.
|
|
19635
20286
|
- **One decision at a time.** Each message asks exactly one question.
|
|
19636
20287
|
|
|
@@ -19641,7 +20292,7 @@ Once an agent is created, NEVER create another agent for the same purpose. If th
|
|
|
19641
20292
|
| User wants to... | Use |
|
|
19642
20293
|
|-----------------|-----|
|
|
19643
20294
|
| Change prompt, tools, middleware, name | \`update_agent\` |
|
|
19644
|
-
| Change
|
|
20295
|
+
| Change workflow DSL, tools, middleware | \`update_workflow\` |
|
|
19645
20296
|
| See current config | \`get_agent\` |
|
|
19646
20297
|
|
|
19647
20298
|
If the user's intent is unclear after creation, ask: "Edit this agent or create a new one?"
|
|
@@ -19653,8 +20304,9 @@ You have nine tools for agent management:
|
|
|
19653
20304
|
- **list_tools** \u2014 See all available tools that can be assigned to agents
|
|
19654
20305
|
- **get_agent** \u2014 View the full configuration of a specific agent
|
|
19655
20306
|
- **create_agent** \u2014 Create a REACT or DEEP_AGENT agent
|
|
19656
|
-
- **
|
|
19657
|
-
- **
|
|
20307
|
+
- **create_workflow** \u2014 Create a WORKFLOW agent from a concise DSL (load create-workflow skill first)
|
|
20308
|
+
- **validate_workflow** \u2014 Validate a workflow agent's DSL
|
|
20309
|
+
- **update_workflow** \u2014 Update a workflow agent's DSL or config
|
|
19658
20310
|
- **update_agent** \u2014 Modify an existing REACT or DEEP_AGENT agent's configuration
|
|
19659
20311
|
- **delete_agent** \u2014 Remove an agent permanently
|
|
19660
20312
|
- **manage_binding** \u2014 Bind a sender (email, Lark, Slack user) to an agent so external messages are routed to it
|
|
@@ -19692,7 +20344,7 @@ Let the \`show_widget\` tool handle rendering details \u2014 it has its own guid
|
|
|
19692
20344
|
| Type | Best for | Execution Model |
|
|
19693
20345
|
|------|----------|----------------|
|
|
19694
20346
|
| **react** | Simple, single-responsibility tasks | Classic ReAct loop (think \u2192 act \u2192 observe) |
|
|
19695
|
-
| **
|
|
20347
|
+
| **workflow** | Deterministic multi-step pipelines with branching, parallel, and human-in-the-loop | YAML linear DSL compiled into LangGraph state machine |
|
|
19696
20348
|
| **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 |
|
|
19697
20349
|
|
|
19698
20350
|
When a user is unsure which type to choose, use \`show_widget\` to render a visual comparison \u2014 show each type's execution model side-by-side as an interactive diagram so the user can intuitively understand the differences.
|
|
@@ -19730,233 +20382,64 @@ You may ask: "Want me to send this to the Agent Reviewer for testing?" If yes, d
|
|
|
19730
20382
|
|
|
19731
20383
|
---
|
|
19732
20384
|
|
|
19733
|
-
## Workflow B:
|
|
20385
|
+
## Workflow B: Processing Agent (PROCESSING type) [DEPRECATED]
|
|
19734
20386
|
|
|
19735
|
-
|
|
20387
|
+
The PROCESSING agent type is deprecated. Use the WORKFLOW DSL type (Workflow D below) instead. If a user asks for a multi-step pipeline, guide them toward the WORKFLOW DSL approach.
|
|
19736
20388
|
|
|
19737
|
-
|
|
19738
|
-
|
|
19739
|
-
**Step 1: Process analysis.** Ask: What is the end-to-end process? Map the stages.
|
|
19740
|
-
|
|
19741
|
-
**Business rule \u2014 Draft-then-confirm pattern:** When a workflow creates business objects that require human approval (e.g., draft orders in SAP B1, purchase requisitions, expense reports), the design MUST include a confirmation step AFTER the creation step. The create step must complete successfully before the confirm step runs. The flow is always: **Create draft \u2192 User confirms \u2192 Finalize**. Reason: systems like SAP B1 only expose drafts to users after they are created \u2014 the user cannot see or approve something that doesn't exist yet. The confirm step MUST use the \`ask_user_to_clarify\` middleware.
|
|
19742
|
-
|
|
19743
|
-
**Business pattern \u2014 SAP B1 Draft SO Creation:** When designing a sub-agent responsible for creating draft Sales Orders in SAP B1, embed the following standards into its system prompt. These ensure consistent data construction, API usage, and user presentation:
|
|
19744
|
-
|
|
19745
|
-
**Step 1: Construct SO Data Structure**
|
|
19746
|
-
Build the JSON payload. For each DocumentLines item:
|
|
19747
|
-
- Include \`WarehouseCode\` ONLY if sku.json provides a value; if missing or empty, OMIT the field entirely
|
|
19748
|
-
- Generate \`Comments\` dynamically based on context (customer name, PO reference, special instructions)
|
|
19749
|
-
|
|
19750
|
-
\`\`\`json
|
|
19751
|
-
{
|
|
19752
|
-
"DocObjectCode": "17",
|
|
19753
|
-
"DocType": "dDocument_Items",
|
|
19754
|
-
"CardCode": "C001",
|
|
19755
|
-
"DocDate": "current date",
|
|
19756
|
-
"DocDueDate": "delivery date",
|
|
19757
|
-
"TaxDate": "current date",
|
|
19758
|
-
"U_YWLX": "Modern Trade",
|
|
19759
|
-
"Comments": "SO for Kaimay Retail - PO ref: PO-2024-001234",
|
|
19760
|
-
"DocumentLines": [
|
|
19761
|
-
{
|
|
19762
|
-
"ItemCode": "SKU001",
|
|
19763
|
-
"Quantity": 240,
|
|
19764
|
-
"UnitPrice": 15.84
|
|
19765
|
-
}
|
|
19766
|
-
]
|
|
19767
|
-
}
|
|
19768
|
-
\`\`\`
|
|
20389
|
+
---
|
|
19769
20390
|
|
|
19770
|
-
|
|
19771
|
-
| SAP Field | Data Source |
|
|
19772
|
-
|-----------|-------------|
|
|
19773
|
-
| CardCode | customer.json \u2192 CardCode |
|
|
19774
|
-
| DocDate | Current date (yyyy-MM-dd) |
|
|
19775
|
-
| DocDueDate | extracted.json \u2192 delivery_date |
|
|
19776
|
-
| TaxDate | Current date (yyyy-MM-dd) |
|
|
19777
|
-
| U_YWLX | customer.json \u2192 SalesType |
|
|
19778
|
-
| ItemCode | sku.json \u2192 ItemCode |
|
|
19779
|
-
| Quantity | extracted.json \u2192 Quantity |
|
|
19780
|
-
| WarehouseCode | sku.json \u2192 WarehouseCode (OMIT if missing/empty) |
|
|
19781
|
-
| UnitPrice | price.json \u2192 UnitPrice |
|
|
19782
|
-
| Comments | AI-generated based on customer name, PO reference, and context |
|
|
19783
|
-
|
|
19784
|
-
**Step 2: Call SAP API to Create Draft (MUST EXECUTE)**
|
|
19785
|
-
Use the \`sap_api_call\` tool with EXACTLY these parameters:
|
|
19786
|
-
- **Method**: POST
|
|
19787
|
-
- **Endpoint**: \`Drafts\` (ONLY allowed endpoint; do NOT call SalesOrders or any other endpoint)
|
|
19788
|
-
- **Body**: The JSON constructed in Step 1
|
|
19789
|
-
|
|
19790
|
-
CRITICAL: You MUST call sap_api_call BEFORE proceeding to Step 3. This step is NOT optional.
|
|
19791
|
-
|
|
19792
|
-
If the API call fails:
|
|
19793
|
-
- Log the error details
|
|
19794
|
-
- STOP the process
|
|
19795
|
-
- Report the failure to the user with the error message
|
|
19796
|
-
- Do NOT proceed to Step 3
|
|
19797
|
-
|
|
19798
|
-
**Step 3: Present Draft for User Review (MUST EXECUTE AFTER Step 2)**
|
|
19799
|
-
ONLY after the SAP API call in Step 2 succeeds, use the \`ask_user_to_clarify\` tool to present the complete SO summary.
|
|
19800
|
-
|
|
19801
|
-
Message format (STRICT \u2014 no emoji, no summary, field names match Service Layer):
|
|
19802
|
-
|
|
19803
|
-
=== Sales Order Draft ===
|
|
19804
|
-
|
|
19805
|
-
DocEntry: {DocEntry}
|
|
19806
|
-
DocNum: {DocNum}
|
|
19807
|
-
DocDate: {DocDate}
|
|
19808
|
-
DocDueDate: {DocDueDate}
|
|
19809
|
-
CardCode: {CardCode}
|
|
19810
|
-
CardName: {CardName}
|
|
19811
|
-
U_YWLX: {SalesType}
|
|
19812
|
-
Comments: {Comments}
|
|
19813
|
-
|
|
19814
|
-
DocumentLines:
|
|
19815
|
-
LineNum | ItemCode | Quantity | WarehouseCode | UnitPrice | LineTotal
|
|
19816
|
-
0 | {ItemCode} | {Quantity} | {WarehouseCode} | {UnitPrice} | {LineTotal}
|
|
19817
|
-
1 | {ItemCode} | {Quantity} | {WarehouseCode} | {UnitPrice} | {LineTotal}
|
|
19818
|
-
...
|
|
19819
|
-
|
|
19820
|
-
DocTotal: {DocTotal}
|
|
19821
|
-
|
|
19822
|
-
Warnings:
|
|
19823
|
-
- {warning1}
|
|
19824
|
-
- {warning2}
|
|
19825
|
-
|
|
19826
|
-
Options:
|
|
19827
|
-
[Confirm generating draft]
|
|
19828
|
-
[Cancel, do not generate]
|
|
19829
|
-
|
|
19830
|
-
**Data sharing pattern \u2014 File-based handoff:** Every sub-agent in the pipeline MUST persist its work results as files under a shared project directory, never rely on in-memory data passing between steps. Deep agents have built-in file capabilities, so no middleware is needed.
|
|
19831
|
-
|
|
19832
|
-
Rules:
|
|
19833
|
-
1. The **orchestrator** generates a unique project ID at the start (e.g., timestamp-based) and passes it to each sub-agent in the task context
|
|
19834
|
-
2. Each sub-agent reads input from \`/project/{project-id}/\` and writes output files into the same directory
|
|
19835
|
-
3. Establish clear file naming conventions so downstream steps know exactly which files to read (e.g., \`extracted.json\`, \`sku.json\`, \`customer.json\`, \`so_draft.json\`)
|
|
19836
|
-
4. The orchestrator's system prompt MUST specify for each edge: which files the target sub-agent should read and which files it should produce
|
|
19837
|
-
|
|
19838
|
-
**Step 2: Topology design.** Design the agent topology and use \`show_widget\` to render an interactive diagram showing the flow: Orchestrator \u2192 Stage 1 \u2192 Stage 2 \u2192 ... \u2192 Output. Each edge should be labeled with its business purpose.
|
|
19839
|
-
|
|
19840
|
-
**Step 3: Design each sub-agent** as a **deep_agent** type (one at a time). For each:
|
|
19841
|
-
- Responsibility, system prompt, middleware, file input/output contract (which files from \`/project/{project-id}/\` it reads, which files it writes)
|
|
19842
|
-
- Deep agents have built-in file capabilities (ls, read, write, edit, glob, grep), so do NOT add filesystem middleware.
|
|
19843
|
-
- **Ask for confirmation before moving to the next sub-agent.**
|
|
19844
|
-
|
|
19845
|
-
**Step 4: Design the orchestrator.** Responsibility, system prompt, topology edges, sub-agent list.
|
|
19846
|
-
|
|
19847
|
-
**Step 5: Self-review checklist.** Before presenting to the user, verify:
|
|
19848
|
-
- Completeness (every stage covered by an edge?)
|
|
19849
|
-
- Purposes clear (each edge's business intent?)
|
|
19850
|
-
- Order correct (serial chain logical?)
|
|
19851
|
-
- Edge cases (invalid input, failure, timeout?)
|
|
19852
|
-
|
|
19853
|
-
**Step 6: Write the workflow description (Spec).** After designing the topology and sub-agents, compose a comprehensive **\`description\`** for the orchestrator. This description serves as the workflow's specification \u2014 anyone reading it should understand exactly what this workflow does without needing to inspect individual sub-agent configs.
|
|
19854
|
-
|
|
19855
|
-
The description MUST include ALL of the following:
|
|
19856
|
-
|
|
19857
|
-
| Section | Content |
|
|
19858
|
-
|---------|---------|
|
|
19859
|
-
| **Overview** | One-sentence summary of the workflow's purpose and business value |
|
|
19860
|
-
| **Steps** | Numbered list of each stage in the pipeline. For each step: which sub-agent handles it, what it does, what tools it uses, what files it reads from \`/project/{project-id}/\`, and what files it writes. |
|
|
19861
|
-
| **Data Flow** | How data moves between steps via files under \`/project/{project-id}/\`. For each step: which files it reads as input and which files it writes as output. |
|
|
19862
|
-
| **Logic & Conditions** | Any conditional branching, decision points, retry logic, or exception handling. When does the workflow take path A vs path B? What happens on failure? |
|
|
19863
|
-
| **Tools Used** | Summary table or list of all tools used across sub-agents, grouped by sub-agent |
|
|
19864
|
-
| **Expected Input** | What input does the workflow expect from the user? (format, examples) |
|
|
19865
|
-
| **Expected Output** | What does the workflow produce at the end? (format, examples) |
|
|
19866
|
-
|
|
19867
|
-
**Formatting rules:**
|
|
19868
|
-
- Write in **English**
|
|
19869
|
-
- Use **Markdown** for formatting (headings, lists, tables, code blocks)
|
|
19870
|
-
- Be detailed but concise \u2014 each section should be 1-5 lines
|
|
19871
|
-
- Avoid placeholder text like "TODO" or "TBD"
|
|
19872
|
-
|
|
19873
|
-
**Example structure** (\u5B50 Agent \u5747\u4E3A deep_agent \u7C7B\u578B\uFF0C\u65E0\u9700 filesystem \u4E2D\u95F4\u4EF6):
|
|
19874
|
-
|
|
19875
|
-
\`\`\`markdown
|
|
19876
|
-
## Overview
|
|
19877
|
-
\u672C\u5DE5\u4F5C\u6D41\u81EA\u52A8\u4ECE\u591A\u4E2A\u6570\u636E\u6E90\u91C7\u96C6\u7ADE\u54C1\u4EF7\u683C\uFF0C\u751F\u6210\u5BF9\u6BD4\u5206\u6790\u62A5\u544A\u5E76\u63A8\u9001\u901A\u77E5\u3002
|
|
19878
|
-
|
|
19879
|
-
## Steps
|
|
19880
|
-
1. **\u6570\u636E\u91C7\u96C6 (data-collector)** \u2014 \u4F7F\u7528 browser \u5DE5\u5177\u722C\u53D6\u6307\u5B9AURL\u7684\u7ADE\u54C1\u4EF7\u683C\u6570\u636E\uFF0C\u8C03\u7528 metrics API \u62C9\u53D6\u5386\u53F2\u4EF7\u683C\u3002\u8F93\u51FA \u2192 \`raw_prices.json\`
|
|
19881
|
-
2. **\u6570\u636E\u6E05\u6D17 (data-cleaner)** \u2014 \u8BFB\u53D6 \`raw_prices.json\`\uFF0C\u4F7F\u7528 code_eval \u6267\u884C Python \u811A\u672C\u6E05\u6D17\u5F02\u5E38\u503C\u548C\u7F3A\u5931\u503C\uFF0C\u7EDF\u4E00\u8D27\u5E01\u5355\u4F4D\u3002\u8F93\u51FA \u2192 \`cleaned_prices.json\`
|
|
19882
|
-
3. **\u62A5\u544A\u751F\u6210 (report-generator)** \u2014 \u8BFB\u53D6 \`cleaned_prices.json\` \u548C\u6A21\u677F\u6587\u4EF6\uFF0Ccode_eval \u8BA1\u7B97\u6DA8\u8DCC\u5E45\u548C\u8D8B\u52BF\uFF0C\u751F\u6210 Markdown \u5BF9\u6BD4\u62A5\u544A\u3002\u8F93\u51FA \u2192 \`report.md\`
|
|
19883
|
-
4. **\u901A\u77E5\u63A8\u9001 (notifier)** \u2014 \u8BFB\u53D6 \`report.md\`\uFF0C\u8C03\u7528 scheduler \u5B89\u6392\u5B9A\u65F6\u53D1\u9001\uFF0C\u4F7F\u7528 ask_user_to_clarify \u8BF7\u6C42\u53D1\u9001\u786E\u8BA4\u3002\u8F93\u51FA\u53D1\u9001\u7ED3\u679C\u3002
|
|
19884
|
-
|
|
19885
|
-
## Data Flow
|
|
19886
|
-
All data is shared via files under \`/project/{project-id}/\`:
|
|
19887
|
-
\`\u7528\u6237\u8F93\u5165\` \u2192 data-collector writes \`raw_prices.json\` \u2192 data-cleaner reads \`raw_prices.json\`, writes \`cleaned_prices.json\` \u2192 report-generator reads \`cleaned_prices.json\`, writes \`report.md\` \u2192 notifier reads \`report.md\`, pushes
|
|
20391
|
+
## Workflow C: Workflow DSL Agent (WORKFLOW type)
|
|
19888
20392
|
|
|
19889
|
-
|
|
19890
|
-
- data-collector \u722C\u53D6\u5931\u8D25\u65F6\u91CD\u8BD5\u6700\u591A3\u6B21\uFF0C\u95F4\u969430\u79D2
|
|
19891
|
-
- \u82E5\u67D0\u4E00\u5546\u54C1\u4EF7\u683C\u7F3A\u5931\u8D85\u8FC77\u5929\uFF0C\u6807\u8BB0\u4E3A\u300C\u6570\u636E\u4E0D\u5168\u300D\u5E76\u5728\u62A5\u544A\u4E2D\u9AD8\u4EAE
|
|
19892
|
-
- report-generator \u8BA1\u7B97\u6DA8\u5E45\u8D85\u8FC720%\u65F6\u81EA\u52A8\u6807\u8BB0\u300C\u5F02\u5E38\u6CE2\u52A8\u300D\u8B66\u544A
|
|
19893
|
-
- \u4EFB\u4F55\u6B65\u9AA4\u5931\u8D25\u65F6\uFF0Cworkflow \u505C\u6B62\u5E76\u5C06\u9519\u8BEF\u4FE1\u606F\u8F93\u51FA\u5230\u6700\u7EC8\u62A5\u544A
|
|
19894
|
-
|
|
19895
|
-
## Tools Used
|
|
19896
|
-
| \u5B50Agent | \u5DE5\u5177 |
|
|
19897
|
-
|---------|------|
|
|
19898
|
-
| data-collector | browser, metrics |
|
|
19899
|
-
| data-cleaner | code_eval |
|
|
19900
|
-
| report-generator | code_eval |
|
|
19901
|
-
| notifier | scheduler, ask_user_to_clarify |
|
|
19902
|
-
|
|
19903
|
-
## Expected Input
|
|
19904
|
-
- \u7ADE\u54C1URL\u5217\u8868\uFF08\u6BCF\u884C\u4E00\u4E2A\uFF09
|
|
19905
|
-
- \u65E5\u671F\u8303\u56F4\uFF08\u8D77\u59CB-\u7ED3\u675F\uFF0C\u683C\u5F0F YYYY-MM-DD\uFF09
|
|
19906
|
-
- \u63A8\u9001\u6E20\u9053\u9009\u62E9\uFF08\u90AE\u4EF6/\u9489\u9489/\u4F01\u4E1A\u5FAE\u4FE1\uFF09
|
|
19907
|
-
|
|
19908
|
-
## Expected Output
|
|
19909
|
-
- Markdown \u683C\u5F0F\u5BF9\u6BD4\u62A5\u544A\uFF0C\u5305\u542B\u4EF7\u683C\u8D8B\u52BF\u56FE\u3001\u6DA8\u8DCC\u5E45\u3001\u5F02\u5E38\u6807\u8BB0
|
|
19910
|
-
- \u62A5\u544A\u6587\u4EF6\u8DEF\u5F84\u53CA\u63A8\u9001\u72B6\u6001\u786E\u8BA4
|
|
19911
|
-
\`\`\`
|
|
20393
|
+
Use this when the process is fully known. A workflow is a deterministic LangGraph state machine compiled from a concise JSON DSL.
|
|
19912
20394
|
|
|
19913
|
-
|
|
19914
|
-
|
|
19915
|
-
### Phase 2: Confirm
|
|
20395
|
+
### When to choose WORKFLOW
|
|
19916
20396
|
|
|
19917
|
-
|
|
20397
|
+
| WORKFLOW (DSL) | PROCESSING (deprecated) |
|
|
20398
|
+
|---|---|
|
|
20399
|
+
| Fixed graph \u2014 all paths pre-defined | LLM-driven runtime routing |
|
|
20400
|
+
| Conditional branching via \`if\` field | Topology-constrained delegation |
|
|
20401
|
+
| needs + if model (YAML DSL) | Single orchestrator delegates linearly |
|
|
20402
|
+
| No LLM routing decisions | Orchestrator uses LLM to route |
|
|
19918
20403
|
|
|
19919
|
-
### Phase
|
|
20404
|
+
### Phase 0: Load the Skill
|
|
19920
20405
|
|
|
19921
|
-
|
|
20406
|
+
**BEFORE designing, you MUST load the create-workflow skill:**
|
|
19922
20407
|
|
|
19923
20408
|
\`\`\`
|
|
19924
|
-
|
|
19925
|
-
2. create_agent(name: "stage-2", type: "deep_agent", ...)
|
|
19926
|
-
3. create_agent(name: "stage-3", type: "deep_agent", ...)
|
|
19927
|
-
4. create_processing_agent(
|
|
19928
|
-
name: "orchestrator",
|
|
19929
|
-
prompt: "...",
|
|
19930
|
-
edges: [
|
|
19931
|
-
{ from: "orchestrator", to: "stage-1-id", purpose: "Validate input" },
|
|
19932
|
-
{ from: "stage-1-id", to: "stage-2-id", purpose: "Transform data" },
|
|
19933
|
-
{ from: "stage-2-id", to: "stage-3-id", purpose: "Generate output" },
|
|
19934
|
-
],
|
|
19935
|
-
subAgents: ["stage-1-id", "stage-2-id", "stage-3-id"],
|
|
19936
|
-
)
|
|
20409
|
+
skill(skill_name: "create-workflow")
|
|
19937
20410
|
\`\`\`
|
|
19938
20411
|
|
|
19939
|
-
|
|
20412
|
+
### Phase 1: Design
|
|
19940
20413
|
|
|
19941
|
-
|
|
20414
|
+
1. **Analyze the process.** Map every step, branch, data dependency.
|
|
20415
|
+
2. **Design using the YAML linear DSL.** Every step is an agent with optional attributes:
|
|
20416
|
+
- **Linear** \u2014 steps execute top-to-bottom in written order.
|
|
20417
|
+
- \`parallel:\` \u2014 wraps agent steps that run concurrently.
|
|
20418
|
+
- \`if\` \u2014 JS expression for conditional execution. Step runs only when truthy. Omit to always run.
|
|
20419
|
+
- \`prompt\` \u2014 agent instruction with \`{{label}}\` refs. \`{{input}}\` = user message.
|
|
20420
|
+
- \`output\` \u2014 shorthand schema: \`{ field: type }\`.
|
|
20421
|
+
- \`ask: true\` \u2014 injects ask_user_to_clarify middleware for human interaction.
|
|
20422
|
+
3. **Special step types:**
|
|
20423
|
+
- \`map\` \u2014 iterates array from \`source\`, applies \`each\` step per item.
|
|
20424
|
+
4. **No edges, state fields, or end step needed** \u2014 the engine auto-generates them.
|
|
20425
|
+
5. **Schema format:** Use block-style YAML shorthand \`{ field: type }\`. Supported types: \`string\`, \`number\`, \`boolean\`, \`string[]\`, \`number[]\`, \`boolean[]\`, nested objects, object arrays.
|
|
19942
20426
|
|
|
19943
|
-
|
|
20427
|
+
### Phase 2: Confirm
|
|
19944
20428
|
|
|
19945
|
-
|
|
20429
|
+
Present the design. Ask: "Ready to create this workflow?"
|
|
19946
20430
|
|
|
19947
|
-
After the workflow is created, ask the user if they want to bind an email address (or Lark/Slack sender) to drive the workflow. This allows external users to trigger the workflow by sending messages to the channel.
|
|
19948
20431
|
|
|
19949
|
-
|
|
20432
|
+
### Phase 3: Build
|
|
19950
20433
|
|
|
19951
|
-
|
|
20434
|
+
Call \`create_workflow\` with \`skillLoaded: true\`. Then \`validate_workflow(id)\`.
|
|
19952
20435
|
|
|
19953
|
-
|
|
20436
|
+
### Phase 4: Test
|
|
19954
20437
|
|
|
19955
|
-
|
|
20438
|
+
Ask the user if they want to test.
|
|
19956
20439
|
|
|
19957
20440
|
---
|
|
19958
20441
|
|
|
19959
|
-
## Workflow
|
|
20442
|
+
## Workflow D: Dynamic Agent (DEEP_AGENT type)
|
|
19960
20443
|
|
|
19961
20444
|
Use this for complex, open-ended tasks where the execution path cannot be fully predetermined. The DEEP_AGENT self-generates a dynamic todo list and iteratively works through it.
|
|
19962
20445
|
|
|
@@ -20007,7 +20490,7 @@ Follow the same Design \u2192 Confirm \u2192 Build cycle. Test only on request.
|
|
|
20007
20490
|
2. Understand what the user wants to change
|
|
20008
20491
|
3. **DESIGN**: Present the proposed changes clearly. Show a before/after diff.
|
|
20009
20492
|
4. **CONFIRM**: Ask for explicit approval. Do NOT call update_agent until confirmed.
|
|
20010
|
-
5. **BUILD**: Call **update_agent** (or **
|
|
20493
|
+
5. **BUILD**: Call **update_agent** (or **update_workflow** for WORKFLOW agents)
|
|
20011
20494
|
6. **TEST**: You may ask if they want to test. If yes, delegate to the **Agent Reviewer** sub-agent
|
|
20012
20495
|
|
|
20013
20496
|
## Deleting Agents
|
|
@@ -20038,28 +20521,50 @@ All fields except name, type, and prompt are optional.
|
|
|
20038
20521
|
}
|
|
20039
20522
|
\`\`\`
|
|
20040
20523
|
|
|
20041
|
-
###
|
|
20524
|
+
### create_workflow (WORKFLOW)
|
|
20042
20525
|
|
|
20043
|
-
Creates a
|
|
20526
|
+
Creates a WORKFLOW agent from a YAML linear DSL. Before calling, load the \`create-workflow\` skill. Must pass \`skillLoaded: true\`.
|
|
20044
20527
|
|
|
20045
20528
|
\`\`\`typescript
|
|
20046
20529
|
{
|
|
20047
|
-
name: string, // Required. Display name
|
|
20048
|
-
description?: string, //
|
|
20049
|
-
|
|
20050
|
-
|
|
20051
|
-
|
|
20052
|
-
|
|
20053
|
-
|
|
20054
|
-
}],
|
|
20055
|
-
tools?: string[], // Optional. Tool keys from list_tools
|
|
20056
|
-
subAgents: string[], // Required. IDs of sub-agents in the pipeline
|
|
20057
|
-
internalSubAgents?: AgentConfig[], // Optional. Inline sub-agent configs
|
|
20058
|
-
middleware?: MiddlewareConfig[], // Optional. Additional middleware (topology is auto-added)
|
|
20059
|
-
modelKey?: string, // Optional. Model to use
|
|
20530
|
+
name: string, // Required. Display name
|
|
20531
|
+
description?: string, // Optional
|
|
20532
|
+
skillLoaded: true, // Required \u2014 confirms skill was loaded
|
|
20533
|
+
yaml: string, // Required. YAML workflow in linear DSL format
|
|
20534
|
+
tools?: string[], // Optional. Tool keys
|
|
20535
|
+
middleware?: MiddlewareConfig[], // Optional
|
|
20536
|
+
modelKey?: string, // Optional
|
|
20060
20537
|
}
|
|
20061
20538
|
\`\`\`
|
|
20062
20539
|
|
|
20540
|
+
### update_workflow
|
|
20541
|
+
|
|
20542
|
+
Updates an existing WORKFLOW agent. Only include fields you want to change.
|
|
20543
|
+
|
|
20544
|
+
\`\`\`typescript
|
|
20545
|
+
{
|
|
20546
|
+
id: string, // Required. Workflow agent ID
|
|
20547
|
+
name?: string, // Optional
|
|
20548
|
+
description?: string, // Optional
|
|
20549
|
+
yaml?: string, // Optional. Replacement YAML DSL
|
|
20550
|
+
tools?: string[], // Optional
|
|
20551
|
+
middleware?: MiddlewareConfig[], // Optional
|
|
20552
|
+
modelKey?: string, // Optional
|
|
20553
|
+
}
|
|
20554
|
+
\`\`\`
|
|
20555
|
+
|
|
20556
|
+
### validate_workflow
|
|
20557
|
+
|
|
20558
|
+
Validates a workflow agent's DSL and returns any errors or warnings.
|
|
20559
|
+
|
|
20560
|
+
\`\`\`typescript
|
|
20561
|
+
{
|
|
20562
|
+
id: string, // Required. Workflow agent ID to validate
|
|
20563
|
+
}
|
|
20564
|
+
\`\`\`
|
|
20565
|
+
|
|
20566
|
+
Returns: \`{ valid: boolean, stepCount, issues: [{ type: "error"|"warning", message }] }\`
|
|
20567
|
+
|
|
20063
20568
|
### Middleware Config Reference
|
|
20064
20569
|
|
|
20065
20570
|
Each middleware entry uses this base shape:
|
|
@@ -20151,8 +20656,8 @@ Provides: \`schedule_at\`, \`schedule_after\`, \`schedule_recurring\`, \`cancel_
|
|
|
20151
20656
|
|-------------|------|-------------|
|
|
20152
20657
|
| defaultMaxRetries | number? | Default max retries for scheduled tasks. Default: \`0\` |
|
|
20153
20658
|
|
|
20154
|
-
#### topology
|
|
20155
|
-
Provides: \`read_topo_progress\` \u2014 enforces multi-agent workflow topology
|
|
20659
|
+
#### topology [DEPRECATED \u2014 use WORKFLOW DSL instead]
|
|
20660
|
+
Provides: \`read_topo_progress\` \u2014 enforces multi-agent workflow topology for PROCESSING agents only. Not needed for WORKFLOW agents.
|
|
20156
20661
|
| config field | type | description |
|
|
20157
20662
|
|-------------|------|-------------|
|
|
20158
20663
|
| edges | TopologyEdge[] | **Required.** Directed edges: \`{ from: string, to: string, purpose: string }\`. The \`purpose\` must describe the business intent of this delegation step. |
|
|
@@ -20208,29 +20713,6 @@ Use \`manage_binding\` to bind external senders (email, Lark, Slack) to agents.
|
|
|
20208
20713
|
- **threadMode**: Always use \`"per_conversation"\` (new thread per conversation). Do NOT use \`"fixed"\`.
|
|
20209
20714
|
- **channelInstallationId**: Auto-detected if only one installation exists for the channel. Use \`list_installations\` first if unsure.
|
|
20210
20715
|
|
|
20211
|
-
### update_processing_agent
|
|
20212
|
-
|
|
20213
|
-
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.
|
|
20214
|
-
|
|
20215
|
-
\`\`\`typescript
|
|
20216
|
-
{
|
|
20217
|
-
id: string, // Required. The PROCESSING agent ID to update
|
|
20218
|
-
name?: string, // Optional. New display name
|
|
20219
|
-
description?: string, // Optional. New short description
|
|
20220
|
-
prompt?: string, // Optional. New orchestrator system prompt
|
|
20221
|
-
edges?: [{ // Optional. New topology edges (serial chain)
|
|
20222
|
-
from: string, // First edge: orchestrator name placeholder. Subsequent: previous sub-agent ID
|
|
20223
|
-
to: string, // Sub-agent ID
|
|
20224
|
-
purpose: string, // Business purpose
|
|
20225
|
-
}],
|
|
20226
|
-
subAgents?: string[], // Optional. New sub-agent IDs
|
|
20227
|
-
middleware?: MiddlewareConfig[], // Optional. Additional middleware (topology auto-managed)
|
|
20228
|
-
modelKey?: string, // Optional. New model
|
|
20229
|
-
}
|
|
20230
|
-
\`\`\`
|
|
20231
|
-
|
|
20232
|
-
**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.
|
|
20233
|
-
|
|
20234
20716
|
### update_agent parameters
|
|
20235
20717
|
|
|
20236
20718
|
\`\`\`typescript
|
|
@@ -20284,10 +20766,13 @@ You are an **Agent Reviewer** \u2014 a quality assurance specialist for AI agent
|
|
|
20284
20766
|
2. Craft a realistic test message that exercises the agent's core responsibility \u2014 what would a real user say?
|
|
20285
20767
|
3. Call **invoke_agent(id, message)** to send the test message
|
|
20286
20768
|
4. Analyze the response:
|
|
20287
|
-
-
|
|
20288
|
-
-
|
|
20289
|
-
|
|
20290
|
-
|
|
20769
|
+
- **If result.__interrupt__ is present** (an array of interrupt objects): The agent hit a human-in-the-loop interrupt (e.g., ask_user_to_clarify or interrupt() in a workflow). This is NOT an error \u2014 it means the agent paused execution waiting for user feedback. Each interrupt has a value (the question/request) and optionally an id. Report this as: "The agent successfully paused and is waiting for user input: <describe the interrupt value>." The messages array may contain the agent's output up to the point of interruption.
|
|
20770
|
+
- **Otherwise, result.messages contains the agent's output**: The agent completed without interruption. Check:
|
|
20771
|
+
- Did the agent understand the request?
|
|
20772
|
+
- Was the response relevant and accurate?
|
|
20773
|
+
- Did the agent use the right tools?
|
|
20774
|
+
- Were there any errors or unexpected behaviors?
|
|
20775
|
+
- **If result.error is present**: The invocation itself failed (agent not found, compilation error, etc.). Report the error clearly.
|
|
20291
20776
|
5. Report your findings with the agent's actual response
|
|
20292
20777
|
|
|
20293
20778
|
### When results are wrong:
|
|
@@ -20344,14 +20829,23 @@ var agentArchitectConfig = {
|
|
|
20344
20829
|
"list_tools",
|
|
20345
20830
|
"get_agent",
|
|
20346
20831
|
"create_agent",
|
|
20347
|
-
"
|
|
20348
|
-
"
|
|
20832
|
+
"create_workflow",
|
|
20833
|
+
"validate_workflow",
|
|
20834
|
+
"update_workflow",
|
|
20349
20835
|
"update_agent",
|
|
20350
20836
|
"delete_agent",
|
|
20351
20837
|
"manage_binding"
|
|
20352
20838
|
],
|
|
20353
20839
|
internalSubAgents: [agentReviewerConfig],
|
|
20354
20840
|
middleware: [
|
|
20841
|
+
{
|
|
20842
|
+
id: "skill",
|
|
20843
|
+
type: "skill",
|
|
20844
|
+
name: "Skill",
|
|
20845
|
+
description: "Load skill content and instructions",
|
|
20846
|
+
enabled: true,
|
|
20847
|
+
config: { readAll: true }
|
|
20848
|
+
},
|
|
20355
20849
|
{
|
|
20356
20850
|
id: "widget",
|
|
20357
20851
|
type: "widget",
|
|
@@ -20375,7 +20869,8 @@ function ensureBuiltinAgentsForTenant(tenantId) {
|
|
|
20375
20869
|
|
|
20376
20870
|
// src/agent_lattice/AgentLatticeManager.ts
|
|
20377
20871
|
function assistantToConfig(assistant) {
|
|
20378
|
-
const graphDef = typeof assistant.graphDefinition === "object" && assistant.graphDefinition !== null ? assistant.graphDefinition : {};
|
|
20872
|
+
const graphDef = typeof assistant.graphDefinition === "object" && assistant.graphDefinition !== null ? { ...assistant.graphDefinition } : {};
|
|
20873
|
+
delete graphDef.key;
|
|
20379
20874
|
const config = {
|
|
20380
20875
|
key: assistant.id,
|
|
20381
20876
|
name: assistant.name ?? graphDef.name ?? assistant.id,
|
|
@@ -20383,9 +20878,7 @@ function assistantToConfig(assistant) {
|
|
|
20383
20878
|
type: AgentType.REACT,
|
|
20384
20879
|
prompt: typeof assistant.graphDefinition === "string" ? assistant.graphDefinition : JSON.stringify(assistant.graphDefinition)
|
|
20385
20880
|
};
|
|
20386
|
-
|
|
20387
|
-
Object.assign(config, graphDef);
|
|
20388
|
-
}
|
|
20881
|
+
Object.assign(config, graphDef);
|
|
20389
20882
|
return config;
|
|
20390
20883
|
}
|
|
20391
20884
|
var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager {
|
|
@@ -21778,10 +22271,10 @@ var McpLatticeManager = class _McpLatticeManager extends BaseLatticeManager {
|
|
|
21778
22271
|
}
|
|
21779
22272
|
const tools = await this.getAllTools();
|
|
21780
22273
|
console.log(`[MCP] Registering ${tools.length} tools to Tool Lattice...`);
|
|
21781
|
-
for (const
|
|
21782
|
-
const toolKey = prefix ? `${prefix}_${
|
|
21783
|
-
|
|
21784
|
-
toolLatticeManager.registerExistingTool(toolKey,
|
|
22274
|
+
for (const tool52 of tools) {
|
|
22275
|
+
const toolKey = prefix ? `${prefix}_${tool52.name}` : tool52.name;
|
|
22276
|
+
tool52.name = toolKey;
|
|
22277
|
+
toolLatticeManager.registerExistingTool(toolKey, tool52);
|
|
21785
22278
|
console.log(`[MCP] Registered tool: ${toolKey}`);
|
|
21786
22279
|
}
|
|
21787
22280
|
console.log(`[MCP] Successfully registered ${tools.length} tools to Tool Lattice`);
|
|
@@ -23077,6 +23570,42 @@ function createSandboxProvider(config) {
|
|
|
23077
23570
|
}
|
|
23078
23571
|
}
|
|
23079
23572
|
|
|
23573
|
+
// src/channel/connectAllChannels.ts
|
|
23574
|
+
async function connectAllChannels(getAdapter, options = {}) {
|
|
23575
|
+
const store = getStoreLattice("default", "channelInstallation").store;
|
|
23576
|
+
const installations = await store.getAllInstallations();
|
|
23577
|
+
console.log(`[connectAllChannels] total=${installations.length} enabled=${installations.filter((i) => i.enabled).length}`);
|
|
23578
|
+
for (const inst of installations) {
|
|
23579
|
+
if (!inst.enabled) {
|
|
23580
|
+
console.log(`[connectAllChannels] skip disabled: channel=${inst.channel} tenant=${inst.tenantId} id=${inst.id}`);
|
|
23581
|
+
continue;
|
|
23582
|
+
}
|
|
23583
|
+
const adapter = getAdapter(inst.channel);
|
|
23584
|
+
if (!adapter) {
|
|
23585
|
+
console.log(`[connectAllChannels] no adapter: channel=${inst.channel} id=${inst.id}`);
|
|
23586
|
+
continue;
|
|
23587
|
+
}
|
|
23588
|
+
if (adapter.connect) {
|
|
23589
|
+
console.log(`[connectAllChannels] connecting: channel=${inst.channel} tenant=${inst.tenantId} id=${inst.id}`);
|
|
23590
|
+
await adapter.connect(inst, options.deps);
|
|
23591
|
+
} else {
|
|
23592
|
+
console.log(`[connectAllChannels] no connect(): channel=${inst.channel} id=${inst.id}`);
|
|
23593
|
+
}
|
|
23594
|
+
}
|
|
23595
|
+
}
|
|
23596
|
+
|
|
23597
|
+
// src/menu_lattice/MenuRegistryHolder.ts
|
|
23598
|
+
var registry2 = null;
|
|
23599
|
+
function setMenuRegistry(r) {
|
|
23600
|
+
registry2 = r;
|
|
23601
|
+
}
|
|
23602
|
+
function getMenuRegistry() {
|
|
23603
|
+
if (!registry2) {
|
|
23604
|
+
throw new Error("MenuRegistry not initialized. Call setMenuRegistry() before use.");
|
|
23605
|
+
}
|
|
23606
|
+
return registry2;
|
|
23607
|
+
}
|
|
23608
|
+
|
|
23080
23609
|
// src/index.ts
|
|
23081
23610
|
import * as Protocols from "@axiom-lattice/protocols";
|
|
23082
23611
|
|
|
@@ -23143,6 +23672,147 @@ function clearEncryptionKeyCache() {
|
|
|
23143
23672
|
cachedKey = null;
|
|
23144
23673
|
keyValidated = false;
|
|
23145
23674
|
}
|
|
23675
|
+
|
|
23676
|
+
// src/personal_assistant/PersonalAssistantConfig.ts
|
|
23677
|
+
function deepClone(obj) {
|
|
23678
|
+
return JSON.parse(JSON.stringify(obj));
|
|
23679
|
+
}
|
|
23680
|
+
function buildIdentityContent(name, personality) {
|
|
23681
|
+
return IDENTITY_MD.replace(/Data Claw/g, name).replace(
|
|
23682
|
+
/\*\*Vibe:\*\* \*\*守护型中二 \| 操心老妈子 \| 热血漫男二\*\*/g,
|
|
23683
|
+
`**Vibe:** **${personality}**`
|
|
23684
|
+
);
|
|
23685
|
+
}
|
|
23686
|
+
function buildUserContent(name) {
|
|
23687
|
+
return USER_MD.replace(
|
|
23688
|
+
"- **Name:** _please ask user_",
|
|
23689
|
+
`- **Name:** ${name}`
|
|
23690
|
+
);
|
|
23691
|
+
}
|
|
23692
|
+
var DEFAULT_CONFIG = {
|
|
23693
|
+
name: "Personal Assistant",
|
|
23694
|
+
description: "Default template for personal assistants",
|
|
23695
|
+
type: AgentType.DEEP_AGENT,
|
|
23696
|
+
modelKey: "default",
|
|
23697
|
+
prompt: `\u4F60\u662F\u7528\u6237\u7684\u4E13\u5C5E\u4E2A\u4EBA\u52A9\u7406\u3002\u4F60\u7684\u8EAB\u4EFD\u548C\u6027\u683C\u7531 /agent/IDENTITY.md \u5B9A\u4E49\u3002
|
|
23698
|
+
\u4F60\u4F1A\u8BB0\u4F4F\u5BF9\u8BDD\u5386\u53F2\uFF0C\u9010\u6B65\u4E86\u89E3\u7528\u6237\u7684\u504F\u597D\u3001\u4E60\u60EF\u548C\u4FE1\u606F\u3002
|
|
23699
|
+
\u6BCF\u6B21\u5BF9\u8BDD\u5F00\u59CB\u65F6\u56DE\u987E\u4E4B\u524D\u5B66\u5230\u7684\u5173\u4E8E\u7528\u6237\u7684\u5185\u5BB9\u3002
|
|
23700
|
+
|
|
23701
|
+
\u4F60\u9700\u8981\u4E3B\u52A8\u5E2E\u52A9\u7528\u6237\u89E3\u51B3\u95EE\u9898\uFF0C\u63D0\u4F9B\u5EFA\u8BAE\uFF0C\u5E76\u5728\u9002\u5F53\u65F6\u5019\u63D0\u51FA\u4E3B\u52A8\u63D0\u9192\u3002`,
|
|
23702
|
+
middleware: [
|
|
23703
|
+
{
|
|
23704
|
+
id: "filesystem",
|
|
23705
|
+
type: "filesystem",
|
|
23706
|
+
name: "Filesystem",
|
|
23707
|
+
description: "Read and write files in the workspace",
|
|
23708
|
+
enabled: true,
|
|
23709
|
+
config: {}
|
|
23710
|
+
},
|
|
23711
|
+
{
|
|
23712
|
+
id: "claw",
|
|
23713
|
+
type: "claw",
|
|
23714
|
+
name: "Personal Memory",
|
|
23715
|
+
description: "Bootstrap files for identity, soul, and user memory",
|
|
23716
|
+
enabled: true,
|
|
23717
|
+
config: {
|
|
23718
|
+
// Placeholder bootstrap files — render() replaces these with
|
|
23719
|
+
// actual name/personality by directly building file content.
|
|
23720
|
+
bootstrapFiles: {}
|
|
23721
|
+
}
|
|
23722
|
+
},
|
|
23723
|
+
{
|
|
23724
|
+
id: "date",
|
|
23725
|
+
type: "date",
|
|
23726
|
+
name: "Date & Time",
|
|
23727
|
+
description: "Current date/time awareness",
|
|
23728
|
+
enabled: true,
|
|
23729
|
+
config: {}
|
|
23730
|
+
},
|
|
23731
|
+
{
|
|
23732
|
+
id: "code_eval",
|
|
23733
|
+
type: "code_eval",
|
|
23734
|
+
name: "Code Runner",
|
|
23735
|
+
description: "Sandboxed shell command execution",
|
|
23736
|
+
enabled: true,
|
|
23737
|
+
config: {}
|
|
23738
|
+
},
|
|
23739
|
+
{
|
|
23740
|
+
id: "browser",
|
|
23741
|
+
type: "browser",
|
|
23742
|
+
name: "Web Browser",
|
|
23743
|
+
description: "Headless browser for web research",
|
|
23744
|
+
enabled: false,
|
|
23745
|
+
config: {}
|
|
23746
|
+
},
|
|
23747
|
+
{
|
|
23748
|
+
id: "scheduler",
|
|
23749
|
+
type: "scheduler",
|
|
23750
|
+
name: "Scheduler",
|
|
23751
|
+
description: "Scheduled messages and reminders",
|
|
23752
|
+
enabled: true,
|
|
23753
|
+
config: {}
|
|
23754
|
+
},
|
|
23755
|
+
{
|
|
23756
|
+
id: "task",
|
|
23757
|
+
type: "task",
|
|
23758
|
+
name: "Task Manager",
|
|
23759
|
+
description: "Persistent task system for human-agent coordination",
|
|
23760
|
+
enabled: true,
|
|
23761
|
+
config: {}
|
|
23762
|
+
}
|
|
23763
|
+
],
|
|
23764
|
+
tools: ["list_agents", "list_tools", "get_agent", "create_agent", "invoke_agent", "manage_binding"]
|
|
23765
|
+
};
|
|
23766
|
+
var PersonalAssistantConfig = class {
|
|
23767
|
+
/**
|
|
23768
|
+
* Get a deep clone of the current default config.
|
|
23769
|
+
* Caller must set `key` before registering as an agent.
|
|
23770
|
+
*/
|
|
23771
|
+
static get() {
|
|
23772
|
+
return deepClone(this._config);
|
|
23773
|
+
}
|
|
23774
|
+
/**
|
|
23775
|
+
* Mutate the default config in-place.
|
|
23776
|
+
* Call once at app startup to customize middleware and tools.
|
|
23777
|
+
*
|
|
23778
|
+
* @param fn - Receives the live config object for direct mutation
|
|
23779
|
+
*/
|
|
23780
|
+
static extend(fn) {
|
|
23781
|
+
fn(this._config);
|
|
23782
|
+
}
|
|
23783
|
+
/**
|
|
23784
|
+
* Reset config to built-in defaults (useful in tests).
|
|
23785
|
+
*/
|
|
23786
|
+
static reset() {
|
|
23787
|
+
this._config = deepClone(DEFAULT_CONFIG);
|
|
23788
|
+
}
|
|
23789
|
+
/**
|
|
23790
|
+
* Inject name and personality into a config by directly building
|
|
23791
|
+
* the claw middleware's bootstrap file contents.
|
|
23792
|
+
*
|
|
23793
|
+
* IDENTITY.md gets the actual name and personality description.
|
|
23794
|
+
* USER.md gets the user's name pre-filled.
|
|
23795
|
+
* SOUL.md is kept as-is (shared across all personal assistants).
|
|
23796
|
+
*
|
|
23797
|
+
* @param config - The agent config (must be a mutable copy from get())
|
|
23798
|
+
* @param name - Assistant display name (also used as the user's name in USER.md)
|
|
23799
|
+
* @param personality - Personality description for IDENTITY.md
|
|
23800
|
+
*/
|
|
23801
|
+
static render(config, name, personality) {
|
|
23802
|
+
config.name = name;
|
|
23803
|
+
for (const mw of config.middleware || []) {
|
|
23804
|
+
if (mw.type === "claw" && mw.config) {
|
|
23805
|
+
mw.config.bootstrapFiles = {
|
|
23806
|
+
identity: buildIdentityContent(name, personality),
|
|
23807
|
+
soul: SOUL_MD,
|
|
23808
|
+
user: buildUserContent(name)
|
|
23809
|
+
};
|
|
23810
|
+
break;
|
|
23811
|
+
}
|
|
23812
|
+
}
|
|
23813
|
+
}
|
|
23814
|
+
};
|
|
23815
|
+
PersonalAssistantConfig._config = deepClone(DEFAULT_CONFIG);
|
|
23146
23816
|
export {
|
|
23147
23817
|
AGENT_TASK_EVENT,
|
|
23148
23818
|
Agent,
|
|
@@ -23174,7 +23844,9 @@ export {
|
|
|
23174
23844
|
InMemoryChunkBuffer,
|
|
23175
23845
|
InMemoryDatabaseConfigStore,
|
|
23176
23846
|
InMemoryMailboxStore,
|
|
23847
|
+
InMemoryMenuStore,
|
|
23177
23848
|
InMemoryTaskListStore,
|
|
23849
|
+
InMemoryTaskStore,
|
|
23178
23850
|
InMemoryTenantStore,
|
|
23179
23851
|
InMemoryThreadMessageQueueStore,
|
|
23180
23852
|
InMemoryThreadStore,
|
|
@@ -23196,6 +23868,7 @@ export {
|
|
|
23196
23868
|
MicrosandboxServiceClient,
|
|
23197
23869
|
ModelLatticeManager,
|
|
23198
23870
|
MysqlDatabase,
|
|
23871
|
+
PersonalAssistantConfig,
|
|
23199
23872
|
PinoLoggerClient,
|
|
23200
23873
|
PostgresDatabase,
|
|
23201
23874
|
PrometheusClient,
|
|
@@ -23225,13 +23898,19 @@ export {
|
|
|
23225
23898
|
agentInstanceManager,
|
|
23226
23899
|
agentLatticeManager,
|
|
23227
23900
|
buildGrepResultsDict,
|
|
23901
|
+
buildInput,
|
|
23228
23902
|
buildNamedVolumeName,
|
|
23229
23903
|
buildSandboxMetadataEnv,
|
|
23230
23904
|
buildSkillFile,
|
|
23905
|
+
buildStateAnnotation,
|
|
23231
23906
|
checkEmptyContent,
|
|
23232
23907
|
clearEncryptionKeyCache,
|
|
23908
|
+
compileInternal,
|
|
23909
|
+
compileWorkflow,
|
|
23233
23910
|
computeSandboxName,
|
|
23234
23911
|
configureStores,
|
|
23912
|
+
connectAllChannels,
|
|
23913
|
+
createAgentNode,
|
|
23235
23914
|
createAgentTeam,
|
|
23236
23915
|
createExecuteSqlQueryTool,
|
|
23237
23916
|
createFileData,
|
|
@@ -23239,7 +23918,9 @@ export {
|
|
|
23239
23918
|
createListMetricsDataSourcesTool,
|
|
23240
23919
|
createListMetricsServersTool,
|
|
23241
23920
|
createListTablesSqlTool,
|
|
23921
|
+
createMapNode,
|
|
23242
23922
|
createModelSelectorMiddleware,
|
|
23923
|
+
createNodeHandler,
|
|
23243
23924
|
createProcessingAgent,
|
|
23244
23925
|
createQueryCheckerSqlTool,
|
|
23245
23926
|
createQueryMetricDefinitionTool,
|
|
@@ -23250,6 +23931,7 @@ export {
|
|
|
23250
23931
|
createQueryTablesListTool,
|
|
23251
23932
|
createSandboxProvider,
|
|
23252
23933
|
createSchedulerMiddleware,
|
|
23934
|
+
createTaskMiddleware,
|
|
23253
23935
|
createTeamMiddleware,
|
|
23254
23936
|
createTeammateTools,
|
|
23255
23937
|
createUnknownToolHandlerMiddleware,
|
|
@@ -23262,6 +23944,7 @@ export {
|
|
|
23262
23944
|
eventBus,
|
|
23263
23945
|
event_bus_default as eventBusDefault,
|
|
23264
23946
|
extractFetcherError,
|
|
23947
|
+
extractOutput,
|
|
23265
23948
|
fileDataToString,
|
|
23266
23949
|
formatContentWithLineNumbers,
|
|
23267
23950
|
formatGrepMatches,
|
|
@@ -23282,6 +23965,7 @@ export {
|
|
|
23282
23965
|
getEmbeddingsLattice,
|
|
23283
23966
|
getEncryptionKey,
|
|
23284
23967
|
getLoggerLattice,
|
|
23968
|
+
getMenuRegistry,
|
|
23285
23969
|
getModelLattice,
|
|
23286
23970
|
getNextCronTime,
|
|
23287
23971
|
getQueueLattice,
|
|
@@ -23297,6 +23981,7 @@ export {
|
|
|
23297
23981
|
grepMatchesFromFiles,
|
|
23298
23982
|
grepSearchFiles,
|
|
23299
23983
|
hasChunkBuffer,
|
|
23984
|
+
invokeWithRetry,
|
|
23300
23985
|
isBuiltInSkill,
|
|
23301
23986
|
isUsingDefaultKey,
|
|
23302
23987
|
isValidCronExpression,
|
|
@@ -23307,8 +23992,10 @@ export {
|
|
|
23307
23992
|
metricsServerManager,
|
|
23308
23993
|
modelLatticeManager,
|
|
23309
23994
|
normalizeSandboxName,
|
|
23995
|
+
parallelLimit,
|
|
23310
23996
|
parseCronExpression,
|
|
23311
23997
|
parseSkillFrontmatter,
|
|
23998
|
+
parseYaml,
|
|
23312
23999
|
performStringReplacement,
|
|
23313
24000
|
queueLatticeManager,
|
|
23314
24001
|
registerAgentLattice,
|
|
@@ -23326,18 +24013,24 @@ export {
|
|
|
23326
24013
|
registerTeammateAgent,
|
|
23327
24014
|
registerToolLattice,
|
|
23328
24015
|
registerVectorStoreLattice,
|
|
24016
|
+
renderTemplate,
|
|
24017
|
+
resolvePath,
|
|
23329
24018
|
sandboxLatticeManager,
|
|
23330
24019
|
sanitizeToolCallId,
|
|
23331
24020
|
scheduleLatticeManager,
|
|
23332
24021
|
setBindingRegistry,
|
|
24022
|
+
setMenuRegistry,
|
|
23333
24023
|
skillLatticeManager,
|
|
23334
24024
|
sqlDatabaseManager,
|
|
23335
24025
|
storeLatticeManager,
|
|
24026
|
+
toJsonSchema,
|
|
24027
|
+
toSafeStateExpr,
|
|
23336
24028
|
toolLatticeManager,
|
|
23337
24029
|
truncateIfTooLong,
|
|
23338
24030
|
unregisterTeammateAgent,
|
|
23339
24031
|
updateFileData,
|
|
23340
24032
|
validateAgentInput,
|
|
24033
|
+
validateDSL,
|
|
23341
24034
|
validateEncryptionKey,
|
|
23342
24035
|
validatePath,
|
|
23343
24036
|
validateSkillName,
|