@axiom-lattice/core 2.1.78 → 2.1.80
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-FN4TRQK4.mjs +1258 -0
- package/dist/chunk-FN4TRQK4.mjs.map +1 -0
- package/dist/compile-SYSKVQHB.mjs +9 -0
- package/dist/compile-SYSKVQHB.mjs.map +1 -0
- package/dist/index.d.mts +122 -3
- package/dist/index.d.ts +122 -3
- package/dist/index.js +2602 -765
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +776 -588
- 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 +2 -2
package/dist/index.mjs
CHANGED
|
@@ -1,245 +1,27 @@
|
|
|
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
|
-
* @param tenantId 租户ID
|
|
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
|
+
compileWorkflow,
|
|
12
|
+
createAgentNode,
|
|
13
|
+
createHumanFeedbackNode,
|
|
14
|
+
createMapNode,
|
|
15
|
+
createNodeHandler,
|
|
16
|
+
createTerminalNode,
|
|
17
|
+
expand,
|
|
18
|
+
extractOutput,
|
|
19
|
+
invokeWithRetry,
|
|
20
|
+
parallelLimit,
|
|
21
|
+
renderTemplate,
|
|
22
|
+
resolvePath,
|
|
23
|
+
validateDSL
|
|
24
|
+
} from "./chunk-FN4TRQK4.mjs";
|
|
243
25
|
|
|
244
26
|
// src/model_lattice/ModelLattice.ts
|
|
245
27
|
import { ChatDeepSeek } from "@langchain/deepseek";
|
|
@@ -2436,6 +2218,14 @@ var InMemoryWorkflowTrackingStore = class {
|
|
|
2436
2218
|
this.steps.set(request.runId, runSteps);
|
|
2437
2219
|
return step;
|
|
2438
2220
|
}
|
|
2221
|
+
async upsertRunStep(request) {
|
|
2222
|
+
const runSteps = this.steps.get(request.runId) || [];
|
|
2223
|
+
const existing = runSteps.find(
|
|
2224
|
+
(s) => s.stepType === request.stepType && s.stepName === request.stepName
|
|
2225
|
+
);
|
|
2226
|
+
if (existing) return existing;
|
|
2227
|
+
return this.createRunStep(request);
|
|
2228
|
+
}
|
|
2439
2229
|
async updateRunStep(runId, stepId, updates) {
|
|
2440
2230
|
const runSteps = this.steps.get(runId);
|
|
2441
2231
|
if (!runSteps) return null;
|
|
@@ -7049,86 +6839,6 @@ import {
|
|
|
7049
6839
|
getSubAgentsFromConfig
|
|
7050
6840
|
} from "@axiom-lattice/protocols";
|
|
7051
6841
|
|
|
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
6842
|
// src/agent_lattice/builders/state.ts
|
|
7133
6843
|
import "@langchain/langgraph/zod";
|
|
7134
6844
|
import { MessagesZodState } from "@langchain/langgraph";
|
|
@@ -7606,7 +7316,355 @@ metadata:
|
|
|
7606
7316
|
**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
7317
|
|
|
7608
7318
|
Then iterate based on what the user says.
|
|
7609
|
-
|
|
7319
|
+
`,
|
|
7320
|
+
"create-workflow": `---
|
|
7321
|
+
name: create-workflow
|
|
7322
|
+
description: Design and build multi-step AI workflows using the concise Workflow DSL. Use whenever users want to orchestrate agents in a pipeline, build process automation with branching/parallel logic, design approval flows with human-in-the-loop, or process data in stages.
|
|
7323
|
+
license: MIT
|
|
7324
|
+
metadata:
|
|
7325
|
+
category: meta
|
|
7326
|
+
version: "3.0"
|
|
7327
|
+
---
|
|
7328
|
+
|
|
7329
|
+
# Workflow Designer
|
|
7330
|
+
|
|
7331
|
+
This skill guides you through designing and creating workflow agents. A workflow is a LangGraph state machine compiled from a concise JSON DSL \u2014 steps define what happens, order defines the flow, and the engine handles the rest.
|
|
7332
|
+
|
|
7333
|
+
Every step runs on the workflow's built-in general-purpose agent \u2014 no external agent registration needed.
|
|
7334
|
+
|
|
7335
|
+
## Core Principle: id is everything
|
|
7336
|
+
|
|
7337
|
+
A step's \`id\` serves triple duty:
|
|
7338
|
+
1. **Node identifier** in the graph
|
|
7339
|
+
2. **State key** \u2014 output is stored at \`state.<id>\`
|
|
7340
|
+
3. **Template reference** \u2014 downstream steps use \`{{id}}\` to read it
|
|
7341
|
+
|
|
7342
|
+
If you omit \`id\`, a unique identifier is auto-generated (but you won't be able to reference the output).
|
|
7343
|
+
|
|
7344
|
+
## Step Types
|
|
7345
|
+
|
|
7346
|
+
### agent \u2014 a step for the workflow's built-in agent
|
|
7347
|
+
|
|
7348
|
+
\`\`\`json
|
|
7349
|
+
{ "id": "classify", "name": "Classify Intent", "prompt": "Classify the intent of: {{input}}", "schema": { "type": "object", "properties": { "intent": { "type": "string" } } } }
|
|
7350
|
+
\`\`\`
|
|
7351
|
+
|
|
7352
|
+
| Field | Required | Description |
|
|
7353
|
+
|-------|----------|-------------|
|
|
7354
|
+
| id | no | State key for referencing output. Auto-generated if omitted, but required if downstream steps reference this step via \`{{id}}\` |
|
|
7355
|
+
| name | no | Human-readable label for this step |
|
|
7356
|
+
| prompt | yes | Task description with {{id}} refs |
|
|
7357
|
+
| schema | **yes** | Standard JSON Schema ONLY: \`{ "type": "object", "properties": { "field": { "type": "string" } } }\`. \`true\` is REJECTED \u2014 must be a concrete schema. Legacy shorthand \`{ "field": "string" }\` is REJECTED.
|
|
7358
|
+
|
|
7359
|
+
**Schema Rules (MUST follow \u2014 shorthand is rejected):**
|
|
7360
|
+
- Always wrap in \`{ "type": "object", "properties": { ... } }\`
|
|
7361
|
+
- Each property must be \`{ "type": "string"|"number"|"boolean"|"array"|"object" }\`
|
|
7362
|
+
- Arrays need \`"items"\`: \`{ "type": "array", "items": { "type": "string" } }\`
|
|
7363
|
+
- \u274C \`{ "field": "string" }\` \u2014 REJECTED (no "type"/"properties" wrapper)
|
|
7364
|
+
- \u274C \`{ "schema": { "intent": "string" } }\` \u2014 REJECTED (legacy shorthand)
|
|
7365
|
+
|
|
7366
|
+
The agent's response is stored at \`state.<id>\` (or an auto-generated key if \`id\` is omitted).
|
|
7367
|
+
|
|
7368
|
+
### condition \u2014 branch on state
|
|
7369
|
+
|
|
7370
|
+
**Binary (then/else):**
|
|
7371
|
+
|
|
7372
|
+
\`\`\`json
|
|
7373
|
+
{ "type": "condition", "if": "intent",
|
|
7374
|
+
"then": { "id": "support", "name": "Handle Support", "prompt": "Handle support: {{input}}" },
|
|
7375
|
+
"else": { "id": "sales", "name": "Handle Sales", "prompt": "Handle sales: {{input}}" }
|
|
7376
|
+
}
|
|
7377
|
+
\`\`\`
|
|
7378
|
+
|
|
7379
|
+
| Field | Required | Description |
|
|
7380
|
+
|-------|----------|-------------|
|
|
7381
|
+
| if | yes | State field name (e.g. "approved") or expression (e.g. "score >= 60"). **CRITICAL: \`{{}}\` is FORBIDDEN in \`if\`** \u2014 it is a plain JavaScript expression, not a template. \u274C \`"if": "{{intent}}"\` is WRONG. \u2705 \`"if": "intent"\` is correct. |
|
|
7382
|
+
| then | yes | Step(s) to run when condition is truthy |
|
|
7383
|
+
| else | no | Step(s) to run when condition is falsy |
|
|
7384
|
+
|
|
7385
|
+
The engine evaluates \`if\` as a JavaScript expression prefixed with \`state.\`. Both \`then\` and \`else\` can be a single step or an array of steps. After both branches, execution rejoins at the next step after the condition.
|
|
7386
|
+
|
|
7387
|
+
**Switch (branches):**
|
|
7388
|
+
|
|
7389
|
+
When branching on a discrete set of known values, use \`branches\` for cleaner multi-way routing:
|
|
7390
|
+
|
|
7391
|
+
\`\`\`json
|
|
7392
|
+
{ "type": "condition", "if": "intent",
|
|
7393
|
+
"branches": {
|
|
7394
|
+
"support": { "id": "support", "prompt": "Handle support: {{input}}" },
|
|
7395
|
+
"sales": { "id": "sales", "prompt": "Handle sales: {{input}}" },
|
|
7396
|
+
"billing": { "id": "billing", "prompt": "Handle billing: {{input}}" },
|
|
7397
|
+
"default": { "id": "fallback", "prompt": "Send to human: {{input}}" }
|
|
7398
|
+
}
|
|
7399
|
+
}
|
|
7400
|
+
\`\`\`
|
|
7401
|
+
|
|
7402
|
+
| Field | Required | Description |
|
|
7403
|
+
|-------|----------|-------------|
|
|
7404
|
+
| if | yes | State field whose STRING VALUE is matched against branch keys. **Same rule \u2014 \`{{}}\` is FORBIDDEN here.** |
|
|
7405
|
+
| branches | yes | Map of value \u2192 step(s). \`"default"\` key is a catch-all for unmatched values |
|
|
7406
|
+
| then/else | no | Not used when branches is present |
|
|
7407
|
+
|
|
7408
|
+
Unlike \`then\`/\`else\` (truthy/falsy ternary), \`branches\` does exact string match against the state field value. Always include a \`"default"\` branch.
|
|
7409
|
+
|
|
7410
|
+
### human \u2014 pause for human input
|
|
7411
|
+
|
|
7412
|
+
The human step invokes an agent with ask_user_to_clarify middleware. The agent is a **facilitator** \u2014 it presents information to the user and collects their response. The agent does NOT make decisions itself; it asks the user. The agent's structured output is stored under the step's \`id\`.
|
|
7413
|
+
|
|
7414
|
+
\`\`\`json
|
|
7415
|
+
{ "id": "review", "type": "human",
|
|
7416
|
+
"title": "Approval",
|
|
7417
|
+
"prompt": "Present the following draft to the user for approval. Ask whether to approve or reject, and collect any comments.\\n\\nDraft:\\n{{draft}}",
|
|
7418
|
+
"schema": { "type": "object", "properties": { "approved": { "type": "boolean" }, "comments": { "type": "string" } } }
|
|
7419
|
+
}
|
|
7420
|
+
\`\`\`
|
|
7421
|
+
|
|
7422
|
+
Access results with dot notation: \`{{review.approved}}\`, \`{{review.comments}}\`. Use \`schema\` to constrain the agent's output.
|
|
7423
|
+
|
|
7424
|
+
| Field | Required | Description |
|
|
7425
|
+
|-------|----------|-------------|
|
|
7426
|
+
| id | no | State key for the agent's structured output |
|
|
7427
|
+
| type | yes | Must be \`"human"\` |
|
|
7428
|
+
| prompt | yes | Tell the agent what to present to the user and what to ask. The agent is a facilitator \u2014 write instructions like "Present X to the user and ask Y", NOT "You are a reviewer. Review X..." |
|
|
7429
|
+
| title | no | Display label for the human step |
|
|
7430
|
+
| schema | no | JSON Schema constraining the agent's structured output format |
|
|
7431
|
+
|
|
7432
|
+
### map \u2014 iterate over an array
|
|
7433
|
+
|
|
7434
|
+
\`\`\`json
|
|
7435
|
+
{ "id": "results", "type": "map",
|
|
7436
|
+
"source": "items",
|
|
7437
|
+
"each": { "prompt": "Audit: {{item}}", "schema": { "type": "object", "properties": { "result": { "type": "string" } } } },
|
|
7438
|
+
"batch": 10, "concurrency": 3
|
|
7439
|
+
}
|
|
7440
|
+
\`\`\`
|
|
7441
|
+
|
|
7442
|
+
| Field | Required | Description |
|
|
7443
|
+
|-------|----------|-------------|
|
|
7444
|
+
| id | yes | Output key for the results array |
|
|
7445
|
+
| source | yes | id of the step whose output is the array to iterate |
|
|
7446
|
+
| each | yes | Step applied to each element. Use {{item}} for the current element |
|
|
7447
|
+
| reduce | no | Step to aggregate results |
|
|
7448
|
+
| batch | no | Items per batch (default 50) |
|
|
7449
|
+
| concurrency | no | Max parallel items (default 5) |
|
|
7450
|
+
|
|
7451
|
+
### parallel \u2014 fixed fan-out
|
|
7452
|
+
|
|
7453
|
+
\`\`\`json
|
|
7454
|
+
{ "type": "parallel", "steps": [
|
|
7455
|
+
{ "id": "legal", "prompt": "Legal review: {{input}}" },
|
|
7456
|
+
{ "id": "finance", "prompt": "Finance: {{input}}" }
|
|
7457
|
+
]}
|
|
7458
|
+
\`\`\`
|
|
7459
|
+
|
|
7460
|
+
All steps run simultaneously. After all complete, execution continues to the next step.
|
|
7461
|
+
|
|
7462
|
+
### end \u2014 terminate the workflow
|
|
7463
|
+
|
|
7464
|
+
\`\`\`json
|
|
7465
|
+
{ "type": "end" }
|
|
7466
|
+
\`\`\`
|
|
7467
|
+
|
|
7468
|
+
Always include at the end of the steps array. \`status\` defaults to "success".
|
|
7469
|
+
|
|
7470
|
+
**Number of terminal nodes:**
|
|
7471
|
+
|
|
7472
|
+
- **Every workflow MUST have at least one \`{ "type": "end" }\`** \u2014 without it, the graph hangs at the last node.
|
|
7473
|
+
- **One is enough** even for complex workflows: all branches can converge to a single \`end\` node (parallel fan-in, condition branches rejoining, etc.).
|
|
7474
|
+
- **Use multiple end nodes ONLY when different branches need different \`status\`** values \u2014 e.g., success path vs failure path:
|
|
7475
|
+
|
|
7476
|
+
\`\`\`json
|
|
7477
|
+
{ "type": "condition", "if": "score >= 60",
|
|
7478
|
+
"then": { "type": "end", "status": "success" },
|
|
7479
|
+
"else": { "type": "end", "status": "failed" }
|
|
7480
|
+
}
|
|
7481
|
+
\`\`\`
|
|
7482
|
+
|
|
7483
|
+
- If all outcomes share the same final status, use a single \`end\` node after the condition/parallel block \u2014 the engine automatically converges all paths to it.
|
|
7484
|
+
|
|
7485
|
+
## Template Syntax
|
|
7486
|
+
|
|
7487
|
+
| Syntax | Resolves to | When to use |
|
|
7488
|
+
|--------|------------|-------------|
|
|
7489
|
+
| \`{{input}}\` | Initial user message | First step or any step needing the original question |
|
|
7490
|
+
| \`{{id}}\` | Output of step with given id | Referencing any upstream step's result |
|
|
7491
|
+
| \`{{item}}\` | Current element in map iteration | Inside map \`each.prompt\` |
|
|
7492
|
+
|
|
7493
|
+
## \u26A0\uFE0F CRITICAL: \`{{}}\` is ONLY for \`prompt\` fields
|
|
7494
|
+
|
|
7495
|
+
The template markers \`{{id}}\`, \`{{input}}\`, and \`{{item}}\` work **exclusively inside \`prompt\` strings**. All other string fields \u2014 including \`if\`, \`source\`, \`id\`, \`name\`, \`title\`, \`status\` \u2014 must use plain values without any \`{{}}\` wrapping.
|
|
7496
|
+
|
|
7497
|
+
**Common mistake the AI makes:**
|
|
7498
|
+
\`\`\`json
|
|
7499
|
+
// \u274C WRONG \u2014 {{}} does not belong in if:
|
|
7500
|
+
{ "type": "condition", "if": "{{intent}}", "then": {...}, "else": {...} }
|
|
7501
|
+
|
|
7502
|
+
// \u2705 CORRECT \u2014 if is a plain expression:
|
|
7503
|
+
{ "type": "condition", "if": "intent", "then": {...}, "else": {...} }
|
|
7504
|
+
\`\`\`
|
|
7505
|
+
|
|
7506
|
+
## What You NEVER Write
|
|
7507
|
+
|
|
7508
|
+
The engine auto-generates these \u2014 do NOT include them in your DSL:
|
|
7509
|
+
|
|
7510
|
+
- **state.fields** \u2014 auto-declared from every \`id\`
|
|
7511
|
+
- **edges** \u2014 auto-generated from step order (linear) and types (fan-out for parallel, conditional for condition)
|
|
7512
|
+
- **output.key** \u2014 always equals \`id\`
|
|
7513
|
+
- **version** \u2014 always "1.0" internally
|
|
7514
|
+
- **node IDs** \u2014 prefixed internally to avoid conflicts with state channel names
|
|
7515
|
+
- **human step type** \u2014 the human step has ask_user_to_clarify built-in. Use \`{ "type": "human", ... }\` in the DSL for user interaction. Do NOT manually add ask_user_to_clarify middleware to regular agent steps \u2014 use the dedicated \`human\` step instead.
|
|
7516
|
+
|
|
7517
|
+
## Design Patterns
|
|
7518
|
+
|
|
7519
|
+
### Pattern 1: Linear Pipeline
|
|
7520
|
+
|
|
7521
|
+
\`\`\`json
|
|
7522
|
+
{
|
|
7523
|
+
"name": "knowledge-qa",
|
|
7524
|
+
"steps": [
|
|
7525
|
+
{ "id": "research", "name": "Research Topic", "prompt": "Research: {{input}}", "schema": { "type": "object", "properties": { "findings": { "type": "string" } } } },
|
|
7526
|
+
{ "id": "answer", "name": "Write Answer", "prompt": "Write answer based on: {{research}}", "schema": { "type": "object", "properties": { "answer": { "type": "string" } } } },
|
|
7527
|
+
{ "type": "end" }
|
|
7528
|
+
]
|
|
7529
|
+
}
|
|
7530
|
+
\`\`\`
|
|
7531
|
+
|
|
7532
|
+
### Pattern 2: Classify then Route
|
|
7533
|
+
|
|
7534
|
+
\`\`\`json
|
|
7535
|
+
{
|
|
7536
|
+
"name": "customer-router",
|
|
7537
|
+
"steps": [
|
|
7538
|
+
{ "id": "intent", "name": "Classify Intent", "prompt": "Classify: {{input}}", "schema": { "type": "object", "properties": { "intent": { "type": "string" } } } },
|
|
7539
|
+
{ "type": "condition", "if": "intent",
|
|
7540
|
+
"then": { "id": "support", "name": "Handle Support", "prompt": "Handle support: {{input}}", "schema": { "type": "object", "properties": { "response": { "type": "string" } } } },
|
|
7541
|
+
"else": { "id": "sales", "name": "Handle Sales", "prompt": "Handle sales: {{input}}", "schema": { "type": "object", "properties": { "response": { "type": "string" } } } }
|
|
7542
|
+
},
|
|
7543
|
+
{ "type": "end" }
|
|
7544
|
+
]
|
|
7545
|
+
}
|
|
7546
|
+
\`\`\`
|
|
7547
|
+
|
|
7548
|
+
### Pattern 2b: Classify then Switch
|
|
7549
|
+
|
|
7550
|
+
For routing to 3+ categories, use \`branches\` instead of nested \`then\`/\`else\`:
|
|
7551
|
+
|
|
7552
|
+
\`\`\`json
|
|
7553
|
+
{
|
|
7554
|
+
"name": "ticket-router",
|
|
7555
|
+
"steps": [
|
|
7556
|
+
{ "id": "intent", "name": "Classify", "prompt": "Classify: {{input}}", "schema": { "type": "object", "properties": { "category": { "type": "string" } } } },
|
|
7557
|
+
{ "type": "condition", "if": "intent.category",
|
|
7558
|
+
"branches": {
|
|
7559
|
+
"support": { "id": "support", "prompt": "Handle support: {{input}}" },
|
|
7560
|
+
"sales": { "id": "sales", "prompt": "Handle sales: {{input}}" },
|
|
7561
|
+
"billing": { "id": "billing", "prompt": "Handle billing: {{input}}" },
|
|
7562
|
+
"default": { "id": "fallback", "prompt": "Send to human: {{input}}" }
|
|
7563
|
+
}
|
|
7564
|
+
},
|
|
7565
|
+
{ "type": "end" }
|
|
7566
|
+
]
|
|
7567
|
+
}
|
|
7568
|
+
\`\`\`
|
|
7569
|
+
|
|
7570
|
+
### Pattern 3: Extract \u2192 Review \u2192 Approve
|
|
7571
|
+
|
|
7572
|
+
\`\`\`json
|
|
7573
|
+
{
|
|
7574
|
+
"name": "approval-flow",
|
|
7575
|
+
"steps": [
|
|
7576
|
+
{ "id": "draft", "name": "Draft Response", "prompt": "Draft a response to: {{input}}", "schema": { "type": "object", "properties": { "content": { "type": "string" } } } },
|
|
7577
|
+
{ "id": "review", "type": "human",
|
|
7578
|
+
"title": "Approval",
|
|
7579
|
+
"prompt": "Present the draft below to the user for approval. Ask whether to approve or reject with comments.\\n\\nDraft:\\n{{draft}}",
|
|
7580
|
+
"schema": { "type": "object", "properties": { "approved": { "type": "boolean" }, "comments": { "type": "string" } } } },
|
|
7581
|
+
{ "type": "condition", "if": "review.approved",
|
|
7582
|
+
"then": { "id": "published", "name": "Publish", "prompt": "Publish: {{draft}}", "schema": { "type": "object", "properties": { "status": { "type": "string" } } } },
|
|
7583
|
+
"else": { "id": "revised", "name": "Revise", "prompt": "Revise based on: {{review.comments}}", "schema": { "type": "object", "properties": { "content": { "type": "string" } } } }
|
|
7584
|
+
},
|
|
7585
|
+
{ "type": "end" }
|
|
7586
|
+
]
|
|
7587
|
+
}
|
|
7588
|
+
\`\`\`
|
|
7589
|
+
|
|
7590
|
+
### Pattern 4: Parallel Research
|
|
7591
|
+
|
|
7592
|
+
\`\`\`json
|
|
7593
|
+
{
|
|
7594
|
+
"name": "due-diligence",
|
|
7595
|
+
"steps": [
|
|
7596
|
+
{ "id": "info", "name": "Gather Info", "prompt": "Gather info: {{input}}", "schema": { "type": "object", "properties": { "rawData": { "type": "string" } } } },
|
|
7597
|
+
{ "type": "parallel", "steps": [
|
|
7598
|
+
{ "id": "legal", "name": "Legal Review", "prompt": "Legal review: {{info}}", "schema": { "type": "object", "properties": { "risks": { "type": "array", "items": { "type": "string" } } } } },
|
|
7599
|
+
{ "id": "finance", "name": "Finance Review", "prompt": "Finance review: {{info}}", "schema": { "type": "object", "properties": { "score": { "type": "number" } } } },
|
|
7600
|
+
{ "id": "market", "name": "Market Analysis", "prompt": "Market analysis: {{info}}", "schema": { "type": "object", "properties": { "trend": { "type": "string" } } } }
|
|
7601
|
+
]},
|
|
7602
|
+
{ "id": "synthesis", "name": "Synthesize", "prompt": "Synthesize: legal={{legal}} finance={{finance}} market={{market}}", "schema": { "type": "object", "properties": { "report": { "type": "string" } } } },
|
|
7603
|
+
{ "type": "end" }
|
|
7604
|
+
]
|
|
7605
|
+
}
|
|
7606
|
+
\`\`\`
|
|
7607
|
+
|
|
7608
|
+
### Pattern 5: Batch Map + Reduce
|
|
7609
|
+
|
|
7610
|
+
\`\`\`json
|
|
7611
|
+
{
|
|
7612
|
+
"name": "sentiment-analysis",
|
|
7613
|
+
"steps": [
|
|
7614
|
+
{ "id": "posts", "name": "Scrape Posts", "prompt": "Scrape posts about: {{input}}", "schema": { "type": "object", "properties": { "posts": { "type": "array", "items": { "type": "object", "properties": { "text": { "type": "string" } } } } } } },
|
|
7615
|
+
{ "id": "sentiments", "type": "map", "source": "posts",
|
|
7616
|
+
"each": { "prompt": "Analyze sentiment: {{item}}", "schema": { "type": "object", "properties": { "sentiment": { "type": "string" } } } },
|
|
7617
|
+
"reduce": { "prompt": "Summarize: {{sentiments}}", "schema": { "type": "object", "properties": { "summary": { "type": "string" } } } }
|
|
7618
|
+
},
|
|
7619
|
+
{ "id": "report", "name": "Generate Report", "prompt": "Generate report from: {{sentiments}}", "schema": { "type": "object", "properties": { "report": { "type": "string" } } } },
|
|
7620
|
+
{ "type": "end" }
|
|
7621
|
+
]
|
|
7622
|
+
}
|
|
7623
|
+
\`\`\`
|
|
7624
|
+
|
|
7625
|
+
## Step 1: Understand the Process
|
|
7626
|
+
|
|
7627
|
+
Ask the user:
|
|
7628
|
+
- What are the steps in order?
|
|
7629
|
+
- Are there branches (if condition then A else B)?
|
|
7630
|
+
- Can any steps run in parallel?
|
|
7631
|
+
- Is human approval/review needed?
|
|
7632
|
+
- What data flows between steps?
|
|
7633
|
+
|
|
7634
|
+
## Step 2: Prepare Dependencies
|
|
7635
|
+
|
|
7636
|
+
1. Call \`list_tools\` to see available tools for the workflow agent.
|
|
7637
|
+
|
|
7638
|
+
## Step 3: Write the DSL
|
|
7639
|
+
|
|
7640
|
+
Use \`create_workflow\` with \`skillLoaded: true\`. Never write \`state.fields\`, \`edges\`, \`version\`, or \`output.key\` \u2014 they are auto-generated.
|
|
7641
|
+
|
|
7642
|
+
**Checklist before calling:**
|
|
7643
|
+
- Every step that produces data referenced downstream has an \`id\`
|
|
7644
|
+
- Every agent/map-each step has a valid \`schema\` in standard JSON Schema format (with \`"type": "object"\` and \`"properties"\`)
|
|
7645
|
+
- Schema uses \`{ "type": "object", "properties": { ... } }\` \u2014 \`true\` and legacy \`{ "field": "string" }\` are REJECTED
|
|
7646
|
+
- Downstream steps reference upstream data with \`{{id}}\`
|
|
7647
|
+
- **Condition \`if\` fields do NOT use \`{{}}\`** \u2014 they are plain expressions like \`"intent"\` or \`"score >= 60"\`
|
|
7648
|
+
- Condition steps have \`then\`/\`else\` (binary) or \`branches\` (switch)
|
|
7649
|
+
- Human steps have \`schema\` constraining the agent's structured output
|
|
7650
|
+
- Map steps have \`source\` pointing to an existing step id
|
|
7651
|
+
- Parallel steps have sibling steps with unique \`id\`s
|
|
7652
|
+
- Workflow ends with \`{ "type": "end" }\`
|
|
7653
|
+
- Use \`human\` step type for user interaction (clarify middleware is built-in)
|
|
7654
|
+
|
|
7655
|
+
## Step 4: Test
|
|
7656
|
+
|
|
7657
|
+
After creating, optionally call \`validate_workflow(id)\` to check the workflow compiles correctly. Then test with \`invoke_agent\`.
|
|
7658
|
+
|
|
7659
|
+
## Debugging Tips
|
|
7660
|
+
|
|
7661
|
+
- If output is missing: check the producing step has an \`id\`
|
|
7662
|
+
- The human step invokes an agent that can use ask_user_to_clarify. The agent's structured output is stored under the step's \`id\`. Access nested results with dot notation: \`{{review.approved}}\`, \`{{review.comments}}\`
|
|
7663
|
+
- Map results are an array; use \`reduce\` to aggregate into a summary
|
|
7664
|
+
- Condition branching uses truthiness: empty string, 0, null, false \u2192 else path
|
|
7665
|
+
- \`{{input}}\` contains the user's initial message; it's always available
|
|
7666
|
+
- Parallel + condition: a parallel group cannot be the first step inside a condition's then/else (LangGraph limitation). Add a preceding agent step.
|
|
7667
|
+
`
|
|
7610
7668
|
};
|
|
7611
7669
|
function getBuiltInSkillMeta(name) {
|
|
7612
7670
|
const content = BUILTIN_SKILLS[name];
|
|
@@ -13764,7 +13822,8 @@ var ReActAgentGraphBuilder = class {
|
|
|
13764
13822
|
name: agentLattice.config.name,
|
|
13765
13823
|
checkpointer: getCheckpointSaver("default"),
|
|
13766
13824
|
stateSchema: stateSchema2,
|
|
13767
|
-
middleware: middlewares
|
|
13825
|
+
middleware: middlewares,
|
|
13826
|
+
responseFormat: params.responseFormat
|
|
13768
13827
|
});
|
|
13769
13828
|
}
|
|
13770
13829
|
};
|
|
@@ -16127,6 +16186,7 @@ var DeepAgentGraphBuilder = class {
|
|
|
16127
16186
|
contextSchema: params.stateSchema,
|
|
16128
16187
|
systemPrompt: params.prompt,
|
|
16129
16188
|
subagents,
|
|
16189
|
+
responseFormat: params.responseFormat,
|
|
16130
16190
|
checkpointer: getCheckpointSaver("default"),
|
|
16131
16191
|
skills: params.skillCategories,
|
|
16132
16192
|
backend: filesystemBackend,
|
|
@@ -18179,6 +18239,7 @@ var ProcessingAgentGraphBuilder = class {
|
|
|
18179
18239
|
contextSchema: params.stateSchema,
|
|
18180
18240
|
systemPrompt: params.prompt,
|
|
18181
18241
|
subagents,
|
|
18242
|
+
responseFormat: params.responseFormat,
|
|
18182
18243
|
checkpointer: getCheckpointSaver("default"),
|
|
18183
18244
|
skills: params.skillCategories,
|
|
18184
18245
|
backend: filesystemBackend,
|
|
@@ -18410,6 +18471,100 @@ function extractLastHumanMessage(messages) {
|
|
|
18410
18471
|
return "";
|
|
18411
18472
|
}
|
|
18412
18473
|
|
|
18474
|
+
// src/agent_lattice/builders/WorkflowAgentGraphBuilder.ts
|
|
18475
|
+
import { createAgent as createAgent7 } from "langchain";
|
|
18476
|
+
import { isWorkflowAgentConfig } from "@axiom-lattice/protocols";
|
|
18477
|
+
var DEFAULT_AGENT_PROMPT = "Complete the task accurately and concisely. Follow the instructions in the user's message.";
|
|
18478
|
+
var WorkflowAgentGraphBuilder = class {
|
|
18479
|
+
async build(agentLattice, params) {
|
|
18480
|
+
if (!isWorkflowAgentConfig(agentLattice.config)) {
|
|
18481
|
+
throw new Error(
|
|
18482
|
+
`WorkflowAgentGraphBuilder received wrong agent type: ${agentLattice.config.type}`
|
|
18483
|
+
);
|
|
18484
|
+
}
|
|
18485
|
+
const config = agentLattice.config;
|
|
18486
|
+
const dsl = config.workflow;
|
|
18487
|
+
const tenantId = agentLattice.config.tenantId ?? "default";
|
|
18488
|
+
const checkpointer = getCheckpointSaver("default");
|
|
18489
|
+
const tools = params.tools.map((t) => t.executor).filter(Boolean);
|
|
18490
|
+
const middlewareConfigs = params.middleware || [];
|
|
18491
|
+
const middlewares = await createCommonMiddlewares(middlewareConfigs, void 0, false);
|
|
18492
|
+
const humanMiddlewares = await createCommonMiddlewares([
|
|
18493
|
+
{
|
|
18494
|
+
id: "ask_user_to_clarify",
|
|
18495
|
+
type: "ask_user_to_clarify",
|
|
18496
|
+
name: "Ask User Clarify",
|
|
18497
|
+
description: "For human_feedback workflow nodes",
|
|
18498
|
+
enabled: true,
|
|
18499
|
+
config: {}
|
|
18500
|
+
}
|
|
18501
|
+
], void 0, false);
|
|
18502
|
+
const noWrapMiddlewares = middlewares.filter((m) => !m.wrapModelCall);
|
|
18503
|
+
const noWrapHumanMiddlewares = humanMiddlewares.filter((m) => !m.wrapModelCall);
|
|
18504
|
+
console.log(`[WF BUILDER] building default agent | toolCount=${tools.length} | middlewareCount=${middlewares.length}`);
|
|
18505
|
+
const defaultAgent = createAgent7({
|
|
18506
|
+
model: params.model,
|
|
18507
|
+
tools,
|
|
18508
|
+
systemPrompt: params.prompt || DEFAULT_AGENT_PROMPT,
|
|
18509
|
+
checkpointer,
|
|
18510
|
+
middleware: middlewares
|
|
18511
|
+
});
|
|
18512
|
+
console.log(`[WF BUILDER] default agent built`);
|
|
18513
|
+
const agentCache = /* @__PURE__ */ new Map();
|
|
18514
|
+
const resolveAgent = async (ref, responseFormat, stepType) => {
|
|
18515
|
+
if (ref) {
|
|
18516
|
+
console.log(`[WF BUILDER] resolveAgent: looking up ref="${ref}"`);
|
|
18517
|
+
return await getAgentClientAsync(tenantId, ref);
|
|
18518
|
+
}
|
|
18519
|
+
const isHuman = stepType === "human_feedback";
|
|
18520
|
+
if (responseFormat) {
|
|
18521
|
+
const key = (isHuman ? "human:" : "agent:") + JSON.stringify(responseFormat);
|
|
18522
|
+
console.log(`[WF BUILDER] resolveAgent: cacheKey=${key.slice(0, 80)}... | cached=${agentCache.has(key)}`);
|
|
18523
|
+
if (!agentCache.has(key)) {
|
|
18524
|
+
console.log(`[WF BUILDER] creating ${isHuman ? "human" : "agent"} with responseFormat`);
|
|
18525
|
+
const agent = createAgent7({
|
|
18526
|
+
model: params.model,
|
|
18527
|
+
tools,
|
|
18528
|
+
systemPrompt: params.prompt || DEFAULT_AGENT_PROMPT,
|
|
18529
|
+
checkpointer,
|
|
18530
|
+
middleware: isHuman ? noWrapHumanMiddlewares : noWrapMiddlewares,
|
|
18531
|
+
responseFormat
|
|
18532
|
+
});
|
|
18533
|
+
agentCache.set(key, agent);
|
|
18534
|
+
}
|
|
18535
|
+
return agentCache.get(key);
|
|
18536
|
+
}
|
|
18537
|
+
if (isHuman) {
|
|
18538
|
+
const key = "human:default";
|
|
18539
|
+
if (!agentCache.has(key)) {
|
|
18540
|
+
console.log(`[WF BUILDER] creating human_feedback default agent`);
|
|
18541
|
+
const agent = createAgent7({
|
|
18542
|
+
model: params.model,
|
|
18543
|
+
tools,
|
|
18544
|
+
systemPrompt: params.prompt || DEFAULT_AGENT_PROMPT,
|
|
18545
|
+
checkpointer,
|
|
18546
|
+
middleware: humanMiddlewares
|
|
18547
|
+
});
|
|
18548
|
+
agentCache.set(key, agent);
|
|
18549
|
+
}
|
|
18550
|
+
return agentCache.get(key);
|
|
18551
|
+
}
|
|
18552
|
+
console.log(`[WF BUILDER] resolveAgent: using defaultAgent`);
|
|
18553
|
+
return defaultAgent;
|
|
18554
|
+
};
|
|
18555
|
+
let trackingStore;
|
|
18556
|
+
try {
|
|
18557
|
+
const storeLattice = getStoreLattice("default", "workflowTracking");
|
|
18558
|
+
trackingStore = storeLattice.store;
|
|
18559
|
+
console.log(`[WF BUILDER] trackingStore registered: step input/output will be persisted`);
|
|
18560
|
+
} catch {
|
|
18561
|
+
console.warn(`[WF BUILDER] no trackingStore registered \u2014 step input/output will NOT be persisted. Register a WorkflowTrackingStore under key "workflowTracking".`);
|
|
18562
|
+
}
|
|
18563
|
+
const graph = compileWorkflow(dsl, resolveAgent, checkpointer, trackingStore);
|
|
18564
|
+
return graph;
|
|
18565
|
+
}
|
|
18566
|
+
};
|
|
18567
|
+
|
|
18413
18568
|
// src/agent_lattice/builders/AgentGraphBuilderFactory.ts
|
|
18414
18569
|
var AgentGraphBuilderFactory = class _AgentGraphBuilderFactory {
|
|
18415
18570
|
constructor() {
|
|
@@ -18434,6 +18589,7 @@ var AgentGraphBuilderFactory = class _AgentGraphBuilderFactory {
|
|
|
18434
18589
|
this.builders.set(AgentType.TEAM, new TeamAgentGraphBuilder());
|
|
18435
18590
|
this.builders.set(AgentType.PROCESSING, new ProcessingAgentGraphBuilder());
|
|
18436
18591
|
this.builders.set(AgentType.A2A_REMOTE, new RemoteAgentGraphBuilder());
|
|
18592
|
+
this.builders.set(AgentType.WORKFLOW, new WorkflowAgentGraphBuilder());
|
|
18437
18593
|
}
|
|
18438
18594
|
/**
|
|
18439
18595
|
* 注册自定义Builder
|
|
@@ -18526,6 +18682,7 @@ var AgentParamsBuilder = class {
|
|
|
18526
18682
|
subAgents: [...subAgents, ...internalSubAgents],
|
|
18527
18683
|
prompt: agentLattice.config.prompt,
|
|
18528
18684
|
stateSchema: agentLattice.config.schema,
|
|
18685
|
+
responseFormat: agentLattice.config.responseFormat,
|
|
18529
18686
|
skillCategories: skills,
|
|
18530
18687
|
middleware: agentLattice.config.middleware,
|
|
18531
18688
|
tenantId: agentLattice.config.tenantId
|
|
@@ -19335,6 +19492,190 @@ registerToolLattice(
|
|
|
19335
19492
|
}
|
|
19336
19493
|
}
|
|
19337
19494
|
);
|
|
19495
|
+
var workflowStepLazy = z55.lazy(
|
|
19496
|
+
() => z55.discriminatedUnion("type", [
|
|
19497
|
+
z55.object({ type: z55.literal("agent").optional(), id: z55.string().optional(), name: z55.string().optional(), prompt: z55.string(), schema: z55.record(z55.any()) }),
|
|
19498
|
+
z55.object({ type: z55.literal("human"), id: z55.string().optional(), prompt: z55.string(), title: z55.string().optional(), schema: z55.union([z55.boolean(), z55.record(z55.any())]).optional() }),
|
|
19499
|
+
z55.object({ type: z55.literal("condition"), id: z55.string().optional(), if: z55.string().refine((v) => !v.includes("{{"), { message: 'The `if` field takes a plain state field name or JavaScript expression (e.g. "intent", "score >= 60"). Do NOT use {{}} template markers \u2014 those are only for `prompt` fields.' }), then: z55.union([z55.lazy(() => workflowStepLazy), z55.array(z55.lazy(() => workflowStepLazy))]).optional(), else: z55.union([z55.lazy(() => workflowStepLazy), z55.array(z55.lazy(() => workflowStepLazy))]).optional(), branches: z55.record(z55.union([z55.lazy(() => workflowStepLazy), z55.array(z55.lazy(() => workflowStepLazy))])).optional() }),
|
|
19500
|
+
z55.object({ type: z55.literal("map"), id: z55.string(), source: z55.string(), each: z55.object({ prompt: z55.string(), schema: z55.record(z55.any()) }), reduce: z55.object({ prompt: z55.string(), schema: z55.record(z55.any()) }).optional(), batch: z55.number().int().min(1).optional(), concurrency: z55.number().int().min(1).optional() }),
|
|
19501
|
+
z55.object({ type: z55.literal("parallel"), id: z55.string().optional(), steps: z55.array(z55.lazy(() => workflowStepLazy)) }),
|
|
19502
|
+
z55.object({ type: z55.literal("end"), status: z55.enum(["success", "failed"]).optional() })
|
|
19503
|
+
])
|
|
19504
|
+
);
|
|
19505
|
+
var workflowDSLSchema = z55.object({
|
|
19506
|
+
name: z55.string().describe("Workflow identifier (kebab-case slug)"),
|
|
19507
|
+
steps: z55.array(workflowStepLazy).min(1).describe("Workflow steps. Edges and state fields are auto-generated. Use {{id}} to reference step outputs. Always end with { type: 'end' }.")
|
|
19508
|
+
});
|
|
19509
|
+
var createWorkflowSchema = z55.object({
|
|
19510
|
+
name: z55.string().describe("Display name for the workflow agent"),
|
|
19511
|
+
description: z55.string().optional().describe("Short description of what this workflow does"),
|
|
19512
|
+
skillLoaded: z55.literal(true).describe("MUST be true. Set this to true ONLY after loading the 'create-workflow' skill via skill(skill_name: 'create-workflow'). This confirms you have read the DSL specification and design guidelines."),
|
|
19513
|
+
workflow: workflowDSLSchema.describe("The concise Workflow DSL definition. Each step has a type (agent/human/condition/map/parallel/end) and a prompt. Edges are auto-generated from step order. Use {{id}} to reference upstream step outputs."),
|
|
19514
|
+
tools: z55.array(z55.string()).optional().describe("Tool keys for the workflow's built-in general agent"),
|
|
19515
|
+
middleware: z55.array(middlewareConfigSchema).optional().describe("Middleware configs for the workflow's general agent"),
|
|
19516
|
+
modelKey: z55.string().optional().describe("Model key for the workflow's general agent")
|
|
19517
|
+
});
|
|
19518
|
+
registerToolLattice(
|
|
19519
|
+
"create_workflow",
|
|
19520
|
+
{
|
|
19521
|
+
name: "create_workflow",
|
|
19522
|
+
description: `Create a WORKFLOW agent from a concise DSL. IMPORTANT: Load the 'create-workflow' skill first, then set skillLoaded=true. Steps are defined in order \u2014 the engine auto-generates edges and state fields. Types: agent(id?, name?, prompt, schema), human(prompt, title?, schema?), condition(if, then, else? OR if, branches with 'default' catch-all), map(source, each, reduce?), parallel(steps), end. Use {{id}} to reference step outputs, {{input}} for user message, {{item}} in map each prompts. Always end with { type: 'end' }. CRITICAL: schema MUST be standard JSON Schema: { "type": "object", "properties": { ... } }. Legacy shorthand { "field": "string" } is REJECTED.`,
|
|
19523
|
+
schema: createWorkflowSchema
|
|
19524
|
+
},
|
|
19525
|
+
async (input, exeConfig) => {
|
|
19526
|
+
try {
|
|
19527
|
+
const tenantId = getTenantId(exeConfig);
|
|
19528
|
+
const store = getAssistStore();
|
|
19529
|
+
const id = await generateAgentId(tenantId, input.name);
|
|
19530
|
+
const config = {
|
|
19531
|
+
key: id,
|
|
19532
|
+
name: input.name,
|
|
19533
|
+
description: input.description || "",
|
|
19534
|
+
type: AgentType3.WORKFLOW,
|
|
19535
|
+
prompt: input.description || `Workflow: ${input.name}`,
|
|
19536
|
+
workflow: input.workflow,
|
|
19537
|
+
...input.tools && input.tools.length > 0 ? { tools: input.tools } : {},
|
|
19538
|
+
...input.middleware && input.middleware.length > 0 ? { middleware: input.middleware } : {},
|
|
19539
|
+
...input.modelKey ? { modelKey: input.modelKey } : {}
|
|
19540
|
+
};
|
|
19541
|
+
try {
|
|
19542
|
+
const { compileWorkflow: compileWorkflow2 } = await import("./compile-SYSKVQHB.mjs");
|
|
19543
|
+
const { getCheckpointSaver: getCheckpointSaver2 } = await import("./memory_lattice-E66HTTVV.mjs");
|
|
19544
|
+
await compileWorkflow2(input.workflow, async () => ({ invoke: async () => ({}) }), getCheckpointSaver2("default"));
|
|
19545
|
+
} catch (e) {
|
|
19546
|
+
return JSON.stringify({ error: `DSL validation failed: ${e.message}`, issues: [{ type: "error", message: e.message }] });
|
|
19547
|
+
}
|
|
19548
|
+
await store.createAssistant(tenantId, id, {
|
|
19549
|
+
name: input.name,
|
|
19550
|
+
description: input.description,
|
|
19551
|
+
graphDefinition: config
|
|
19552
|
+
});
|
|
19553
|
+
eventBus.publish("assistant:created", { id, name: input.name, tenantId });
|
|
19554
|
+
return JSON.stringify({
|
|
19555
|
+
id,
|
|
19556
|
+
name: input.name,
|
|
19557
|
+
type: "workflow",
|
|
19558
|
+
stepCount: input.workflow.steps.length
|
|
19559
|
+
});
|
|
19560
|
+
} catch (error) {
|
|
19561
|
+
return JSON.stringify({ error: `Failed to create workflow: ${error.message}` });
|
|
19562
|
+
}
|
|
19563
|
+
}
|
|
19564
|
+
);
|
|
19565
|
+
registerToolLattice(
|
|
19566
|
+
"validate_workflow",
|
|
19567
|
+
{
|
|
19568
|
+
name: "validate_workflow",
|
|
19569
|
+
description: "Validate a workflow agent's DSL for correctness by compiling it. Returns errors if the DSL is invalid. Use after create_workflow or update_workflow to verify.",
|
|
19570
|
+
schema: z55.object({
|
|
19571
|
+
id: z55.string().describe("The workflow agent ID to validate")
|
|
19572
|
+
})
|
|
19573
|
+
},
|
|
19574
|
+
async (input, exeConfig) => {
|
|
19575
|
+
try {
|
|
19576
|
+
const tenantId = getTenantId(exeConfig);
|
|
19577
|
+
const store = getAssistStore();
|
|
19578
|
+
const agent = await store.getAssistantById(tenantId, input.id);
|
|
19579
|
+
if (!agent) {
|
|
19580
|
+
return JSON.stringify({ error: `Agent '${input.id}' not found` });
|
|
19581
|
+
}
|
|
19582
|
+
const graphDef = agent.graphDefinition;
|
|
19583
|
+
if (!graphDef || graphDef.type !== AgentType3.WORKFLOW) {
|
|
19584
|
+
return JSON.stringify({ error: `Agent '${input.id}' is not a workflow agent (type: ${graphDef?.type ?? "unknown"})` });
|
|
19585
|
+
}
|
|
19586
|
+
const workflow = graphDef.workflow;
|
|
19587
|
+
if (!workflow || !workflow.steps) {
|
|
19588
|
+
return JSON.stringify({ error: `Agent '${input.id}' has no valid workflow DSL` });
|
|
19589
|
+
}
|
|
19590
|
+
try {
|
|
19591
|
+
const { compileWorkflow: compileWorkflow2 } = await import("./compile-SYSKVQHB.mjs");
|
|
19592
|
+
const { getCheckpointSaver: getCheckpointSaver2 } = await import("./memory_lattice-E66HTTVV.mjs");
|
|
19593
|
+
await compileWorkflow2(workflow, async () => ({ invoke: async () => ({}) }), getCheckpointSaver2("default"));
|
|
19594
|
+
} catch (e) {
|
|
19595
|
+
return JSON.stringify({
|
|
19596
|
+
agentId: input.id,
|
|
19597
|
+
valid: false,
|
|
19598
|
+
stepCount: workflow.steps?.length ?? 0,
|
|
19599
|
+
issues: [{ type: "error", message: e.message }]
|
|
19600
|
+
});
|
|
19601
|
+
}
|
|
19602
|
+
return JSON.stringify({
|
|
19603
|
+
agentId: input.id,
|
|
19604
|
+
valid: true,
|
|
19605
|
+
stepCount: workflow.steps?.length ?? 0,
|
|
19606
|
+
issues: []
|
|
19607
|
+
});
|
|
19608
|
+
} catch (error) {
|
|
19609
|
+
return JSON.stringify({ error: `Failed to validate workflow: ${error.message}` });
|
|
19610
|
+
}
|
|
19611
|
+
}
|
|
19612
|
+
);
|
|
19613
|
+
var updateWorkflowSchema = z55.object({
|
|
19614
|
+
id: z55.string().describe("The workflow agent ID to update"),
|
|
19615
|
+
name: z55.string().optional().describe("New display name"),
|
|
19616
|
+
description: z55.string().optional().describe("New description"),
|
|
19617
|
+
workflow: workflowDSLSchema.optional().describe("Replacement Workflow DSL definition. Omit to keep the existing."),
|
|
19618
|
+
tools: z55.array(z55.string()).optional().describe("Replacement tool keys for the general agent"),
|
|
19619
|
+
middleware: z55.array(middlewareConfigSchema).optional().describe("Replacement middleware configs"),
|
|
19620
|
+
modelKey: z55.string().optional().describe("Replacement model key")
|
|
19621
|
+
});
|
|
19622
|
+
registerToolLattice(
|
|
19623
|
+
"update_workflow",
|
|
19624
|
+
{
|
|
19625
|
+
name: "update_workflow",
|
|
19626
|
+
description: "Update an existing workflow agent. Provide the agent ID and only the fields you want to change. To replace the entire DSL, pass a new workflow object. To keep the DSL and only update config (tools, middleware, modelKey), omit the workflow field. Use validate_workflow after updating to check for issues.",
|
|
19627
|
+
schema: updateWorkflowSchema
|
|
19628
|
+
},
|
|
19629
|
+
async (input, exeConfig) => {
|
|
19630
|
+
try {
|
|
19631
|
+
const tenantId = getTenantId(exeConfig);
|
|
19632
|
+
const store = getAssistStore();
|
|
19633
|
+
const existing = await store.getAssistantById(tenantId, input.id);
|
|
19634
|
+
if (!existing) {
|
|
19635
|
+
return JSON.stringify({ error: `Agent '${input.id}' not found` });
|
|
19636
|
+
}
|
|
19637
|
+
const existingConfig = existing.graphDefinition || {};
|
|
19638
|
+
if (existingConfig.type !== AgentType3.WORKFLOW) {
|
|
19639
|
+
return JSON.stringify({ error: `Agent '${input.id}' is not a workflow agent` });
|
|
19640
|
+
}
|
|
19641
|
+
const mergedConfig = { ...existingConfig };
|
|
19642
|
+
if (input.name !== void 0) mergedConfig.name = input.name;
|
|
19643
|
+
if (input.description !== void 0) mergedConfig.description = input.description;
|
|
19644
|
+
if (input.workflow !== void 0) mergedConfig.workflow = input.workflow;
|
|
19645
|
+
if (input.tools !== void 0) mergedConfig.tools = input.tools;
|
|
19646
|
+
if (input.middleware !== void 0) mergedConfig.middleware = input.middleware;
|
|
19647
|
+
if (input.modelKey !== void 0) mergedConfig.modelKey = input.modelKey;
|
|
19648
|
+
if (input.workflow !== void 0) {
|
|
19649
|
+
try {
|
|
19650
|
+
const { compileWorkflow: compileWorkflow2 } = await import("./compile-SYSKVQHB.mjs");
|
|
19651
|
+
const { getCheckpointSaver: getCheckpointSaver2 } = await import("./memory_lattice-E66HTTVV.mjs");
|
|
19652
|
+
await compileWorkflow2(input.workflow, async () => ({ invoke: async () => ({}) }), getCheckpointSaver2("default"));
|
|
19653
|
+
} catch (e) {
|
|
19654
|
+
return JSON.stringify({
|
|
19655
|
+
error: `DSL validation failed: ${e.message}`,
|
|
19656
|
+
issues: [{ type: "error", message: e.message }]
|
|
19657
|
+
});
|
|
19658
|
+
}
|
|
19659
|
+
}
|
|
19660
|
+
const newName = input.name || existing.name;
|
|
19661
|
+
await store.updateAssistant(tenantId, input.id, {
|
|
19662
|
+
name: newName,
|
|
19663
|
+
description: input.description !== void 0 ? input.description : existing.description,
|
|
19664
|
+
graphDefinition: mergedConfig
|
|
19665
|
+
});
|
|
19666
|
+
eventBus.publish("assistant:updated", { id: input.id, name: newName, tenantId });
|
|
19667
|
+
const workflow = mergedConfig.workflow;
|
|
19668
|
+
return JSON.stringify({
|
|
19669
|
+
id: input.id,
|
|
19670
|
+
name: newName,
|
|
19671
|
+
type: "workflow",
|
|
19672
|
+
stepCount: workflow?.steps?.length ?? 0
|
|
19673
|
+
});
|
|
19674
|
+
} catch (error) {
|
|
19675
|
+
return JSON.stringify({ error: `Failed to update workflow: ${error.message}` });
|
|
19676
|
+
}
|
|
19677
|
+
}
|
|
19678
|
+
);
|
|
19338
19679
|
var updateProcessingAgentSchema = z55.object({
|
|
19339
19680
|
id: z55.string().describe("The PROCESSING agent ID to update"),
|
|
19340
19681
|
name: z55.string().optional().describe("New display name for the orchestrator"),
|
|
@@ -19591,17 +19932,9 @@ registerToolLattice(
|
|
|
19591
19932
|
thread_id: threadId
|
|
19592
19933
|
});
|
|
19593
19934
|
const result = await agent.invoke({ input: { message } });
|
|
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
|
-
});
|
|
19935
|
+
return JSON.stringify({ agentId: id, threadId, result });
|
|
19604
19936
|
} catch (error) {
|
|
19937
|
+
console.error(`[invoke_agent] FAILED for agent="${input.id}":`, error.stack || error.message);
|
|
19605
19938
|
return JSON.stringify({ error: `Failed to invoke agent: ${error.message}` });
|
|
19606
19939
|
}
|
|
19607
19940
|
}
|
|
@@ -19625,12 +19958,12 @@ Every agent interaction follows this cycle. You MUST NOT skip any phase:
|
|
|
19625
19958
|
|-------|-------------|-------------------|
|
|
19626
19959
|
| **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
19960
|
| **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\`, \`
|
|
19961
|
+
| **3. BUILD** | Call \`create_agent\`, \`create_workflow\`, or \`update_agent\` / \`update_workflow\` | Only after confirmation. Report the result (ID, name). |
|
|
19629
19962
|
| **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
19963
|
|
|
19631
19964
|
**CRITICAL RULES:**
|
|
19632
19965
|
- **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 \`
|
|
19966
|
+
- **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
19967
|
- **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
19968
|
- **One decision at a time.** Each message asks exactly one question.
|
|
19636
19969
|
|
|
@@ -19641,7 +19974,7 @@ Once an agent is created, NEVER create another agent for the same purpose. If th
|
|
|
19641
19974
|
| User wants to... | Use |
|
|
19642
19975
|
|-----------------|-----|
|
|
19643
19976
|
| Change prompt, tools, middleware, name | \`update_agent\` |
|
|
19644
|
-
| Change
|
|
19977
|
+
| Change workflow DSL, tools, middleware | \`update_workflow\` |
|
|
19645
19978
|
| See current config | \`get_agent\` |
|
|
19646
19979
|
|
|
19647
19980
|
If the user's intent is unclear after creation, ask: "Edit this agent or create a new one?"
|
|
@@ -19653,8 +19986,9 @@ You have nine tools for agent management:
|
|
|
19653
19986
|
- **list_tools** \u2014 See all available tools that can be assigned to agents
|
|
19654
19987
|
- **get_agent** \u2014 View the full configuration of a specific agent
|
|
19655
19988
|
- **create_agent** \u2014 Create a REACT or DEEP_AGENT agent
|
|
19656
|
-
- **
|
|
19657
|
-
- **
|
|
19989
|
+
- **create_workflow** \u2014 Create a WORKFLOW agent from a concise DSL (load create-workflow skill first)
|
|
19990
|
+
- **validate_workflow** \u2014 Validate a workflow agent's DSL
|
|
19991
|
+
- **update_workflow** \u2014 Update a workflow agent's DSL or config
|
|
19658
19992
|
- **update_agent** \u2014 Modify an existing REACT or DEEP_AGENT agent's configuration
|
|
19659
19993
|
- **delete_agent** \u2014 Remove an agent permanently
|
|
19660
19994
|
- **manage_binding** \u2014 Bind a sender (email, Lark, Slack user) to an agent so external messages are routed to it
|
|
@@ -19692,7 +20026,7 @@ Let the \`show_widget\` tool handle rendering details \u2014 it has its own guid
|
|
|
19692
20026
|
| Type | Best for | Execution Model |
|
|
19693
20027
|
|------|----------|----------------|
|
|
19694
20028
|
| **react** | Simple, single-responsibility tasks | Classic ReAct loop (think \u2192 act \u2192 observe) |
|
|
19695
|
-
| **
|
|
20029
|
+
| **workflow** | Deterministic multi-step pipelines with branching, parallel, and human-in-the-loop | Concise DSL compiled into LangGraph state machine |
|
|
19696
20030
|
| **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
20031
|
|
|
19698
20032
|
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 +20064,61 @@ You may ask: "Want me to send this to the Agent Reviewer for testing?" If yes, d
|
|
|
19730
20064
|
|
|
19731
20065
|
---
|
|
19732
20066
|
|
|
19733
|
-
## Workflow B:
|
|
19734
|
-
|
|
19735
|
-
Use this when the task follows a standard BPO (Business Process Orchestration) pattern \u2014 a predefined topology of sub-agents working through a preset pipeline.
|
|
19736
|
-
|
|
19737
|
-
### Phase 1: Design
|
|
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.
|
|
20067
|
+
## Workflow B: Processing Agent (PROCESSING type) [DEPRECATED]
|
|
19742
20068
|
|
|
19743
|
-
|
|
20069
|
+
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.
|
|
19744
20070
|
|
|
19745
|
-
|
|
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
|
-
\`\`\`
|
|
20071
|
+
---
|
|
19769
20072
|
|
|
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
|
|
19888
|
-
|
|
19889
|
-
## Logic & Conditions
|
|
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
|
-
\`\`\`
|
|
20073
|
+
## Workflow C: Workflow DSL Agent (WORKFLOW type)
|
|
19912
20074
|
|
|
19913
|
-
|
|
20075
|
+
Use this when the process is fully known. A workflow is a deterministic LangGraph state machine compiled from a concise JSON DSL.
|
|
19914
20076
|
|
|
19915
|
-
|
|
20077
|
+
### When to choose WORKFLOW
|
|
19916
20078
|
|
|
19917
|
-
|
|
20079
|
+
| WORKFLOW (DSL) | PROCESSING (deprecated) |
|
|
20080
|
+
|---|---|
|
|
20081
|
+
| Fixed graph \u2014 all paths pre-defined | LLM-driven runtime routing |
|
|
20082
|
+
| Conditional branching via \`if\` field | Topology-constrained delegation |
|
|
20083
|
+
| human, map, parallel, condition | Single orchestrator delegates linearly |
|
|
20084
|
+
| No LLM routing decisions | Orchestrator uses LLM to route |
|
|
19918
20085
|
|
|
19919
|
-
### Phase
|
|
20086
|
+
### Phase 0: Load the Skill
|
|
19920
20087
|
|
|
19921
|
-
|
|
20088
|
+
**BEFORE designing, you MUST load the create-workflow skill:**
|
|
19922
20089
|
|
|
19923
20090
|
\`\`\`
|
|
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
|
-
)
|
|
20091
|
+
skill(skill_name: "create-workflow")
|
|
19937
20092
|
\`\`\`
|
|
19938
20093
|
|
|
19939
|
-
|
|
19940
|
-
|
|
19941
|
-
### Phase 4: Test (ask first)
|
|
20094
|
+
### Phase 1: Design
|
|
19942
20095
|
|
|
19943
|
-
|
|
20096
|
+
1. **Analyze the process.** Map every step, branch, data dependency.
|
|
20097
|
+
2. **Choose step types:**
|
|
20098
|
+
- \`agent\` \u2014 runs on the workflow's built-in agent. Output at \`state.<id>\`.
|
|
20099
|
+
- \`human\` \u2014 pauses for human input (built-in clarify middleware). Has \`prompt\`, \`title\`, \`schema\`.
|
|
20100
|
+
- \`condition\` \u2014 branches on \`if\` (field or expression). Has \`then\`/\`else\` or \`branches\` (switch with \`default\`).
|
|
20101
|
+
- \`map\` \u2014 iterates array from \`source\`, applies \`each\`, optionally \`reduce\`.
|
|
20102
|
+
- \`parallel\` \u2014 runs \`steps\` simultaneously, then rejoins.
|
|
20103
|
+
- \`end\` \u2014 terminates. Always required at end.
|
|
20104
|
+
3. **Write prompts** with \`{{id}}\` refs. \`{{input}}\` = user message. \`{{item}}\` = map element.
|
|
20105
|
+
4. **No edges or state fields needed** \u2014 the engine auto-generates them.
|
|
19944
20106
|
|
|
19945
|
-
### Phase
|
|
20107
|
+
### Phase 2: Confirm
|
|
19946
20108
|
|
|
19947
|
-
|
|
20109
|
+
Present the design. Ask: "Ready to create this workflow?"
|
|
19948
20110
|
|
|
19949
|
-
|
|
20111
|
+
### Phase 3: Build
|
|
19950
20112
|
|
|
19951
|
-
|
|
20113
|
+
Call \`create_workflow\` with \`skillLoaded: true\`. Then \`validate_workflow(id)\`.
|
|
19952
20114
|
|
|
19953
|
-
|
|
20115
|
+
### Phase 4: Test
|
|
19954
20116
|
|
|
19955
|
-
|
|
20117
|
+
Ask the user if they want to test.
|
|
19956
20118
|
|
|
19957
20119
|
---
|
|
19958
20120
|
|
|
19959
|
-
## Workflow
|
|
20121
|
+
## Workflow D: Dynamic Agent (DEEP_AGENT type)
|
|
19960
20122
|
|
|
19961
20123
|
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
20124
|
|
|
@@ -20007,7 +20169,7 @@ Follow the same Design \u2192 Confirm \u2192 Build cycle. Test only on request.
|
|
|
20007
20169
|
2. Understand what the user wants to change
|
|
20008
20170
|
3. **DESIGN**: Present the proposed changes clearly. Show a before/after diff.
|
|
20009
20171
|
4. **CONFIRM**: Ask for explicit approval. Do NOT call update_agent until confirmed.
|
|
20010
|
-
5. **BUILD**: Call **update_agent** (or **
|
|
20172
|
+
5. **BUILD**: Call **update_agent** (or **update_workflow** for WORKFLOW agents)
|
|
20011
20173
|
6. **TEST**: You may ask if they want to test. If yes, delegate to the **Agent Reviewer** sub-agent
|
|
20012
20174
|
|
|
20013
20175
|
## Deleting Agents
|
|
@@ -20038,28 +20200,53 @@ All fields except name, type, and prompt are optional.
|
|
|
20038
20200
|
}
|
|
20039
20201
|
\`\`\`
|
|
20040
20202
|
|
|
20041
|
-
###
|
|
20203
|
+
### create_workflow (WORKFLOW)
|
|
20042
20204
|
|
|
20043
|
-
Creates a
|
|
20205
|
+
Creates a WORKFLOW agent from a concise DSL. Before calling, load the \`create-workflow\` skill for the complete DSL specification. Must pass \`skillLoaded: true\`.
|
|
20044
20206
|
|
|
20045
20207
|
\`\`\`typescript
|
|
20046
20208
|
{
|
|
20047
|
-
name: string, // Required. Display name
|
|
20048
|
-
description?: string, //
|
|
20049
|
-
|
|
20050
|
-
|
|
20051
|
-
|
|
20052
|
-
|
|
20053
|
-
|
|
20054
|
-
|
|
20055
|
-
|
|
20056
|
-
|
|
20057
|
-
|
|
20058
|
-
|
|
20059
|
-
|
|
20209
|
+
name: string, // Required. Display name
|
|
20210
|
+
description?: string, // Optional. Short description
|
|
20211
|
+
skillLoaded: true, // Required. Must be true \u2014 confirms skill was loaded
|
|
20212
|
+
workflow: { // Required. Concise DSL definition
|
|
20213
|
+
name: string, // Workflow slug identifier
|
|
20214
|
+
steps: WorkflowStep[], // agent | human | condition | map | parallel | end
|
|
20215
|
+
},
|
|
20216
|
+
tools?: string[], // Optional. Tool keys for the built-in general agent
|
|
20217
|
+
middleware?: MiddlewareConfig[], // Optional. Middleware for the general agent
|
|
20218
|
+
modelKey?: string, // Optional. Model for the general agent
|
|
20219
|
+
}
|
|
20220
|
+
\`\`\`
|
|
20221
|
+
|
|
20222
|
+
### update_workflow
|
|
20223
|
+
|
|
20224
|
+
Updates an existing WORKFLOW agent. Only include fields you want to change.
|
|
20225
|
+
|
|
20226
|
+
\`\`\`typescript
|
|
20227
|
+
{
|
|
20228
|
+
id: string, // Required. Workflow agent ID
|
|
20229
|
+
name?: string, // Optional
|
|
20230
|
+
description?: string, // Optional
|
|
20231
|
+
workflow?: { name: string, steps: WorkflowStep[] }, // Optional. Replacement DSL
|
|
20232
|
+
tools?: string[], // Optional
|
|
20233
|
+
middleware?: MiddlewareConfig[], // Optional
|
|
20234
|
+
modelKey?: string, // Optional
|
|
20060
20235
|
}
|
|
20061
20236
|
\`\`\`
|
|
20062
20237
|
|
|
20238
|
+
### validate_workflow
|
|
20239
|
+
|
|
20240
|
+
Validates a workflow agent's DSL and returns any errors or warnings.
|
|
20241
|
+
|
|
20242
|
+
\`\`\`typescript
|
|
20243
|
+
{
|
|
20244
|
+
id: string, // Required. Workflow agent ID to validate
|
|
20245
|
+
}
|
|
20246
|
+
\`\`\`
|
|
20247
|
+
|
|
20248
|
+
Returns: \`{ valid: boolean, stepCount, issues: [{ type: "error"|"warning", message }] }\`
|
|
20249
|
+
|
|
20063
20250
|
### Middleware Config Reference
|
|
20064
20251
|
|
|
20065
20252
|
Each middleware entry uses this base shape:
|
|
@@ -20151,8 +20338,8 @@ Provides: \`schedule_at\`, \`schedule_after\`, \`schedule_recurring\`, \`cancel_
|
|
|
20151
20338
|
|-------------|------|-------------|
|
|
20152
20339
|
| defaultMaxRetries | number? | Default max retries for scheduled tasks. Default: \`0\` |
|
|
20153
20340
|
|
|
20154
|
-
#### topology
|
|
20155
|
-
Provides: \`read_topo_progress\` \u2014 enforces multi-agent workflow topology
|
|
20341
|
+
#### topology [DEPRECATED \u2014 use WORKFLOW DSL instead]
|
|
20342
|
+
Provides: \`read_topo_progress\` \u2014 enforces multi-agent workflow topology for PROCESSING agents only. Not needed for WORKFLOW agents.
|
|
20156
20343
|
| config field | type | description |
|
|
20157
20344
|
|-------------|------|-------------|
|
|
20158
20345
|
| edges | TopologyEdge[] | **Required.** Directed edges: \`{ from: string, to: string, purpose: string }\`. The \`purpose\` must describe the business intent of this delegation step. |
|
|
@@ -20208,29 +20395,6 @@ Use \`manage_binding\` to bind external senders (email, Lark, Slack) to agents.
|
|
|
20208
20395
|
- **threadMode**: Always use \`"per_conversation"\` (new thread per conversation). Do NOT use \`"fixed"\`.
|
|
20209
20396
|
- **channelInstallationId**: Auto-detected if only one installation exists for the channel. Use \`list_installations\` first if unsure.
|
|
20210
20397
|
|
|
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
20398
|
### update_agent parameters
|
|
20235
20399
|
|
|
20236
20400
|
\`\`\`typescript
|
|
@@ -20344,14 +20508,23 @@ var agentArchitectConfig = {
|
|
|
20344
20508
|
"list_tools",
|
|
20345
20509
|
"get_agent",
|
|
20346
20510
|
"create_agent",
|
|
20347
|
-
"
|
|
20348
|
-
"
|
|
20511
|
+
"create_workflow",
|
|
20512
|
+
"validate_workflow",
|
|
20513
|
+
"update_workflow",
|
|
20349
20514
|
"update_agent",
|
|
20350
20515
|
"delete_agent",
|
|
20351
20516
|
"manage_binding"
|
|
20352
20517
|
],
|
|
20353
20518
|
internalSubAgents: [agentReviewerConfig],
|
|
20354
20519
|
middleware: [
|
|
20520
|
+
{
|
|
20521
|
+
id: "skill",
|
|
20522
|
+
type: "skill",
|
|
20523
|
+
name: "Skill",
|
|
20524
|
+
description: "Load skill content and instructions",
|
|
20525
|
+
enabled: true,
|
|
20526
|
+
config: { readAll: true }
|
|
20527
|
+
},
|
|
20355
20528
|
{
|
|
20356
20529
|
id: "widget",
|
|
20357
20530
|
type: "widget",
|
|
@@ -23225,21 +23398,28 @@ export {
|
|
|
23225
23398
|
agentInstanceManager,
|
|
23226
23399
|
agentLatticeManager,
|
|
23227
23400
|
buildGrepResultsDict,
|
|
23401
|
+
buildInput,
|
|
23228
23402
|
buildNamedVolumeName,
|
|
23229
23403
|
buildSandboxMetadataEnv,
|
|
23230
23404
|
buildSkillFile,
|
|
23405
|
+
buildStateAnnotation,
|
|
23231
23406
|
checkEmptyContent,
|
|
23232
23407
|
clearEncryptionKeyCache,
|
|
23408
|
+
compileWorkflow,
|
|
23233
23409
|
computeSandboxName,
|
|
23234
23410
|
configureStores,
|
|
23411
|
+
createAgentNode,
|
|
23235
23412
|
createAgentTeam,
|
|
23236
23413
|
createExecuteSqlQueryTool,
|
|
23237
23414
|
createFileData,
|
|
23415
|
+
createHumanFeedbackNode,
|
|
23238
23416
|
createInfoSqlTool,
|
|
23239
23417
|
createListMetricsDataSourcesTool,
|
|
23240
23418
|
createListMetricsServersTool,
|
|
23241
23419
|
createListTablesSqlTool,
|
|
23420
|
+
createMapNode,
|
|
23242
23421
|
createModelSelectorMiddleware,
|
|
23422
|
+
createNodeHandler,
|
|
23243
23423
|
createProcessingAgent,
|
|
23244
23424
|
createQueryCheckerSqlTool,
|
|
23245
23425
|
createQueryMetricDefinitionTool,
|
|
@@ -23252,6 +23432,7 @@ export {
|
|
|
23252
23432
|
createSchedulerMiddleware,
|
|
23253
23433
|
createTeamMiddleware,
|
|
23254
23434
|
createTeammateTools,
|
|
23435
|
+
createTerminalNode,
|
|
23255
23436
|
createUnknownToolHandlerMiddleware,
|
|
23256
23437
|
createWidgetMiddleware,
|
|
23257
23438
|
decrypt,
|
|
@@ -23261,7 +23442,9 @@ export {
|
|
|
23261
23442
|
ensureBuiltinAgentsForTenant,
|
|
23262
23443
|
eventBus,
|
|
23263
23444
|
event_bus_default as eventBusDefault,
|
|
23445
|
+
expand,
|
|
23264
23446
|
extractFetcherError,
|
|
23447
|
+
extractOutput,
|
|
23265
23448
|
fileDataToString,
|
|
23266
23449
|
formatContentWithLineNumbers,
|
|
23267
23450
|
formatGrepMatches,
|
|
@@ -23297,6 +23480,7 @@ export {
|
|
|
23297
23480
|
grepMatchesFromFiles,
|
|
23298
23481
|
grepSearchFiles,
|
|
23299
23482
|
hasChunkBuffer,
|
|
23483
|
+
invokeWithRetry,
|
|
23300
23484
|
isBuiltInSkill,
|
|
23301
23485
|
isUsingDefaultKey,
|
|
23302
23486
|
isValidCronExpression,
|
|
@@ -23307,6 +23491,7 @@ export {
|
|
|
23307
23491
|
metricsServerManager,
|
|
23308
23492
|
modelLatticeManager,
|
|
23309
23493
|
normalizeSandboxName,
|
|
23494
|
+
parallelLimit,
|
|
23310
23495
|
parseCronExpression,
|
|
23311
23496
|
parseSkillFrontmatter,
|
|
23312
23497
|
performStringReplacement,
|
|
@@ -23326,6 +23511,8 @@ export {
|
|
|
23326
23511
|
registerTeammateAgent,
|
|
23327
23512
|
registerToolLattice,
|
|
23328
23513
|
registerVectorStoreLattice,
|
|
23514
|
+
renderTemplate,
|
|
23515
|
+
resolvePath,
|
|
23329
23516
|
sandboxLatticeManager,
|
|
23330
23517
|
sanitizeToolCallId,
|
|
23331
23518
|
scheduleLatticeManager,
|
|
@@ -23338,6 +23525,7 @@ export {
|
|
|
23338
23525
|
unregisterTeammateAgent,
|
|
23339
23526
|
updateFileData,
|
|
23340
23527
|
validateAgentInput,
|
|
23528
|
+
validateDSL,
|
|
23341
23529
|
validateEncryptionKey,
|
|
23342
23530
|
validatePath,
|
|
23343
23531
|
validateSkillName,
|