@axiom-lattice/core 2.1.79 → 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.js
CHANGED
|
@@ -5,6 +5,9 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
5
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
6
|
var __getProtoOf = Object.getPrototypeOf;
|
|
7
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __esm = (fn, res) => function __init() {
|
|
9
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
10
|
+
};
|
|
8
11
|
var __export = (target, all) => {
|
|
9
12
|
for (var name in all)
|
|
10
13
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -15,17 +18,1631 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
18
|
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
19
|
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
20
|
}
|
|
18
|
-
return to;
|
|
19
|
-
};
|
|
20
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
-
mod
|
|
27
|
-
));
|
|
28
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
21
|
+
return to;
|
|
22
|
+
};
|
|
23
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
24
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
25
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
26
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
27
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
28
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
29
|
+
mod
|
|
30
|
+
));
|
|
31
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
32
|
+
|
|
33
|
+
// src/base/BaseLatticeManager.ts
|
|
34
|
+
var _BaseLatticeManager, BaseLatticeManager;
|
|
35
|
+
var init_BaseLatticeManager = __esm({
|
|
36
|
+
"src/base/BaseLatticeManager.ts"() {
|
|
37
|
+
"use strict";
|
|
38
|
+
_BaseLatticeManager = class _BaseLatticeManager {
|
|
39
|
+
/**
|
|
40
|
+
* 受保护的构造函数,防止外部直接实例化
|
|
41
|
+
*/
|
|
42
|
+
constructor() {
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* 获取管理器实例(由子类实现)
|
|
46
|
+
*/
|
|
47
|
+
static getInstance() {
|
|
48
|
+
throw new Error("\u5FC5\u987B\u7531\u5B50\u7C7B\u5B9E\u73B0");
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* 构造完整的键名,包含类型前缀和租户ID
|
|
52
|
+
* @param tenantId 租户ID,全局共享使用 "default"
|
|
53
|
+
* @param key 原始键名
|
|
54
|
+
*/
|
|
55
|
+
getFullKey(tenantId, key) {
|
|
56
|
+
return `${this.getLatticeType()}:${tenantId}:${key}`;
|
|
57
|
+
}
|
|
58
|
+
// ========== 带租户的新API ==========
|
|
59
|
+
/**
|
|
60
|
+
* 带租户的注册项目
|
|
61
|
+
* @param tenantId 租户ID
|
|
62
|
+
* @param key 项目键名(不含前缀)
|
|
63
|
+
* @param item 项目实例
|
|
64
|
+
*/
|
|
65
|
+
registerWithTenant(tenantId, key, item) {
|
|
66
|
+
const fullKey = this.getFullKey(tenantId, key);
|
|
67
|
+
if (_BaseLatticeManager.registry.has(fullKey)) {
|
|
68
|
+
throw new Error(`\u9879\u76EE "${fullKey}" \u5DF2\u7ECF\u5B58\u5728\uFF0C\u65E0\u6CD5\u91CD\u590D\u6CE8\u518C`);
|
|
69
|
+
}
|
|
70
|
+
_BaseLatticeManager.registry.set(fullKey, item);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* 带租户的获取指定项目(同步)
|
|
74
|
+
* @param tenantId 租户ID
|
|
75
|
+
* @param key 项目键名(不含前缀)
|
|
76
|
+
*/
|
|
77
|
+
getWithTenant(tenantId, key) {
|
|
78
|
+
const fullKey = this.getFullKey(tenantId, key);
|
|
79
|
+
return _BaseLatticeManager.registry.get(fullKey);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* 带租户的获取指定项目(异步,支持从store回退加载)
|
|
83
|
+
* 如果内存中不存在且子类实现了loadItemFromStore,则尝试从store加载
|
|
84
|
+
* @param tenantId 租户ID
|
|
85
|
+
* @param key 项目键名(不含前缀)
|
|
86
|
+
* @returns 项目实例,如果未找到则返回undefined
|
|
87
|
+
*/
|
|
88
|
+
async getOrLoadWithTenant(tenantId, key) {
|
|
89
|
+
const item = this.getWithTenant(tenantId, key);
|
|
90
|
+
if (item !== void 0) {
|
|
91
|
+
return item;
|
|
92
|
+
}
|
|
93
|
+
if (this.loadItemFromStore) {
|
|
94
|
+
const loadedItem = await this.loadItemFromStore(tenantId, key);
|
|
95
|
+
if (loadedItem !== void 0) {
|
|
96
|
+
this.registerWithTenant(tenantId, key, loadedItem);
|
|
97
|
+
return loadedItem;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return void 0;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* 带租户的检查项目是否存在(同步)
|
|
104
|
+
* @param tenantId 租户ID
|
|
105
|
+
* @param key 项目键名(不含前缀)
|
|
106
|
+
*/
|
|
107
|
+
hasWithTenant(tenantId, key) {
|
|
108
|
+
const fullKey = this.getFullKey(tenantId, key);
|
|
109
|
+
return _BaseLatticeManager.registry.has(fullKey);
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* 带租户的检查项目是否存在(异步,支持从store回退加载)
|
|
113
|
+
* 如果内存中不存在且子类实现了loadItemFromStore,则尝试从store加载
|
|
114
|
+
* @param tenantId 租户ID
|
|
115
|
+
* @param key 项目键名(不含前缀)
|
|
116
|
+
* @returns 如果存在或能从store加载则返回true
|
|
117
|
+
*/
|
|
118
|
+
async hasOrLoadWithTenant(tenantId, key) {
|
|
119
|
+
if (this.hasWithTenant(tenantId, key)) {
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
if (this.loadItemFromStore) {
|
|
123
|
+
const loadedItem = await this.loadItemFromStore(tenantId, key);
|
|
124
|
+
if (loadedItem !== void 0) {
|
|
125
|
+
this.registerWithTenant(tenantId, key, loadedItem);
|
|
126
|
+
return true;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* 带租户的移除项目
|
|
133
|
+
* @param tenantId 租户ID
|
|
134
|
+
* @param key 项目键名(不含前缀)
|
|
135
|
+
*/
|
|
136
|
+
removeWithTenant(tenantId, key) {
|
|
137
|
+
const fullKey = this.getFullKey(tenantId, key);
|
|
138
|
+
return _BaseLatticeManager.registry.delete(fullKey);
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* 获取指定租户的所有项目
|
|
142
|
+
* @param tenantId 租户ID
|
|
143
|
+
*/
|
|
144
|
+
getAllByTenant(tenantId) {
|
|
145
|
+
const prefix = `${this.getLatticeType()}:${tenantId}:`;
|
|
146
|
+
const result = [];
|
|
147
|
+
for (const [key, value] of _BaseLatticeManager.registry.entries()) {
|
|
148
|
+
if (key.startsWith(prefix)) {
|
|
149
|
+
result.push(value);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return result;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* 清空指定租户的所有项目
|
|
156
|
+
* @param tenantId 租户ID
|
|
157
|
+
*/
|
|
158
|
+
clearByTenant(tenantId) {
|
|
159
|
+
const prefix = `${this.getLatticeType()}:${tenantId}:`;
|
|
160
|
+
const keysToDelete = [];
|
|
161
|
+
for (const key of _BaseLatticeManager.registry.keys()) {
|
|
162
|
+
if (key.startsWith(prefix)) {
|
|
163
|
+
keysToDelete.push(key);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
for (const key of keysToDelete) {
|
|
167
|
+
_BaseLatticeManager.registry.delete(key);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
// ========== 向后兼容的旧API(使用 default 租户) ==========
|
|
171
|
+
/**
|
|
172
|
+
* 注册项目(向后兼容,使用 "default" 租户)
|
|
173
|
+
* @deprecated Use registerWithTenant(tenantId, key, item) instead
|
|
174
|
+
* @param key 项目键名(不含前缀)
|
|
175
|
+
* @param item 项目实例
|
|
176
|
+
*/
|
|
177
|
+
register(key, item) {
|
|
178
|
+
this.registerWithTenant("default", key, item);
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* 获取指定项目(向后兼容,使用 "default" 租户)
|
|
182
|
+
* @deprecated Use getWithTenant(tenantId, key) instead
|
|
183
|
+
* @param key 项目键名(不含前缀)
|
|
184
|
+
*/
|
|
185
|
+
get(key) {
|
|
186
|
+
return this.getWithTenant("default", key);
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* 获取所有当前类型的项目(向后兼容,包含所有租户)
|
|
190
|
+
*/
|
|
191
|
+
getAll() {
|
|
192
|
+
const prefix = `${this.getLatticeType()}:`;
|
|
193
|
+
const result = [];
|
|
194
|
+
for (const [key, value] of _BaseLatticeManager.registry.entries()) {
|
|
195
|
+
if (key.startsWith(prefix)) {
|
|
196
|
+
result.push(value);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
return result;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* 检查项目是否存在(向后兼容,使用 "default" 租户)
|
|
203
|
+
* @deprecated Use hasWithTenant(tenantId, key) instead
|
|
204
|
+
* @param key 项目键名(不含前缀)
|
|
205
|
+
*/
|
|
206
|
+
has(key) {
|
|
207
|
+
return this.hasWithTenant("default", key);
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* 移除项目(向后兼容,使用 "default" 租户)
|
|
211
|
+
* @deprecated Use removeWithTenant(tenantId, key) instead
|
|
212
|
+
* @param key 项目键名(不含前缀)
|
|
213
|
+
*/
|
|
214
|
+
remove(key) {
|
|
215
|
+
return this.removeWithTenant("default", key);
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* 清空当前类型的所有项目(向后兼容,包含所有租户)
|
|
219
|
+
*/
|
|
220
|
+
clear() {
|
|
221
|
+
const prefix = `${this.getLatticeType()}:`;
|
|
222
|
+
const keysToDelete = [];
|
|
223
|
+
for (const key of _BaseLatticeManager.registry.keys()) {
|
|
224
|
+
if (key.startsWith(prefix)) {
|
|
225
|
+
keysToDelete.push(key);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
for (const key of keysToDelete) {
|
|
229
|
+
_BaseLatticeManager.registry.delete(key);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* 获取当前类型的项目数量(向后兼容,包含所有租户)
|
|
234
|
+
*/
|
|
235
|
+
count() {
|
|
236
|
+
const prefix = `${this.getLatticeType()}:`;
|
|
237
|
+
let count = 0;
|
|
238
|
+
for (const key of _BaseLatticeManager.registry.keys()) {
|
|
239
|
+
if (key.startsWith(prefix)) {
|
|
240
|
+
count++;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
return count;
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* 获取当前类型的项目键名列表(向后兼容,包含所有租户)
|
|
247
|
+
* 返回格式: {tenantId}:{key}
|
|
248
|
+
*/
|
|
249
|
+
keys() {
|
|
250
|
+
const prefix = `${this.getLatticeType()}:`;
|
|
251
|
+
const prefixLength = prefix.length;
|
|
252
|
+
const result = [];
|
|
253
|
+
for (const key of _BaseLatticeManager.registry.keys()) {
|
|
254
|
+
if (key.startsWith(prefix)) {
|
|
255
|
+
result.push(key.substring(prefixLength));
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
return result;
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* 获取当前类型的项目键名列表(仅指定租户,不含租户前缀)
|
|
262
|
+
* @param tenantId 租户ID
|
|
263
|
+
*/
|
|
264
|
+
keysByTenant(tenantId) {
|
|
265
|
+
const prefix = `${this.getLatticeType()}:${tenantId}:`;
|
|
266
|
+
const prefixLength = prefix.length;
|
|
267
|
+
const result = [];
|
|
268
|
+
for (const key of _BaseLatticeManager.registry.keys()) {
|
|
269
|
+
if (key.startsWith(prefix)) {
|
|
270
|
+
result.push(key.substring(prefixLength));
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
return result;
|
|
274
|
+
}
|
|
275
|
+
};
|
|
276
|
+
// 全局统一的Lattice注册表
|
|
277
|
+
_BaseLatticeManager.registry = /* @__PURE__ */ new Map();
|
|
278
|
+
BaseLatticeManager = _BaseLatticeManager;
|
|
279
|
+
}
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
// src/memory_lattice/MemoryLatticeManager.ts
|
|
283
|
+
var import_protocols2, _MemoryLatticeManager, MemoryLatticeManager, getCheckpointSaver, registerCheckpointSaver;
|
|
284
|
+
var init_MemoryLatticeManager = __esm({
|
|
285
|
+
"src/memory_lattice/MemoryLatticeManager.ts"() {
|
|
286
|
+
"use strict";
|
|
287
|
+
init_BaseLatticeManager();
|
|
288
|
+
import_protocols2 = require("@axiom-lattice/protocols");
|
|
289
|
+
_MemoryLatticeManager = class _MemoryLatticeManager extends BaseLatticeManager {
|
|
290
|
+
/**
|
|
291
|
+
* 私有构造函数,防止外部直接实例化
|
|
292
|
+
*/
|
|
293
|
+
constructor() {
|
|
294
|
+
super();
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* 获取单例实例
|
|
298
|
+
*/
|
|
299
|
+
static getInstance() {
|
|
300
|
+
if (!_MemoryLatticeManager.instance) {
|
|
301
|
+
_MemoryLatticeManager.instance = new _MemoryLatticeManager();
|
|
302
|
+
}
|
|
303
|
+
return _MemoryLatticeManager.instance;
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* 获取Lattice类型
|
|
307
|
+
*/
|
|
308
|
+
getLatticeType() {
|
|
309
|
+
return "memory";
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* 注册检查点保存器
|
|
313
|
+
* @param key 保存器键名
|
|
314
|
+
* @param saver 检查点保存器实例
|
|
315
|
+
*/
|
|
316
|
+
registerCheckpointSaver(key, saver) {
|
|
317
|
+
if (_MemoryLatticeManager.checkpointSavers.has(key)) {
|
|
318
|
+
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`);
|
|
319
|
+
}
|
|
320
|
+
_MemoryLatticeManager.checkpointSavers.set(key, saver);
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* 获取检查点保存器
|
|
324
|
+
* @param key 保存器键名
|
|
325
|
+
*/
|
|
326
|
+
getCheckpointSaver(key) {
|
|
327
|
+
const saver = _MemoryLatticeManager.checkpointSavers.get(key);
|
|
328
|
+
if (!saver) {
|
|
329
|
+
throw new Error(`\u68C0\u67E5\u70B9\u4FDD\u5B58\u5668 "${key}" \u4E0D\u5B58\u5728`);
|
|
330
|
+
}
|
|
331
|
+
return saver;
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* 获取所有已注册的检查点保存器键名
|
|
335
|
+
*/
|
|
336
|
+
getCheckpointSaverKeys() {
|
|
337
|
+
return Array.from(_MemoryLatticeManager.checkpointSavers.keys());
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* 检查检查点保存器是否存在
|
|
341
|
+
* @param key 保存器键名
|
|
342
|
+
*/
|
|
343
|
+
hasCheckpointSaver(key) {
|
|
344
|
+
return _MemoryLatticeManager.checkpointSavers.has(key);
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* 移除检查点保存器
|
|
348
|
+
* @param key 保存器键名
|
|
349
|
+
*/
|
|
350
|
+
removeCheckpointSaver(key) {
|
|
351
|
+
return _MemoryLatticeManager.checkpointSavers.delete(key);
|
|
352
|
+
}
|
|
353
|
+
};
|
|
354
|
+
// 检查点保存器注册表
|
|
355
|
+
_MemoryLatticeManager.checkpointSavers = /* @__PURE__ */ new Map();
|
|
356
|
+
MemoryLatticeManager = _MemoryLatticeManager;
|
|
357
|
+
getCheckpointSaver = (key) => MemoryLatticeManager.getInstance().getCheckpointSaver(key);
|
|
358
|
+
registerCheckpointSaver = (key, saver) => MemoryLatticeManager.getInstance().registerCheckpointSaver(key, saver);
|
|
359
|
+
}
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
// src/memory_lattice/DefaultMemorySaver.ts
|
|
363
|
+
var import_langgraph2, memory;
|
|
364
|
+
var init_DefaultMemorySaver = __esm({
|
|
365
|
+
"src/memory_lattice/DefaultMemorySaver.ts"() {
|
|
366
|
+
"use strict";
|
|
367
|
+
import_langgraph2 = require("@langchain/langgraph");
|
|
368
|
+
init_MemoryLatticeManager();
|
|
369
|
+
memory = new import_langgraph2.MemorySaver();
|
|
370
|
+
registerCheckpointSaver("default", memory);
|
|
371
|
+
}
|
|
372
|
+
});
|
|
373
|
+
|
|
374
|
+
// src/memory_lattice/index.ts
|
|
375
|
+
var memory_lattice_exports = {};
|
|
376
|
+
__export(memory_lattice_exports, {
|
|
377
|
+
MemoryLatticeManager: () => MemoryLatticeManager,
|
|
378
|
+
MemoryType: () => import_protocols2.MemoryType,
|
|
379
|
+
getCheckpointSaver: () => getCheckpointSaver,
|
|
380
|
+
registerCheckpointSaver: () => registerCheckpointSaver
|
|
381
|
+
});
|
|
382
|
+
var init_memory_lattice = __esm({
|
|
383
|
+
"src/memory_lattice/index.ts"() {
|
|
384
|
+
"use strict";
|
|
385
|
+
init_DefaultMemorySaver();
|
|
386
|
+
init_MemoryLatticeManager();
|
|
387
|
+
}
|
|
388
|
+
});
|
|
389
|
+
|
|
390
|
+
// src/workflow/utils.ts
|
|
391
|
+
function buildStateAnnotation(fields) {
|
|
392
|
+
const annotations = {};
|
|
393
|
+
if (fields) {
|
|
394
|
+
for (const [key, field] of Object.entries(fields)) {
|
|
395
|
+
annotations[key] = (0, import_langgraph15.Annotation)({
|
|
396
|
+
default: () => field.default ?? defaultValueForType(field.type),
|
|
397
|
+
reducer: buildReducer(field.reducer ?? "replace")
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
if (!annotations["messages"]) {
|
|
402
|
+
annotations["messages"] = (0, import_langgraph15.Annotation)({
|
|
403
|
+
default: () => [],
|
|
404
|
+
reducer: (prev, next) => [...prev, ...next]
|
|
405
|
+
});
|
|
406
|
+
}
|
|
407
|
+
annotations["phase"] = (0, import_langgraph15.Annotation)({
|
|
408
|
+
default: () => "init",
|
|
409
|
+
reducer: (_prev, next) => next
|
|
410
|
+
});
|
|
411
|
+
if (!annotations["status"]) {
|
|
412
|
+
annotations["status"] = (0, import_langgraph15.Annotation)({
|
|
413
|
+
default: () => "",
|
|
414
|
+
reducer: (_prev, next) => next
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
if (!annotations["_runId"]) {
|
|
418
|
+
annotations["_runId"] = (0, import_langgraph15.Annotation)({
|
|
419
|
+
default: () => void 0,
|
|
420
|
+
reducer: (_prev, next) => next ?? _prev
|
|
421
|
+
});
|
|
422
|
+
}
|
|
423
|
+
return import_langgraph15.Annotation.Root(annotations);
|
|
424
|
+
}
|
|
425
|
+
function defaultValueForType(type) {
|
|
426
|
+
switch (type) {
|
|
427
|
+
case "string":
|
|
428
|
+
return "";
|
|
429
|
+
case "number":
|
|
430
|
+
return null;
|
|
431
|
+
case "boolean":
|
|
432
|
+
return false;
|
|
433
|
+
case "object":
|
|
434
|
+
return null;
|
|
435
|
+
case "array":
|
|
436
|
+
return [];
|
|
437
|
+
default:
|
|
438
|
+
return null;
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
function buildReducer(kind) {
|
|
442
|
+
switch (kind) {
|
|
443
|
+
case "append":
|
|
444
|
+
return (prev, next) => {
|
|
445
|
+
const arr = Array.isArray(prev) ? prev : [];
|
|
446
|
+
return arr.concat(Array.isArray(next) ? next : [next]);
|
|
447
|
+
};
|
|
448
|
+
case "merge":
|
|
449
|
+
return (prev, next) => {
|
|
450
|
+
const obj = prev && typeof prev === "object" && !Array.isArray(prev) ? prev : {};
|
|
451
|
+
const merge = next && typeof next === "object" && !Array.isArray(next) ? next : {};
|
|
452
|
+
return { ...obj, ...merge };
|
|
453
|
+
};
|
|
454
|
+
case "replace":
|
|
455
|
+
default:
|
|
456
|
+
return (_prev, next) => next;
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
function resolvePath(obj, path3) {
|
|
460
|
+
const cleanPath = path3.startsWith("state.") ? path3.slice(6) : path3;
|
|
461
|
+
const parts = cleanPath.split(/\.|\[|\]\.?/).filter(Boolean);
|
|
462
|
+
let current = obj;
|
|
463
|
+
for (const part of parts) {
|
|
464
|
+
if (current === null || current === void 0) return void 0;
|
|
465
|
+
if (typeof current === "object") {
|
|
466
|
+
current = current[part];
|
|
467
|
+
} else {
|
|
468
|
+
return void 0;
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
return current;
|
|
472
|
+
}
|
|
473
|
+
function renderTemplate(template, state, item) {
|
|
474
|
+
return template.replace(/\$\{([^}]+)\}/g, (_match, expr) => {
|
|
475
|
+
const trimmed = expr.trim();
|
|
476
|
+
if (trimmed.startsWith("state.")) {
|
|
477
|
+
const val = resolvePath(state, trimmed);
|
|
478
|
+
return val === void 0 ? "" : formatValue(val);
|
|
479
|
+
}
|
|
480
|
+
if (trimmed.startsWith("item.") || trimmed === "item") {
|
|
481
|
+
if (!item) return "";
|
|
482
|
+
if (trimmed === "item") {
|
|
483
|
+
if (typeof item === "object" && "item" in item) {
|
|
484
|
+
return formatValue(item.item);
|
|
485
|
+
}
|
|
486
|
+
return formatValue(item);
|
|
487
|
+
}
|
|
488
|
+
const itemPath = trimmed;
|
|
489
|
+
const val = resolvePath({ item }, itemPath);
|
|
490
|
+
return val === void 0 ? "" : formatValue(val);
|
|
491
|
+
}
|
|
492
|
+
if (item && typeof item === "object") {
|
|
493
|
+
const firstSeg = trimmed.split(".")[0];
|
|
494
|
+
if (firstSeg in item) {
|
|
495
|
+
const val = resolvePath({ item }, `item.${trimmed}`);
|
|
496
|
+
return val === void 0 ? "" : formatValue(val);
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
return `\${${trimmed}}`;
|
|
500
|
+
});
|
|
501
|
+
}
|
|
502
|
+
function formatValue(val) {
|
|
503
|
+
if (typeof val === "string") return val;
|
|
504
|
+
if (val === null || val === void 0) return "";
|
|
505
|
+
if (Array.isArray(val)) {
|
|
506
|
+
const parts = val.map((item) => {
|
|
507
|
+
const content = item?.content ?? item?.kwargs?.content;
|
|
508
|
+
if (typeof content === "string") return content;
|
|
509
|
+
if (Array.isArray(content)) {
|
|
510
|
+
return content.filter((c) => c?.type === "text").map((c) => String(c.text ?? "")).join("\n");
|
|
511
|
+
}
|
|
512
|
+
if (content && typeof content === "object") return JSON.stringify(content, null, 2);
|
|
513
|
+
if (item && typeof item === "object") return JSON.stringify(item, null, 2);
|
|
514
|
+
return String(item);
|
|
515
|
+
});
|
|
516
|
+
const result = parts.filter(Boolean).join("\n");
|
|
517
|
+
return result || JSON.stringify(val, null, 2);
|
|
518
|
+
}
|
|
519
|
+
return JSON.stringify(val, null, 2);
|
|
520
|
+
}
|
|
521
|
+
function buildInput(input, state, item, outputSchema) {
|
|
522
|
+
let prompt = input?.template ? renderTemplate(input.template, state, item) : "";
|
|
523
|
+
if (outputSchema) {
|
|
524
|
+
const example = schemaToExample(outputSchema);
|
|
525
|
+
const schemaInstruction = `
|
|
526
|
+
|
|
527
|
+
Output must be valid JSON in exactly this shape. Return ONLY the JSON, no other text or markdown:
|
|
528
|
+
${example}`;
|
|
529
|
+
prompt = prompt + schemaInstruction;
|
|
530
|
+
}
|
|
531
|
+
return { messages: [new import_messages6.HumanMessage(prompt)] };
|
|
532
|
+
}
|
|
533
|
+
function schemaToExample(schema) {
|
|
534
|
+
const example = schemaValueToExample(schema);
|
|
535
|
+
return JSON.stringify(example, null, 2);
|
|
536
|
+
}
|
|
537
|
+
function schemaValueToExample(value) {
|
|
538
|
+
if (value === null || value === void 0) return null;
|
|
539
|
+
if (typeof value !== "object") return value;
|
|
540
|
+
const obj = value;
|
|
541
|
+
if (obj.type === "string") return "<string>";
|
|
542
|
+
if (obj.type === "number") return "<number>";
|
|
543
|
+
if (obj.type === "boolean") return "<boolean>";
|
|
544
|
+
if (obj.type === "integer") return "<integer>";
|
|
545
|
+
if (obj.type === "array" && obj.items) {
|
|
546
|
+
return [schemaValueToExample(obj.items)];
|
|
547
|
+
}
|
|
548
|
+
if (obj.type === "object" && obj.properties && typeof obj.properties === "object") {
|
|
549
|
+
const example2 = {};
|
|
550
|
+
for (const [k, v] of Object.entries(obj.properties)) {
|
|
551
|
+
example2[k] = schemaValueToExample(v);
|
|
552
|
+
}
|
|
553
|
+
return example2;
|
|
554
|
+
}
|
|
555
|
+
if (obj.type === "object") return {};
|
|
556
|
+
if (Array.isArray(value)) {
|
|
557
|
+
if (value.length === 1) {
|
|
558
|
+
return [schemaValueToExample(value[0])];
|
|
559
|
+
}
|
|
560
|
+
return value.map(schemaValueToExample);
|
|
561
|
+
}
|
|
562
|
+
const example = {};
|
|
563
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
564
|
+
example[k] = schemaValueToExample(v);
|
|
565
|
+
}
|
|
566
|
+
return example;
|
|
567
|
+
}
|
|
568
|
+
function extractOutput(result) {
|
|
569
|
+
if ("structuredResponse" in result && result.structuredResponse !== void 0) {
|
|
570
|
+
return result.structuredResponse;
|
|
571
|
+
}
|
|
572
|
+
const messages = result.messages;
|
|
573
|
+
if (messages && Array.isArray(messages)) {
|
|
574
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
575
|
+
const msg = messages[i];
|
|
576
|
+
if (msg._getType() === "ai") {
|
|
577
|
+
const content = msg.content;
|
|
578
|
+
if (typeof content === "object" && content !== null && !Array.isArray(content)) {
|
|
579
|
+
return content;
|
|
580
|
+
}
|
|
581
|
+
if (Array.isArray(content)) {
|
|
582
|
+
const textParts = content.filter(
|
|
583
|
+
(c) => typeof c === "object" && c !== null && c.type === "text"
|
|
584
|
+
).map((c) => c.text).join("\n");
|
|
585
|
+
if (textParts) {
|
|
586
|
+
try {
|
|
587
|
+
return JSON.parse(textParts);
|
|
588
|
+
} catch {
|
|
589
|
+
const fenced = extractJsonFromFence(textParts);
|
|
590
|
+
if (fenced !== void 0) return fenced;
|
|
591
|
+
return textParts;
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
return content;
|
|
595
|
+
}
|
|
596
|
+
if (typeof content === "string") {
|
|
597
|
+
try {
|
|
598
|
+
return JSON.parse(content);
|
|
599
|
+
} catch {
|
|
600
|
+
const fenced = extractJsonFromFence(content);
|
|
601
|
+
if (fenced !== void 0) return fenced;
|
|
602
|
+
return content;
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
return content;
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
const { messages: _msgs, ...rest } = result;
|
|
610
|
+
void _msgs;
|
|
611
|
+
return rest;
|
|
612
|
+
}
|
|
613
|
+
function extractJsonFromFence(text) {
|
|
614
|
+
const jsonFence = text.match(/```json\s*\n([\s\S]*?)```/);
|
|
615
|
+
if (jsonFence) {
|
|
616
|
+
try {
|
|
617
|
+
return JSON.parse(jsonFence[1].trim());
|
|
618
|
+
} catch {
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
const plainFence = text.match(/```\s*\n([\s\S]*?)```/);
|
|
622
|
+
if (plainFence) {
|
|
623
|
+
try {
|
|
624
|
+
return JSON.parse(plainFence[1].trim());
|
|
625
|
+
} catch {
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
return void 0;
|
|
629
|
+
}
|
|
630
|
+
async function parallelLimit(items, limit, fn) {
|
|
631
|
+
const results = new Array(items.length);
|
|
632
|
+
let index = 0;
|
|
633
|
+
async function worker() {
|
|
634
|
+
while (index < items.length) {
|
|
635
|
+
const i = index++;
|
|
636
|
+
results[i] = await fn(items[i], i);
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
await Promise.all(Array.from({ length: Math.min(limit, items.length) }, () => worker()));
|
|
640
|
+
return results;
|
|
641
|
+
}
|
|
642
|
+
async function invokeWithRetry(fn, maxRetries, retryOn, timeoutMs) {
|
|
643
|
+
let lastError;
|
|
644
|
+
for (let i = 0; i <= maxRetries; i++) {
|
|
645
|
+
try {
|
|
646
|
+
const promise = fn();
|
|
647
|
+
if (timeoutMs && timeoutMs > 0) {
|
|
648
|
+
return await withTimeout(promise, timeoutMs);
|
|
649
|
+
}
|
|
650
|
+
return await promise;
|
|
651
|
+
} catch (err) {
|
|
652
|
+
if (err?.name === "GraphInterrupt") {
|
|
653
|
+
throw err;
|
|
654
|
+
}
|
|
655
|
+
lastError = err;
|
|
656
|
+
if (i === maxRetries) throw err;
|
|
657
|
+
if (retryOn?.length) {
|
|
658
|
+
const errName = err?.name ?? "";
|
|
659
|
+
if (!retryOn.includes(errName)) throw err;
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
throw lastError;
|
|
664
|
+
}
|
|
665
|
+
function withTimeout(promise, ms) {
|
|
666
|
+
return Promise.race([
|
|
667
|
+
promise,
|
|
668
|
+
new Promise(
|
|
669
|
+
(_, reject) => setTimeout(() => reject(new Error(`Operation timed out after ${ms}ms`)), ms)
|
|
670
|
+
)
|
|
671
|
+
]);
|
|
672
|
+
}
|
|
673
|
+
function createAgentNode(node, resolveAgent, trackingStore) {
|
|
674
|
+
return async (state, config) => {
|
|
675
|
+
const runId = state._runId;
|
|
676
|
+
const tenantId = config?.configurable?.tenantId ?? "default";
|
|
677
|
+
const startedAt = Date.now();
|
|
678
|
+
let stepId;
|
|
679
|
+
if (trackingStore && runId) {
|
|
680
|
+
trackingStore.updateWorkflowRun(runId, {
|
|
681
|
+
status: "running",
|
|
682
|
+
completedAt: null
|
|
683
|
+
}).catch(() => {
|
|
684
|
+
});
|
|
685
|
+
}
|
|
686
|
+
try {
|
|
687
|
+
console.log(`[WF][${node.id}] START "${node.name}" | hasSchema=${!!node.output?.schema}`);
|
|
688
|
+
const responseFormat = node.output?.schema;
|
|
689
|
+
console.log(`[WF][${node.id}] resolving agent...`);
|
|
690
|
+
const client = await resolveAgent(node.ref, responseFormat, node.type);
|
|
691
|
+
console.log(`[WF][${node.id}] agent resolved, building input...`);
|
|
692
|
+
const input = buildInput(
|
|
693
|
+
node.input,
|
|
694
|
+
state,
|
|
695
|
+
void 0,
|
|
696
|
+
responseFormat ? void 0 : node.output?.schema
|
|
697
|
+
);
|
|
698
|
+
const renderedInput = input.messages[0]?.content ?? "";
|
|
699
|
+
console.log(`[WF][${node.id}] === INPUT (full) ===
|
|
700
|
+
${renderedInput}
|
|
701
|
+
=== END INPUT ===`);
|
|
702
|
+
if (trackingStore && runId) {
|
|
703
|
+
const step = await trackingStore.upsertRunStep({
|
|
704
|
+
runId,
|
|
705
|
+
tenantId,
|
|
706
|
+
stepType: node.type,
|
|
707
|
+
stepName: node.name,
|
|
708
|
+
input: { template: node.input?.template, rendered: renderedInput }
|
|
709
|
+
}).catch((e) => {
|
|
710
|
+
console.warn("Failed to upsert run step:", e.message);
|
|
711
|
+
return null;
|
|
712
|
+
});
|
|
713
|
+
stepId = step?.id;
|
|
714
|
+
if (step && step.status === "interrupted") {
|
|
715
|
+
trackingStore.updateRunStep(runId, step.id, { status: "running" }).catch(() => {
|
|
716
|
+
});
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
const subConfig = {
|
|
720
|
+
...config,
|
|
721
|
+
configurable: {
|
|
722
|
+
...config?.configurable ?? {},
|
|
723
|
+
thread_id: `${config?.configurable?.thread_id ?? "default"}:${node.id}`
|
|
724
|
+
}
|
|
725
|
+
};
|
|
726
|
+
let result;
|
|
727
|
+
try {
|
|
728
|
+
console.log(`[WF][${node.id}] invoking agent.invoke()...`);
|
|
729
|
+
result = await invokeWithRetry(
|
|
730
|
+
() => client.invoke(input, subConfig),
|
|
731
|
+
node.config?.maxRetries ?? 0,
|
|
732
|
+
node.config?.retryOn,
|
|
733
|
+
node.config?.timeout
|
|
734
|
+
);
|
|
735
|
+
console.log(`[WF][${node.id}] invoke SUCCESS, extracting output...`);
|
|
736
|
+
} catch (err) {
|
|
737
|
+
if (err?.name === "GraphInterrupt") {
|
|
738
|
+
if (trackingStore && runId && stepId) {
|
|
739
|
+
trackingStore.updateRunStep(runId, stepId, { status: "interrupted" }).catch(() => {
|
|
740
|
+
});
|
|
741
|
+
}
|
|
742
|
+
if (trackingStore && runId) {
|
|
743
|
+
trackingStore.updateWorkflowRun(runId, { status: "interrupted", completedAt: null }).catch(() => {
|
|
744
|
+
});
|
|
745
|
+
}
|
|
746
|
+
throw err;
|
|
747
|
+
}
|
|
748
|
+
const errMsg = err?.message ?? "";
|
|
749
|
+
console.log(`[WF][${node.id}] invoke FAILED: ${errMsg}`);
|
|
750
|
+
if (responseFormat && (errMsg.includes("tool_choice") || errMsg.includes("thinking") || errMsg.includes("reasoning") || errMsg.includes("InvalidParameter"))) {
|
|
751
|
+
console.log(`[WF][${node.id}] attempting fallback (text-based schema injection)...`);
|
|
752
|
+
const fallbackClient = await resolveAgent(node.ref, void 0, node.type);
|
|
753
|
+
const fallbackInput = buildInput(node.input, state, void 0, responseFormat);
|
|
754
|
+
result = await invokeWithRetry(
|
|
755
|
+
() => fallbackClient.invoke(fallbackInput, subConfig),
|
|
756
|
+
node.config?.maxRetries ?? 0,
|
|
757
|
+
node.config?.retryOn,
|
|
758
|
+
node.config?.timeout
|
|
759
|
+
);
|
|
760
|
+
console.log(`[WF][${node.id}] fallback invoke SUCCESS`);
|
|
761
|
+
} else {
|
|
762
|
+
throw err;
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
const output = extractOutput(result);
|
|
766
|
+
console.log(`[WF][${node.id}] === OUTPUT (full) | key=${node.output?.key} ===
|
|
767
|
+
${JSON.stringify(output, null, 2)}
|
|
768
|
+
=== END OUTPUT ===`);
|
|
769
|
+
const update = { phase: node.id };
|
|
770
|
+
if (node.output?.key) {
|
|
771
|
+
update[node.output.key] = output;
|
|
772
|
+
}
|
|
773
|
+
const subMessages = result.messages;
|
|
774
|
+
if (subMessages && Array.isArray(subMessages)) {
|
|
775
|
+
const aiMessages = subMessages.filter((m) => {
|
|
776
|
+
const t = typeof m._getType === "function" ? m._getType() : m.role ?? m.type;
|
|
777
|
+
return t === "ai";
|
|
778
|
+
});
|
|
779
|
+
if (aiMessages.length > 0) {
|
|
780
|
+
update.messages = aiMessages;
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
console.log(`[WF][${node.id}] DONE (${Date.now() - startedAt}ms)`);
|
|
784
|
+
if (trackingStore && runId && stepId) {
|
|
785
|
+
trackingStore.updateRunStep(runId, stepId, {
|
|
786
|
+
status: "completed",
|
|
787
|
+
output,
|
|
788
|
+
completedAt: /* @__PURE__ */ new Date(),
|
|
789
|
+
durationMs: Date.now() - startedAt
|
|
790
|
+
}).catch((e) => {
|
|
791
|
+
console.warn("Failed to update run step:", e.message);
|
|
792
|
+
});
|
|
793
|
+
}
|
|
794
|
+
return update;
|
|
795
|
+
} catch (err) {
|
|
796
|
+
if (err?.name === "GraphInterrupt") {
|
|
797
|
+
throw err;
|
|
798
|
+
}
|
|
799
|
+
if (trackingStore && runId) {
|
|
800
|
+
if (stepId) {
|
|
801
|
+
trackingStore.updateRunStep(runId, stepId, {
|
|
802
|
+
status: "failed",
|
|
803
|
+
errorMessage: err.message,
|
|
804
|
+
completedAt: /* @__PURE__ */ new Date(),
|
|
805
|
+
durationMs: Date.now() - startedAt
|
|
806
|
+
}).catch((e) => {
|
|
807
|
+
console.warn("Failed to update run step:", e.message);
|
|
808
|
+
});
|
|
809
|
+
}
|
|
810
|
+
trackingStore.updateWorkflowRun(runId, {
|
|
811
|
+
status: "failed",
|
|
812
|
+
errorMessage: err.message,
|
|
813
|
+
completedAt: /* @__PURE__ */ new Date()
|
|
814
|
+
}).catch((e) => {
|
|
815
|
+
console.warn("Failed to finalize WorkflowRun:", e.message);
|
|
816
|
+
});
|
|
817
|
+
}
|
|
818
|
+
throw err;
|
|
819
|
+
}
|
|
820
|
+
};
|
|
821
|
+
}
|
|
822
|
+
function createHumanFeedbackNode(node, resolveAgent, trackingStore) {
|
|
823
|
+
return async (state, config) => {
|
|
824
|
+
const runId = state._runId;
|
|
825
|
+
const tenantId = config?.configurable?.tenantId ?? "default";
|
|
826
|
+
const startedAt = Date.now();
|
|
827
|
+
let stepId;
|
|
828
|
+
if (trackingStore && runId) {
|
|
829
|
+
trackingStore.updateWorkflowRun(runId, {
|
|
830
|
+
status: "running",
|
|
831
|
+
completedAt: null
|
|
832
|
+
}).catch(() => {
|
|
833
|
+
});
|
|
834
|
+
}
|
|
835
|
+
try {
|
|
836
|
+
console.log(`[WF][${node.id}] HUMAN_FEEDBACK START "${node.config?.title || node.name}"`);
|
|
837
|
+
const responseFormat = node.output?.schema;
|
|
838
|
+
const client = await resolveAgent(void 0, responseFormat, node.type);
|
|
839
|
+
console.log(`[WF][${node.id}] agent resolved, building input...`);
|
|
840
|
+
const input = buildInput(
|
|
841
|
+
node.input,
|
|
842
|
+
state,
|
|
843
|
+
void 0,
|
|
844
|
+
responseFormat ? void 0 : node.output?.schema
|
|
845
|
+
);
|
|
846
|
+
const humanContent = input.messages[0]?.content ?? "";
|
|
847
|
+
input.messages = [
|
|
848
|
+
new import_messages6.SystemMessage(
|
|
849
|
+
`Follow this exact procedure. Do NOT skip any step.
|
|
850
|
+
|
|
851
|
+
STEP 1: Read the prompt. It contains content to present to the user and a question to ask.
|
|
852
|
+
|
|
853
|
+
STEP 2: Call ask_user_to_clarify. Your question text MUST contain the ACTUAL content from the prompt \u2014 copy-paste the relevant text, data, or facts directly into the question. A question like "Do you approve this recommendation?" is WRONG because the user has no idea what the recommendation says. Instead: "Do you approve this recommendation: [paste the actual recommendation text here]?"
|
|
854
|
+
|
|
855
|
+
STEP 3: The tool will pause. The user will see your questions and respond. You will receive their answers.
|
|
856
|
+
|
|
857
|
+
STEP 4: Based on the user's answers, produce your final output.`
|
|
858
|
+
),
|
|
859
|
+
...input.messages
|
|
860
|
+
];
|
|
861
|
+
const renderedInput = humanContent;
|
|
862
|
+
if (trackingStore && runId) {
|
|
863
|
+
const step = await trackingStore.upsertRunStep({
|
|
864
|
+
runId,
|
|
865
|
+
tenantId,
|
|
866
|
+
stepType: node.type,
|
|
867
|
+
stepName: node.name,
|
|
868
|
+
input: { template: node.input?.template, rendered: renderedInput }
|
|
869
|
+
}).catch((e) => {
|
|
870
|
+
console.warn("Failed to upsert run step:", e.message);
|
|
871
|
+
return null;
|
|
872
|
+
});
|
|
873
|
+
stepId = step?.id;
|
|
874
|
+
if (step && step.status === "interrupted") {
|
|
875
|
+
trackingStore.updateRunStep(runId, step.id, { status: "running" }).catch(() => {
|
|
876
|
+
});
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
const subConfig = {
|
|
880
|
+
...config,
|
|
881
|
+
configurable: {
|
|
882
|
+
...config?.configurable ?? {},
|
|
883
|
+
thread_id: `${config?.configurable?.thread_id ?? "default"}:${node.id}`
|
|
884
|
+
}
|
|
885
|
+
};
|
|
886
|
+
console.log(`[WF][${node.id}] === INPUT (full) ===
|
|
887
|
+
${renderedInput}
|
|
888
|
+
=== END INPUT ===`);
|
|
889
|
+
const result = await invokeWithRetry(
|
|
890
|
+
() => client.invoke(input, subConfig),
|
|
891
|
+
node.config?.maxRetries ?? 0,
|
|
892
|
+
node.config?.retryOn,
|
|
893
|
+
node.config?.timeout
|
|
894
|
+
);
|
|
895
|
+
console.log(`[WF][${node.id}] invoke SUCCESS, extracting output...`);
|
|
896
|
+
const output = extractOutput(result);
|
|
897
|
+
console.log(`[WF][${node.id}] === OUTPUT (full) | key=${node.output?.key} ===
|
|
898
|
+
${JSON.stringify(output, null, 2)}
|
|
899
|
+
=== END OUTPUT ===`);
|
|
900
|
+
const update = { phase: node.id };
|
|
901
|
+
if (node.output?.key) {
|
|
902
|
+
update[node.output.key] = output;
|
|
903
|
+
}
|
|
904
|
+
if (output && typeof output === "object" && !Array.isArray(output)) {
|
|
905
|
+
Object.assign(update, output);
|
|
906
|
+
}
|
|
907
|
+
const subMessages = result.messages;
|
|
908
|
+
if (subMessages && Array.isArray(subMessages)) {
|
|
909
|
+
const aiMessages = subMessages.filter((m) => {
|
|
910
|
+
const t = typeof m._getType === "function" ? m._getType() : m.role ?? m.type;
|
|
911
|
+
return t === "ai";
|
|
912
|
+
});
|
|
913
|
+
if (aiMessages.length > 0) {
|
|
914
|
+
update.messages = aiMessages;
|
|
915
|
+
}
|
|
916
|
+
}
|
|
917
|
+
console.log(`[WF][${node.id}] DONE (${Date.now() - startedAt}ms)`);
|
|
918
|
+
if (trackingStore && runId && stepId) {
|
|
919
|
+
trackingStore.updateRunStep(runId, stepId, {
|
|
920
|
+
status: "completed",
|
|
921
|
+
output,
|
|
922
|
+
completedAt: /* @__PURE__ */ new Date(),
|
|
923
|
+
durationMs: Date.now() - startedAt
|
|
924
|
+
}).catch((e) => {
|
|
925
|
+
console.warn("Failed to update run step:", e.message);
|
|
926
|
+
});
|
|
927
|
+
}
|
|
928
|
+
return update;
|
|
929
|
+
} catch (err) {
|
|
930
|
+
if (err?.name === "GraphInterrupt") {
|
|
931
|
+
if (trackingStore && runId && stepId) {
|
|
932
|
+
trackingStore.updateRunStep(runId, stepId, {
|
|
933
|
+
status: "interrupted"
|
|
934
|
+
}).catch(() => {
|
|
935
|
+
});
|
|
936
|
+
}
|
|
937
|
+
if (trackingStore && runId) {
|
|
938
|
+
trackingStore.updateWorkflowRun(runId, {
|
|
939
|
+
status: "interrupted",
|
|
940
|
+
completedAt: null
|
|
941
|
+
}).catch(() => {
|
|
942
|
+
});
|
|
943
|
+
}
|
|
944
|
+
throw err;
|
|
945
|
+
}
|
|
946
|
+
if (trackingStore && runId) {
|
|
947
|
+
if (stepId) {
|
|
948
|
+
trackingStore.updateRunStep(runId, stepId, {
|
|
949
|
+
status: "failed",
|
|
950
|
+
errorMessage: err.message,
|
|
951
|
+
completedAt: /* @__PURE__ */ new Date(),
|
|
952
|
+
durationMs: Date.now() - startedAt
|
|
953
|
+
}).catch((e) => {
|
|
954
|
+
console.warn("Failed to update run step:", e.message);
|
|
955
|
+
});
|
|
956
|
+
}
|
|
957
|
+
trackingStore.updateWorkflowRun(runId, {
|
|
958
|
+
status: "failed",
|
|
959
|
+
errorMessage: err.message,
|
|
960
|
+
completedAt: /* @__PURE__ */ new Date()
|
|
961
|
+
}).catch((e) => {
|
|
962
|
+
console.warn("Failed to finalize WorkflowRun:", e.message);
|
|
963
|
+
});
|
|
964
|
+
}
|
|
965
|
+
throw err;
|
|
966
|
+
}
|
|
967
|
+
};
|
|
968
|
+
}
|
|
969
|
+
function createMapNode(node, resolveAgent, trackingStore) {
|
|
970
|
+
return async (state, config) => {
|
|
971
|
+
const runId = state._runId;
|
|
972
|
+
const tenantId = config?.configurable?.tenantId ?? "default";
|
|
973
|
+
const startedAt = Date.now();
|
|
974
|
+
let stepId;
|
|
975
|
+
if (trackingStore && runId) {
|
|
976
|
+
trackingStore.updateWorkflowRun(runId, {
|
|
977
|
+
status: "running",
|
|
978
|
+
completedAt: null
|
|
979
|
+
}).catch(() => {
|
|
980
|
+
});
|
|
981
|
+
}
|
|
982
|
+
try {
|
|
983
|
+
const items = resolvePath(state, node.source);
|
|
984
|
+
if (trackingStore && runId) {
|
|
985
|
+
const step = await trackingStore.upsertRunStep({
|
|
986
|
+
runId,
|
|
987
|
+
tenantId,
|
|
988
|
+
stepType: node.type,
|
|
989
|
+
stepName: node.name,
|
|
990
|
+
input: { source: node.source, itemCount: Array.isArray(items) ? items.length : 0 }
|
|
991
|
+
}).catch((e) => {
|
|
992
|
+
console.warn("Failed to upsert run step:", e.message);
|
|
993
|
+
return null;
|
|
994
|
+
});
|
|
995
|
+
stepId = step?.id;
|
|
996
|
+
if (step && step.status === "interrupted") {
|
|
997
|
+
trackingStore.updateRunStep(runId, step.id, { status: "running" }).catch(() => {
|
|
998
|
+
});
|
|
999
|
+
}
|
|
1000
|
+
}
|
|
1001
|
+
if (!Array.isArray(items)) {
|
|
1002
|
+
throw new Error(
|
|
1003
|
+
`Map source "${node.source}" resolved to ${typeof items}, expected array`
|
|
1004
|
+
);
|
|
1005
|
+
}
|
|
1006
|
+
const batchSize = node.config?.batchSize ?? 50;
|
|
1007
|
+
const maxConcurrency = node.config?.maxConcurrency ?? 10;
|
|
1008
|
+
const innerConcurrency = node.config?.innerConcurrency ?? 5;
|
|
1009
|
+
const itemKey = node.itemKey ?? "item";
|
|
1010
|
+
const innerClient = await resolveAgent(node.node.ref, node.node.schema, node.type);
|
|
1011
|
+
const batches = chunk(items, batchSize);
|
|
1012
|
+
const batchResults = await parallelLimit(batches, maxConcurrency, async (batch) => {
|
|
1013
|
+
const itemResults = await parallelLimit(batch, innerConcurrency, async (item, itemIdx) => {
|
|
1014
|
+
const itemCtx = { [itemKey]: item };
|
|
1015
|
+
const input = buildInput(node.node.input, state, itemCtx);
|
|
1016
|
+
const subConfig = {
|
|
1017
|
+
...config,
|
|
1018
|
+
configurable: {
|
|
1019
|
+
...config?.configurable ?? {},
|
|
1020
|
+
thread_id: `${config?.configurable?.thread_id ?? "default"}:${node.id}:item:${itemIdx}`
|
|
1021
|
+
}
|
|
1022
|
+
};
|
|
1023
|
+
const result = await invokeWithRetry(
|
|
1024
|
+
() => innerClient.invoke(input, subConfig),
|
|
1025
|
+
node.config?.maxRetries ?? 0,
|
|
1026
|
+
node.config?.retryOn,
|
|
1027
|
+
node.config?.timeout
|
|
1028
|
+
);
|
|
1029
|
+
return extractOutput(result);
|
|
1030
|
+
});
|
|
1031
|
+
return itemResults;
|
|
1032
|
+
});
|
|
1033
|
+
const allResults = batchResults.flat();
|
|
1034
|
+
let finalOutput = allResults;
|
|
1035
|
+
if (node.reduce) {
|
|
1036
|
+
const reduceClient = await resolveAgent(node.reduce.ref, node.reduce.schema, node.type);
|
|
1037
|
+
const tempResultsKey = node.output?.key ?? `${node.id}_results`;
|
|
1038
|
+
const tempState = { ...state, [tempResultsKey]: allResults };
|
|
1039
|
+
const reduceInput = buildInput(node.reduce.input, tempState);
|
|
1040
|
+
const reduceResult = await invokeWithRetry(
|
|
1041
|
+
() => reduceClient.invoke(reduceInput, {
|
|
1042
|
+
...config,
|
|
1043
|
+
configurable: {
|
|
1044
|
+
...config?.configurable ?? {},
|
|
1045
|
+
thread_id: `${config?.configurable?.thread_id ?? "default"}:${node.id}:reduce`
|
|
1046
|
+
}
|
|
1047
|
+
}),
|
|
1048
|
+
node.config?.maxRetries ?? 0,
|
|
1049
|
+
node.config?.retryOn,
|
|
1050
|
+
node.config?.timeout
|
|
1051
|
+
);
|
|
1052
|
+
finalOutput = extractOutput(reduceResult);
|
|
1053
|
+
}
|
|
1054
|
+
const update = { phase: node.id };
|
|
1055
|
+
if (node.output?.key) {
|
|
1056
|
+
update[node.output.key] = finalOutput;
|
|
1057
|
+
}
|
|
1058
|
+
if (trackingStore && runId && stepId) {
|
|
1059
|
+
trackingStore.updateRunStep(runId, stepId, {
|
|
1060
|
+
status: "completed",
|
|
1061
|
+
output: finalOutput,
|
|
1062
|
+
completedAt: /* @__PURE__ */ new Date(),
|
|
1063
|
+
durationMs: Date.now() - startedAt
|
|
1064
|
+
}).catch((e) => {
|
|
1065
|
+
console.warn("Failed to update run step:", e.message);
|
|
1066
|
+
});
|
|
1067
|
+
}
|
|
1068
|
+
return update;
|
|
1069
|
+
} catch (err) {
|
|
1070
|
+
if (err?.name === "GraphInterrupt") {
|
|
1071
|
+
if (trackingStore && runId && stepId) {
|
|
1072
|
+
trackingStore.updateRunStep(runId, stepId, { status: "interrupted" }).catch(() => {
|
|
1073
|
+
});
|
|
1074
|
+
}
|
|
1075
|
+
if (trackingStore && runId) {
|
|
1076
|
+
trackingStore.updateWorkflowRun(runId, { status: "interrupted", completedAt: null }).catch(() => {
|
|
1077
|
+
});
|
|
1078
|
+
}
|
|
1079
|
+
throw err;
|
|
1080
|
+
}
|
|
1081
|
+
console.error(`[WF][${node.id}] FAILED after ${Date.now() - startedAt}ms:`, err.stack || err.message);
|
|
1082
|
+
if (trackingStore && runId) {
|
|
1083
|
+
if (stepId) {
|
|
1084
|
+
trackingStore.updateRunStep(runId, stepId, {
|
|
1085
|
+
status: "failed",
|
|
1086
|
+
errorMessage: err.message,
|
|
1087
|
+
completedAt: /* @__PURE__ */ new Date(),
|
|
1088
|
+
durationMs: Date.now() - startedAt
|
|
1089
|
+
}).catch(() => {
|
|
1090
|
+
});
|
|
1091
|
+
}
|
|
1092
|
+
trackingStore.updateWorkflowRun(runId, {
|
|
1093
|
+
status: "failed",
|
|
1094
|
+
errorMessage: err.message,
|
|
1095
|
+
completedAt: /* @__PURE__ */ new Date()
|
|
1096
|
+
}).catch(() => {
|
|
1097
|
+
});
|
|
1098
|
+
}
|
|
1099
|
+
throw err;
|
|
1100
|
+
}
|
|
1101
|
+
};
|
|
1102
|
+
}
|
|
1103
|
+
function createInputNode(node, trackingStore) {
|
|
1104
|
+
return async (state, config) => {
|
|
1105
|
+
const tenantId = config?.configurable?.tenantId ?? "default";
|
|
1106
|
+
const threadId = config?.configurable?.thread_id ?? "default";
|
|
1107
|
+
const assistantId = config?.configurable?.assistantId || config?.configurable?.assistant_id || "unknown";
|
|
1108
|
+
const messages = state.messages;
|
|
1109
|
+
const humanMsg = messages?.find((m) => m._getType() === "human");
|
|
1110
|
+
const inputText = typeof humanMsg?.content === "string" ? humanMsg.content : JSON.stringify(humanMsg?.content ?? "");
|
|
1111
|
+
console.log(`[WF][n_input] input captured: "${inputText.slice(0, 200)}"`);
|
|
1112
|
+
const update = { phase: node.id };
|
|
1113
|
+
if (node.output?.key) update[node.output.key] = inputText;
|
|
1114
|
+
if (trackingStore && !state._runId) {
|
|
1115
|
+
try {
|
|
1116
|
+
const run = await trackingStore.createWorkflowRun({
|
|
1117
|
+
tenantId,
|
|
1118
|
+
assistantId,
|
|
1119
|
+
threadId,
|
|
1120
|
+
topologyEdges: [],
|
|
1121
|
+
metadata: { workflowName: node.name }
|
|
1122
|
+
});
|
|
1123
|
+
update._runId = run.id;
|
|
1124
|
+
await trackingStore.createRunStep({
|
|
1125
|
+
runId: run.id,
|
|
1126
|
+
tenantId,
|
|
1127
|
+
stepType: node.type,
|
|
1128
|
+
stepName: node.name,
|
|
1129
|
+
input: { rendered: inputText }
|
|
1130
|
+
}).catch((e) => {
|
|
1131
|
+
console.warn("Failed to create input run step:", e.message);
|
|
1132
|
+
});
|
|
1133
|
+
} catch (e) {
|
|
1134
|
+
console.warn("Failed to create workflow run:", e.message);
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
1137
|
+
return update;
|
|
1138
|
+
};
|
|
1139
|
+
}
|
|
1140
|
+
function terminalStatusToRunStatus(status) {
|
|
1141
|
+
switch (status) {
|
|
1142
|
+
case "failed":
|
|
1143
|
+
return "failed";
|
|
1144
|
+
case "cancelled":
|
|
1145
|
+
return "cancelled";
|
|
1146
|
+
case "success":
|
|
1147
|
+
default:
|
|
1148
|
+
return "completed";
|
|
1149
|
+
}
|
|
1150
|
+
}
|
|
1151
|
+
function createTerminalNode(node, trackingStore) {
|
|
1152
|
+
const runStatus = terminalStatusToRunStatus(node.status);
|
|
1153
|
+
return async (state) => {
|
|
1154
|
+
const runId = state._runId;
|
|
1155
|
+
if (trackingStore && runId) {
|
|
1156
|
+
try {
|
|
1157
|
+
await trackingStore.updateWorkflowRun(runId, {
|
|
1158
|
+
status: runStatus,
|
|
1159
|
+
completedAt: /* @__PURE__ */ new Date()
|
|
1160
|
+
});
|
|
1161
|
+
} catch (e) {
|
|
1162
|
+
console.warn(`[WF][terminal] Failed to finalize WorkflowRun "${runId}":`, e.message);
|
|
1163
|
+
}
|
|
1164
|
+
try {
|
|
1165
|
+
await trackingStore.createRunStep({
|
|
1166
|
+
runId,
|
|
1167
|
+
tenantId: state._tenantId ?? "default",
|
|
1168
|
+
stepType: "terminal",
|
|
1169
|
+
stepName: node.name,
|
|
1170
|
+
input: { status: node.status }
|
|
1171
|
+
});
|
|
1172
|
+
} catch (e) {
|
|
1173
|
+
console.warn(`[WF][terminal] Failed to create terminal RunStep:`, e.message);
|
|
1174
|
+
}
|
|
1175
|
+
}
|
|
1176
|
+
return {
|
|
1177
|
+
status: node.status,
|
|
1178
|
+
phase: node.id
|
|
1179
|
+
};
|
|
1180
|
+
};
|
|
1181
|
+
}
|
|
1182
|
+
function createNodeHandler(node, resolveAgent, trackingStore) {
|
|
1183
|
+
switch (node.type) {
|
|
1184
|
+
case "agent":
|
|
1185
|
+
return createAgentNode(node, resolveAgent, trackingStore);
|
|
1186
|
+
case "human_feedback":
|
|
1187
|
+
return createHumanFeedbackNode(node, resolveAgent, trackingStore);
|
|
1188
|
+
case "map":
|
|
1189
|
+
return createMapNode(node, resolveAgent, trackingStore);
|
|
1190
|
+
case "terminal":
|
|
1191
|
+
return createTerminalNode(node, trackingStore);
|
|
1192
|
+
case "input":
|
|
1193
|
+
return createInputNode(node, trackingStore);
|
|
1194
|
+
default:
|
|
1195
|
+
throw new Error(`Unknown node type: ${node.type}`);
|
|
1196
|
+
}
|
|
1197
|
+
}
|
|
1198
|
+
function chunk(arr, size) {
|
|
1199
|
+
const result = [];
|
|
1200
|
+
for (let i = 0; i < arr.length; i += size) {
|
|
1201
|
+
result.push(arr.slice(i, i + size));
|
|
1202
|
+
}
|
|
1203
|
+
return result;
|
|
1204
|
+
}
|
|
1205
|
+
var import_langgraph15, import_messages6;
|
|
1206
|
+
var init_utils = __esm({
|
|
1207
|
+
"src/workflow/utils.ts"() {
|
|
1208
|
+
"use strict";
|
|
1209
|
+
import_langgraph15 = require("@langchain/langgraph");
|
|
1210
|
+
import_messages6 = require("@langchain/core/messages");
|
|
1211
|
+
}
|
|
1212
|
+
});
|
|
1213
|
+
|
|
1214
|
+
// src/workflow/normalize.ts
|
|
1215
|
+
function uid(prefix) {
|
|
1216
|
+
return `${prefix}_${_counter++}`;
|
|
1217
|
+
}
|
|
1218
|
+
function nodeId(stepId) {
|
|
1219
|
+
return `n_${stepId}`;
|
|
1220
|
+
}
|
|
1221
|
+
function translate(template) {
|
|
1222
|
+
return template.replace(/\{\{([^}]+)\}\}/g, (_m, expr) => {
|
|
1223
|
+
const t = expr.trim();
|
|
1224
|
+
if (t === "item") return "${item}";
|
|
1225
|
+
return `\${state.${t}}`;
|
|
1226
|
+
});
|
|
1227
|
+
}
|
|
1228
|
+
function inferFieldType(id) {
|
|
1229
|
+
if (/s$|list|array|items|results/i.test(id)) return { type: "array", default: [] };
|
|
1230
|
+
return { type: "string" };
|
|
1231
|
+
}
|
|
1232
|
+
function expandStep(step) {
|
|
1233
|
+
switch (step.type ?? "agent") {
|
|
1234
|
+
case "agent":
|
|
1235
|
+
return expandAgent(step);
|
|
1236
|
+
case "human":
|
|
1237
|
+
return expandHuman(step);
|
|
1238
|
+
case "condition":
|
|
1239
|
+
return expandCondition(step);
|
|
1240
|
+
case "map":
|
|
1241
|
+
return expandMap(step);
|
|
1242
|
+
case "parallel":
|
|
1243
|
+
return expandParallel(step);
|
|
1244
|
+
case "end":
|
|
1245
|
+
return expandEnd(step);
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
function validateSchema(schema, stepId) {
|
|
1249
|
+
if (schema.type !== "object") {
|
|
1250
|
+
throw new Error(
|
|
1251
|
+
`Step "${stepId}": schema.type must be "object", got "${String(schema.type)}". Use standard JSON Schema: { "type": "object", "properties": { ... } }`
|
|
1252
|
+
);
|
|
1253
|
+
}
|
|
1254
|
+
if (!schema.properties || typeof schema.properties !== "object") {
|
|
1255
|
+
throw new Error(
|
|
1256
|
+
`Step "${stepId}": schema must have a "properties" object. Legacy shorthand like { "field": "string" } is not supported. Use: { "type": "object", "properties": { "field": { "type": "string" } } }`
|
|
1257
|
+
);
|
|
1258
|
+
}
|
|
1259
|
+
}
|
|
1260
|
+
function expandAgent(s) {
|
|
1261
|
+
const sid = s.id || uid("agent");
|
|
1262
|
+
const nid = nodeId(sid);
|
|
1263
|
+
if (s.schema !== void 0 && s.schema !== null) {
|
|
1264
|
+
if (typeof s.schema !== "object") {
|
|
1265
|
+
throw new Error(
|
|
1266
|
+
`Step "${sid}": schema must be a JSON Schema object, e.g. { "type": "object", "properties": { ... } }. Got ${typeof s.schema} (${JSON.stringify(s.schema)}).`
|
|
1267
|
+
);
|
|
1268
|
+
}
|
|
1269
|
+
validateSchema(s.schema, sid);
|
|
1270
|
+
}
|
|
1271
|
+
const schema = s.schema && typeof s.schema === "object" ? s.schema : void 0;
|
|
1272
|
+
console.log(`[WF EXPAND] agent step id="${sid}" nodeId="${nid}" | hasSchema=${!!schema}`);
|
|
1273
|
+
return {
|
|
1274
|
+
nodes: [{ id: nid, type: "agent", name: sid, input: { template: translate(s.prompt) }, output: { key: sid, ...schema ? { schema } : {} } }],
|
|
1275
|
+
edges: [],
|
|
1276
|
+
entryId: nid,
|
|
1277
|
+
exitIds: [nid]
|
|
1278
|
+
};
|
|
1279
|
+
}
|
|
1280
|
+
function expandHuman(s) {
|
|
1281
|
+
const sid = s.id || uid("human");
|
|
1282
|
+
const nid = nodeId(sid);
|
|
1283
|
+
if (s.schema !== void 0 && s.schema !== null) {
|
|
1284
|
+
if (typeof s.schema !== "object") {
|
|
1285
|
+
throw new Error(
|
|
1286
|
+
`Step "${sid}": schema must be a JSON Schema object, e.g. { "type": "object", "properties": { ... } }. Got ${typeof s.schema} (${JSON.stringify(s.schema)}).`
|
|
1287
|
+
);
|
|
1288
|
+
}
|
|
1289
|
+
validateSchema(s.schema, sid);
|
|
1290
|
+
}
|
|
1291
|
+
const schema = s.schema && typeof s.schema === "object" ? s.schema : void 0;
|
|
1292
|
+
return {
|
|
1293
|
+
nodes: [{ id: nid, type: "human_feedback", name: sid, config: { title: s.title ?? sid }, input: { template: translate(s.prompt) }, output: { key: sid, ...schema ? { schema } : {} } }],
|
|
1294
|
+
edges: [],
|
|
1295
|
+
entryId: nid,
|
|
1296
|
+
exitIds: [nid]
|
|
1297
|
+
};
|
|
1298
|
+
}
|
|
1299
|
+
function expandCondition(s) {
|
|
1300
|
+
const sid = s.id || uid("cond");
|
|
1301
|
+
const nid = nodeId(sid);
|
|
1302
|
+
if (s.branches) {
|
|
1303
|
+
const branchExps = {};
|
|
1304
|
+
for (const [key, steps] of Object.entries(s.branches)) {
|
|
1305
|
+
branchExps[key] = expandSteps(Array.isArray(steps) ? steps : [steps]);
|
|
1306
|
+
}
|
|
1307
|
+
const allNodes = Object.values(branchExps).flatMap((e) => e.nodes);
|
|
1308
|
+
const allEdges = Object.values(branchExps).flatMap((e) => e.edges);
|
|
1309
|
+
const allExitIds = [...new Set(Object.values(branchExps).flatMap((e) => e.exitIds))];
|
|
1310
|
+
const branchEntryIds = Object.fromEntries(
|
|
1311
|
+
Object.entries(branchExps).map(([k, v]) => [k, v.entryId])
|
|
1312
|
+
);
|
|
1313
|
+
return {
|
|
1314
|
+
nodes: allNodes,
|
|
1315
|
+
edges: allEdges,
|
|
1316
|
+
entryId: nid,
|
|
1317
|
+
exitIds: allExitIds,
|
|
1318
|
+
branchEntryIds
|
|
1319
|
+
};
|
|
1320
|
+
}
|
|
1321
|
+
if (!s.then) {
|
|
1322
|
+
throw new Error(`Condition step "${sid}": must have either "then" or "branches"`);
|
|
1323
|
+
}
|
|
1324
|
+
const thenSteps = Array.isArray(s.then) ? s.then : [s.then];
|
|
1325
|
+
const elseSteps = s.else ? Array.isArray(s.else) ? s.else : [s.else] : [];
|
|
1326
|
+
const thenExp = expandSteps(thenSteps);
|
|
1327
|
+
const elseExp = expandSteps(elseSteps);
|
|
1328
|
+
return {
|
|
1329
|
+
nodes: [...thenExp.nodes, ...elseExp.nodes],
|
|
1330
|
+
edges: [...thenExp.edges, ...elseExp.edges],
|
|
1331
|
+
entryId: nid,
|
|
1332
|
+
exitIds: [...thenExp.exitIds, ...elseExp.exitIds],
|
|
1333
|
+
thenEntryId: thenExp.entryId,
|
|
1334
|
+
elseEntryId: elseExp.entryId
|
|
1335
|
+
};
|
|
1336
|
+
}
|
|
1337
|
+
function expandMap(s) {
|
|
1338
|
+
const sid = s.id;
|
|
1339
|
+
const nid = nodeId(sid);
|
|
1340
|
+
const inner = s.each;
|
|
1341
|
+
return {
|
|
1342
|
+
nodes: [{
|
|
1343
|
+
id: nid,
|
|
1344
|
+
type: "map",
|
|
1345
|
+
name: sid,
|
|
1346
|
+
source: `state.${s.source}`,
|
|
1347
|
+
itemKey: "item",
|
|
1348
|
+
config: { batchSize: s.batch ?? 50, maxConcurrency: s.concurrency ?? 5, innerConcurrency: s.concurrency ?? 5 },
|
|
1349
|
+
node: { type: "agent", input: inner.prompt ? { template: translate(inner.prompt) } : void 0, ...inner.schema && typeof inner.schema === "object" ? { schema: inner.schema } : {} },
|
|
1350
|
+
...s.reduce ? { reduce: { input: s.reduce.prompt ? { template: translate(s.reduce.prompt) } : void 0, ...s.reduce.schema && typeof s.reduce.schema === "object" ? { schema: s.reduce.schema } : {} } } : {},
|
|
1351
|
+
output: { key: sid }
|
|
1352
|
+
}],
|
|
1353
|
+
edges: [],
|
|
1354
|
+
entryId: nid,
|
|
1355
|
+
exitIds: [nid]
|
|
1356
|
+
};
|
|
1357
|
+
}
|
|
1358
|
+
function expandParallel(s) {
|
|
1359
|
+
const nodes = [];
|
|
1360
|
+
const edges = [];
|
|
1361
|
+
const entryIds = [];
|
|
1362
|
+
const exitIds = [];
|
|
1363
|
+
for (const step of s.steps) {
|
|
1364
|
+
const exp = expandStep(step);
|
|
1365
|
+
nodes.push(...exp.nodes);
|
|
1366
|
+
edges.push(...exp.edges);
|
|
1367
|
+
entryIds.push(exp.entryId);
|
|
1368
|
+
if (exp.exitIds.length > 0) exitIds.push(...exp.exitIds);
|
|
1369
|
+
}
|
|
1370
|
+
return { nodes, edges, entryId: entryIds[0], exitIds };
|
|
1371
|
+
}
|
|
1372
|
+
function expandEnd(s) {
|
|
1373
|
+
const sid = uid("end");
|
|
1374
|
+
const nid = nodeId(sid);
|
|
1375
|
+
return { nodes: [{ id: nid, type: "terminal", name: sid, status: s.status ?? "success" }], edges: [], entryId: nid, exitIds: [] };
|
|
1376
|
+
}
|
|
1377
|
+
function expandSteps(steps, fromStart = false) {
|
|
1378
|
+
if (steps.length === 0) return { nodes: [], edges: [], entryId: "END", exitIds: ["END"] };
|
|
1379
|
+
const allNodes = [];
|
|
1380
|
+
const allEdges = [];
|
|
1381
|
+
let prevExitIds = [];
|
|
1382
|
+
let firstEntryId = null;
|
|
1383
|
+
for (let i = 0; i < steps.length; i++) {
|
|
1384
|
+
const exp = expandStep(steps[i]);
|
|
1385
|
+
if (exp.nodes.length > 0) allNodes.push(...exp.nodes);
|
|
1386
|
+
if (exp.edges.length > 0) allEdges.push(...exp.edges);
|
|
1387
|
+
if (firstEntryId === null) firstEntryId = exp.entryId;
|
|
1388
|
+
if (prevExitIds.length > 0) addEdge(steps[i], exp, prevExitIds, allEdges);
|
|
1389
|
+
else if (fromStart && i === 0) addEdge(steps[i], exp, ["START"], allEdges);
|
|
1390
|
+
prevExitIds = exp.exitIds.length > 0 ? exp.exitIds : prevExitIds;
|
|
1391
|
+
}
|
|
1392
|
+
return { nodes: allNodes, edges: allEdges, entryId: firstEntryId || "END", exitIds: prevExitIds };
|
|
1393
|
+
}
|
|
1394
|
+
function toSafeStateExpr(expr) {
|
|
1395
|
+
const match = expr.match(/^([a-zA-Z_][a-zA-Z0-9_-]*)/);
|
|
1396
|
+
if (!match) return `state.${expr}`;
|
|
1397
|
+
const field = match[0];
|
|
1398
|
+
const rest = expr.slice(field.length);
|
|
1399
|
+
return `state["${field}"]${rest}`;
|
|
1400
|
+
}
|
|
1401
|
+
function addEdge(step, exp, fromIds, allEdges) {
|
|
1402
|
+
if (step.type === "condition") {
|
|
1403
|
+
const s = step;
|
|
1404
|
+
if (s.if.includes("{{")) {
|
|
1405
|
+
throw new Error(
|
|
1406
|
+
`Condition step "${s.id || "unnamed"}": the \`if\` field contains "{{". Use a plain state field name or JavaScript expression (e.g. "intent", "score >= 60"). Template markers {{...}} are only for \`prompt\` fields, not \`if\`. Found: "${s.if}"`
|
|
1407
|
+
);
|
|
1408
|
+
}
|
|
1409
|
+
if (s.branches) {
|
|
1410
|
+
const condExp = exp;
|
|
1411
|
+
const exprCode = toSafeStateExpr(s.if);
|
|
1412
|
+
const mapping = {};
|
|
1413
|
+
for (const [key, branchId] of Object.entries(condExp.branchEntryIds)) {
|
|
1414
|
+
if (branchId) mapping[key] = branchId;
|
|
1415
|
+
}
|
|
1416
|
+
for (const fromId of fromIds) allEdges.push({ from: fromId, type: "conditional", rule: { type: "expression", code: exprCode, mapping } });
|
|
1417
|
+
} else {
|
|
1418
|
+
const condExp = exp;
|
|
1419
|
+
const exprCode = `${toSafeStateExpr(s.if)} ? 'then' : 'else'`;
|
|
1420
|
+
const mapping = {};
|
|
1421
|
+
if (condExp.thenEntryId) mapping.then = condExp.thenEntryId;
|
|
1422
|
+
if (condExp.elseEntryId) mapping.else = condExp.elseEntryId;
|
|
1423
|
+
for (const fromId of fromIds) allEdges.push({ from: fromId, type: "conditional", rule: { type: "expression", code: exprCode, mapping } });
|
|
1424
|
+
}
|
|
1425
|
+
} else if (step.type === "parallel") {
|
|
1426
|
+
for (const fromId of fromIds) {
|
|
1427
|
+
for (const sub of step.steps) allEdges.push({ from: fromId, to: expandStep(sub).entryId });
|
|
1428
|
+
}
|
|
1429
|
+
} else {
|
|
1430
|
+
for (const fromId of fromIds) allEdges.push({ from: fromId, to: exp.entryId });
|
|
1431
|
+
}
|
|
1432
|
+
}
|
|
1433
|
+
function collectIds(steps) {
|
|
1434
|
+
const ids = [];
|
|
1435
|
+
function walk(s) {
|
|
1436
|
+
const id = s.type === "condition" ? s.id || uid("cond") : s.type === "parallel" ? s.id || uid("par") : s.type === "end" ? uid("end") : s.id || s.id || uid("human");
|
|
1437
|
+
if (s.type !== "end" && s.type !== "condition") ids.push(id);
|
|
1438
|
+
if (s.type === "condition") {
|
|
1439
|
+
const c = s;
|
|
1440
|
+
if (c.branches) {
|
|
1441
|
+
for (const steps2 of Object.values(c.branches)) {
|
|
1442
|
+
(Array.isArray(steps2) ? steps2 : [steps2]).forEach(walk);
|
|
1443
|
+
}
|
|
1444
|
+
} else {
|
|
1445
|
+
(Array.isArray(c.then) ? c.then : [c.then]).forEach(walk);
|
|
1446
|
+
if (c.else) (Array.isArray(c.else) ? c.else : [c.else]).forEach(walk);
|
|
1447
|
+
}
|
|
1448
|
+
}
|
|
1449
|
+
if (s.type === "parallel") s.steps.forEach(walk);
|
|
1450
|
+
}
|
|
1451
|
+
steps.forEach(walk);
|
|
1452
|
+
return [...new Set(ids)];
|
|
1453
|
+
}
|
|
1454
|
+
function collectSourceIds(steps) {
|
|
1455
|
+
const ids = [];
|
|
1456
|
+
function walk(s) {
|
|
1457
|
+
if (s.type === "map") ids.push(s.source);
|
|
1458
|
+
if (s.type === "condition") {
|
|
1459
|
+
const c = s;
|
|
1460
|
+
if (c.branches) {
|
|
1461
|
+
for (const steps2 of Object.values(c.branches)) {
|
|
1462
|
+
(Array.isArray(steps2) ? steps2 : [steps2]).forEach(walk);
|
|
1463
|
+
}
|
|
1464
|
+
} else {
|
|
1465
|
+
(Array.isArray(c.then) ? c.then : [c.then]).forEach(walk);
|
|
1466
|
+
if (c.else) (Array.isArray(c.else) ? c.else : [c.else]).forEach(walk);
|
|
1467
|
+
}
|
|
1468
|
+
}
|
|
1469
|
+
if (s.type === "parallel") s.steps.forEach(walk);
|
|
1470
|
+
}
|
|
1471
|
+
steps.forEach(walk);
|
|
1472
|
+
return [...new Set(ids)];
|
|
1473
|
+
}
|
|
1474
|
+
function expand(dsl) {
|
|
1475
|
+
_counter = 0;
|
|
1476
|
+
console.log(`[WF EXPAND] expanding workflow "${dsl.name}" | stepCount=${dsl.steps.length}`);
|
|
1477
|
+
const inputNode = {
|
|
1478
|
+
id: "n_input",
|
|
1479
|
+
type: "input",
|
|
1480
|
+
name: "input",
|
|
1481
|
+
output: { key: "input" }
|
|
1482
|
+
};
|
|
1483
|
+
const expanded = expandSteps(dsl.steps, true);
|
|
1484
|
+
const edges = expanded.entryId === "END" ? [{ from: "START", to: "n_input" }] : [
|
|
1485
|
+
...expanded.edges.map((e) => ({ ...e, from: e.from === "START" ? "n_input" : e.from })),
|
|
1486
|
+
{ from: "START", to: "n_input" }
|
|
1487
|
+
];
|
|
1488
|
+
const nodes = [inputNode, ...expanded.nodes];
|
|
1489
|
+
const ids = collectIds(dsl.steps);
|
|
1490
|
+
const sourceIds = collectSourceIds(dsl.steps);
|
|
1491
|
+
const fields = { input: { type: "string" } };
|
|
1492
|
+
for (const id of ids) fields[id] = inferFieldType(id);
|
|
1493
|
+
for (const id of sourceIds) {
|
|
1494
|
+
if (!fields[id]) fields[id] = inferFieldType(id);
|
|
1495
|
+
}
|
|
1496
|
+
const result = { version: "1.0", name: dsl.name, state: { fields }, nodes, edges };
|
|
1497
|
+
console.log(`[WF EXPAND] done | nodeCount=${result.nodes.length} | nodeIds=[${result.nodes.map((n) => `${n.id}:${n.type}`).join(", ")}] | fieldIds=[${Object.keys(fields).join(", ")}]`);
|
|
1498
|
+
return result;
|
|
1499
|
+
}
|
|
1500
|
+
var _counter;
|
|
1501
|
+
var init_normalize = __esm({
|
|
1502
|
+
"src/workflow/normalize.ts"() {
|
|
1503
|
+
"use strict";
|
|
1504
|
+
_counter = 0;
|
|
1505
|
+
}
|
|
1506
|
+
});
|
|
1507
|
+
|
|
1508
|
+
// src/workflow/compile.ts
|
|
1509
|
+
var compile_exports = {};
|
|
1510
|
+
__export(compile_exports, {
|
|
1511
|
+
compileWorkflow: () => compileWorkflow,
|
|
1512
|
+
validateDSL: () => validateDSL
|
|
1513
|
+
});
|
|
1514
|
+
function compileWorkflow(dsl, resolveAgent, checkpointer, trackingStore) {
|
|
1515
|
+
console.log(`[WF COMPILE] compiling "${dsl.name}" | stepCount=${dsl.steps.length}`);
|
|
1516
|
+
const ir = expand(dsl);
|
|
1517
|
+
validateAndThrow(ir);
|
|
1518
|
+
console.log(`[WF COMPILE] validation passed`);
|
|
1519
|
+
const StateAnnotation = buildStateAnnotation(ir.state?.fields);
|
|
1520
|
+
const builder = new import_langgraph16.StateGraph(StateAnnotation);
|
|
1521
|
+
for (const node of ir.nodes) {
|
|
1522
|
+
console.log(`[WF COMPILE] registering node: id=${node.id} type=${node.type} name=${node.name}`);
|
|
1523
|
+
const handler = createNodeHandler(node, resolveAgent, trackingStore);
|
|
1524
|
+
builder.addNode(node.id, handler);
|
|
1525
|
+
}
|
|
1526
|
+
for (const node of ir.nodes) {
|
|
1527
|
+
if (node.type === "terminal") {
|
|
1528
|
+
builder.addEdge(node.id, import_langgraph16.END);
|
|
1529
|
+
}
|
|
1530
|
+
}
|
|
1531
|
+
for (const edge of ir.edges) {
|
|
1532
|
+
const from = edge.from === "START" ? import_langgraph16.START : edge.from;
|
|
1533
|
+
if (edge.type === "conditional") {
|
|
1534
|
+
if (!edge.rule) {
|
|
1535
|
+
throw new Error(`Conditional edge from "${edge.from}" has no rule`);
|
|
1536
|
+
}
|
|
1537
|
+
const router = buildRouter(edge.rule);
|
|
1538
|
+
builder.addConditionalEdges(from, router, edge.rule.mapping);
|
|
1539
|
+
} else {
|
|
1540
|
+
const targets = Array.isArray(edge.to) ? edge.to : [edge.to];
|
|
1541
|
+
for (const to of targets) {
|
|
1542
|
+
builder.addEdge(from, to === "END" ? import_langgraph16.END : to);
|
|
1543
|
+
}
|
|
1544
|
+
}
|
|
1545
|
+
}
|
|
1546
|
+
const graph = builder.compile({ checkpointer, name: ir.name });
|
|
1547
|
+
console.log(`[WF COMPILE] graph compiled successfully, ready to run`);
|
|
1548
|
+
return graph;
|
|
1549
|
+
}
|
|
1550
|
+
function validateDSL(dsl) {
|
|
1551
|
+
const errors = [];
|
|
1552
|
+
const nodeIds = /* @__PURE__ */ new Set();
|
|
1553
|
+
for (const node of dsl.nodes) {
|
|
1554
|
+
if (nodeIds.has(node.id)) {
|
|
1555
|
+
errors.push({ type: "error", message: `Duplicate node id "${node.id}"` });
|
|
1556
|
+
}
|
|
1557
|
+
nodeIds.add(node.id);
|
|
1558
|
+
}
|
|
1559
|
+
const terminalIds = new Set(
|
|
1560
|
+
dsl.nodes.filter((n) => n.type === "terminal").map((n) => n.id)
|
|
1561
|
+
);
|
|
1562
|
+
const declaredFields = new Set(Object.keys(dsl.state?.fields ?? {}));
|
|
1563
|
+
for (const edge of dsl.edges) {
|
|
1564
|
+
if (edge.from !== "START" && !nodeIds.has(edge.from)) {
|
|
1565
|
+
errors.push({ type: "error", message: `Edge from "${edge.from}" references unknown node` });
|
|
1566
|
+
}
|
|
1567
|
+
if (edge.from !== "START" && terminalIds.has(edge.from)) {
|
|
1568
|
+
errors.push({ type: "error", message: `Terminal node "${edge.from}" cannot have outgoing edges` });
|
|
1569
|
+
}
|
|
1570
|
+
const targets = Array.isArray(edge.to) ? edge.to : edge.to ? [edge.to] : [];
|
|
1571
|
+
for (const to of targets) {
|
|
1572
|
+
if (to !== "END" && !nodeIds.has(to)) {
|
|
1573
|
+
errors.push({ type: "error", message: `Edge to "${to}" references unknown node` });
|
|
1574
|
+
}
|
|
1575
|
+
}
|
|
1576
|
+
if (edge.type === "conditional" && edge.rule) {
|
|
1577
|
+
for (const targetId of Object.values(edge.rule.mapping)) {
|
|
1578
|
+
if (targetId !== "END" && !nodeIds.has(targetId)) {
|
|
1579
|
+
errors.push({ type: "error", message: `Conditional edge mapping references unknown node "${targetId}"` });
|
|
1580
|
+
}
|
|
1581
|
+
}
|
|
1582
|
+
if (edge.rule.type === "state_field" && edge.rule.field) {
|
|
1583
|
+
if (!declaredFields.has(edge.rule.field)) {
|
|
1584
|
+
errors.push({ type: "warning", message: `Conditional edge reads "${edge.rule.field}" but it is not declared in state.fields` });
|
|
1585
|
+
}
|
|
1586
|
+
}
|
|
1587
|
+
}
|
|
1588
|
+
}
|
|
1589
|
+
for (const node of dsl.nodes) {
|
|
1590
|
+
if (node.type === "terminal") {
|
|
1591
|
+
const hasIncoming = dsl.edges.some((e) => {
|
|
1592
|
+
const targets = Array.isArray(e.to) ? e.to : e.to ? [e.to] : [];
|
|
1593
|
+
return targets.includes(node.id) || e.type === "conditional" && e.rule && Object.values(e.rule.mapping).includes(node.id);
|
|
1594
|
+
});
|
|
1595
|
+
if (!hasIncoming) {
|
|
1596
|
+
errors.push({ type: "warning", message: `Terminal node "${node.id}" has no incoming edge` });
|
|
1597
|
+
}
|
|
1598
|
+
}
|
|
1599
|
+
}
|
|
1600
|
+
return errors;
|
|
1601
|
+
}
|
|
1602
|
+
function validateAndThrow(dsl) {
|
|
1603
|
+
const errors = validateDSL(dsl);
|
|
1604
|
+
const critical = errors.filter((e) => e.type === "error");
|
|
1605
|
+
if (critical.length > 0) {
|
|
1606
|
+
throw new Error(critical.map((e) => e.message).join("; "));
|
|
1607
|
+
}
|
|
1608
|
+
}
|
|
1609
|
+
function buildRouter(rule) {
|
|
1610
|
+
if (rule.type === "state_field") {
|
|
1611
|
+
if (!rule.field) throw new Error("state_field rule requires a field name");
|
|
1612
|
+
return (state) => {
|
|
1613
|
+
const value = resolvePath(state, `state.${rule.field}`);
|
|
1614
|
+
const key = String(value);
|
|
1615
|
+
if (rule.mapping[key] !== void 0) return key;
|
|
1616
|
+
if (rule.mapping["default"] !== void 0) return "default";
|
|
1617
|
+
throw new Error(
|
|
1618
|
+
`Conditional router produced key "${key}" (from field "${rule.field}"), but it is not in mapping: ${JSON.stringify(Object.keys(rule.mapping))}`
|
|
1619
|
+
);
|
|
1620
|
+
};
|
|
1621
|
+
}
|
|
1622
|
+
if (rule.type === "expression") {
|
|
1623
|
+
if (!rule.code) throw new Error("expression rule requires code");
|
|
1624
|
+
const fn = new Function("state", `return ${rule.code}`);
|
|
1625
|
+
return (state) => {
|
|
1626
|
+
const value = fn(state);
|
|
1627
|
+
const key = String(value);
|
|
1628
|
+
if (rule.mapping[key] !== void 0) return key;
|
|
1629
|
+
if (rule.mapping["default"] !== void 0) return "default";
|
|
1630
|
+
throw new Error(
|
|
1631
|
+
`Conditional router produced key "${key}" (from expression "${rule.code}"), but it is not in mapping: ${JSON.stringify(Object.keys(rule.mapping))}`
|
|
1632
|
+
);
|
|
1633
|
+
};
|
|
1634
|
+
}
|
|
1635
|
+
throw new Error(`Unknown rule type: ${rule.type}`);
|
|
1636
|
+
}
|
|
1637
|
+
var import_langgraph16;
|
|
1638
|
+
var init_compile = __esm({
|
|
1639
|
+
"src/workflow/compile.ts"() {
|
|
1640
|
+
"use strict";
|
|
1641
|
+
import_langgraph16 = require("@langchain/langgraph");
|
|
1642
|
+
init_utils();
|
|
1643
|
+
init_normalize();
|
|
1644
|
+
}
|
|
1645
|
+
});
|
|
29
1646
|
|
|
30
1647
|
// src/index.ts
|
|
31
1648
|
var index_exports = {};
|
|
@@ -52,7 +1669,7 @@ __export(index_exports, {
|
|
|
52
1669
|
EmbeddingsLatticeManager: () => EmbeddingsLatticeManager,
|
|
53
1670
|
FileSystemSkillStore: () => FileSystemSkillStore,
|
|
54
1671
|
FilesystemBackend: () => FilesystemBackend,
|
|
55
|
-
HumanMessage: () =>
|
|
1672
|
+
HumanMessage: () => import_messages7.HumanMessage,
|
|
56
1673
|
InMemoryA2AApiKeyStore: () => InMemoryA2AApiKeyStore,
|
|
57
1674
|
InMemoryAssistantStore: () => InMemoryAssistantStore,
|
|
58
1675
|
InMemoryBindingStore: () => InMemoryBindingStore,
|
|
@@ -111,21 +1728,28 @@ __export(index_exports, {
|
|
|
111
1728
|
agentInstanceManager: () => agentInstanceManager,
|
|
112
1729
|
agentLatticeManager: () => agentLatticeManager,
|
|
113
1730
|
buildGrepResultsDict: () => buildGrepResultsDict,
|
|
1731
|
+
buildInput: () => buildInput,
|
|
114
1732
|
buildNamedVolumeName: () => buildNamedVolumeName,
|
|
115
1733
|
buildSandboxMetadataEnv: () => buildSandboxMetadataEnv,
|
|
116
1734
|
buildSkillFile: () => buildSkillFile,
|
|
1735
|
+
buildStateAnnotation: () => buildStateAnnotation,
|
|
117
1736
|
checkEmptyContent: () => checkEmptyContent,
|
|
118
1737
|
clearEncryptionKeyCache: () => clearEncryptionKeyCache,
|
|
1738
|
+
compileWorkflow: () => compileWorkflow,
|
|
119
1739
|
computeSandboxName: () => computeSandboxName,
|
|
120
1740
|
configureStores: () => configureStores,
|
|
1741
|
+
createAgentNode: () => createAgentNode,
|
|
121
1742
|
createAgentTeam: () => createAgentTeam,
|
|
122
1743
|
createExecuteSqlQueryTool: () => createExecuteSqlQueryTool,
|
|
123
1744
|
createFileData: () => createFileData,
|
|
1745
|
+
createHumanFeedbackNode: () => createHumanFeedbackNode,
|
|
124
1746
|
createInfoSqlTool: () => createInfoSqlTool,
|
|
125
1747
|
createListMetricsDataSourcesTool: () => createListMetricsDataSourcesTool,
|
|
126
1748
|
createListMetricsServersTool: () => createListMetricsServersTool,
|
|
127
1749
|
createListTablesSqlTool: () => createListTablesSqlTool,
|
|
1750
|
+
createMapNode: () => createMapNode,
|
|
128
1751
|
createModelSelectorMiddleware: () => createModelSelectorMiddleware,
|
|
1752
|
+
createNodeHandler: () => createNodeHandler,
|
|
129
1753
|
createProcessingAgent: () => createProcessingAgent,
|
|
130
1754
|
createQueryCheckerSqlTool: () => createQueryCheckerSqlTool,
|
|
131
1755
|
createQueryMetricDefinitionTool: () => createQueryMetricDefinitionTool,
|
|
@@ -138,6 +1762,7 @@ __export(index_exports, {
|
|
|
138
1762
|
createSchedulerMiddleware: () => createSchedulerMiddleware,
|
|
139
1763
|
createTeamMiddleware: () => createTeamMiddleware,
|
|
140
1764
|
createTeammateTools: () => createTeammateTools,
|
|
1765
|
+
createTerminalNode: () => createTerminalNode,
|
|
141
1766
|
createUnknownToolHandlerMiddleware: () => createUnknownToolHandlerMiddleware,
|
|
142
1767
|
createWidgetMiddleware: () => createWidgetMiddleware,
|
|
143
1768
|
decrypt: () => decrypt,
|
|
@@ -147,7 +1772,9 @@ __export(index_exports, {
|
|
|
147
1772
|
ensureBuiltinAgentsForTenant: () => ensureBuiltinAgentsForTenant,
|
|
148
1773
|
eventBus: () => eventBus,
|
|
149
1774
|
eventBusDefault: () => event_bus_default,
|
|
1775
|
+
expand: () => expand,
|
|
150
1776
|
extractFetcherError: () => extractFetcherError,
|
|
1777
|
+
extractOutput: () => extractOutput,
|
|
151
1778
|
fileDataToString: () => fileDataToString,
|
|
152
1779
|
formatContentWithLineNumbers: () => formatContentWithLineNumbers,
|
|
153
1780
|
formatGrepMatches: () => formatGrepMatches,
|
|
@@ -157,323 +1784,88 @@ __export(index_exports, {
|
|
|
157
1784
|
getAgentConfig: () => getAgentConfig,
|
|
158
1785
|
getAllAgentConfigs: () => getAllAgentConfigs,
|
|
159
1786
|
getAllBuiltInSkillMetas: () => getAllBuiltInSkillMetas,
|
|
160
|
-
getAllToolDefinitions: () => getAllToolDefinitions,
|
|
161
|
-
getBindingRegistry: () => getBindingRegistry,
|
|
162
|
-
getBuiltInSkillContent: () => getBuiltInSkillContent,
|
|
163
|
-
getBuiltInSkillMeta: () => getBuiltInSkillMeta,
|
|
164
|
-
getBuiltInSkillNames: () => getBuiltInSkillNames,
|
|
165
|
-
getCheckpointSaver: () => getCheckpointSaver,
|
|
166
|
-
getChunkBuffer: () => getChunkBuffer,
|
|
167
|
-
getEmbeddingsClient: () => getEmbeddingsClient,
|
|
168
|
-
getEmbeddingsLattice: () => getEmbeddingsLattice,
|
|
169
|
-
getEncryptionKey: () => getEncryptionKey,
|
|
170
|
-
getLoggerLattice: () => getLoggerLattice,
|
|
171
|
-
getModelLattice: () => getModelLattice,
|
|
172
|
-
getNextCronTime: () => getNextCronTime,
|
|
173
|
-
getQueueLattice: () => getQueueLattice,
|
|
174
|
-
getSandBoxManager: () => getSandBoxManager,
|
|
175
|
-
getScheduleLattice: () => getScheduleLattice,
|
|
176
|
-
getStoreLattice: () => getStoreLattice,
|
|
177
|
-
getToolClient: () => getToolClient,
|
|
178
|
-
getToolDefinition: () => getToolDefinition,
|
|
179
|
-
getToolLattice: () => getToolLattice,
|
|
180
|
-
getVectorStoreClient: () => getVectorStoreClient,
|
|
181
|
-
getVectorStoreLattice: () => getVectorStoreLattice,
|
|
182
|
-
globSearchFiles: () => globSearchFiles,
|
|
183
|
-
grepMatchesFromFiles: () => grepMatchesFromFiles,
|
|
184
|
-
grepSearchFiles: () => grepSearchFiles,
|
|
185
|
-
hasChunkBuffer: () => hasChunkBuffer,
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
/**
|
|
243
|
-
* 获取管理器实例(由子类实现)
|
|
244
|
-
*/
|
|
245
|
-
static getInstance() {
|
|
246
|
-
throw new Error("\u5FC5\u987B\u7531\u5B50\u7C7B\u5B9E\u73B0");
|
|
247
|
-
}
|
|
248
|
-
/**
|
|
249
|
-
* 构造完整的键名,包含类型前缀和租户ID
|
|
250
|
-
* @param tenantId 租户ID,全局共享使用 "default"
|
|
251
|
-
* @param key 原始键名
|
|
252
|
-
*/
|
|
253
|
-
getFullKey(tenantId, key) {
|
|
254
|
-
return `${this.getLatticeType()}:${tenantId}:${key}`;
|
|
255
|
-
}
|
|
256
|
-
// ========== 带租户的新API ==========
|
|
257
|
-
/**
|
|
258
|
-
* 带租户的注册项目
|
|
259
|
-
* @param tenantId 租户ID
|
|
260
|
-
* @param key 项目键名(不含前缀)
|
|
261
|
-
* @param item 项目实例
|
|
262
|
-
*/
|
|
263
|
-
registerWithTenant(tenantId, key, item) {
|
|
264
|
-
const fullKey = this.getFullKey(tenantId, key);
|
|
265
|
-
if (_BaseLatticeManager.registry.has(fullKey)) {
|
|
266
|
-
throw new Error(`\u9879\u76EE "${fullKey}" \u5DF2\u7ECF\u5B58\u5728\uFF0C\u65E0\u6CD5\u91CD\u590D\u6CE8\u518C`);
|
|
267
|
-
}
|
|
268
|
-
_BaseLatticeManager.registry.set(fullKey, item);
|
|
269
|
-
}
|
|
270
|
-
/**
|
|
271
|
-
* 带租户的获取指定项目(同步)
|
|
272
|
-
* @param tenantId 租户ID
|
|
273
|
-
* @param key 项目键名(不含前缀)
|
|
274
|
-
*/
|
|
275
|
-
getWithTenant(tenantId, key) {
|
|
276
|
-
const fullKey = this.getFullKey(tenantId, key);
|
|
277
|
-
return _BaseLatticeManager.registry.get(fullKey);
|
|
278
|
-
}
|
|
279
|
-
/**
|
|
280
|
-
* 带租户的获取指定项目(异步,支持从store回退加载)
|
|
281
|
-
* 如果内存中不存在且子类实现了loadItemFromStore,则尝试从store加载
|
|
282
|
-
* @param tenantId 租户ID
|
|
283
|
-
* @param key 项目键名(不含前缀)
|
|
284
|
-
* @returns 项目实例,如果未找到则返回undefined
|
|
285
|
-
*/
|
|
286
|
-
async getOrLoadWithTenant(tenantId, key) {
|
|
287
|
-
const item = this.getWithTenant(tenantId, key);
|
|
288
|
-
if (item !== void 0) {
|
|
289
|
-
return item;
|
|
290
|
-
}
|
|
291
|
-
if (this.loadItemFromStore) {
|
|
292
|
-
const loadedItem = await this.loadItemFromStore(tenantId, key);
|
|
293
|
-
if (loadedItem !== void 0) {
|
|
294
|
-
this.registerWithTenant(tenantId, key, loadedItem);
|
|
295
|
-
return loadedItem;
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
return void 0;
|
|
299
|
-
}
|
|
300
|
-
/**
|
|
301
|
-
* 带租户的检查项目是否存在(同步)
|
|
302
|
-
* @param tenantId 租户ID
|
|
303
|
-
* @param key 项目键名(不含前缀)
|
|
304
|
-
*/
|
|
305
|
-
hasWithTenant(tenantId, key) {
|
|
306
|
-
const fullKey = this.getFullKey(tenantId, key);
|
|
307
|
-
return _BaseLatticeManager.registry.has(fullKey);
|
|
308
|
-
}
|
|
309
|
-
/**
|
|
310
|
-
* 带租户的检查项目是否存在(异步,支持从store回退加载)
|
|
311
|
-
* 如果内存中不存在且子类实现了loadItemFromStore,则尝试从store加载
|
|
312
|
-
* @param tenantId 租户ID
|
|
313
|
-
* @param key 项目键名(不含前缀)
|
|
314
|
-
* @returns 如果存在或能从store加载则返回true
|
|
315
|
-
*/
|
|
316
|
-
async hasOrLoadWithTenant(tenantId, key) {
|
|
317
|
-
if (this.hasWithTenant(tenantId, key)) {
|
|
318
|
-
return true;
|
|
319
|
-
}
|
|
320
|
-
if (this.loadItemFromStore) {
|
|
321
|
-
const loadedItem = await this.loadItemFromStore(tenantId, key);
|
|
322
|
-
if (loadedItem !== void 0) {
|
|
323
|
-
this.registerWithTenant(tenantId, key, loadedItem);
|
|
324
|
-
return true;
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
return false;
|
|
328
|
-
}
|
|
329
|
-
/**
|
|
330
|
-
* 带租户的移除项目
|
|
331
|
-
* @param tenantId 租户ID
|
|
332
|
-
* @param key 项目键名(不含前缀)
|
|
333
|
-
*/
|
|
334
|
-
removeWithTenant(tenantId, key) {
|
|
335
|
-
const fullKey = this.getFullKey(tenantId, key);
|
|
336
|
-
return _BaseLatticeManager.registry.delete(fullKey);
|
|
337
|
-
}
|
|
338
|
-
/**
|
|
339
|
-
* 获取指定租户的所有项目
|
|
340
|
-
* @param tenantId 租户ID
|
|
341
|
-
*/
|
|
342
|
-
getAllByTenant(tenantId) {
|
|
343
|
-
const prefix = `${this.getLatticeType()}:${tenantId}:`;
|
|
344
|
-
const result = [];
|
|
345
|
-
for (const [key, value] of _BaseLatticeManager.registry.entries()) {
|
|
346
|
-
if (key.startsWith(prefix)) {
|
|
347
|
-
result.push(value);
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
return result;
|
|
351
|
-
}
|
|
352
|
-
/**
|
|
353
|
-
* 清空指定租户的所有项目
|
|
354
|
-
* @param tenantId 租户ID
|
|
355
|
-
*/
|
|
356
|
-
clearByTenant(tenantId) {
|
|
357
|
-
const prefix = `${this.getLatticeType()}:${tenantId}:`;
|
|
358
|
-
const keysToDelete = [];
|
|
359
|
-
for (const key of _BaseLatticeManager.registry.keys()) {
|
|
360
|
-
if (key.startsWith(prefix)) {
|
|
361
|
-
keysToDelete.push(key);
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
for (const key of keysToDelete) {
|
|
365
|
-
_BaseLatticeManager.registry.delete(key);
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
// ========== 向后兼容的旧API(使用 default 租户) ==========
|
|
369
|
-
/**
|
|
370
|
-
* 注册项目(向后兼容,使用 "default" 租户)
|
|
371
|
-
* @deprecated Use registerWithTenant(tenantId, key, item) instead
|
|
372
|
-
* @param key 项目键名(不含前缀)
|
|
373
|
-
* @param item 项目实例
|
|
374
|
-
*/
|
|
375
|
-
register(key, item) {
|
|
376
|
-
this.registerWithTenant("default", key, item);
|
|
377
|
-
}
|
|
378
|
-
/**
|
|
379
|
-
* 获取指定项目(向后兼容,使用 "default" 租户)
|
|
380
|
-
* @deprecated Use getWithTenant(tenantId, key) instead
|
|
381
|
-
* @param key 项目键名(不含前缀)
|
|
382
|
-
*/
|
|
383
|
-
get(key) {
|
|
384
|
-
return this.getWithTenant("default", key);
|
|
385
|
-
}
|
|
386
|
-
/**
|
|
387
|
-
* 获取所有当前类型的项目(向后兼容,包含所有租户)
|
|
388
|
-
*/
|
|
389
|
-
getAll() {
|
|
390
|
-
const prefix = `${this.getLatticeType()}:`;
|
|
391
|
-
const result = [];
|
|
392
|
-
for (const [key, value] of _BaseLatticeManager.registry.entries()) {
|
|
393
|
-
if (key.startsWith(prefix)) {
|
|
394
|
-
result.push(value);
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
return result;
|
|
398
|
-
}
|
|
399
|
-
/**
|
|
400
|
-
* 检查项目是否存在(向后兼容,使用 "default" 租户)
|
|
401
|
-
* @deprecated Use hasWithTenant(tenantId, key) instead
|
|
402
|
-
* @param key 项目键名(不含前缀)
|
|
403
|
-
*/
|
|
404
|
-
has(key) {
|
|
405
|
-
return this.hasWithTenant("default", key);
|
|
406
|
-
}
|
|
407
|
-
/**
|
|
408
|
-
* 移除项目(向后兼容,使用 "default" 租户)
|
|
409
|
-
* @deprecated Use removeWithTenant(tenantId, key) instead
|
|
410
|
-
* @param key 项目键名(不含前缀)
|
|
411
|
-
*/
|
|
412
|
-
remove(key) {
|
|
413
|
-
return this.removeWithTenant("default", key);
|
|
414
|
-
}
|
|
415
|
-
/**
|
|
416
|
-
* 清空当前类型的所有项目(向后兼容,包含所有租户)
|
|
417
|
-
*/
|
|
418
|
-
clear() {
|
|
419
|
-
const prefix = `${this.getLatticeType()}:`;
|
|
420
|
-
const keysToDelete = [];
|
|
421
|
-
for (const key of _BaseLatticeManager.registry.keys()) {
|
|
422
|
-
if (key.startsWith(prefix)) {
|
|
423
|
-
keysToDelete.push(key);
|
|
424
|
-
}
|
|
425
|
-
}
|
|
426
|
-
for (const key of keysToDelete) {
|
|
427
|
-
_BaseLatticeManager.registry.delete(key);
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
/**
|
|
431
|
-
* 获取当前类型的项目数量(向后兼容,包含所有租户)
|
|
432
|
-
*/
|
|
433
|
-
count() {
|
|
434
|
-
const prefix = `${this.getLatticeType()}:`;
|
|
435
|
-
let count = 0;
|
|
436
|
-
for (const key of _BaseLatticeManager.registry.keys()) {
|
|
437
|
-
if (key.startsWith(prefix)) {
|
|
438
|
-
count++;
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
return count;
|
|
442
|
-
}
|
|
443
|
-
/**
|
|
444
|
-
* 获取当前类型的项目键名列表(向后兼容,包含所有租户)
|
|
445
|
-
* 返回格式: {tenantId}:{key}
|
|
446
|
-
*/
|
|
447
|
-
keys() {
|
|
448
|
-
const prefix = `${this.getLatticeType()}:`;
|
|
449
|
-
const prefixLength = prefix.length;
|
|
450
|
-
const result = [];
|
|
451
|
-
for (const key of _BaseLatticeManager.registry.keys()) {
|
|
452
|
-
if (key.startsWith(prefix)) {
|
|
453
|
-
result.push(key.substring(prefixLength));
|
|
454
|
-
}
|
|
455
|
-
}
|
|
456
|
-
return result;
|
|
457
|
-
}
|
|
458
|
-
/**
|
|
459
|
-
* 获取当前类型的项目键名列表(仅指定租户,不含租户前缀)
|
|
460
|
-
* @param tenantId 租户ID
|
|
461
|
-
*/
|
|
462
|
-
keysByTenant(tenantId) {
|
|
463
|
-
const prefix = `${this.getLatticeType()}:${tenantId}:`;
|
|
464
|
-
const prefixLength = prefix.length;
|
|
465
|
-
const result = [];
|
|
466
|
-
for (const key of _BaseLatticeManager.registry.keys()) {
|
|
467
|
-
if (key.startsWith(prefix)) {
|
|
468
|
-
result.push(key.substring(prefixLength));
|
|
469
|
-
}
|
|
470
|
-
}
|
|
471
|
-
return result;
|
|
472
|
-
}
|
|
473
|
-
};
|
|
474
|
-
// 全局统一的Lattice注册表
|
|
475
|
-
_BaseLatticeManager.registry = /* @__PURE__ */ new Map();
|
|
476
|
-
var BaseLatticeManager = _BaseLatticeManager;
|
|
1787
|
+
getAllToolDefinitions: () => getAllToolDefinitions,
|
|
1788
|
+
getBindingRegistry: () => getBindingRegistry,
|
|
1789
|
+
getBuiltInSkillContent: () => getBuiltInSkillContent,
|
|
1790
|
+
getBuiltInSkillMeta: () => getBuiltInSkillMeta,
|
|
1791
|
+
getBuiltInSkillNames: () => getBuiltInSkillNames,
|
|
1792
|
+
getCheckpointSaver: () => getCheckpointSaver,
|
|
1793
|
+
getChunkBuffer: () => getChunkBuffer,
|
|
1794
|
+
getEmbeddingsClient: () => getEmbeddingsClient,
|
|
1795
|
+
getEmbeddingsLattice: () => getEmbeddingsLattice,
|
|
1796
|
+
getEncryptionKey: () => getEncryptionKey,
|
|
1797
|
+
getLoggerLattice: () => getLoggerLattice,
|
|
1798
|
+
getModelLattice: () => getModelLattice,
|
|
1799
|
+
getNextCronTime: () => getNextCronTime,
|
|
1800
|
+
getQueueLattice: () => getQueueLattice,
|
|
1801
|
+
getSandBoxManager: () => getSandBoxManager,
|
|
1802
|
+
getScheduleLattice: () => getScheduleLattice,
|
|
1803
|
+
getStoreLattice: () => getStoreLattice,
|
|
1804
|
+
getToolClient: () => getToolClient,
|
|
1805
|
+
getToolDefinition: () => getToolDefinition,
|
|
1806
|
+
getToolLattice: () => getToolLattice,
|
|
1807
|
+
getVectorStoreClient: () => getVectorStoreClient,
|
|
1808
|
+
getVectorStoreLattice: () => getVectorStoreLattice,
|
|
1809
|
+
globSearchFiles: () => globSearchFiles,
|
|
1810
|
+
grepMatchesFromFiles: () => grepMatchesFromFiles,
|
|
1811
|
+
grepSearchFiles: () => grepSearchFiles,
|
|
1812
|
+
hasChunkBuffer: () => hasChunkBuffer,
|
|
1813
|
+
invokeWithRetry: () => invokeWithRetry,
|
|
1814
|
+
isBuiltInSkill: () => isBuiltInSkill,
|
|
1815
|
+
isUsingDefaultKey: () => isUsingDefaultKey,
|
|
1816
|
+
isValidCronExpression: () => isValidCronExpression,
|
|
1817
|
+
isValidSandboxName: () => isValidSandboxName,
|
|
1818
|
+
isValidSkillName: () => isValidSkillName,
|
|
1819
|
+
loggerLatticeManager: () => loggerLatticeManager,
|
|
1820
|
+
mcpManager: () => mcpManager,
|
|
1821
|
+
metricsServerManager: () => metricsServerManager,
|
|
1822
|
+
modelLatticeManager: () => modelLatticeManager,
|
|
1823
|
+
normalizeSandboxName: () => normalizeSandboxName,
|
|
1824
|
+
parallelLimit: () => parallelLimit,
|
|
1825
|
+
parseCronExpression: () => parseCronExpression,
|
|
1826
|
+
parseSkillFrontmatter: () => parseSkillFrontmatter,
|
|
1827
|
+
performStringReplacement: () => performStringReplacement,
|
|
1828
|
+
queueLatticeManager: () => queueLatticeManager,
|
|
1829
|
+
registerAgentLattice: () => registerAgentLattice,
|
|
1830
|
+
registerAgentLatticeWithTenant: () => registerAgentLatticeWithTenant,
|
|
1831
|
+
registerAgentLattices: () => registerAgentLattices,
|
|
1832
|
+
registerCheckpointSaver: () => registerCheckpointSaver,
|
|
1833
|
+
registerChunkBuffer: () => registerChunkBuffer,
|
|
1834
|
+
registerEmbeddingsLattice: () => registerEmbeddingsLattice,
|
|
1835
|
+
registerExistingTool: () => registerExistingTool,
|
|
1836
|
+
registerLoggerLattice: () => registerLoggerLattice,
|
|
1837
|
+
registerModelLattice: () => registerModelLattice,
|
|
1838
|
+
registerQueueLattice: () => registerQueueLattice,
|
|
1839
|
+
registerScheduleLattice: () => registerScheduleLattice,
|
|
1840
|
+
registerStoreLattice: () => registerStoreLattice,
|
|
1841
|
+
registerTeammateAgent: () => registerTeammateAgent,
|
|
1842
|
+
registerToolLattice: () => registerToolLattice,
|
|
1843
|
+
registerVectorStoreLattice: () => registerVectorStoreLattice,
|
|
1844
|
+
renderTemplate: () => renderTemplate,
|
|
1845
|
+
resolvePath: () => resolvePath,
|
|
1846
|
+
sandboxLatticeManager: () => sandboxLatticeManager,
|
|
1847
|
+
sanitizeToolCallId: () => sanitizeToolCallId,
|
|
1848
|
+
scheduleLatticeManager: () => scheduleLatticeManager,
|
|
1849
|
+
setBindingRegistry: () => setBindingRegistry,
|
|
1850
|
+
skillLatticeManager: () => skillLatticeManager,
|
|
1851
|
+
sqlDatabaseManager: () => sqlDatabaseManager,
|
|
1852
|
+
storeLatticeManager: () => storeLatticeManager,
|
|
1853
|
+
toolLatticeManager: () => toolLatticeManager,
|
|
1854
|
+
truncateIfTooLong: () => truncateIfTooLong,
|
|
1855
|
+
unregisterTeammateAgent: () => unregisterTeammateAgent,
|
|
1856
|
+
updateFileData: () => updateFileData,
|
|
1857
|
+
validateAgentInput: () => validateAgentInput,
|
|
1858
|
+
validateDSL: () => validateDSL,
|
|
1859
|
+
validateEncryptionKey: () => validateEncryptionKey,
|
|
1860
|
+
validatePath: () => validatePath,
|
|
1861
|
+
validateSkillName: () => validateSkillName,
|
|
1862
|
+
validateToolInput: () => validateToolInput,
|
|
1863
|
+
vectorStoreLatticeManager: () => vectorStoreLatticeManager
|
|
1864
|
+
});
|
|
1865
|
+
module.exports = __toCommonJS(index_exports);
|
|
1866
|
+
|
|
1867
|
+
// src/model_lattice/ModelLatticeManager.ts
|
|
1868
|
+
init_BaseLatticeManager();
|
|
477
1869
|
|
|
478
1870
|
// src/model_lattice/ModelLattice.ts
|
|
479
1871
|
var import_deepseek = require("@langchain/deepseek");
|
|
@@ -722,6 +2114,7 @@ var import_zod = __toESM(require("zod"));
|
|
|
722
2114
|
|
|
723
2115
|
// src/tool_lattice/ToolLatticeManager.ts
|
|
724
2116
|
var import_tools = require("@langchain/core/tools");
|
|
2117
|
+
init_BaseLatticeManager();
|
|
725
2118
|
|
|
726
2119
|
// src/util/genUIMarkdown.ts
|
|
727
2120
|
var genUIMarkdown = (type, data) => {
|
|
@@ -1001,6 +2394,9 @@ function getBindingRegistry() {
|
|
|
1001
2394
|
return registry;
|
|
1002
2395
|
}
|
|
1003
2396
|
|
|
2397
|
+
// src/store_lattice/StoreLatticeManager.ts
|
|
2398
|
+
init_BaseLatticeManager();
|
|
2399
|
+
|
|
1004
2400
|
// src/store_lattice/InMemoryThreadStore.ts
|
|
1005
2401
|
var InMemoryThreadStore = class {
|
|
1006
2402
|
constructor() {
|
|
@@ -2666,6 +4062,14 @@ var InMemoryWorkflowTrackingStore = class {
|
|
|
2666
4062
|
this.steps.set(request.runId, runSteps);
|
|
2667
4063
|
return step;
|
|
2668
4064
|
}
|
|
4065
|
+
async upsertRunStep(request) {
|
|
4066
|
+
const runSteps = this.steps.get(request.runId) || [];
|
|
4067
|
+
const existing = runSteps.find(
|
|
4068
|
+
(s) => s.stepType === request.stepType && s.stepName === request.stepName
|
|
4069
|
+
);
|
|
4070
|
+
if (existing) return existing;
|
|
4071
|
+
return this.createRunStep(request);
|
|
4072
|
+
}
|
|
2669
4073
|
async updateRunStep(runId, stepId, updates) {
|
|
2670
4074
|
const runSteps = this.steps.get(runId);
|
|
2671
4075
|
if (!runSteps) return null;
|
|
@@ -5999,6 +7403,9 @@ ${serverKeys.map(
|
|
|
5999
7403
|
// src/tool_lattice/code_eval/index.ts
|
|
6000
7404
|
var import_zod16 = __toESM(require("zod"));
|
|
6001
7405
|
|
|
7406
|
+
// src/sandbox_lattice/SandboxLatticeManager.ts
|
|
7407
|
+
init_BaseLatticeManager();
|
|
7408
|
+
|
|
6002
7409
|
// src/deep_agent_new/backends/volumeFilesystem.ts
|
|
6003
7410
|
var VolumeFilesystem = class {
|
|
6004
7411
|
constructor(client, mountPrefix = "") {
|
|
@@ -7265,90 +8672,16 @@ var createBrowserGetInfoTool = ({ vmIsolation }) => {
|
|
|
7265
8672
|
};
|
|
7266
8673
|
|
|
7267
8674
|
// src/index.ts
|
|
7268
|
-
var
|
|
8675
|
+
var import_messages7 = require("@langchain/core/messages");
|
|
7269
8676
|
|
|
7270
8677
|
// src/agent_lattice/types.ts
|
|
7271
8678
|
var import_protocols = require("@axiom-lattice/protocols");
|
|
7272
8679
|
|
|
7273
|
-
// src/
|
|
7274
|
-
|
|
7275
|
-
|
|
7276
|
-
// src/memory_lattice/MemoryLatticeManager.ts
|
|
7277
|
-
var import_protocols2 = require("@axiom-lattice/protocols");
|
|
7278
|
-
var _MemoryLatticeManager = class _MemoryLatticeManager extends BaseLatticeManager {
|
|
7279
|
-
/**
|
|
7280
|
-
* 私有构造函数,防止外部直接实例化
|
|
7281
|
-
*/
|
|
7282
|
-
constructor() {
|
|
7283
|
-
super();
|
|
7284
|
-
}
|
|
7285
|
-
/**
|
|
7286
|
-
* 获取单例实例
|
|
7287
|
-
*/
|
|
7288
|
-
static getInstance() {
|
|
7289
|
-
if (!_MemoryLatticeManager.instance) {
|
|
7290
|
-
_MemoryLatticeManager.instance = new _MemoryLatticeManager();
|
|
7291
|
-
}
|
|
7292
|
-
return _MemoryLatticeManager.instance;
|
|
7293
|
-
}
|
|
7294
|
-
/**
|
|
7295
|
-
* 获取Lattice类型
|
|
7296
|
-
*/
|
|
7297
|
-
getLatticeType() {
|
|
7298
|
-
return "memory";
|
|
7299
|
-
}
|
|
7300
|
-
/**
|
|
7301
|
-
* 注册检查点保存器
|
|
7302
|
-
* @param key 保存器键名
|
|
7303
|
-
* @param saver 检查点保存器实例
|
|
7304
|
-
*/
|
|
7305
|
-
registerCheckpointSaver(key, saver) {
|
|
7306
|
-
if (_MemoryLatticeManager.checkpointSavers.has(key)) {
|
|
7307
|
-
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`);
|
|
7308
|
-
}
|
|
7309
|
-
_MemoryLatticeManager.checkpointSavers.set(key, saver);
|
|
7310
|
-
}
|
|
7311
|
-
/**
|
|
7312
|
-
* 获取检查点保存器
|
|
7313
|
-
* @param key 保存器键名
|
|
7314
|
-
*/
|
|
7315
|
-
getCheckpointSaver(key) {
|
|
7316
|
-
const saver = _MemoryLatticeManager.checkpointSavers.get(key);
|
|
7317
|
-
if (!saver) {
|
|
7318
|
-
throw new Error(`\u68C0\u67E5\u70B9\u4FDD\u5B58\u5668 "${key}" \u4E0D\u5B58\u5728`);
|
|
7319
|
-
}
|
|
7320
|
-
return saver;
|
|
7321
|
-
}
|
|
7322
|
-
/**
|
|
7323
|
-
* 获取所有已注册的检查点保存器键名
|
|
7324
|
-
*/
|
|
7325
|
-
getCheckpointSaverKeys() {
|
|
7326
|
-
return Array.from(_MemoryLatticeManager.checkpointSavers.keys());
|
|
7327
|
-
}
|
|
7328
|
-
/**
|
|
7329
|
-
* 检查检查点保存器是否存在
|
|
7330
|
-
* @param key 保存器键名
|
|
7331
|
-
*/
|
|
7332
|
-
hasCheckpointSaver(key) {
|
|
7333
|
-
return _MemoryLatticeManager.checkpointSavers.has(key);
|
|
7334
|
-
}
|
|
7335
|
-
/**
|
|
7336
|
-
* 移除检查点保存器
|
|
7337
|
-
* @param key 保存器键名
|
|
7338
|
-
*/
|
|
7339
|
-
removeCheckpointSaver(key) {
|
|
7340
|
-
return _MemoryLatticeManager.checkpointSavers.delete(key);
|
|
7341
|
-
}
|
|
7342
|
-
};
|
|
7343
|
-
// 检查点保存器注册表
|
|
7344
|
-
_MemoryLatticeManager.checkpointSavers = /* @__PURE__ */ new Map();
|
|
7345
|
-
var MemoryLatticeManager = _MemoryLatticeManager;
|
|
7346
|
-
var getCheckpointSaver = (key) => MemoryLatticeManager.getInstance().getCheckpointSaver(key);
|
|
7347
|
-
var registerCheckpointSaver = (key, saver) => MemoryLatticeManager.getInstance().registerCheckpointSaver(key, saver);
|
|
8680
|
+
// src/agent_lattice/AgentLatticeManager.ts
|
|
8681
|
+
init_BaseLatticeManager();
|
|
7348
8682
|
|
|
7349
|
-
// src/
|
|
7350
|
-
|
|
7351
|
-
registerCheckpointSaver("default", memory);
|
|
8683
|
+
// src/agent_lattice/builders/ReActAgentGraphBuilder.ts
|
|
8684
|
+
init_memory_lattice();
|
|
7352
8685
|
|
|
7353
8686
|
// src/agent_lattice/builders/state.ts
|
|
7354
8687
|
var import_zod41 = require("@langchain/langgraph/zod");
|
|
@@ -7753,81 +9086,429 @@ When iterating based on feedback:
|
|
|
7753
9086
|
3. **Look for repeated work** \u2014 if all test runs involved writing the same helper script, bundle that script into \`resources/scripts/\` and have the skill reference it instead.
|
|
7754
9087
|
4. **Explain the why** \u2014 if you're adding a constraint because of a failure, explain the context so the model understands when to apply it and when it's safe to deviate.
|
|
7755
9088
|
|
|
7756
|
-
Repeat the test \u2192 review \u2192 improve loop until the user is satisfied.
|
|
9089
|
+
Repeat the test \u2192 review \u2192 improve loop until the user is satisfied.
|
|
9090
|
+
|
|
9091
|
+
---
|
|
9092
|
+
|
|
9093
|
+
## Step 5: Optimize the Description (Optional)
|
|
9094
|
+
|
|
9095
|
+
After the skill works well, offer to optimize the description for better triggering accuracy.
|
|
9096
|
+
|
|
9097
|
+
### How Triggering Works
|
|
9098
|
+
|
|
9099
|
+
The agent sees skills as a list of name + description pairs. It decides whether to consult a skill based on that description. Important: agents only consult skills for tasks they can't easily handle on their own. Simple one-step queries may not trigger a skill even if the description matches \u2014 so make sure the description emphasizes the COMPLEX or SPECIALIZED nature of the task.
|
|
9100
|
+
|
|
9101
|
+
### Optimization Approach
|
|
9102
|
+
|
|
9103
|
+
1. Create 10-15 eval queries \u2014 a mix of should-trigger and should-not-trigger prompts
|
|
9104
|
+
2. For **should-trigger** (6-8): different phrasings of the same intent \u2014 formal, casual, indirect. Include cases where the user doesn't explicitly name the skill but clearly needs it
|
|
9105
|
+
3. For **should-not-trigger** (6-8): focus on near-misses \u2014 queries that share keywords but need something different. Don't make them obviously irrelevant
|
|
9106
|
+
4. Test the description against these queries and adjust based on misfires
|
|
9107
|
+
5. Show the user before/after and explain what changed
|
|
9108
|
+
|
|
9109
|
+
---
|
|
9110
|
+
|
|
9111
|
+
## Step 6: Package and Present
|
|
9112
|
+
|
|
9113
|
+
When the skill is ready:
|
|
9114
|
+
1. Verify the SKILL.md is at \`/root/.agents/skills/{skill-name}/SKILL.md\` with correct frontmatter
|
|
9115
|
+
2. Confirm all resource files are in place under \`resources/\`
|
|
9116
|
+
3. Tell the user the skill is ready and available at its path
|
|
9117
|
+
4. Remind them that the skill will now appear in the available skills list for any agent using the skill system
|
|
9118
|
+
|
|
9119
|
+
## Updating Existing Skills
|
|
9120
|
+
|
|
9121
|
+
When the user wants to improve an existing skill:
|
|
9122
|
+
1. Read the current SKILL.md from \`/root/.agents/skills/{skill-name}/SKILL.md\`
|
|
9123
|
+
2. Understand what it currently does and where it falls short
|
|
9124
|
+
3. Follow the same interview \u2192 draft \u2192 test \u2192 iterate loop
|
|
9125
|
+
4. **Preserve the original name** \u2014 the directory name and \`name\` frontmatter field should stay the same
|
|
9126
|
+
5. Write the updated version back to the same path
|
|
9127
|
+
|
|
9128
|
+
---
|
|
9129
|
+
|
|
9130
|
+
## Example Walkthrough
|
|
9131
|
+
|
|
9132
|
+
**User**: "I want a skill that helps me analyze CSV data"
|
|
9133
|
+
|
|
9134
|
+
**You** (interview):
|
|
9135
|
+
- "What kinds of analysis \u2014 summary stats, filtering, charting?"
|
|
9136
|
+
- "Are the CSVs always the same format or varied?"
|
|
9137
|
+
- "Should it output results as text, new CSV, or visualizations?"
|
|
9138
|
+
|
|
9139
|
+
**User**: "Mostly summary stats and filtering. The files vary but all have headers."
|
|
9140
|
+
|
|
9141
|
+
**You** (draft frontmatter):
|
|
9142
|
+
\`\`\`yaml
|
|
9143
|
+
---
|
|
9144
|
+
name: csv-analyzer
|
|
9145
|
+
description: Analyze CSV data with statistical summaries, filtering, and aggregation. Use whenever users want to explore, summarize, or extract insights from CSV files \u2014 even if they don't say "analyze" explicitly.
|
|
9146
|
+
metadata:
|
|
9147
|
+
category: data
|
|
9148
|
+
version: "1.0"
|
|
9149
|
+
---
|
|
9150
|
+
\`\`\`
|
|
9151
|
+
|
|
9152
|
+
**You** (draft body): Write a workflow that teaches the agent to:
|
|
9153
|
+
1. Inspect the CSV structure and headers
|
|
9154
|
+
2. Let the user choose analysis type (summary, filter, aggregate)
|
|
9155
|
+
3. Execute the analysis and present results clearly
|
|
9156
|
+
4. Handle edge cases: missing headers, empty files, mixed types
|
|
9157
|
+
|
|
9158
|
+
**You** (write): Create \`/root/.agents/skills/csv-analyzer/SKILL.md\`
|
|
9159
|
+
|
|
9160
|
+
**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."
|
|
9161
|
+
|
|
9162
|
+
Then iterate based on what the user says.
|
|
9163
|
+
`,
|
|
9164
|
+
"create-workflow": `---
|
|
9165
|
+
name: create-workflow
|
|
9166
|
+
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.
|
|
9167
|
+
license: MIT
|
|
9168
|
+
metadata:
|
|
9169
|
+
category: meta
|
|
9170
|
+
version: "3.0"
|
|
9171
|
+
---
|
|
9172
|
+
|
|
9173
|
+
# Workflow Designer
|
|
9174
|
+
|
|
9175
|
+
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.
|
|
9176
|
+
|
|
9177
|
+
Every step runs on the workflow's built-in general-purpose agent \u2014 no external agent registration needed.
|
|
9178
|
+
|
|
9179
|
+
## Core Principle: id is everything
|
|
9180
|
+
|
|
9181
|
+
A step's \`id\` serves triple duty:
|
|
9182
|
+
1. **Node identifier** in the graph
|
|
9183
|
+
2. **State key** \u2014 output is stored at \`state.<id>\`
|
|
9184
|
+
3. **Template reference** \u2014 downstream steps use \`{{id}}\` to read it
|
|
9185
|
+
|
|
9186
|
+
If you omit \`id\`, a unique identifier is auto-generated (but you won't be able to reference the output).
|
|
9187
|
+
|
|
9188
|
+
## Step Types
|
|
9189
|
+
|
|
9190
|
+
### agent \u2014 a step for the workflow's built-in agent
|
|
9191
|
+
|
|
9192
|
+
\`\`\`json
|
|
9193
|
+
{ "id": "classify", "name": "Classify Intent", "prompt": "Classify the intent of: {{input}}", "schema": { "type": "object", "properties": { "intent": { "type": "string" } } } }
|
|
9194
|
+
\`\`\`
|
|
9195
|
+
|
|
9196
|
+
| Field | Required | Description |
|
|
9197
|
+
|-------|----------|-------------|
|
|
9198
|
+
| id | no | State key for referencing output. Auto-generated if omitted, but required if downstream steps reference this step via \`{{id}}\` |
|
|
9199
|
+
| name | no | Human-readable label for this step |
|
|
9200
|
+
| prompt | yes | Task description with {{id}} refs |
|
|
9201
|
+
| 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.
|
|
9202
|
+
|
|
9203
|
+
**Schema Rules (MUST follow \u2014 shorthand is rejected):**
|
|
9204
|
+
- Always wrap in \`{ "type": "object", "properties": { ... } }\`
|
|
9205
|
+
- Each property must be \`{ "type": "string"|"number"|"boolean"|"array"|"object" }\`
|
|
9206
|
+
- Arrays need \`"items"\`: \`{ "type": "array", "items": { "type": "string" } }\`
|
|
9207
|
+
- \u274C \`{ "field": "string" }\` \u2014 REJECTED (no "type"/"properties" wrapper)
|
|
9208
|
+
- \u274C \`{ "schema": { "intent": "string" } }\` \u2014 REJECTED (legacy shorthand)
|
|
9209
|
+
|
|
9210
|
+
The agent's response is stored at \`state.<id>\` (or an auto-generated key if \`id\` is omitted).
|
|
9211
|
+
|
|
9212
|
+
### condition \u2014 branch on state
|
|
9213
|
+
|
|
9214
|
+
**Binary (then/else):**
|
|
9215
|
+
|
|
9216
|
+
\`\`\`json
|
|
9217
|
+
{ "type": "condition", "if": "intent",
|
|
9218
|
+
"then": { "id": "support", "name": "Handle Support", "prompt": "Handle support: {{input}}" },
|
|
9219
|
+
"else": { "id": "sales", "name": "Handle Sales", "prompt": "Handle sales: {{input}}" }
|
|
9220
|
+
}
|
|
9221
|
+
\`\`\`
|
|
9222
|
+
|
|
9223
|
+
| Field | Required | Description |
|
|
9224
|
+
|-------|----------|-------------|
|
|
9225
|
+
| 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. |
|
|
9226
|
+
| then | yes | Step(s) to run when condition is truthy |
|
|
9227
|
+
| else | no | Step(s) to run when condition is falsy |
|
|
9228
|
+
|
|
9229
|
+
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.
|
|
9230
|
+
|
|
9231
|
+
**Switch (branches):**
|
|
9232
|
+
|
|
9233
|
+
When branching on a discrete set of known values, use \`branches\` for cleaner multi-way routing:
|
|
9234
|
+
|
|
9235
|
+
\`\`\`json
|
|
9236
|
+
{ "type": "condition", "if": "intent",
|
|
9237
|
+
"branches": {
|
|
9238
|
+
"support": { "id": "support", "prompt": "Handle support: {{input}}" },
|
|
9239
|
+
"sales": { "id": "sales", "prompt": "Handle sales: {{input}}" },
|
|
9240
|
+
"billing": { "id": "billing", "prompt": "Handle billing: {{input}}" },
|
|
9241
|
+
"default": { "id": "fallback", "prompt": "Send to human: {{input}}" }
|
|
9242
|
+
}
|
|
9243
|
+
}
|
|
9244
|
+
\`\`\`
|
|
9245
|
+
|
|
9246
|
+
| Field | Required | Description |
|
|
9247
|
+
|-------|----------|-------------|
|
|
9248
|
+
| if | yes | State field whose STRING VALUE is matched against branch keys. **Same rule \u2014 \`{{}}\` is FORBIDDEN here.** |
|
|
9249
|
+
| branches | yes | Map of value \u2192 step(s). \`"default"\` key is a catch-all for unmatched values |
|
|
9250
|
+
| then/else | no | Not used when branches is present |
|
|
9251
|
+
|
|
9252
|
+
Unlike \`then\`/\`else\` (truthy/falsy ternary), \`branches\` does exact string match against the state field value. Always include a \`"default"\` branch.
|
|
9253
|
+
|
|
9254
|
+
### human \u2014 pause for human input
|
|
9255
|
+
|
|
9256
|
+
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\`.
|
|
9257
|
+
|
|
9258
|
+
\`\`\`json
|
|
9259
|
+
{ "id": "review", "type": "human",
|
|
9260
|
+
"title": "Approval",
|
|
9261
|
+
"prompt": "Present the following draft to the user for approval. Ask whether to approve or reject, and collect any comments.\\n\\nDraft:\\n{{draft}}",
|
|
9262
|
+
"schema": { "type": "object", "properties": { "approved": { "type": "boolean" }, "comments": { "type": "string" } } }
|
|
9263
|
+
}
|
|
9264
|
+
\`\`\`
|
|
9265
|
+
|
|
9266
|
+
Access results with dot notation: \`{{review.approved}}\`, \`{{review.comments}}\`. Use \`schema\` to constrain the agent's output.
|
|
9267
|
+
|
|
9268
|
+
| Field | Required | Description |
|
|
9269
|
+
|-------|----------|-------------|
|
|
9270
|
+
| id | no | State key for the agent's structured output |
|
|
9271
|
+
| type | yes | Must be \`"human"\` |
|
|
9272
|
+
| 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..." |
|
|
9273
|
+
| title | no | Display label for the human step |
|
|
9274
|
+
| schema | no | JSON Schema constraining the agent's structured output format |
|
|
9275
|
+
|
|
9276
|
+
### map \u2014 iterate over an array
|
|
9277
|
+
|
|
9278
|
+
\`\`\`json
|
|
9279
|
+
{ "id": "results", "type": "map",
|
|
9280
|
+
"source": "items",
|
|
9281
|
+
"each": { "prompt": "Audit: {{item}}", "schema": { "type": "object", "properties": { "result": { "type": "string" } } } },
|
|
9282
|
+
"batch": 10, "concurrency": 3
|
|
9283
|
+
}
|
|
9284
|
+
\`\`\`
|
|
9285
|
+
|
|
9286
|
+
| Field | Required | Description |
|
|
9287
|
+
|-------|----------|-------------|
|
|
9288
|
+
| id | yes | Output key for the results array |
|
|
9289
|
+
| source | yes | id of the step whose output is the array to iterate |
|
|
9290
|
+
| each | yes | Step applied to each element. Use {{item}} for the current element |
|
|
9291
|
+
| reduce | no | Step to aggregate results |
|
|
9292
|
+
| batch | no | Items per batch (default 50) |
|
|
9293
|
+
| concurrency | no | Max parallel items (default 5) |
|
|
9294
|
+
|
|
9295
|
+
### parallel \u2014 fixed fan-out
|
|
9296
|
+
|
|
9297
|
+
\`\`\`json
|
|
9298
|
+
{ "type": "parallel", "steps": [
|
|
9299
|
+
{ "id": "legal", "prompt": "Legal review: {{input}}" },
|
|
9300
|
+
{ "id": "finance", "prompt": "Finance: {{input}}" }
|
|
9301
|
+
]}
|
|
9302
|
+
\`\`\`
|
|
9303
|
+
|
|
9304
|
+
All steps run simultaneously. After all complete, execution continues to the next step.
|
|
9305
|
+
|
|
9306
|
+
### end \u2014 terminate the workflow
|
|
9307
|
+
|
|
9308
|
+
\`\`\`json
|
|
9309
|
+
{ "type": "end" }
|
|
9310
|
+
\`\`\`
|
|
9311
|
+
|
|
9312
|
+
Always include at the end of the steps array. \`status\` defaults to "success".
|
|
9313
|
+
|
|
9314
|
+
**Number of terminal nodes:**
|
|
9315
|
+
|
|
9316
|
+
- **Every workflow MUST have at least one \`{ "type": "end" }\`** \u2014 without it, the graph hangs at the last node.
|
|
9317
|
+
- **One is enough** even for complex workflows: all branches can converge to a single \`end\` node (parallel fan-in, condition branches rejoining, etc.).
|
|
9318
|
+
- **Use multiple end nodes ONLY when different branches need different \`status\`** values \u2014 e.g., success path vs failure path:
|
|
9319
|
+
|
|
9320
|
+
\`\`\`json
|
|
9321
|
+
{ "type": "condition", "if": "score >= 60",
|
|
9322
|
+
"then": { "type": "end", "status": "success" },
|
|
9323
|
+
"else": { "type": "end", "status": "failed" }
|
|
9324
|
+
}
|
|
9325
|
+
\`\`\`
|
|
9326
|
+
|
|
9327
|
+
- 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.
|
|
9328
|
+
|
|
9329
|
+
## Template Syntax
|
|
9330
|
+
|
|
9331
|
+
| Syntax | Resolves to | When to use |
|
|
9332
|
+
|--------|------------|-------------|
|
|
9333
|
+
| \`{{input}}\` | Initial user message | First step or any step needing the original question |
|
|
9334
|
+
| \`{{id}}\` | Output of step with given id | Referencing any upstream step's result |
|
|
9335
|
+
| \`{{item}}\` | Current element in map iteration | Inside map \`each.prompt\` |
|
|
9336
|
+
|
|
9337
|
+
## \u26A0\uFE0F CRITICAL: \`{{}}\` is ONLY for \`prompt\` fields
|
|
9338
|
+
|
|
9339
|
+
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.
|
|
9340
|
+
|
|
9341
|
+
**Common mistake the AI makes:**
|
|
9342
|
+
\`\`\`json
|
|
9343
|
+
// \u274C WRONG \u2014 {{}} does not belong in if:
|
|
9344
|
+
{ "type": "condition", "if": "{{intent}}", "then": {...}, "else": {...} }
|
|
9345
|
+
|
|
9346
|
+
// \u2705 CORRECT \u2014 if is a plain expression:
|
|
9347
|
+
{ "type": "condition", "if": "intent", "then": {...}, "else": {...} }
|
|
9348
|
+
\`\`\`
|
|
9349
|
+
|
|
9350
|
+
## What You NEVER Write
|
|
7757
9351
|
|
|
7758
|
-
|
|
9352
|
+
The engine auto-generates these \u2014 do NOT include them in your DSL:
|
|
7759
9353
|
|
|
7760
|
-
|
|
9354
|
+
- **state.fields** \u2014 auto-declared from every \`id\`
|
|
9355
|
+
- **edges** \u2014 auto-generated from step order (linear) and types (fan-out for parallel, conditional for condition)
|
|
9356
|
+
- **output.key** \u2014 always equals \`id\`
|
|
9357
|
+
- **version** \u2014 always "1.0" internally
|
|
9358
|
+
- **node IDs** \u2014 prefixed internally to avoid conflicts with state channel names
|
|
9359
|
+
- **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.
|
|
7761
9360
|
|
|
7762
|
-
|
|
9361
|
+
## Design Patterns
|
|
7763
9362
|
|
|
7764
|
-
###
|
|
9363
|
+
### Pattern 1: Linear Pipeline
|
|
7765
9364
|
|
|
7766
|
-
|
|
9365
|
+
\`\`\`json
|
|
9366
|
+
{
|
|
9367
|
+
"name": "knowledge-qa",
|
|
9368
|
+
"steps": [
|
|
9369
|
+
{ "id": "research", "name": "Research Topic", "prompt": "Research: {{input}}", "schema": { "type": "object", "properties": { "findings": { "type": "string" } } } },
|
|
9370
|
+
{ "id": "answer", "name": "Write Answer", "prompt": "Write answer based on: {{research}}", "schema": { "type": "object", "properties": { "answer": { "type": "string" } } } },
|
|
9371
|
+
{ "type": "end" }
|
|
9372
|
+
]
|
|
9373
|
+
}
|
|
9374
|
+
\`\`\`
|
|
7767
9375
|
|
|
7768
|
-
###
|
|
9376
|
+
### Pattern 2: Classify then Route
|
|
7769
9377
|
|
|
7770
|
-
|
|
7771
|
-
|
|
7772
|
-
|
|
7773
|
-
|
|
7774
|
-
|
|
9378
|
+
\`\`\`json
|
|
9379
|
+
{
|
|
9380
|
+
"name": "customer-router",
|
|
9381
|
+
"steps": [
|
|
9382
|
+
{ "id": "intent", "name": "Classify Intent", "prompt": "Classify: {{input}}", "schema": { "type": "object", "properties": { "intent": { "type": "string" } } } },
|
|
9383
|
+
{ "type": "condition", "if": "intent",
|
|
9384
|
+
"then": { "id": "support", "name": "Handle Support", "prompt": "Handle support: {{input}}", "schema": { "type": "object", "properties": { "response": { "type": "string" } } } },
|
|
9385
|
+
"else": { "id": "sales", "name": "Handle Sales", "prompt": "Handle sales: {{input}}", "schema": { "type": "object", "properties": { "response": { "type": "string" } } } }
|
|
9386
|
+
},
|
|
9387
|
+
{ "type": "end" }
|
|
9388
|
+
]
|
|
9389
|
+
}
|
|
9390
|
+
\`\`\`
|
|
7775
9391
|
|
|
7776
|
-
|
|
9392
|
+
### Pattern 2b: Classify then Switch
|
|
7777
9393
|
|
|
7778
|
-
|
|
9394
|
+
For routing to 3+ categories, use \`branches\` instead of nested \`then\`/\`else\`:
|
|
7779
9395
|
|
|
7780
|
-
|
|
7781
|
-
|
|
7782
|
-
|
|
7783
|
-
|
|
7784
|
-
|
|
9396
|
+
\`\`\`json
|
|
9397
|
+
{
|
|
9398
|
+
"name": "ticket-router",
|
|
9399
|
+
"steps": [
|
|
9400
|
+
{ "id": "intent", "name": "Classify", "prompt": "Classify: {{input}}", "schema": { "type": "object", "properties": { "category": { "type": "string" } } } },
|
|
9401
|
+
{ "type": "condition", "if": "intent.category",
|
|
9402
|
+
"branches": {
|
|
9403
|
+
"support": { "id": "support", "prompt": "Handle support: {{input}}" },
|
|
9404
|
+
"sales": { "id": "sales", "prompt": "Handle sales: {{input}}" },
|
|
9405
|
+
"billing": { "id": "billing", "prompt": "Handle billing: {{input}}" },
|
|
9406
|
+
"default": { "id": "fallback", "prompt": "Send to human: {{input}}" }
|
|
9407
|
+
}
|
|
9408
|
+
},
|
|
9409
|
+
{ "type": "end" }
|
|
9410
|
+
]
|
|
9411
|
+
}
|
|
9412
|
+
\`\`\`
|
|
9413
|
+
|
|
9414
|
+
### Pattern 3: Extract \u2192 Review \u2192 Approve
|
|
9415
|
+
|
|
9416
|
+
\`\`\`json
|
|
9417
|
+
{
|
|
9418
|
+
"name": "approval-flow",
|
|
9419
|
+
"steps": [
|
|
9420
|
+
{ "id": "draft", "name": "Draft Response", "prompt": "Draft a response to: {{input}}", "schema": { "type": "object", "properties": { "content": { "type": "string" } } } },
|
|
9421
|
+
{ "id": "review", "type": "human",
|
|
9422
|
+
"title": "Approval",
|
|
9423
|
+
"prompt": "Present the draft below to the user for approval. Ask whether to approve or reject with comments.\\n\\nDraft:\\n{{draft}}",
|
|
9424
|
+
"schema": { "type": "object", "properties": { "approved": { "type": "boolean" }, "comments": { "type": "string" } } } },
|
|
9425
|
+
{ "type": "condition", "if": "review.approved",
|
|
9426
|
+
"then": { "id": "published", "name": "Publish", "prompt": "Publish: {{draft}}", "schema": { "type": "object", "properties": { "status": { "type": "string" } } } },
|
|
9427
|
+
"else": { "id": "revised", "name": "Revise", "prompt": "Revise based on: {{review.comments}}", "schema": { "type": "object", "properties": { "content": { "type": "string" } } } }
|
|
9428
|
+
},
|
|
9429
|
+
{ "type": "end" }
|
|
9430
|
+
]
|
|
9431
|
+
}
|
|
9432
|
+
\`\`\`
|
|
7785
9433
|
|
|
7786
|
-
|
|
9434
|
+
### Pattern 4: Parallel Research
|
|
9435
|
+
|
|
9436
|
+
\`\`\`json
|
|
9437
|
+
{
|
|
9438
|
+
"name": "due-diligence",
|
|
9439
|
+
"steps": [
|
|
9440
|
+
{ "id": "info", "name": "Gather Info", "prompt": "Gather info: {{input}}", "schema": { "type": "object", "properties": { "rawData": { "type": "string" } } } },
|
|
9441
|
+
{ "type": "parallel", "steps": [
|
|
9442
|
+
{ "id": "legal", "name": "Legal Review", "prompt": "Legal review: {{info}}", "schema": { "type": "object", "properties": { "risks": { "type": "array", "items": { "type": "string" } } } } },
|
|
9443
|
+
{ "id": "finance", "name": "Finance Review", "prompt": "Finance review: {{info}}", "schema": { "type": "object", "properties": { "score": { "type": "number" } } } },
|
|
9444
|
+
{ "id": "market", "name": "Market Analysis", "prompt": "Market analysis: {{info}}", "schema": { "type": "object", "properties": { "trend": { "type": "string" } } } }
|
|
9445
|
+
]},
|
|
9446
|
+
{ "id": "synthesis", "name": "Synthesize", "prompt": "Synthesize: legal={{legal}} finance={{finance}} market={{market}}", "schema": { "type": "object", "properties": { "report": { "type": "string" } } } },
|
|
9447
|
+
{ "type": "end" }
|
|
9448
|
+
]
|
|
9449
|
+
}
|
|
9450
|
+
\`\`\`
|
|
7787
9451
|
|
|
7788
|
-
|
|
7789
|
-
|
|
7790
|
-
|
|
7791
|
-
|
|
7792
|
-
|
|
7793
|
-
|
|
9452
|
+
### Pattern 5: Batch Map + Reduce
|
|
9453
|
+
|
|
9454
|
+
\`\`\`json
|
|
9455
|
+
{
|
|
9456
|
+
"name": "sentiment-analysis",
|
|
9457
|
+
"steps": [
|
|
9458
|
+
{ "id": "posts", "name": "Scrape Posts", "prompt": "Scrape posts about: {{input}}", "schema": { "type": "object", "properties": { "posts": { "type": "array", "items": { "type": "object", "properties": { "text": { "type": "string" } } } } } } },
|
|
9459
|
+
{ "id": "sentiments", "type": "map", "source": "posts",
|
|
9460
|
+
"each": { "prompt": "Analyze sentiment: {{item}}", "schema": { "type": "object", "properties": { "sentiment": { "type": "string" } } } },
|
|
9461
|
+
"reduce": { "prompt": "Summarize: {{sentiments}}", "schema": { "type": "object", "properties": { "summary": { "type": "string" } } } }
|
|
9462
|
+
},
|
|
9463
|
+
{ "id": "report", "name": "Generate Report", "prompt": "Generate report from: {{sentiments}}", "schema": { "type": "object", "properties": { "report": { "type": "string" } } } },
|
|
9464
|
+
{ "type": "end" }
|
|
9465
|
+
]
|
|
9466
|
+
}
|
|
9467
|
+
\`\`\`
|
|
7794
9468
|
|
|
7795
|
-
|
|
9469
|
+
## Step 1: Understand the Process
|
|
7796
9470
|
|
|
7797
|
-
|
|
9471
|
+
Ask the user:
|
|
9472
|
+
- What are the steps in order?
|
|
9473
|
+
- Are there branches (if condition then A else B)?
|
|
9474
|
+
- Can any steps run in parallel?
|
|
9475
|
+
- Is human approval/review needed?
|
|
9476
|
+
- What data flows between steps?
|
|
7798
9477
|
|
|
7799
|
-
|
|
9478
|
+
## Step 2: Prepare Dependencies
|
|
7800
9479
|
|
|
7801
|
-
|
|
7802
|
-
- "What kinds of analysis \u2014 summary stats, filtering, charting?"
|
|
7803
|
-
- "Are the CSVs always the same format or varied?"
|
|
7804
|
-
- "Should it output results as text, new CSV, or visualizations?"
|
|
9480
|
+
1. Call \`list_tools\` to see available tools for the workflow agent.
|
|
7805
9481
|
|
|
7806
|
-
|
|
9482
|
+
## Step 3: Write the DSL
|
|
7807
9483
|
|
|
7808
|
-
|
|
7809
|
-
\`\`\`yaml
|
|
7810
|
-
---
|
|
7811
|
-
name: csv-analyzer
|
|
7812
|
-
description: Analyze CSV data with statistical summaries, filtering, and aggregation. Use whenever users want to explore, summarize, or extract insights from CSV files \u2014 even if they don't say "analyze" explicitly.
|
|
7813
|
-
metadata:
|
|
7814
|
-
category: data
|
|
7815
|
-
version: "1.0"
|
|
7816
|
-
---
|
|
7817
|
-
\`\`\`
|
|
9484
|
+
Use \`create_workflow\` with \`skillLoaded: true\`. Never write \`state.fields\`, \`edges\`, \`version\`, or \`output.key\` \u2014 they are auto-generated.
|
|
7818
9485
|
|
|
7819
|
-
**
|
|
7820
|
-
|
|
7821
|
-
|
|
7822
|
-
|
|
7823
|
-
|
|
9486
|
+
**Checklist before calling:**
|
|
9487
|
+
- Every step that produces data referenced downstream has an \`id\`
|
|
9488
|
+
- Every agent/map-each step has a valid \`schema\` in standard JSON Schema format (with \`"type": "object"\` and \`"properties"\`)
|
|
9489
|
+
- Schema uses \`{ "type": "object", "properties": { ... } }\` \u2014 \`true\` and legacy \`{ "field": "string" }\` are REJECTED
|
|
9490
|
+
- Downstream steps reference upstream data with \`{{id}}\`
|
|
9491
|
+
- **Condition \`if\` fields do NOT use \`{{}}\`** \u2014 they are plain expressions like \`"intent"\` or \`"score >= 60"\`
|
|
9492
|
+
- Condition steps have \`then\`/\`else\` (binary) or \`branches\` (switch)
|
|
9493
|
+
- Human steps have \`schema\` constraining the agent's structured output
|
|
9494
|
+
- Map steps have \`source\` pointing to an existing step id
|
|
9495
|
+
- Parallel steps have sibling steps with unique \`id\`s
|
|
9496
|
+
- Workflow ends with \`{ "type": "end" }\`
|
|
9497
|
+
- Use \`human\` step type for user interaction (clarify middleware is built-in)
|
|
7824
9498
|
|
|
7825
|
-
|
|
9499
|
+
## Step 4: Test
|
|
7826
9500
|
|
|
7827
|
-
|
|
9501
|
+
After creating, optionally call \`validate_workflow(id)\` to check the workflow compiles correctly. Then test with \`invoke_agent\`.
|
|
7828
9502
|
|
|
7829
|
-
|
|
7830
|
-
|
|
9503
|
+
## Debugging Tips
|
|
9504
|
+
|
|
9505
|
+
- If output is missing: check the producing step has an \`id\`
|
|
9506
|
+
- 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}}\`
|
|
9507
|
+
- Map results are an array; use \`reduce\` to aggregate into a summary
|
|
9508
|
+
- Condition branching uses truthiness: empty string, 0, null, false \u2192 else path
|
|
9509
|
+
- \`{{input}}\` contains the user's initial message; it's always available
|
|
9510
|
+
- Parallel + condition: a parallel group cannot be the first step inside a condition's then/else (LangGraph limitation). Add a preceding agent step.
|
|
9511
|
+
`
|
|
7831
9512
|
};
|
|
7832
9513
|
function getBuiltInSkillMeta(name) {
|
|
7833
9514
|
const content = BUILTIN_SKILLS[name];
|
|
@@ -8064,15 +9745,15 @@ function formatContentWithLineNumbers(content, startLine = 1) {
|
|
|
8064
9745
|
for (let chunkIdx = 0; chunkIdx < numChunks; chunkIdx++) {
|
|
8065
9746
|
const start = chunkIdx * MAX_LINE_LENGTH;
|
|
8066
9747
|
const end = Math.min(start + MAX_LINE_LENGTH, line.length);
|
|
8067
|
-
const
|
|
9748
|
+
const chunk2 = line.substring(start, end);
|
|
8068
9749
|
if (chunkIdx === 0) {
|
|
8069
9750
|
resultLines.push(
|
|
8070
|
-
`${lineNum.toString().padStart(LINE_NUMBER_WIDTH)} ${
|
|
9751
|
+
`${lineNum.toString().padStart(LINE_NUMBER_WIDTH)} ${chunk2}`
|
|
8071
9752
|
);
|
|
8072
9753
|
} else {
|
|
8073
9754
|
const continuationMarker = `${lineNum}.${chunkIdx}`;
|
|
8074
9755
|
resultLines.push(
|
|
8075
|
-
`${continuationMarker.padStart(LINE_NUMBER_WIDTH)} ${
|
|
9756
|
+
`${continuationMarker.padStart(LINE_NUMBER_WIDTH)} ${chunk2}`
|
|
8076
9757
|
);
|
|
8077
9758
|
}
|
|
8078
9759
|
}
|
|
@@ -10742,6 +12423,7 @@ var import_uuid2 = require("uuid");
|
|
|
10742
12423
|
var import_protocols8 = require("@axiom-lattice/protocols");
|
|
10743
12424
|
|
|
10744
12425
|
// src/schedule_lattice/ScheduleLatticeManager.ts
|
|
12426
|
+
init_BaseLatticeManager();
|
|
10745
12427
|
var import_protocols5 = require("@axiom-lattice/protocols");
|
|
10746
12428
|
|
|
10747
12429
|
// src/schedule_lattice/DefaultScheduleClient.ts
|
|
@@ -11733,6 +13415,7 @@ var getScheduleLattice = (key) => scheduleLatticeManager.getScheduleLattice(key)
|
|
|
11733
13415
|
var import_events = require("events");
|
|
11734
13416
|
|
|
11735
13417
|
// src/queue_lattice/QueueLatticeManager.ts
|
|
13418
|
+
init_BaseLatticeManager();
|
|
11736
13419
|
var import_protocols6 = require("@axiom-lattice/protocols");
|
|
11737
13420
|
|
|
11738
13421
|
// src/queue_lattice/MemoryQueueClient.ts
|
|
@@ -12070,9 +13753,9 @@ var InMemoryChunkBuffer = class extends ChunkBuffer {
|
|
|
12070
13753
|
}
|
|
12071
13754
|
async addChunk(threadId, arg2, arg3) {
|
|
12072
13755
|
const buffer2 = this.getOrCreateBuffer(threadId);
|
|
12073
|
-
let
|
|
13756
|
+
let chunk2;
|
|
12074
13757
|
if (typeof arg2 === "string" && arg3 !== void 0) {
|
|
12075
|
-
|
|
13758
|
+
chunk2 = {
|
|
12076
13759
|
type: import_protocols7.MessageChunkTypes.AI,
|
|
12077
13760
|
data: {
|
|
12078
13761
|
id: arg2,
|
|
@@ -12080,10 +13763,10 @@ var InMemoryChunkBuffer = class extends ChunkBuffer {
|
|
|
12080
13763
|
}
|
|
12081
13764
|
};
|
|
12082
13765
|
} else {
|
|
12083
|
-
|
|
13766
|
+
chunk2 = arg2;
|
|
12084
13767
|
}
|
|
12085
|
-
buffer2.chunks.push(
|
|
12086
|
-
buffer2.chunks$.next(
|
|
13768
|
+
buffer2.chunks.push(chunk2);
|
|
13769
|
+
buffer2.chunks$.next(chunk2);
|
|
12087
13770
|
buffer2.updatedAt = Date.now();
|
|
12088
13771
|
buffer2.expiresAt = Date.now() + this.config.ttl;
|
|
12089
13772
|
buffer2.status = "active" /* ACTIVE */;
|
|
@@ -12130,12 +13813,12 @@ var InMemoryChunkBuffer = class extends ChunkBuffer {
|
|
|
12130
13813
|
async getAccumulatedContent(threadId) {
|
|
12131
13814
|
const buffer2 = this.getBufferIfValid(threadId);
|
|
12132
13815
|
if (!buffer2) return "";
|
|
12133
|
-
return buffer2.chunks.map((
|
|
13816
|
+
return buffer2.chunks.map((chunk2) => chunk2.data?.content || "").join("");
|
|
12134
13817
|
}
|
|
12135
13818
|
async getChunksByMessageId(threadId, messageId) {
|
|
12136
13819
|
const buffer2 = this.getBufferIfValid(threadId);
|
|
12137
13820
|
if (!buffer2) return [];
|
|
12138
|
-
return buffer2.chunks.filter((
|
|
13821
|
+
return buffer2.chunks.filter((chunk2) => chunk2.data?.id === messageId);
|
|
12139
13822
|
}
|
|
12140
13823
|
async clearThread(threadId) {
|
|
12141
13824
|
this.buffers.delete(threadId);
|
|
@@ -12203,12 +13886,12 @@ var InMemoryChunkBuffer = class extends ChunkBuffer {
|
|
|
12203
13886
|
const filtered$ = buffer2.chunks$.pipe(
|
|
12204
13887
|
(0, import_rxjs.observeOn)(import_rxjs.asyncScheduler),
|
|
12205
13888
|
// 1. 从指定 messageId 开始
|
|
12206
|
-
(0, import_operators.filter)((
|
|
12207
|
-
if (
|
|
13889
|
+
(0, import_operators.filter)((chunk2) => {
|
|
13890
|
+
if (chunk2.data?.id === messageId) startYieldChunk = true;
|
|
12208
13891
|
return startYieldChunk;
|
|
12209
13892
|
}),
|
|
12210
13893
|
// 2. 包含指定的停止类型,但收到后停止
|
|
12211
|
-
(0, import_operators.takeWhile)((
|
|
13894
|
+
(0, import_operators.takeWhile)((chunk2) => !typesToStop.includes(chunk2.type), true)
|
|
12212
13895
|
);
|
|
12213
13896
|
yield* (0, import_rxjs_for_await.eachValueFrom)(filtered$);
|
|
12214
13897
|
}
|
|
@@ -12255,6 +13938,7 @@ var InMemoryChunkBuffer = class extends ChunkBuffer {
|
|
|
12255
13938
|
};
|
|
12256
13939
|
|
|
12257
13940
|
// src/chunk_buffer_lattice/ChunkBufferLatticeManager.ts
|
|
13941
|
+
init_BaseLatticeManager();
|
|
12258
13942
|
var ChunkBufferLatticeManager = class _ChunkBufferLatticeManager extends BaseLatticeManager {
|
|
12259
13943
|
/**
|
|
12260
13944
|
* Private constructor for singleton pattern
|
|
@@ -12422,26 +14106,26 @@ var Agent = class {
|
|
|
12422
14106
|
}
|
|
12423
14107
|
);
|
|
12424
14108
|
try {
|
|
12425
|
-
for await (const
|
|
14109
|
+
for await (const chunk2 of agentStream) {
|
|
12426
14110
|
if (signal?.aborted) {
|
|
12427
14111
|
await lifecycleManager.chunkBuffer.abortThread(lifecycleManager.thread_id);
|
|
12428
14112
|
throw new Error("Agent execution was aborted");
|
|
12429
14113
|
}
|
|
12430
14114
|
let data;
|
|
12431
14115
|
let chunkContent = "";
|
|
12432
|
-
if (
|
|
12433
|
-
const update =
|
|
14116
|
+
if (chunk2[0] === "updates") {
|
|
14117
|
+
const update = chunk2[1];
|
|
12434
14118
|
const values = Object.values(update);
|
|
12435
14119
|
const messages2 = values[0]?.messages;
|
|
12436
14120
|
if (messages2?.[0]?.tool_call_id) {
|
|
12437
14121
|
data = messages2[0].toDict();
|
|
12438
14122
|
}
|
|
12439
|
-
} else if (
|
|
12440
|
-
const messages2 =
|
|
14123
|
+
} else if (chunk2[0] === "messages") {
|
|
14124
|
+
const messages2 = chunk2[1];
|
|
12441
14125
|
data = messages2?.[0]?.toDict();
|
|
12442
14126
|
}
|
|
12443
|
-
if (
|
|
12444
|
-
const interruptData =
|
|
14127
|
+
if (chunk2?.[1]?.__interrupt__) {
|
|
14128
|
+
const interruptData = chunk2?.[1]?.__interrupt__[0];
|
|
12445
14129
|
data = {
|
|
12446
14130
|
type: "interrupt",
|
|
12447
14131
|
id: interruptData.id,
|
|
@@ -12784,8 +14468,8 @@ var Agent = class {
|
|
|
12784
14468
|
return {
|
|
12785
14469
|
[Symbol.asyncIterator]: async function* () {
|
|
12786
14470
|
try {
|
|
12787
|
-
for await (const
|
|
12788
|
-
yield
|
|
14471
|
+
for await (const chunk2 of stream) {
|
|
14472
|
+
yield chunk2;
|
|
12789
14473
|
}
|
|
12790
14474
|
} catch (error) {
|
|
12791
14475
|
if (error?.message === "Thread aborted") {
|
|
@@ -13972,7 +15656,8 @@ var ReActAgentGraphBuilder = class {
|
|
|
13972
15656
|
name: agentLattice.config.name,
|
|
13973
15657
|
checkpointer: getCheckpointSaver("default"),
|
|
13974
15658
|
stateSchema: stateSchema2,
|
|
13975
|
-
middleware: middlewares
|
|
15659
|
+
middleware: middlewares,
|
|
15660
|
+
responseFormat: params.responseFormat
|
|
13976
15661
|
});
|
|
13977
15662
|
}
|
|
13978
15663
|
};
|
|
@@ -14145,6 +15830,7 @@ function createAgentWorkerGraph() {
|
|
|
14145
15830
|
var agentWorkerGraph = createAgentWorkerGraph();
|
|
14146
15831
|
|
|
14147
15832
|
// src/deep_agent_new/middleware/subagents.ts
|
|
15833
|
+
init_MemoryLatticeManager();
|
|
14148
15834
|
var DEFAULT_SUBAGENT_PROMPT = "In order to complete the objective that the user asks of you, you have access to a number of standard tools.";
|
|
14149
15835
|
var EXCLUDED_STATE_KEYS = ["messages", "todos", "jumpTo"];
|
|
14150
15836
|
var DEFAULT_GENERAL_PURPOSE_DESCRIPTION = "General-purpose agent for researching complex questions, searching for files and content, and executing multi-step tasks. When you are searching for a keyword or file and are not confident that you will find the right match in the first few tries use this agent to perform the search for you. This agent has access to all tools as the main agent.";
|
|
@@ -16273,6 +17959,7 @@ ${BASE_PROMPT}` : BASE_PROMPT;
|
|
|
16273
17959
|
}
|
|
16274
17960
|
|
|
16275
17961
|
// src/agent_lattice/builders/DeepAgentGraphBuilder.ts
|
|
17962
|
+
init_MemoryLatticeManager();
|
|
16276
17963
|
var DeepAgentGraphBuilder = class {
|
|
16277
17964
|
/**
|
|
16278
17965
|
* 构建Deep Agent Graph
|
|
@@ -16315,6 +18002,7 @@ var DeepAgentGraphBuilder = class {
|
|
|
16315
18002
|
contextSchema: params.stateSchema,
|
|
16316
18003
|
systemPrompt: params.prompt,
|
|
16317
18004
|
subagents,
|
|
18005
|
+
responseFormat: params.responseFormat,
|
|
16318
18006
|
checkpointer: getCheckpointSaver("default"),
|
|
16319
18007
|
skills: params.skillCategories,
|
|
16320
18008
|
backend: filesystemBackend,
|
|
@@ -16324,6 +18012,9 @@ var DeepAgentGraphBuilder = class {
|
|
|
16324
18012
|
}
|
|
16325
18013
|
};
|
|
16326
18014
|
|
|
18015
|
+
// src/agent_team/builders/TeamAgentGraphBuilder.ts
|
|
18016
|
+
init_MemoryLatticeManager();
|
|
18017
|
+
|
|
16327
18018
|
// src/agent_team/agent_team.ts
|
|
16328
18019
|
var import_v35 = require("zod/v3");
|
|
16329
18020
|
var import_langchain63 = require("langchain");
|
|
@@ -17024,6 +18715,7 @@ function createTeammateTools(options) {
|
|
|
17024
18715
|
}
|
|
17025
18716
|
|
|
17026
18717
|
// src/agent_team/middleware/team.ts
|
|
18718
|
+
init_MemoryLatticeManager();
|
|
17027
18719
|
var TEAM_LEAD_AGENT_ID = "team_lead";
|
|
17028
18720
|
var DEFAULT_POLL_INTERVAL_MS = 5e3;
|
|
17029
18721
|
var DEFAULT_SCHEDULE_LATTICE_KEY = "default";
|
|
@@ -18323,6 +20015,7 @@ ${BASE_PROMPT2}` : BASE_PROMPT2;
|
|
|
18323
20015
|
}
|
|
18324
20016
|
|
|
18325
20017
|
// src/agent_lattice/builders/ProcessingAgentGraphBuilder.ts
|
|
20018
|
+
init_MemoryLatticeManager();
|
|
18326
20019
|
var ProcessingAgentGraphBuilder = class {
|
|
18327
20020
|
async build(agentLattice, params) {
|
|
18328
20021
|
const tools = params.tools.map((t) => {
|
|
@@ -18362,6 +20055,7 @@ var ProcessingAgentGraphBuilder = class {
|
|
|
18362
20055
|
contextSchema: params.stateSchema,
|
|
18363
20056
|
systemPrompt: params.prompt,
|
|
18364
20057
|
subagents,
|
|
20058
|
+
responseFormat: params.responseFormat,
|
|
18365
20059
|
checkpointer: getCheckpointSaver("default"),
|
|
18366
20060
|
skills: params.skillCategories,
|
|
18367
20061
|
backend: filesystemBackend,
|
|
@@ -18593,6 +20287,102 @@ function extractLastHumanMessage(messages) {
|
|
|
18593
20287
|
return "";
|
|
18594
20288
|
}
|
|
18595
20289
|
|
|
20290
|
+
// src/agent_lattice/builders/WorkflowAgentGraphBuilder.ts
|
|
20291
|
+
var import_langchain67 = require("langchain");
|
|
20292
|
+
init_MemoryLatticeManager();
|
|
20293
|
+
var import_protocols10 = require("@axiom-lattice/protocols");
|
|
20294
|
+
init_compile();
|
|
20295
|
+
var DEFAULT_AGENT_PROMPT = "Complete the task accurately and concisely. Follow the instructions in the user's message.";
|
|
20296
|
+
var WorkflowAgentGraphBuilder = class {
|
|
20297
|
+
async build(agentLattice, params) {
|
|
20298
|
+
if (!(0, import_protocols10.isWorkflowAgentConfig)(agentLattice.config)) {
|
|
20299
|
+
throw new Error(
|
|
20300
|
+
`WorkflowAgentGraphBuilder received wrong agent type: ${agentLattice.config.type}`
|
|
20301
|
+
);
|
|
20302
|
+
}
|
|
20303
|
+
const config = agentLattice.config;
|
|
20304
|
+
const dsl = config.workflow;
|
|
20305
|
+
const tenantId = agentLattice.config.tenantId ?? "default";
|
|
20306
|
+
const checkpointer = getCheckpointSaver("default");
|
|
20307
|
+
const tools = params.tools.map((t) => t.executor).filter(Boolean);
|
|
20308
|
+
const middlewareConfigs = params.middleware || [];
|
|
20309
|
+
const middlewares = await createCommonMiddlewares(middlewareConfigs, void 0, false);
|
|
20310
|
+
const humanMiddlewares = await createCommonMiddlewares([
|
|
20311
|
+
{
|
|
20312
|
+
id: "ask_user_to_clarify",
|
|
20313
|
+
type: "ask_user_to_clarify",
|
|
20314
|
+
name: "Ask User Clarify",
|
|
20315
|
+
description: "For human_feedback workflow nodes",
|
|
20316
|
+
enabled: true,
|
|
20317
|
+
config: {}
|
|
20318
|
+
}
|
|
20319
|
+
], void 0, false);
|
|
20320
|
+
const noWrapMiddlewares = middlewares.filter((m) => !m.wrapModelCall);
|
|
20321
|
+
const noWrapHumanMiddlewares = humanMiddlewares.filter((m) => !m.wrapModelCall);
|
|
20322
|
+
console.log(`[WF BUILDER] building default agent | toolCount=${tools.length} | middlewareCount=${middlewares.length}`);
|
|
20323
|
+
const defaultAgent = (0, import_langchain67.createAgent)({
|
|
20324
|
+
model: params.model,
|
|
20325
|
+
tools,
|
|
20326
|
+
systemPrompt: params.prompt || DEFAULT_AGENT_PROMPT,
|
|
20327
|
+
checkpointer,
|
|
20328
|
+
middleware: middlewares
|
|
20329
|
+
});
|
|
20330
|
+
console.log(`[WF BUILDER] default agent built`);
|
|
20331
|
+
const agentCache = /* @__PURE__ */ new Map();
|
|
20332
|
+
const resolveAgent = async (ref, responseFormat, stepType) => {
|
|
20333
|
+
if (ref) {
|
|
20334
|
+
console.log(`[WF BUILDER] resolveAgent: looking up ref="${ref}"`);
|
|
20335
|
+
return await getAgentClientAsync(tenantId, ref);
|
|
20336
|
+
}
|
|
20337
|
+
const isHuman = stepType === "human_feedback";
|
|
20338
|
+
if (responseFormat) {
|
|
20339
|
+
const key = (isHuman ? "human:" : "agent:") + JSON.stringify(responseFormat);
|
|
20340
|
+
console.log(`[WF BUILDER] resolveAgent: cacheKey=${key.slice(0, 80)}... | cached=${agentCache.has(key)}`);
|
|
20341
|
+
if (!agentCache.has(key)) {
|
|
20342
|
+
console.log(`[WF BUILDER] creating ${isHuman ? "human" : "agent"} with responseFormat`);
|
|
20343
|
+
const agent = (0, import_langchain67.createAgent)({
|
|
20344
|
+
model: params.model,
|
|
20345
|
+
tools,
|
|
20346
|
+
systemPrompt: params.prompt || DEFAULT_AGENT_PROMPT,
|
|
20347
|
+
checkpointer,
|
|
20348
|
+
middleware: isHuman ? noWrapHumanMiddlewares : noWrapMiddlewares,
|
|
20349
|
+
responseFormat
|
|
20350
|
+
});
|
|
20351
|
+
agentCache.set(key, agent);
|
|
20352
|
+
}
|
|
20353
|
+
return agentCache.get(key);
|
|
20354
|
+
}
|
|
20355
|
+
if (isHuman) {
|
|
20356
|
+
const key = "human:default";
|
|
20357
|
+
if (!agentCache.has(key)) {
|
|
20358
|
+
console.log(`[WF BUILDER] creating human_feedback default agent`);
|
|
20359
|
+
const agent = (0, import_langchain67.createAgent)({
|
|
20360
|
+
model: params.model,
|
|
20361
|
+
tools,
|
|
20362
|
+
systemPrompt: params.prompt || DEFAULT_AGENT_PROMPT,
|
|
20363
|
+
checkpointer,
|
|
20364
|
+
middleware: humanMiddlewares
|
|
20365
|
+
});
|
|
20366
|
+
agentCache.set(key, agent);
|
|
20367
|
+
}
|
|
20368
|
+
return agentCache.get(key);
|
|
20369
|
+
}
|
|
20370
|
+
console.log(`[WF BUILDER] resolveAgent: using defaultAgent`);
|
|
20371
|
+
return defaultAgent;
|
|
20372
|
+
};
|
|
20373
|
+
let trackingStore;
|
|
20374
|
+
try {
|
|
20375
|
+
const storeLattice = getStoreLattice("default", "workflowTracking");
|
|
20376
|
+
trackingStore = storeLattice.store;
|
|
20377
|
+
console.log(`[WF BUILDER] trackingStore registered: step input/output will be persisted`);
|
|
20378
|
+
} catch {
|
|
20379
|
+
console.warn(`[WF BUILDER] no trackingStore registered \u2014 step input/output will NOT be persisted. Register a WorkflowTrackingStore under key "workflowTracking".`);
|
|
20380
|
+
}
|
|
20381
|
+
const graph = compileWorkflow(dsl, resolveAgent, checkpointer, trackingStore);
|
|
20382
|
+
return graph;
|
|
20383
|
+
}
|
|
20384
|
+
};
|
|
20385
|
+
|
|
18596
20386
|
// src/agent_lattice/builders/AgentGraphBuilderFactory.ts
|
|
18597
20387
|
var AgentGraphBuilderFactory = class _AgentGraphBuilderFactory {
|
|
18598
20388
|
constructor() {
|
|
@@ -18617,6 +20407,7 @@ var AgentGraphBuilderFactory = class _AgentGraphBuilderFactory {
|
|
|
18617
20407
|
this.builders.set(import_protocols.AgentType.TEAM, new TeamAgentGraphBuilder());
|
|
18618
20408
|
this.builders.set(import_protocols.AgentType.PROCESSING, new ProcessingAgentGraphBuilder());
|
|
18619
20409
|
this.builders.set(import_protocols.AgentType.A2A_REMOTE, new RemoteAgentGraphBuilder());
|
|
20410
|
+
this.builders.set(import_protocols.AgentType.WORKFLOW, new WorkflowAgentGraphBuilder());
|
|
18620
20411
|
}
|
|
18621
20412
|
/**
|
|
18622
20413
|
* 注册自定义Builder
|
|
@@ -18643,7 +20434,7 @@ var AgentGraphBuilderFactory = class _AgentGraphBuilderFactory {
|
|
|
18643
20434
|
};
|
|
18644
20435
|
|
|
18645
20436
|
// src/agent_lattice/builders/AgentParamsBuilder.ts
|
|
18646
|
-
var
|
|
20437
|
+
var import_protocols11 = require("@axiom-lattice/protocols");
|
|
18647
20438
|
var AgentParamsBuilder = class {
|
|
18648
20439
|
/**
|
|
18649
20440
|
* constructor
|
|
@@ -18661,8 +20452,8 @@ var AgentParamsBuilder = class {
|
|
|
18661
20452
|
* @returns Agent build parameters
|
|
18662
20453
|
*/
|
|
18663
20454
|
async buildParams(agentLattice, options) {
|
|
18664
|
-
const skills = (0,
|
|
18665
|
-
const toolKeys = options?.overrideTools || (0,
|
|
20455
|
+
const skills = (0, import_protocols11.isDeepAgentConfig)(agentLattice.config) || (0, import_protocols11.isProcessingAgentConfig)(agentLattice.config) ? agentLattice.config.skillCategories : void 0;
|
|
20456
|
+
const toolKeys = options?.overrideTools || (0, import_protocols11.getToolsFromConfig)(agentLattice.config);
|
|
18666
20457
|
const tools = toolKeys.map((toolKey) => {
|
|
18667
20458
|
const toolLattice = toolLatticeManager.getToolLattice(toolKey);
|
|
18668
20459
|
if (!toolLattice) {
|
|
@@ -18679,7 +20470,7 @@ var AgentParamsBuilder = class {
|
|
|
18679
20470
|
if (!model) {
|
|
18680
20471
|
throw new Error(`Model "${modelKey}" does not exist`);
|
|
18681
20472
|
}
|
|
18682
|
-
const subAgentKeys = (0,
|
|
20473
|
+
const subAgentKeys = (0, import_protocols11.getSubAgentsFromConfig)(agentLattice.config);
|
|
18683
20474
|
const subAgents = await Promise.all(subAgentKeys.map(async (agentKey) => {
|
|
18684
20475
|
const subAgentLattice = await this.getAgentLatticeFunc(agentKey);
|
|
18685
20476
|
if (!subAgentLattice) {
|
|
@@ -18692,7 +20483,7 @@ var AgentParamsBuilder = class {
|
|
|
18692
20483
|
};
|
|
18693
20484
|
}));
|
|
18694
20485
|
let internalSubAgents = [];
|
|
18695
|
-
if ((0,
|
|
20486
|
+
if ((0, import_protocols11.isDeepAgentConfig)(agentLattice.config) || (0, import_protocols11.isProcessingAgentConfig)(agentLattice.config)) {
|
|
18696
20487
|
internalSubAgents = agentLattice.config.internalSubAgents?.map((i) => ({
|
|
18697
20488
|
key: i.key,
|
|
18698
20489
|
config: i
|
|
@@ -18704,6 +20495,7 @@ var AgentParamsBuilder = class {
|
|
|
18704
20495
|
subAgents: [...subAgents, ...internalSubAgents],
|
|
18705
20496
|
prompt: agentLattice.config.prompt,
|
|
18706
20497
|
stateSchema: agentLattice.config.schema,
|
|
20498
|
+
responseFormat: agentLattice.config.responseFormat,
|
|
18707
20499
|
skillCategories: skills,
|
|
18708
20500
|
middleware: agentLattice.config.middleware,
|
|
18709
20501
|
tenantId: agentLattice.config.tenantId
|
|
@@ -18732,6 +20524,7 @@ function mergeAgentConfig(parent, child) {
|
|
|
18732
20524
|
}
|
|
18733
20525
|
|
|
18734
20526
|
// src/store_lattice/configureStores.ts
|
|
20527
|
+
init_MemoryLatticeManager();
|
|
18735
20528
|
var _disposables = [];
|
|
18736
20529
|
var _cleanupRegistered = false;
|
|
18737
20530
|
function registerSignalCleanup() {
|
|
@@ -19289,7 +21082,7 @@ ${body}` : `${frontmatter}
|
|
|
19289
21082
|
// src/agent_lattice/agentArchitectTools.ts
|
|
19290
21083
|
var import_zod53 = __toESM(require("zod"));
|
|
19291
21084
|
var import_uuid5 = require("uuid");
|
|
19292
|
-
var
|
|
21085
|
+
var import_protocols12 = require("@axiom-lattice/protocols");
|
|
19293
21086
|
function getTenantId(exeConfig) {
|
|
19294
21087
|
const runConfig = exeConfig?.configurable?.runConfig || {};
|
|
19295
21088
|
return runConfig.tenantId || "default";
|
|
@@ -19397,7 +21190,7 @@ registerToolLattice(
|
|
|
19397
21190
|
key: id,
|
|
19398
21191
|
name: input.name,
|
|
19399
21192
|
description: input.description || "",
|
|
19400
|
-
type: input.type === "deep_agent" ?
|
|
21193
|
+
type: input.type === "deep_agent" ? import_protocols12.AgentType.DEEP_AGENT : import_protocols12.AgentType.REACT,
|
|
19401
21194
|
prompt: input.prompt,
|
|
19402
21195
|
...input.tools && input.tools.length > 0 ? { tools: input.tools } : {},
|
|
19403
21196
|
...input.middleware && input.middleware.length > 0 ? { middleware: input.middleware } : {},
|
|
@@ -19486,7 +21279,7 @@ registerToolLattice(
|
|
|
19486
21279
|
key: id,
|
|
19487
21280
|
name: input.name,
|
|
19488
21281
|
description: input.description || "",
|
|
19489
|
-
type:
|
|
21282
|
+
type: import_protocols12.AgentType.PROCESSING,
|
|
19490
21283
|
prompt: input.prompt,
|
|
19491
21284
|
...input.tools && input.tools.length > 0 ? { tools: input.tools } : {},
|
|
19492
21285
|
middleware,
|
|
@@ -19513,6 +21306,190 @@ registerToolLattice(
|
|
|
19513
21306
|
}
|
|
19514
21307
|
}
|
|
19515
21308
|
);
|
|
21309
|
+
var workflowStepLazy = import_zod53.default.lazy(
|
|
21310
|
+
() => import_zod53.default.discriminatedUnion("type", [
|
|
21311
|
+
import_zod53.default.object({ type: import_zod53.default.literal("agent").optional(), id: import_zod53.default.string().optional(), name: import_zod53.default.string().optional(), prompt: import_zod53.default.string(), schema: import_zod53.default.record(import_zod53.default.any()) }),
|
|
21312
|
+
import_zod53.default.object({ type: import_zod53.default.literal("human"), id: import_zod53.default.string().optional(), prompt: import_zod53.default.string(), title: import_zod53.default.string().optional(), schema: import_zod53.default.union([import_zod53.default.boolean(), import_zod53.default.record(import_zod53.default.any())]).optional() }),
|
|
21313
|
+
import_zod53.default.object({ type: import_zod53.default.literal("condition"), id: import_zod53.default.string().optional(), if: import_zod53.default.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: import_zod53.default.union([import_zod53.default.lazy(() => workflowStepLazy), import_zod53.default.array(import_zod53.default.lazy(() => workflowStepLazy))]).optional(), else: import_zod53.default.union([import_zod53.default.lazy(() => workflowStepLazy), import_zod53.default.array(import_zod53.default.lazy(() => workflowStepLazy))]).optional(), branches: import_zod53.default.record(import_zod53.default.union([import_zod53.default.lazy(() => workflowStepLazy), import_zod53.default.array(import_zod53.default.lazy(() => workflowStepLazy))])).optional() }),
|
|
21314
|
+
import_zod53.default.object({ type: import_zod53.default.literal("map"), id: import_zod53.default.string(), source: import_zod53.default.string(), each: import_zod53.default.object({ prompt: import_zod53.default.string(), schema: import_zod53.default.record(import_zod53.default.any()) }), reduce: import_zod53.default.object({ prompt: import_zod53.default.string(), schema: import_zod53.default.record(import_zod53.default.any()) }).optional(), batch: import_zod53.default.number().int().min(1).optional(), concurrency: import_zod53.default.number().int().min(1).optional() }),
|
|
21315
|
+
import_zod53.default.object({ type: import_zod53.default.literal("parallel"), id: import_zod53.default.string().optional(), steps: import_zod53.default.array(import_zod53.default.lazy(() => workflowStepLazy)) }),
|
|
21316
|
+
import_zod53.default.object({ type: import_zod53.default.literal("end"), status: import_zod53.default.enum(["success", "failed"]).optional() })
|
|
21317
|
+
])
|
|
21318
|
+
);
|
|
21319
|
+
var workflowDSLSchema = import_zod53.default.object({
|
|
21320
|
+
name: import_zod53.default.string().describe("Workflow identifier (kebab-case slug)"),
|
|
21321
|
+
steps: import_zod53.default.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' }.")
|
|
21322
|
+
});
|
|
21323
|
+
var createWorkflowSchema = import_zod53.default.object({
|
|
21324
|
+
name: import_zod53.default.string().describe("Display name for the workflow agent"),
|
|
21325
|
+
description: import_zod53.default.string().optional().describe("Short description of what this workflow does"),
|
|
21326
|
+
skillLoaded: import_zod53.default.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."),
|
|
21327
|
+
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."),
|
|
21328
|
+
tools: import_zod53.default.array(import_zod53.default.string()).optional().describe("Tool keys for the workflow's built-in general agent"),
|
|
21329
|
+
middleware: import_zod53.default.array(middlewareConfigSchema).optional().describe("Middleware configs for the workflow's general agent"),
|
|
21330
|
+
modelKey: import_zod53.default.string().optional().describe("Model key for the workflow's general agent")
|
|
21331
|
+
});
|
|
21332
|
+
registerToolLattice(
|
|
21333
|
+
"create_workflow",
|
|
21334
|
+
{
|
|
21335
|
+
name: "create_workflow",
|
|
21336
|
+
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.`,
|
|
21337
|
+
schema: createWorkflowSchema
|
|
21338
|
+
},
|
|
21339
|
+
async (input, exeConfig) => {
|
|
21340
|
+
try {
|
|
21341
|
+
const tenantId = getTenantId(exeConfig);
|
|
21342
|
+
const store = getAssistStore();
|
|
21343
|
+
const id = await generateAgentId(tenantId, input.name);
|
|
21344
|
+
const config = {
|
|
21345
|
+
key: id,
|
|
21346
|
+
name: input.name,
|
|
21347
|
+
description: input.description || "",
|
|
21348
|
+
type: import_protocols12.AgentType.WORKFLOW,
|
|
21349
|
+
prompt: input.description || `Workflow: ${input.name}`,
|
|
21350
|
+
workflow: input.workflow,
|
|
21351
|
+
...input.tools && input.tools.length > 0 ? { tools: input.tools } : {},
|
|
21352
|
+
...input.middleware && input.middleware.length > 0 ? { middleware: input.middleware } : {},
|
|
21353
|
+
...input.modelKey ? { modelKey: input.modelKey } : {}
|
|
21354
|
+
};
|
|
21355
|
+
try {
|
|
21356
|
+
const { compileWorkflow: compileWorkflow2 } = await Promise.resolve().then(() => (init_compile(), compile_exports));
|
|
21357
|
+
const { getCheckpointSaver: getCheckpointSaver2 } = await Promise.resolve().then(() => (init_memory_lattice(), memory_lattice_exports));
|
|
21358
|
+
await compileWorkflow2(input.workflow, async () => ({ invoke: async () => ({}) }), getCheckpointSaver2("default"));
|
|
21359
|
+
} catch (e) {
|
|
21360
|
+
return JSON.stringify({ error: `DSL validation failed: ${e.message}`, issues: [{ type: "error", message: e.message }] });
|
|
21361
|
+
}
|
|
21362
|
+
await store.createAssistant(tenantId, id, {
|
|
21363
|
+
name: input.name,
|
|
21364
|
+
description: input.description,
|
|
21365
|
+
graphDefinition: config
|
|
21366
|
+
});
|
|
21367
|
+
eventBus.publish("assistant:created", { id, name: input.name, tenantId });
|
|
21368
|
+
return JSON.stringify({
|
|
21369
|
+
id,
|
|
21370
|
+
name: input.name,
|
|
21371
|
+
type: "workflow",
|
|
21372
|
+
stepCount: input.workflow.steps.length
|
|
21373
|
+
});
|
|
21374
|
+
} catch (error) {
|
|
21375
|
+
return JSON.stringify({ error: `Failed to create workflow: ${error.message}` });
|
|
21376
|
+
}
|
|
21377
|
+
}
|
|
21378
|
+
);
|
|
21379
|
+
registerToolLattice(
|
|
21380
|
+
"validate_workflow",
|
|
21381
|
+
{
|
|
21382
|
+
name: "validate_workflow",
|
|
21383
|
+
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.",
|
|
21384
|
+
schema: import_zod53.default.object({
|
|
21385
|
+
id: import_zod53.default.string().describe("The workflow agent ID to validate")
|
|
21386
|
+
})
|
|
21387
|
+
},
|
|
21388
|
+
async (input, exeConfig) => {
|
|
21389
|
+
try {
|
|
21390
|
+
const tenantId = getTenantId(exeConfig);
|
|
21391
|
+
const store = getAssistStore();
|
|
21392
|
+
const agent = await store.getAssistantById(tenantId, input.id);
|
|
21393
|
+
if (!agent) {
|
|
21394
|
+
return JSON.stringify({ error: `Agent '${input.id}' not found` });
|
|
21395
|
+
}
|
|
21396
|
+
const graphDef = agent.graphDefinition;
|
|
21397
|
+
if (!graphDef || graphDef.type !== import_protocols12.AgentType.WORKFLOW) {
|
|
21398
|
+
return JSON.stringify({ error: `Agent '${input.id}' is not a workflow agent (type: ${graphDef?.type ?? "unknown"})` });
|
|
21399
|
+
}
|
|
21400
|
+
const workflow = graphDef.workflow;
|
|
21401
|
+
if (!workflow || !workflow.steps) {
|
|
21402
|
+
return JSON.stringify({ error: `Agent '${input.id}' has no valid workflow DSL` });
|
|
21403
|
+
}
|
|
21404
|
+
try {
|
|
21405
|
+
const { compileWorkflow: compileWorkflow2 } = await Promise.resolve().then(() => (init_compile(), compile_exports));
|
|
21406
|
+
const { getCheckpointSaver: getCheckpointSaver2 } = await Promise.resolve().then(() => (init_memory_lattice(), memory_lattice_exports));
|
|
21407
|
+
await compileWorkflow2(workflow, async () => ({ invoke: async () => ({}) }), getCheckpointSaver2("default"));
|
|
21408
|
+
} catch (e) {
|
|
21409
|
+
return JSON.stringify({
|
|
21410
|
+
agentId: input.id,
|
|
21411
|
+
valid: false,
|
|
21412
|
+
stepCount: workflow.steps?.length ?? 0,
|
|
21413
|
+
issues: [{ type: "error", message: e.message }]
|
|
21414
|
+
});
|
|
21415
|
+
}
|
|
21416
|
+
return JSON.stringify({
|
|
21417
|
+
agentId: input.id,
|
|
21418
|
+
valid: true,
|
|
21419
|
+
stepCount: workflow.steps?.length ?? 0,
|
|
21420
|
+
issues: []
|
|
21421
|
+
});
|
|
21422
|
+
} catch (error) {
|
|
21423
|
+
return JSON.stringify({ error: `Failed to validate workflow: ${error.message}` });
|
|
21424
|
+
}
|
|
21425
|
+
}
|
|
21426
|
+
);
|
|
21427
|
+
var updateWorkflowSchema = import_zod53.default.object({
|
|
21428
|
+
id: import_zod53.default.string().describe("The workflow agent ID to update"),
|
|
21429
|
+
name: import_zod53.default.string().optional().describe("New display name"),
|
|
21430
|
+
description: import_zod53.default.string().optional().describe("New description"),
|
|
21431
|
+
workflow: workflowDSLSchema.optional().describe("Replacement Workflow DSL definition. Omit to keep the existing."),
|
|
21432
|
+
tools: import_zod53.default.array(import_zod53.default.string()).optional().describe("Replacement tool keys for the general agent"),
|
|
21433
|
+
middleware: import_zod53.default.array(middlewareConfigSchema).optional().describe("Replacement middleware configs"),
|
|
21434
|
+
modelKey: import_zod53.default.string().optional().describe("Replacement model key")
|
|
21435
|
+
});
|
|
21436
|
+
registerToolLattice(
|
|
21437
|
+
"update_workflow",
|
|
21438
|
+
{
|
|
21439
|
+
name: "update_workflow",
|
|
21440
|
+
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.",
|
|
21441
|
+
schema: updateWorkflowSchema
|
|
21442
|
+
},
|
|
21443
|
+
async (input, exeConfig) => {
|
|
21444
|
+
try {
|
|
21445
|
+
const tenantId = getTenantId(exeConfig);
|
|
21446
|
+
const store = getAssistStore();
|
|
21447
|
+
const existing = await store.getAssistantById(tenantId, input.id);
|
|
21448
|
+
if (!existing) {
|
|
21449
|
+
return JSON.stringify({ error: `Agent '${input.id}' not found` });
|
|
21450
|
+
}
|
|
21451
|
+
const existingConfig = existing.graphDefinition || {};
|
|
21452
|
+
if (existingConfig.type !== import_protocols12.AgentType.WORKFLOW) {
|
|
21453
|
+
return JSON.stringify({ error: `Agent '${input.id}' is not a workflow agent` });
|
|
21454
|
+
}
|
|
21455
|
+
const mergedConfig = { ...existingConfig };
|
|
21456
|
+
if (input.name !== void 0) mergedConfig.name = input.name;
|
|
21457
|
+
if (input.description !== void 0) mergedConfig.description = input.description;
|
|
21458
|
+
if (input.workflow !== void 0) mergedConfig.workflow = input.workflow;
|
|
21459
|
+
if (input.tools !== void 0) mergedConfig.tools = input.tools;
|
|
21460
|
+
if (input.middleware !== void 0) mergedConfig.middleware = input.middleware;
|
|
21461
|
+
if (input.modelKey !== void 0) mergedConfig.modelKey = input.modelKey;
|
|
21462
|
+
if (input.workflow !== void 0) {
|
|
21463
|
+
try {
|
|
21464
|
+
const { compileWorkflow: compileWorkflow2 } = await Promise.resolve().then(() => (init_compile(), compile_exports));
|
|
21465
|
+
const { getCheckpointSaver: getCheckpointSaver2 } = await Promise.resolve().then(() => (init_memory_lattice(), memory_lattice_exports));
|
|
21466
|
+
await compileWorkflow2(input.workflow, async () => ({ invoke: async () => ({}) }), getCheckpointSaver2("default"));
|
|
21467
|
+
} catch (e) {
|
|
21468
|
+
return JSON.stringify({
|
|
21469
|
+
error: `DSL validation failed: ${e.message}`,
|
|
21470
|
+
issues: [{ type: "error", message: e.message }]
|
|
21471
|
+
});
|
|
21472
|
+
}
|
|
21473
|
+
}
|
|
21474
|
+
const newName = input.name || existing.name;
|
|
21475
|
+
await store.updateAssistant(tenantId, input.id, {
|
|
21476
|
+
name: newName,
|
|
21477
|
+
description: input.description !== void 0 ? input.description : existing.description,
|
|
21478
|
+
graphDefinition: mergedConfig
|
|
21479
|
+
});
|
|
21480
|
+
eventBus.publish("assistant:updated", { id: input.id, name: newName, tenantId });
|
|
21481
|
+
const workflow = mergedConfig.workflow;
|
|
21482
|
+
return JSON.stringify({
|
|
21483
|
+
id: input.id,
|
|
21484
|
+
name: newName,
|
|
21485
|
+
type: "workflow",
|
|
21486
|
+
stepCount: workflow?.steps?.length ?? 0
|
|
21487
|
+
});
|
|
21488
|
+
} catch (error) {
|
|
21489
|
+
return JSON.stringify({ error: `Failed to update workflow: ${error.message}` });
|
|
21490
|
+
}
|
|
21491
|
+
}
|
|
21492
|
+
);
|
|
19516
21493
|
var updateProcessingAgentSchema = import_zod53.default.object({
|
|
19517
21494
|
id: import_zod53.default.string().describe("The PROCESSING agent ID to update"),
|
|
19518
21495
|
name: import_zod53.default.string().optional().describe("New display name for the orchestrator"),
|
|
@@ -19554,7 +21531,7 @@ registerToolLattice(
|
|
|
19554
21531
|
return JSON.stringify({ error: `Agent '${input.id}' not found` });
|
|
19555
21532
|
}
|
|
19556
21533
|
const existingConfig = existing.graphDefinition || {};
|
|
19557
|
-
if (existingConfig.type !==
|
|
21534
|
+
if (existingConfig.type !== import_protocols12.AgentType.PROCESSING) {
|
|
19558
21535
|
return JSON.stringify({ error: `Agent '${input.id}' is not a PROCESSING agent (type: ${existingConfig.type})` });
|
|
19559
21536
|
}
|
|
19560
21537
|
const normalize = (s) => s.toLowerCase().replace(/[_\-\s]/g, "");
|
|
@@ -19769,24 +21746,16 @@ registerToolLattice(
|
|
|
19769
21746
|
thread_id: threadId
|
|
19770
21747
|
});
|
|
19771
21748
|
const result = await agent.invoke({ input: { message } });
|
|
19772
|
-
|
|
19773
|
-
const lastAi = [...messages].reverse().find(
|
|
19774
|
-
(m) => m.role === "ai" || m.type === "ai"
|
|
19775
|
-
);
|
|
19776
|
-
const content = lastAi?.content ?? "(no response)";
|
|
19777
|
-
return JSON.stringify({
|
|
19778
|
-
agentId: id,
|
|
19779
|
-
threadId,
|
|
19780
|
-
response: typeof content === "string" ? content : JSON.stringify(content)
|
|
19781
|
-
});
|
|
21749
|
+
return JSON.stringify({ agentId: id, threadId, result });
|
|
19782
21750
|
} catch (error) {
|
|
21751
|
+
console.error(`[invoke_agent] FAILED for agent="${input.id}":`, error.stack || error.message);
|
|
19783
21752
|
return JSON.stringify({ error: `Failed to invoke agent: ${error.message}` });
|
|
19784
21753
|
}
|
|
19785
21754
|
}
|
|
19786
21755
|
);
|
|
19787
21756
|
|
|
19788
21757
|
// src/agent_lattice/agentArchitectConfig.ts
|
|
19789
|
-
var
|
|
21758
|
+
var import_protocols14 = require("@axiom-lattice/protocols");
|
|
19790
21759
|
|
|
19791
21760
|
// src/agent_lattice/agentArchitectPrompt.ts
|
|
19792
21761
|
var AGENT_ARCHITECT_PROMPT = `# Agent Architect
|
|
@@ -19803,12 +21772,12 @@ Every agent interaction follows this cycle. You MUST NOT skip any phase:
|
|
|
19803
21772
|
|-------|-------------|-------------------|
|
|
19804
21773
|
| **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. |
|
|
19805
21774
|
| **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. |
|
|
19806
|
-
| **3. BUILD** | Call \`create_agent\`, \`
|
|
21775
|
+
| **3. BUILD** | Call \`create_agent\`, \`create_workflow\`, or \`update_agent\` / \`update_workflow\` | Only after confirmation. Report the result (ID, name). |
|
|
19807
21776
|
| **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. |
|
|
19808
21777
|
|
|
19809
21778
|
**CRITICAL RULES:**
|
|
19810
21779
|
- **NEVER build before confirming.** Design \u2192 ask \u2192 wait for "yes" \u2192 only then build.
|
|
19811
|
-
- **Edit, don't re-create.** After an agent exists, modifying it ALWAYS means \`update_agent\` or \`
|
|
21780
|
+
- **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.
|
|
19812
21781
|
- **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.
|
|
19813
21782
|
- **One decision at a time.** Each message asks exactly one question.
|
|
19814
21783
|
|
|
@@ -19819,7 +21788,7 @@ Once an agent is created, NEVER create another agent for the same purpose. If th
|
|
|
19819
21788
|
| User wants to... | Use |
|
|
19820
21789
|
|-----------------|-----|
|
|
19821
21790
|
| Change prompt, tools, middleware, name | \`update_agent\` |
|
|
19822
|
-
| Change
|
|
21791
|
+
| Change workflow DSL, tools, middleware | \`update_workflow\` |
|
|
19823
21792
|
| See current config | \`get_agent\` |
|
|
19824
21793
|
|
|
19825
21794
|
If the user's intent is unclear after creation, ask: "Edit this agent or create a new one?"
|
|
@@ -19831,8 +21800,9 @@ You have nine tools for agent management:
|
|
|
19831
21800
|
- **list_tools** \u2014 See all available tools that can be assigned to agents
|
|
19832
21801
|
- **get_agent** \u2014 View the full configuration of a specific agent
|
|
19833
21802
|
- **create_agent** \u2014 Create a REACT or DEEP_AGENT agent
|
|
19834
|
-
- **
|
|
19835
|
-
- **
|
|
21803
|
+
- **create_workflow** \u2014 Create a WORKFLOW agent from a concise DSL (load create-workflow skill first)
|
|
21804
|
+
- **validate_workflow** \u2014 Validate a workflow agent's DSL
|
|
21805
|
+
- **update_workflow** \u2014 Update a workflow agent's DSL or config
|
|
19836
21806
|
- **update_agent** \u2014 Modify an existing REACT or DEEP_AGENT agent's configuration
|
|
19837
21807
|
- **delete_agent** \u2014 Remove an agent permanently
|
|
19838
21808
|
- **manage_binding** \u2014 Bind a sender (email, Lark, Slack user) to an agent so external messages are routed to it
|
|
@@ -19870,7 +21840,7 @@ Let the \`show_widget\` tool handle rendering details \u2014 it has its own guid
|
|
|
19870
21840
|
| Type | Best for | Execution Model |
|
|
19871
21841
|
|------|----------|----------------|
|
|
19872
21842
|
| **react** | Simple, single-responsibility tasks | Classic ReAct loop (think \u2192 act \u2192 observe) |
|
|
19873
|
-
| **
|
|
21843
|
+
| **workflow** | Deterministic multi-step pipelines with branching, parallel, and human-in-the-loop | Concise DSL compiled into LangGraph state machine |
|
|
19874
21844
|
| **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 |
|
|
19875
21845
|
|
|
19876
21846
|
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.
|
|
@@ -19908,233 +21878,61 @@ You may ask: "Want me to send this to the Agent Reviewer for testing?" If yes, d
|
|
|
19908
21878
|
|
|
19909
21879
|
---
|
|
19910
21880
|
|
|
19911
|
-
## Workflow B:
|
|
19912
|
-
|
|
19913
|
-
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.
|
|
19914
|
-
|
|
19915
|
-
### Phase 1: Design
|
|
19916
|
-
|
|
19917
|
-
**Step 1: Process analysis.** Ask: What is the end-to-end process? Map the stages.
|
|
19918
|
-
|
|
19919
|
-
**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.
|
|
19920
|
-
|
|
19921
|
-
**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:
|
|
21881
|
+
## Workflow B: Processing Agent (PROCESSING type) [DEPRECATED]
|
|
19922
21882
|
|
|
19923
|
-
|
|
19924
|
-
Build the JSON payload. For each DocumentLines item:
|
|
19925
|
-
- Include \`WarehouseCode\` ONLY if sku.json provides a value; if missing or empty, OMIT the field entirely
|
|
19926
|
-
- Generate \`Comments\` dynamically based on context (customer name, PO reference, special instructions)
|
|
21883
|
+
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.
|
|
19927
21884
|
|
|
19928
|
-
|
|
19929
|
-
{
|
|
19930
|
-
"DocObjectCode": "17",
|
|
19931
|
-
"DocType": "dDocument_Items",
|
|
19932
|
-
"CardCode": "C001",
|
|
19933
|
-
"DocDate": "current date",
|
|
19934
|
-
"DocDueDate": "delivery date",
|
|
19935
|
-
"TaxDate": "current date",
|
|
19936
|
-
"U_YWLX": "Modern Trade",
|
|
19937
|
-
"Comments": "SO for Kaimay Retail - PO ref: PO-2024-001234",
|
|
19938
|
-
"DocumentLines": [
|
|
19939
|
-
{
|
|
19940
|
-
"ItemCode": "SKU001",
|
|
19941
|
-
"Quantity": 240,
|
|
19942
|
-
"UnitPrice": 15.84
|
|
19943
|
-
}
|
|
19944
|
-
]
|
|
19945
|
-
}
|
|
19946
|
-
\`\`\`
|
|
21885
|
+
---
|
|
19947
21886
|
|
|
19948
|
-
|
|
19949
|
-
| SAP Field | Data Source |
|
|
19950
|
-
|-----------|-------------|
|
|
19951
|
-
| CardCode | customer.json \u2192 CardCode |
|
|
19952
|
-
| DocDate | Current date (yyyy-MM-dd) |
|
|
19953
|
-
| DocDueDate | extracted.json \u2192 delivery_date |
|
|
19954
|
-
| TaxDate | Current date (yyyy-MM-dd) |
|
|
19955
|
-
| U_YWLX | customer.json \u2192 SalesType |
|
|
19956
|
-
| ItemCode | sku.json \u2192 ItemCode |
|
|
19957
|
-
| Quantity | extracted.json \u2192 Quantity |
|
|
19958
|
-
| WarehouseCode | sku.json \u2192 WarehouseCode (OMIT if missing/empty) |
|
|
19959
|
-
| UnitPrice | price.json \u2192 UnitPrice |
|
|
19960
|
-
| Comments | AI-generated based on customer name, PO reference, and context |
|
|
19961
|
-
|
|
19962
|
-
**Step 2: Call SAP API to Create Draft (MUST EXECUTE)**
|
|
19963
|
-
Use the \`sap_api_call\` tool with EXACTLY these parameters:
|
|
19964
|
-
- **Method**: POST
|
|
19965
|
-
- **Endpoint**: \`Drafts\` (ONLY allowed endpoint; do NOT call SalesOrders or any other endpoint)
|
|
19966
|
-
- **Body**: The JSON constructed in Step 1
|
|
19967
|
-
|
|
19968
|
-
CRITICAL: You MUST call sap_api_call BEFORE proceeding to Step 3. This step is NOT optional.
|
|
19969
|
-
|
|
19970
|
-
If the API call fails:
|
|
19971
|
-
- Log the error details
|
|
19972
|
-
- STOP the process
|
|
19973
|
-
- Report the failure to the user with the error message
|
|
19974
|
-
- Do NOT proceed to Step 3
|
|
19975
|
-
|
|
19976
|
-
**Step 3: Present Draft for User Review (MUST EXECUTE AFTER Step 2)**
|
|
19977
|
-
ONLY after the SAP API call in Step 2 succeeds, use the \`ask_user_to_clarify\` tool to present the complete SO summary.
|
|
19978
|
-
|
|
19979
|
-
Message format (STRICT \u2014 no emoji, no summary, field names match Service Layer):
|
|
19980
|
-
|
|
19981
|
-
=== Sales Order Draft ===
|
|
19982
|
-
|
|
19983
|
-
DocEntry: {DocEntry}
|
|
19984
|
-
DocNum: {DocNum}
|
|
19985
|
-
DocDate: {DocDate}
|
|
19986
|
-
DocDueDate: {DocDueDate}
|
|
19987
|
-
CardCode: {CardCode}
|
|
19988
|
-
CardName: {CardName}
|
|
19989
|
-
U_YWLX: {SalesType}
|
|
19990
|
-
Comments: {Comments}
|
|
19991
|
-
|
|
19992
|
-
DocumentLines:
|
|
19993
|
-
LineNum | ItemCode | Quantity | WarehouseCode | UnitPrice | LineTotal
|
|
19994
|
-
0 | {ItemCode} | {Quantity} | {WarehouseCode} | {UnitPrice} | {LineTotal}
|
|
19995
|
-
1 | {ItemCode} | {Quantity} | {WarehouseCode} | {UnitPrice} | {LineTotal}
|
|
19996
|
-
...
|
|
19997
|
-
|
|
19998
|
-
DocTotal: {DocTotal}
|
|
19999
|
-
|
|
20000
|
-
Warnings:
|
|
20001
|
-
- {warning1}
|
|
20002
|
-
- {warning2}
|
|
20003
|
-
|
|
20004
|
-
Options:
|
|
20005
|
-
[Confirm generating draft]
|
|
20006
|
-
[Cancel, do not generate]
|
|
20007
|
-
|
|
20008
|
-
**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.
|
|
20009
|
-
|
|
20010
|
-
Rules:
|
|
20011
|
-
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
|
|
20012
|
-
2. Each sub-agent reads input from \`/project/{project-id}/\` and writes output files into the same directory
|
|
20013
|
-
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\`)
|
|
20014
|
-
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
|
|
20015
|
-
|
|
20016
|
-
**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.
|
|
20017
|
-
|
|
20018
|
-
**Step 3: Design each sub-agent** as a **deep_agent** type (one at a time). For each:
|
|
20019
|
-
- Responsibility, system prompt, middleware, file input/output contract (which files from \`/project/{project-id}/\` it reads, which files it writes)
|
|
20020
|
-
- Deep agents have built-in file capabilities (ls, read, write, edit, glob, grep), so do NOT add filesystem middleware.
|
|
20021
|
-
- **Ask for confirmation before moving to the next sub-agent.**
|
|
20022
|
-
|
|
20023
|
-
**Step 4: Design the orchestrator.** Responsibility, system prompt, topology edges, sub-agent list.
|
|
20024
|
-
|
|
20025
|
-
**Step 5: Self-review checklist.** Before presenting to the user, verify:
|
|
20026
|
-
- Completeness (every stage covered by an edge?)
|
|
20027
|
-
- Purposes clear (each edge's business intent?)
|
|
20028
|
-
- Order correct (serial chain logical?)
|
|
20029
|
-
- Edge cases (invalid input, failure, timeout?)
|
|
20030
|
-
|
|
20031
|
-
**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.
|
|
20032
|
-
|
|
20033
|
-
The description MUST include ALL of the following:
|
|
20034
|
-
|
|
20035
|
-
| Section | Content |
|
|
20036
|
-
|---------|---------|
|
|
20037
|
-
| **Overview** | One-sentence summary of the workflow's purpose and business value |
|
|
20038
|
-
| **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. |
|
|
20039
|
-
| **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. |
|
|
20040
|
-
| **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? |
|
|
20041
|
-
| **Tools Used** | Summary table or list of all tools used across sub-agents, grouped by sub-agent |
|
|
20042
|
-
| **Expected Input** | What input does the workflow expect from the user? (format, examples) |
|
|
20043
|
-
| **Expected Output** | What does the workflow produce at the end? (format, examples) |
|
|
20044
|
-
|
|
20045
|
-
**Formatting rules:**
|
|
20046
|
-
- Write in **English**
|
|
20047
|
-
- Use **Markdown** for formatting (headings, lists, tables, code blocks)
|
|
20048
|
-
- Be detailed but concise \u2014 each section should be 1-5 lines
|
|
20049
|
-
- Avoid placeholder text like "TODO" or "TBD"
|
|
20050
|
-
|
|
20051
|
-
**Example structure** (\u5B50 Agent \u5747\u4E3A deep_agent \u7C7B\u578B\uFF0C\u65E0\u9700 filesystem \u4E2D\u95F4\u4EF6):
|
|
20052
|
-
|
|
20053
|
-
\`\`\`markdown
|
|
20054
|
-
## Overview
|
|
20055
|
-
\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
|
|
20056
|
-
|
|
20057
|
-
## Steps
|
|
20058
|
-
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\`
|
|
20059
|
-
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\`
|
|
20060
|
-
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\`
|
|
20061
|
-
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
|
|
20062
|
-
|
|
20063
|
-
## Data Flow
|
|
20064
|
-
All data is shared via files under \`/project/{project-id}/\`:
|
|
20065
|
-
\`\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
|
|
20066
|
-
|
|
20067
|
-
## Logic & Conditions
|
|
20068
|
-
- data-collector \u722C\u53D6\u5931\u8D25\u65F6\u91CD\u8BD5\u6700\u591A3\u6B21\uFF0C\u95F4\u969430\u79D2
|
|
20069
|
-
- \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
|
|
20070
|
-
- report-generator \u8BA1\u7B97\u6DA8\u5E45\u8D85\u8FC720%\u65F6\u81EA\u52A8\u6807\u8BB0\u300C\u5F02\u5E38\u6CE2\u52A8\u300D\u8B66\u544A
|
|
20071
|
-
- \u4EFB\u4F55\u6B65\u9AA4\u5931\u8D25\u65F6\uFF0Cworkflow \u505C\u6B62\u5E76\u5C06\u9519\u8BEF\u4FE1\u606F\u8F93\u51FA\u5230\u6700\u7EC8\u62A5\u544A
|
|
20072
|
-
|
|
20073
|
-
## Tools Used
|
|
20074
|
-
| \u5B50Agent | \u5DE5\u5177 |
|
|
20075
|
-
|---------|------|
|
|
20076
|
-
| data-collector | browser, metrics |
|
|
20077
|
-
| data-cleaner | code_eval |
|
|
20078
|
-
| report-generator | code_eval |
|
|
20079
|
-
| notifier | scheduler, ask_user_to_clarify |
|
|
20080
|
-
|
|
20081
|
-
## Expected Input
|
|
20082
|
-
- \u7ADE\u54C1URL\u5217\u8868\uFF08\u6BCF\u884C\u4E00\u4E2A\uFF09
|
|
20083
|
-
- \u65E5\u671F\u8303\u56F4\uFF08\u8D77\u59CB-\u7ED3\u675F\uFF0C\u683C\u5F0F YYYY-MM-DD\uFF09
|
|
20084
|
-
- \u63A8\u9001\u6E20\u9053\u9009\u62E9\uFF08\u90AE\u4EF6/\u9489\u9489/\u4F01\u4E1A\u5FAE\u4FE1\uFF09
|
|
20085
|
-
|
|
20086
|
-
## Expected Output
|
|
20087
|
-
- Markdown \u683C\u5F0F\u5BF9\u6BD4\u62A5\u544A\uFF0C\u5305\u542B\u4EF7\u683C\u8D8B\u52BF\u56FE\u3001\u6DA8\u8DCC\u5E45\u3001\u5F02\u5E38\u6807\u8BB0
|
|
20088
|
-
- \u62A5\u544A\u6587\u4EF6\u8DEF\u5F84\u53CA\u63A8\u9001\u72B6\u6001\u786E\u8BA4
|
|
20089
|
-
\`\`\`
|
|
21887
|
+
## Workflow C: Workflow DSL Agent (WORKFLOW type)
|
|
20090
21888
|
|
|
20091
|
-
|
|
21889
|
+
Use this when the process is fully known. A workflow is a deterministic LangGraph state machine compiled from a concise JSON DSL.
|
|
20092
21890
|
|
|
20093
|
-
|
|
21891
|
+
### When to choose WORKFLOW
|
|
20094
21892
|
|
|
20095
|
-
|
|
21893
|
+
| WORKFLOW (DSL) | PROCESSING (deprecated) |
|
|
21894
|
+
|---|---|
|
|
21895
|
+
| Fixed graph \u2014 all paths pre-defined | LLM-driven runtime routing |
|
|
21896
|
+
| Conditional branching via \`if\` field | Topology-constrained delegation |
|
|
21897
|
+
| human, map, parallel, condition | Single orchestrator delegates linearly |
|
|
21898
|
+
| No LLM routing decisions | Orchestrator uses LLM to route |
|
|
20096
21899
|
|
|
20097
|
-
### Phase
|
|
21900
|
+
### Phase 0: Load the Skill
|
|
20098
21901
|
|
|
20099
|
-
|
|
21902
|
+
**BEFORE designing, you MUST load the create-workflow skill:**
|
|
20100
21903
|
|
|
20101
21904
|
\`\`\`
|
|
20102
|
-
|
|
20103
|
-
2. create_agent(name: "stage-2", type: "deep_agent", ...)
|
|
20104
|
-
3. create_agent(name: "stage-3", type: "deep_agent", ...)
|
|
20105
|
-
4. create_processing_agent(
|
|
20106
|
-
name: "orchestrator",
|
|
20107
|
-
prompt: "...",
|
|
20108
|
-
edges: [
|
|
20109
|
-
{ from: "orchestrator", to: "stage-1-id", purpose: "Validate input" },
|
|
20110
|
-
{ from: "stage-1-id", to: "stage-2-id", purpose: "Transform data" },
|
|
20111
|
-
{ from: "stage-2-id", to: "stage-3-id", purpose: "Generate output" },
|
|
20112
|
-
],
|
|
20113
|
-
subAgents: ["stage-1-id", "stage-2-id", "stage-3-id"],
|
|
20114
|
-
)
|
|
21905
|
+
skill(skill_name: "create-workflow")
|
|
20115
21906
|
\`\`\`
|
|
20116
21907
|
|
|
20117
|
-
|
|
20118
|
-
|
|
20119
|
-
### Phase 4: Test (ask first)
|
|
21908
|
+
### Phase 1: Design
|
|
20120
21909
|
|
|
20121
|
-
|
|
21910
|
+
1. **Analyze the process.** Map every step, branch, data dependency.
|
|
21911
|
+
2. **Choose step types:**
|
|
21912
|
+
- \`agent\` \u2014 runs on the workflow's built-in agent. Output at \`state.<id>\`.
|
|
21913
|
+
- \`human\` \u2014 pauses for human input (built-in clarify middleware). Has \`prompt\`, \`title\`, \`schema\`.
|
|
21914
|
+
- \`condition\` \u2014 branches on \`if\` (field or expression). Has \`then\`/\`else\` or \`branches\` (switch with \`default\`).
|
|
21915
|
+
- \`map\` \u2014 iterates array from \`source\`, applies \`each\`, optionally \`reduce\`.
|
|
21916
|
+
- \`parallel\` \u2014 runs \`steps\` simultaneously, then rejoins.
|
|
21917
|
+
- \`end\` \u2014 terminates. Always required at end.
|
|
21918
|
+
3. **Write prompts** with \`{{id}}\` refs. \`{{input}}\` = user message. \`{{item}}\` = map element.
|
|
21919
|
+
4. **No edges or state fields needed** \u2014 the engine auto-generates them.
|
|
20122
21920
|
|
|
20123
|
-
### Phase
|
|
21921
|
+
### Phase 2: Confirm
|
|
20124
21922
|
|
|
20125
|
-
|
|
21923
|
+
Present the design. Ask: "Ready to create this workflow?"
|
|
20126
21924
|
|
|
20127
|
-
|
|
21925
|
+
### Phase 3: Build
|
|
20128
21926
|
|
|
20129
|
-
|
|
21927
|
+
Call \`create_workflow\` with \`skillLoaded: true\`. Then \`validate_workflow(id)\`.
|
|
20130
21928
|
|
|
20131
|
-
|
|
21929
|
+
### Phase 4: Test
|
|
20132
21930
|
|
|
20133
|
-
|
|
21931
|
+
Ask the user if they want to test.
|
|
20134
21932
|
|
|
20135
21933
|
---
|
|
20136
21934
|
|
|
20137
|
-
## Workflow
|
|
21935
|
+
## Workflow D: Dynamic Agent (DEEP_AGENT type)
|
|
20138
21936
|
|
|
20139
21937
|
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.
|
|
20140
21938
|
|
|
@@ -20185,7 +21983,7 @@ Follow the same Design \u2192 Confirm \u2192 Build cycle. Test only on request.
|
|
|
20185
21983
|
2. Understand what the user wants to change
|
|
20186
21984
|
3. **DESIGN**: Present the proposed changes clearly. Show a before/after diff.
|
|
20187
21985
|
4. **CONFIRM**: Ask for explicit approval. Do NOT call update_agent until confirmed.
|
|
20188
|
-
5. **BUILD**: Call **update_agent** (or **
|
|
21986
|
+
5. **BUILD**: Call **update_agent** (or **update_workflow** for WORKFLOW agents)
|
|
20189
21987
|
6. **TEST**: You may ask if they want to test. If yes, delegate to the **Agent Reviewer** sub-agent
|
|
20190
21988
|
|
|
20191
21989
|
## Deleting Agents
|
|
@@ -20216,28 +22014,53 @@ All fields except name, type, and prompt are optional.
|
|
|
20216
22014
|
}
|
|
20217
22015
|
\`\`\`
|
|
20218
22016
|
|
|
20219
|
-
###
|
|
22017
|
+
### create_workflow (WORKFLOW)
|
|
20220
22018
|
|
|
20221
|
-
Creates a
|
|
22019
|
+
Creates a WORKFLOW agent from a concise DSL. Before calling, load the \`create-workflow\` skill for the complete DSL specification. Must pass \`skillLoaded: true\`.
|
|
20222
22020
|
|
|
20223
22021
|
\`\`\`typescript
|
|
20224
22022
|
{
|
|
20225
|
-
name: string, // Required. Display name
|
|
20226
|
-
description?: string, //
|
|
20227
|
-
|
|
20228
|
-
|
|
20229
|
-
|
|
20230
|
-
|
|
20231
|
-
|
|
20232
|
-
|
|
20233
|
-
|
|
20234
|
-
|
|
20235
|
-
internalSubAgents?: AgentConfig[], // Optional. Inline sub-agent configs
|
|
20236
|
-
middleware?: MiddlewareConfig[], // Optional. Additional middleware (topology is auto-added)
|
|
20237
|
-
modelKey?: string, // Optional. Model to use
|
|
22023
|
+
name: string, // Required. Display name
|
|
22024
|
+
description?: string, // Optional. Short description
|
|
22025
|
+
skillLoaded: true, // Required. Must be true \u2014 confirms skill was loaded
|
|
22026
|
+
workflow: { // Required. Concise DSL definition
|
|
22027
|
+
name: string, // Workflow slug identifier
|
|
22028
|
+
steps: WorkflowStep[], // agent | human | condition | map | parallel | end
|
|
22029
|
+
},
|
|
22030
|
+
tools?: string[], // Optional. Tool keys for the built-in general agent
|
|
22031
|
+
middleware?: MiddlewareConfig[], // Optional. Middleware for the general agent
|
|
22032
|
+
modelKey?: string, // Optional. Model for the general agent
|
|
20238
22033
|
}
|
|
20239
22034
|
\`\`\`
|
|
20240
22035
|
|
|
22036
|
+
### update_workflow
|
|
22037
|
+
|
|
22038
|
+
Updates an existing WORKFLOW agent. Only include fields you want to change.
|
|
22039
|
+
|
|
22040
|
+
\`\`\`typescript
|
|
22041
|
+
{
|
|
22042
|
+
id: string, // Required. Workflow agent ID
|
|
22043
|
+
name?: string, // Optional
|
|
22044
|
+
description?: string, // Optional
|
|
22045
|
+
workflow?: { name: string, steps: WorkflowStep[] }, // Optional. Replacement DSL
|
|
22046
|
+
tools?: string[], // Optional
|
|
22047
|
+
middleware?: MiddlewareConfig[], // Optional
|
|
22048
|
+
modelKey?: string, // Optional
|
|
22049
|
+
}
|
|
22050
|
+
\`\`\`
|
|
22051
|
+
|
|
22052
|
+
### validate_workflow
|
|
22053
|
+
|
|
22054
|
+
Validates a workflow agent's DSL and returns any errors or warnings.
|
|
22055
|
+
|
|
22056
|
+
\`\`\`typescript
|
|
22057
|
+
{
|
|
22058
|
+
id: string, // Required. Workflow agent ID to validate
|
|
22059
|
+
}
|
|
22060
|
+
\`\`\`
|
|
22061
|
+
|
|
22062
|
+
Returns: \`{ valid: boolean, stepCount, issues: [{ type: "error"|"warning", message }] }\`
|
|
22063
|
+
|
|
20241
22064
|
### Middleware Config Reference
|
|
20242
22065
|
|
|
20243
22066
|
Each middleware entry uses this base shape:
|
|
@@ -20329,8 +22152,8 @@ Provides: \`schedule_at\`, \`schedule_after\`, \`schedule_recurring\`, \`cancel_
|
|
|
20329
22152
|
|-------------|------|-------------|
|
|
20330
22153
|
| defaultMaxRetries | number? | Default max retries for scheduled tasks. Default: \`0\` |
|
|
20331
22154
|
|
|
20332
|
-
#### topology
|
|
20333
|
-
Provides: \`read_topo_progress\` \u2014 enforces multi-agent workflow topology
|
|
22155
|
+
#### topology [DEPRECATED \u2014 use WORKFLOW DSL instead]
|
|
22156
|
+
Provides: \`read_topo_progress\` \u2014 enforces multi-agent workflow topology for PROCESSING agents only. Not needed for WORKFLOW agents.
|
|
20334
22157
|
| config field | type | description |
|
|
20335
22158
|
|-------------|------|-------------|
|
|
20336
22159
|
| edges | TopologyEdge[] | **Required.** Directed edges: \`{ from: string, to: string, purpose: string }\`. The \`purpose\` must describe the business intent of this delegation step. |
|
|
@@ -20386,29 +22209,6 @@ Use \`manage_binding\` to bind external senders (email, Lark, Slack) to agents.
|
|
|
20386
22209
|
- **threadMode**: Always use \`"per_conversation"\` (new thread per conversation). Do NOT use \`"fixed"\`.
|
|
20387
22210
|
- **channelInstallationId**: Auto-detected if only one installation exists for the channel. Use \`list_installations\` first if unsure.
|
|
20388
22211
|
|
|
20389
|
-
### update_processing_agent
|
|
20390
|
-
|
|
20391
|
-
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.
|
|
20392
|
-
|
|
20393
|
-
\`\`\`typescript
|
|
20394
|
-
{
|
|
20395
|
-
id: string, // Required. The PROCESSING agent ID to update
|
|
20396
|
-
name?: string, // Optional. New display name
|
|
20397
|
-
description?: string, // Optional. New short description
|
|
20398
|
-
prompt?: string, // Optional. New orchestrator system prompt
|
|
20399
|
-
edges?: [{ // Optional. New topology edges (serial chain)
|
|
20400
|
-
from: string, // First edge: orchestrator name placeholder. Subsequent: previous sub-agent ID
|
|
20401
|
-
to: string, // Sub-agent ID
|
|
20402
|
-
purpose: string, // Business purpose
|
|
20403
|
-
}],
|
|
20404
|
-
subAgents?: string[], // Optional. New sub-agent IDs
|
|
20405
|
-
middleware?: MiddlewareConfig[], // Optional. Additional middleware (topology auto-managed)
|
|
20406
|
-
modelKey?: string, // Optional. New model
|
|
20407
|
-
}
|
|
20408
|
-
\`\`\`
|
|
20409
|
-
|
|
20410
|
-
**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.
|
|
20411
|
-
|
|
20412
22212
|
### update_agent parameters
|
|
20413
22213
|
|
|
20414
22214
|
\`\`\`typescript
|
|
@@ -20426,7 +22226,7 @@ Updates a PROCESSING agent's topology edges, name, prompt, or sub-agents. Unlike
|
|
|
20426
22226
|
`;
|
|
20427
22227
|
|
|
20428
22228
|
// src/agent_lattice/agentReviewerConfig.ts
|
|
20429
|
-
var
|
|
22229
|
+
var import_protocols13 = require("@axiom-lattice/protocols");
|
|
20430
22230
|
|
|
20431
22231
|
// src/agent_lattice/agentReviewerPrompt.ts
|
|
20432
22232
|
var AGENT_REVIEWER_PROMPT = `# Agent Reviewer
|
|
@@ -20489,7 +22289,7 @@ var agentReviewerConfig = {
|
|
|
20489
22289
|
key: AGENT_REVIEWER_KEY,
|
|
20490
22290
|
name: "Agent Reviewer",
|
|
20491
22291
|
description: "Review and test AI agents. Use this agent to check agent configurations for correctness and to test agents by invoking them with realistic messages.",
|
|
20492
|
-
type:
|
|
22292
|
+
type: import_protocols13.AgentType.REACT,
|
|
20493
22293
|
prompt: AGENT_REVIEWER_PROMPT,
|
|
20494
22294
|
tools: [
|
|
20495
22295
|
"invoke_agent",
|
|
@@ -20515,21 +22315,30 @@ var agentArchitectConfig = {
|
|
|
20515
22315
|
key: AGENT_ARCHITECT_KEY,
|
|
20516
22316
|
name: "Agent Architect",
|
|
20517
22317
|
description: "Design and manage AI agents through natural language conversation. Use this agent when you want to create a new agent, modify an existing agent, or manage your agent collection (list, view, update, delete).",
|
|
20518
|
-
type:
|
|
22318
|
+
type: import_protocols14.AgentType.DEEP_AGENT,
|
|
20519
22319
|
prompt: AGENT_ARCHITECT_PROMPT,
|
|
20520
22320
|
tools: [
|
|
20521
22321
|
"list_agents",
|
|
20522
22322
|
"list_tools",
|
|
20523
22323
|
"get_agent",
|
|
20524
22324
|
"create_agent",
|
|
20525
|
-
"
|
|
20526
|
-
"
|
|
22325
|
+
"create_workflow",
|
|
22326
|
+
"validate_workflow",
|
|
22327
|
+
"update_workflow",
|
|
20527
22328
|
"update_agent",
|
|
20528
22329
|
"delete_agent",
|
|
20529
22330
|
"manage_binding"
|
|
20530
22331
|
],
|
|
20531
22332
|
internalSubAgents: [agentReviewerConfig],
|
|
20532
22333
|
middleware: [
|
|
22334
|
+
{
|
|
22335
|
+
id: "skill",
|
|
22336
|
+
type: "skill",
|
|
22337
|
+
name: "Skill",
|
|
22338
|
+
description: "Load skill content and instructions",
|
|
22339
|
+
enabled: true,
|
|
22340
|
+
config: { readAll: true }
|
|
22341
|
+
},
|
|
20533
22342
|
{
|
|
20534
22343
|
id: "widget",
|
|
20535
22344
|
type: "widget",
|
|
@@ -20996,7 +22805,11 @@ var getAgentClient = (tenantId, key, options) => agentLatticeManager.initializeC
|
|
|
20996
22805
|
var getAgentClientAsync = async (tenantId, key, options) => agentLatticeManager.initializeClientAsync(tenantId, key, options);
|
|
20997
22806
|
var createAgentClientFromAgentLattice = async (agentLattice, options) => await agentLatticeManager.createAgentClientFromConfig(agentLattice, options);
|
|
20998
22807
|
|
|
22808
|
+
// src/index.ts
|
|
22809
|
+
init_memory_lattice();
|
|
22810
|
+
|
|
20999
22811
|
// src/embeddings_lattice/EmbeddingsLatticeManager.ts
|
|
22812
|
+
init_BaseLatticeManager();
|
|
21000
22813
|
var EmbeddingsLatticeManager = class _EmbeddingsLatticeManager extends BaseLatticeManager {
|
|
21001
22814
|
/**
|
|
21002
22815
|
* Get EmbeddingsLatticeManager singleton instance
|
|
@@ -21089,6 +22902,7 @@ var getEmbeddingsLattice = (key) => embeddingsLatticeManager.getEmbeddingsLattic
|
|
|
21089
22902
|
var getEmbeddingsClient = (key) => embeddingsLatticeManager.getEmbeddingsClient(key);
|
|
21090
22903
|
|
|
21091
22904
|
// src/vectorstore_lattice/VectorStoreLatticeManager.ts
|
|
22905
|
+
init_BaseLatticeManager();
|
|
21092
22906
|
var VectorStoreLatticeManager = class _VectorStoreLatticeManager extends BaseLatticeManager {
|
|
21093
22907
|
/**
|
|
21094
22908
|
* Get VectorStoreLatticeManager singleton instance
|
|
@@ -21181,7 +22995,8 @@ var getVectorStoreLattice = (key) => vectorStoreLatticeManager.getVectorStoreLat
|
|
|
21181
22995
|
var getVectorStoreClient = (key) => vectorStoreLatticeManager.getVectorStoreClient(key);
|
|
21182
22996
|
|
|
21183
22997
|
// src/logger_lattice/LoggerLatticeManager.ts
|
|
21184
|
-
|
|
22998
|
+
init_BaseLatticeManager();
|
|
22999
|
+
var import_protocols15 = require("@axiom-lattice/protocols");
|
|
21185
23000
|
|
|
21186
23001
|
// src/logger_lattice/PinoLoggerClient.ts
|
|
21187
23002
|
var import_pino = __toESM(require("pino"));
|
|
@@ -21403,11 +23218,11 @@ var LoggerLatticeManager = class _LoggerLatticeManager extends BaseLatticeManage
|
|
|
21403
23218
|
if (client) {
|
|
21404
23219
|
loggerClient = client;
|
|
21405
23220
|
} else {
|
|
21406
|
-
if (config.type ===
|
|
23221
|
+
if (config.type === import_protocols15.LoggerType.PINO) {
|
|
21407
23222
|
loggerClient = new PinoLoggerClient(config);
|
|
21408
|
-
} else if (config.type ===
|
|
23223
|
+
} else if (config.type === import_protocols15.LoggerType.CONSOLE) {
|
|
21409
23224
|
loggerClient = new ConsoleLoggerClient(config);
|
|
21410
|
-
} else if (config.type ===
|
|
23225
|
+
} else if (config.type === import_protocols15.LoggerType.CUSTOM) {
|
|
21411
23226
|
throw new Error(
|
|
21412
23227
|
`Custom logger client must be provided. Please pass the client to registerLattice.`
|
|
21413
23228
|
);
|
|
@@ -21496,6 +23311,7 @@ var registerLoggerLattice = (key, config, client) => loggerLatticeManager.regist
|
|
|
21496
23311
|
var getLoggerLattice = (key) => loggerLatticeManager.getLoggerLattice(key);
|
|
21497
23312
|
|
|
21498
23313
|
// src/skill_lattice/SkillLatticeManager.ts
|
|
23314
|
+
init_BaseLatticeManager();
|
|
21499
23315
|
var SkillLatticeManager = class _SkillLatticeManager extends BaseLatticeManager {
|
|
21500
23316
|
/**
|
|
21501
23317
|
* Get SkillLatticeManager singleton instance
|
|
@@ -21867,6 +23683,7 @@ var skillLatticeManager = SkillLatticeManager.getInstance();
|
|
|
21867
23683
|
|
|
21868
23684
|
// src/mcp_lattice/McpLatticeManager.ts
|
|
21869
23685
|
var import_mcp_adapters = require("@langchain/mcp-adapters");
|
|
23686
|
+
init_BaseLatticeManager();
|
|
21870
23687
|
var McpLatticeManager = class _McpLatticeManager extends BaseLatticeManager {
|
|
21871
23688
|
constructor() {
|
|
21872
23689
|
super(...arguments);
|
|
@@ -23319,6 +25136,11 @@ function clearEncryptionKeyCache() {
|
|
|
23319
25136
|
cachedKey = null;
|
|
23320
25137
|
keyValidated = false;
|
|
23321
25138
|
}
|
|
25139
|
+
|
|
25140
|
+
// src/workflow/index.ts
|
|
25141
|
+
init_compile();
|
|
25142
|
+
init_normalize();
|
|
25143
|
+
init_utils();
|
|
23322
25144
|
// Annotate the CommonJS export names for ESM import in node:
|
|
23323
25145
|
0 && (module.exports = {
|
|
23324
25146
|
AGENT_TASK_EVENT,
|
|
@@ -23402,21 +25224,28 @@ function clearEncryptionKeyCache() {
|
|
|
23402
25224
|
agentInstanceManager,
|
|
23403
25225
|
agentLatticeManager,
|
|
23404
25226
|
buildGrepResultsDict,
|
|
25227
|
+
buildInput,
|
|
23405
25228
|
buildNamedVolumeName,
|
|
23406
25229
|
buildSandboxMetadataEnv,
|
|
23407
25230
|
buildSkillFile,
|
|
25231
|
+
buildStateAnnotation,
|
|
23408
25232
|
checkEmptyContent,
|
|
23409
25233
|
clearEncryptionKeyCache,
|
|
25234
|
+
compileWorkflow,
|
|
23410
25235
|
computeSandboxName,
|
|
23411
25236
|
configureStores,
|
|
25237
|
+
createAgentNode,
|
|
23412
25238
|
createAgentTeam,
|
|
23413
25239
|
createExecuteSqlQueryTool,
|
|
23414
25240
|
createFileData,
|
|
25241
|
+
createHumanFeedbackNode,
|
|
23415
25242
|
createInfoSqlTool,
|
|
23416
25243
|
createListMetricsDataSourcesTool,
|
|
23417
25244
|
createListMetricsServersTool,
|
|
23418
25245
|
createListTablesSqlTool,
|
|
25246
|
+
createMapNode,
|
|
23419
25247
|
createModelSelectorMiddleware,
|
|
25248
|
+
createNodeHandler,
|
|
23420
25249
|
createProcessingAgent,
|
|
23421
25250
|
createQueryCheckerSqlTool,
|
|
23422
25251
|
createQueryMetricDefinitionTool,
|
|
@@ -23429,6 +25258,7 @@ function clearEncryptionKeyCache() {
|
|
|
23429
25258
|
createSchedulerMiddleware,
|
|
23430
25259
|
createTeamMiddleware,
|
|
23431
25260
|
createTeammateTools,
|
|
25261
|
+
createTerminalNode,
|
|
23432
25262
|
createUnknownToolHandlerMiddleware,
|
|
23433
25263
|
createWidgetMiddleware,
|
|
23434
25264
|
decrypt,
|
|
@@ -23438,7 +25268,9 @@ function clearEncryptionKeyCache() {
|
|
|
23438
25268
|
ensureBuiltinAgentsForTenant,
|
|
23439
25269
|
eventBus,
|
|
23440
25270
|
eventBusDefault,
|
|
25271
|
+
expand,
|
|
23441
25272
|
extractFetcherError,
|
|
25273
|
+
extractOutput,
|
|
23442
25274
|
fileDataToString,
|
|
23443
25275
|
formatContentWithLineNumbers,
|
|
23444
25276
|
formatGrepMatches,
|
|
@@ -23474,6 +25306,7 @@ function clearEncryptionKeyCache() {
|
|
|
23474
25306
|
grepMatchesFromFiles,
|
|
23475
25307
|
grepSearchFiles,
|
|
23476
25308
|
hasChunkBuffer,
|
|
25309
|
+
invokeWithRetry,
|
|
23477
25310
|
isBuiltInSkill,
|
|
23478
25311
|
isUsingDefaultKey,
|
|
23479
25312
|
isValidCronExpression,
|
|
@@ -23484,6 +25317,7 @@ function clearEncryptionKeyCache() {
|
|
|
23484
25317
|
metricsServerManager,
|
|
23485
25318
|
modelLatticeManager,
|
|
23486
25319
|
normalizeSandboxName,
|
|
25320
|
+
parallelLimit,
|
|
23487
25321
|
parseCronExpression,
|
|
23488
25322
|
parseSkillFrontmatter,
|
|
23489
25323
|
performStringReplacement,
|
|
@@ -23503,6 +25337,8 @@ function clearEncryptionKeyCache() {
|
|
|
23503
25337
|
registerTeammateAgent,
|
|
23504
25338
|
registerToolLattice,
|
|
23505
25339
|
registerVectorStoreLattice,
|
|
25340
|
+
renderTemplate,
|
|
25341
|
+
resolvePath,
|
|
23506
25342
|
sandboxLatticeManager,
|
|
23507
25343
|
sanitizeToolCallId,
|
|
23508
25344
|
scheduleLatticeManager,
|
|
@@ -23515,6 +25351,7 @@ function clearEncryptionKeyCache() {
|
|
|
23515
25351
|
unregisterTeammateAgent,
|
|
23516
25352
|
updateFileData,
|
|
23517
25353
|
validateAgentInput,
|
|
25354
|
+
validateDSL,
|
|
23518
25355
|
validateEncryptionKey,
|
|
23519
25356
|
validatePath,
|
|
23520
25357
|
validateSkillName,
|