@axiom-lattice/protocols 2.1.42 → 2.1.43
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/.eslintrc.json +22 -0
- package/.turbo/turbo-build.log +8 -8
- package/CHANGELOG.md +6 -0
- package/dist/index.d.mts +447 -95
- package/dist/index.d.ts +447 -95
- package/dist/index.js.map +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/AgentLatticeProtocol.ts +8 -9
- package/src/AssistantStoreProtocol.ts +19 -0
- package/src/ChannelAdapterProtocol.ts +20 -0
- package/src/ChannelInstallationStoreProtocol.ts +8 -0
- package/src/InternalDSL.ts +11 -21
- package/src/MenuProtocol.ts +70 -0
- package/src/MessageProtocol.ts +1 -1
- package/src/SkillStoreProtocol.ts +1 -1
- package/src/TaskStoreProtocol.ts +306 -0
- package/src/UILatticeProtocol.ts +4 -4
- package/src/WorkflowDSL.ts +53 -328
- package/src/WorkflowTrackingStoreProtocol.ts +4 -1
- package/src/index.ts +2 -0
package/src/WorkflowDSL.ts
CHANGED
|
@@ -1,347 +1,72 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Workflow DSL
|
|
2
|
+
* YAML Workflow DSL — linear model with parallel blocks
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Steps execute top-to-bottom. `parallel:` blocks declare concurrency.
|
|
5
|
+
* `if` on any step skips it. `map` iterates over arrays.
|
|
6
|
+
* No `needs` — execution order = reading order.
|
|
7
7
|
*
|
|
8
8
|
* Template syntax:
|
|
9
|
-
* {{input}}
|
|
10
|
-
* {{
|
|
11
|
-
* {{
|
|
9
|
+
* {{input}} — initial user input
|
|
10
|
+
* {{label}} — output of step with given label
|
|
11
|
+
* {{label.field}} — nested field access on structured output
|
|
12
|
+
* {{item}} — current element in map iterations
|
|
12
13
|
*/
|
|
13
14
|
|
|
14
15
|
// ─── Top-level ─────────────────────────────────────────────────────────────
|
|
15
16
|
|
|
16
|
-
export interface
|
|
17
|
-
name
|
|
18
|
-
steps: WorkflowStep[];
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export type WorkflowStep =
|
|
22
|
-
| AgentStep
|
|
23
|
-
| ConditionStep
|
|
24
|
-
| HumanStep
|
|
25
|
-
| MapStep
|
|
26
|
-
| ParallelStep
|
|
27
|
-
| EndStep;
|
|
28
|
-
|
|
29
|
-
// ─── Steps ─────────────────────────────────────────────────────────────────
|
|
30
|
-
|
|
31
|
-
/** invoke the workflow's built-in agent. type defaults to "agent". */
|
|
32
|
-
export interface AgentStep {
|
|
33
|
-
id?: string;
|
|
34
|
-
type?: "agent";
|
|
17
|
+
export interface YamlWorkflow {
|
|
18
|
+
/** Optional workflow name — defaults to "workflow" if omitted. */
|
|
35
19
|
name?: string;
|
|
36
|
-
|
|
37
|
-
schema?: Record<string, unknown>;
|
|
20
|
+
steps: YamlTopLevelStep[];
|
|
38
21
|
}
|
|
39
22
|
|
|
40
|
-
|
|
41
|
-
export interface ConditionStep {
|
|
42
|
-
id?: string;
|
|
43
|
-
type: "condition";
|
|
44
|
-
if: string;
|
|
45
|
-
then?: WorkflowStep[] | WorkflowStep;
|
|
46
|
-
else?: WorkflowStep[] | WorkflowStep;
|
|
47
|
-
branches?: Record<string, WorkflowStep[] | WorkflowStep>;
|
|
48
|
-
}
|
|
23
|
+
export type YamlTopLevelStep = YamlAgentStep | YamlParallelBlock | YamlMapStep;
|
|
49
24
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
25
|
+
// ─── Agent step ────────────────────────────────────────────────────────────
|
|
26
|
+
|
|
27
|
+
export interface YamlAgentStep {
|
|
28
|
+
/** Unique label serving as state key and template reference. */
|
|
29
|
+
label: string;
|
|
30
|
+
/** JS expression evaluated as boolean. Step skipped when falsy. */
|
|
31
|
+
if?: string;
|
|
32
|
+
/** Agent instruction with {{template}} references. */
|
|
54
33
|
prompt: string;
|
|
55
|
-
|
|
56
|
-
|
|
34
|
+
/** Shorthand output schema: { field: "string" | "number" | "boolean" } */
|
|
35
|
+
output?: Record<string, unknown>;
|
|
36
|
+
/** When true, inject ask_user_to_clarify middleware. */
|
|
37
|
+
ask?: boolean;
|
|
57
38
|
}
|
|
58
39
|
|
|
59
|
-
|
|
60
|
-
export interface MapStep {
|
|
61
|
-
id: string;
|
|
62
|
-
type: "map";
|
|
63
|
-
source: string; // id of the step that produces the array
|
|
64
|
-
each: AgentStep; // applied to every element
|
|
65
|
-
reduce?: AgentStep; // optional aggregation
|
|
66
|
-
batch?: number; // default 50
|
|
67
|
-
concurrency?: number; // default 5
|
|
68
|
-
}
|
|
40
|
+
// ─── Parallel block ────────────────────────────────────────────────────────
|
|
69
41
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
42
|
+
export interface YamlParallelBlock {
|
|
43
|
+
parallel: YamlAgentStep[];
|
|
44
|
+
/** JS expression evaluated as boolean. Entire block skipped when falsy. */
|
|
45
|
+
if?: string;
|
|
46
|
+
/** Shorthand output schema for aggregated results. */
|
|
47
|
+
output?: Record<string, unknown>;
|
|
75
48
|
}
|
|
76
49
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
50
|
+
// ─── Map step ──────────────────────────────────────────────────────────────
|
|
51
|
+
|
|
52
|
+
export interface YamlMapStep {
|
|
53
|
+
map: {
|
|
54
|
+
/** Path to source array (e.g. "extract.items"). */
|
|
55
|
+
source: string;
|
|
56
|
+
/** Step label for referencing in templates (e.g. {{label}}). */
|
|
57
|
+
label: string;
|
|
58
|
+
/** JS expression evaluated as boolean. Entire map skipped when falsy. */
|
|
59
|
+
if?: string;
|
|
60
|
+
/** Agent applied to each element. Use {{item}} for current element. */
|
|
61
|
+
each: {
|
|
62
|
+
prompt: string;
|
|
63
|
+
output?: Record<string, unknown>;
|
|
64
|
+
};
|
|
65
|
+
/** Shorthand output schema for the aggregated results. */
|
|
66
|
+
output?: Record<string, unknown>;
|
|
67
|
+
/** Items per batch (default 50). */
|
|
68
|
+
batch?: number;
|
|
69
|
+
/** Max parallel items (default 5). */
|
|
70
|
+
concurrency?: number;
|
|
71
|
+
};
|
|
81
72
|
}
|
|
82
|
-
|
|
83
|
-
// ─── Examples ─────────────────────────────────────────────────────────────
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Example 1 — Linear: agent → agent → end
|
|
87
|
-
*
|
|
88
|
-
* When `id` is omitted, one is auto-generated. Template uses {{id}} to
|
|
89
|
-
* reference previous step outputs.
|
|
90
|
-
*
|
|
91
|
-
* @example
|
|
92
|
-
* ```json
|
|
93
|
-
* {
|
|
94
|
-
* "name": "知识问答",
|
|
95
|
-
* "steps": [
|
|
96
|
-
* { "id": "researcher", "prompt": "查询: {{input}}" },
|
|
97
|
-
* { "id": "writer", "prompt": "根据 {{researcher}} 写回答" },
|
|
98
|
-
* { "type": "end" }
|
|
99
|
-
* ]
|
|
100
|
-
* }
|
|
101
|
-
* ```
|
|
102
|
-
*/
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* Example 2 — Structured output with schema
|
|
106
|
-
*
|
|
107
|
-
* `schema: true` tells the agent to return JSON. The model infers the shape
|
|
108
|
-
* from the prompt description. For strict validation, pass a JSON Schema object.
|
|
109
|
-
*
|
|
110
|
-
* @example
|
|
111
|
-
* ```json
|
|
112
|
-
* {
|
|
113
|
-
* "name": "订单提取",
|
|
114
|
-
* "steps": [
|
|
115
|
-
* {
|
|
116
|
-
* "id": "order",
|
|
117
|
-
* "prompt": "提取订单: {items: [{name, qty, price}], total, urgent}",
|
|
118
|
-
* "schema": true
|
|
119
|
-
* },
|
|
120
|
-
* {
|
|
121
|
-
* "type": "condition", "if": "order.urgent",
|
|
122
|
-
* "then": { "id": "fast", "prompt": "加急: {{order}}" },
|
|
123
|
-
* "else": { "id": "normal", "prompt": "常规: {{order}}" }
|
|
124
|
-
* },
|
|
125
|
-
* { "type": "end" }
|
|
126
|
-
* ]
|
|
127
|
-
* }
|
|
128
|
-
* ```
|
|
129
|
-
*/
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* Example 3 — Custom id for semantic naming
|
|
133
|
-
*
|
|
134
|
-
* @example
|
|
135
|
-
* ```json
|
|
136
|
-
* {
|
|
137
|
-
* "name": "翻译",
|
|
138
|
-
* "steps": [
|
|
139
|
-
* { "id": "原文", "prompt": "翻译: {{input}}" },
|
|
140
|
-
* { "id": "校对", "prompt": "校对: {{原文}}" },
|
|
141
|
-
* { "type": "end" }
|
|
142
|
-
* ]
|
|
143
|
-
* }
|
|
144
|
-
* ```
|
|
145
|
-
*/
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* Example 4 — Condition (binary if/else)
|
|
149
|
-
*
|
|
150
|
-
* @example
|
|
151
|
-
* ```json
|
|
152
|
-
* {
|
|
153
|
-
* "name": "客服分流",
|
|
154
|
-
* "steps": [
|
|
155
|
-
* { "id": "intent", "prompt": "分类: {{input}}" },
|
|
156
|
-
* {
|
|
157
|
-
* "type": "condition", "if": "intent",
|
|
158
|
-
* "then": { "id": "support", "prompt": "支持: {{input}}" },
|
|
159
|
-
* "else": { "id": "sales", "prompt": "销售: {{input}}" }
|
|
160
|
-
* },
|
|
161
|
-
* { "type": "end" }
|
|
162
|
-
* ]
|
|
163
|
-
* }
|
|
164
|
-
* ```
|
|
165
|
-
*/
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
* Example 4b — Switch (multi-branch condition)
|
|
169
|
-
*
|
|
170
|
-
* When the agent's output is a fixed set of categories, use `branches`
|
|
171
|
-
* instead of nested if/else. The `if` expression evaluates to the state field
|
|
172
|
-
* value, which is matched against the branch keys. `default` is a catch-all.
|
|
173
|
-
*
|
|
174
|
-
* @example
|
|
175
|
-
* ```json
|
|
176
|
-
* {
|
|
177
|
-
* "name": "客服分流",
|
|
178
|
-
* "steps": [
|
|
179
|
-
* { "id": "intent", "prompt": "分类意图: {{input}}" },
|
|
180
|
-
* {
|
|
181
|
-
* "type": "condition", "if": "intent",
|
|
182
|
-
* "branches": {
|
|
183
|
-
* "support": { "id": "support", "prompt": "技术支持: {{input}}" },
|
|
184
|
-
* "sales": { "id": "sales", "prompt": "销售咨询: {{input}}" },
|
|
185
|
-
* "billing": { "id": "billing", "prompt": "账单查询: {{input}}" },
|
|
186
|
-
* "default": { "id": "fallback", "prompt": "转接人工: {{input}}" }
|
|
187
|
-
* }
|
|
188
|
-
* },
|
|
189
|
-
* { "type": "end" }
|
|
190
|
-
* ]
|
|
191
|
-
* }
|
|
192
|
-
* ```
|
|
193
|
-
*/
|
|
194
|
-
|
|
195
|
-
/**
|
|
196
|
-
* Example 5 — Condition with expression
|
|
197
|
-
*
|
|
198
|
-
* @example
|
|
199
|
-
* ```json
|
|
200
|
-
* {
|
|
201
|
-
* "name": "评分判定",
|
|
202
|
-
* "steps": [
|
|
203
|
-
* { "id": "score", "prompt": "打分: {{input}}" },
|
|
204
|
-
* {
|
|
205
|
-
* "type": "condition", "if": "score >= 60",
|
|
206
|
-
* "then": [
|
|
207
|
-
* { "id": "congrats", "prompt": "恭喜通过" },
|
|
208
|
-
* { "type": "end" }
|
|
209
|
-
* ],
|
|
210
|
-
* "else": { "type": "end", "status": "failed" }
|
|
211
|
-
* }
|
|
212
|
-
* ]
|
|
213
|
-
* }
|
|
214
|
-
* ```
|
|
215
|
-
*/
|
|
216
|
-
|
|
217
|
-
/**
|
|
218
|
-
* Example 6 — Human feedback (agent + clarify middleware)
|
|
219
|
-
*
|
|
220
|
-
* The human step invokes an agent with ask_user_to_clarify middleware.
|
|
221
|
-
* The agent decides what questions to ask based on the prompt. A schema
|
|
222
|
-
* constrains the structured output stored under the step's id.
|
|
223
|
-
*
|
|
224
|
-
* @example
|
|
225
|
-
* ```json
|
|
226
|
-
* {
|
|
227
|
-
* "name": "审批流程",
|
|
228
|
-
* "steps": [
|
|
229
|
-
* { "id": "draft", "prompt": "起草: {{input}}" },
|
|
230
|
-
* { "id": "review", "type": "human",
|
|
231
|
-
* "title": "审批",
|
|
232
|
-
* "prompt": "你是审批员。审核以下方案并请用户选择通过或驳回,附上意见。\\n\\n方案:\\n{{draft}}",
|
|
233
|
-
* "schema": { "type": "object", "properties": { "approved": { "type": "boolean" }, "comments": { "type": "string" } } } },
|
|
234
|
-
* {
|
|
235
|
-
* "type": "condition", "if": "review.approved",
|
|
236
|
-
* "then": { "prompt": "发布: {{draft}}" },
|
|
237
|
-
* "else": { "prompt": "修改: {{review.comments}}" }
|
|
238
|
-
* },
|
|
239
|
-
* { "type": "end" }
|
|
240
|
-
* ]
|
|
241
|
-
* }
|
|
242
|
-
* ```
|
|
243
|
-
*/
|
|
244
|
-
|
|
245
|
-
/**
|
|
246
|
-
* Example 7 — Parallel (fixed fan-out)
|
|
247
|
-
*
|
|
248
|
-
* @example
|
|
249
|
-
* ```json
|
|
250
|
-
* {
|
|
251
|
-
* "name": "尽职调查",
|
|
252
|
-
* "steps": [
|
|
253
|
-
* { "id": "info", "prompt": "收集: {{input}}" },
|
|
254
|
-
* {
|
|
255
|
-
* "type": "parallel", "steps": [
|
|
256
|
-
* { "id": "legal", "prompt": "法务: {{info}}" },
|
|
257
|
-
* { "id": "finance", "prompt": "财务: {{info}}" },
|
|
258
|
-
* { "id": "market", "prompt": "市场: {{info}}" }
|
|
259
|
-
* ]
|
|
260
|
-
* },
|
|
261
|
-
* { "id": "report", "prompt": "汇总: {{legal}} {{finance}} {{market}}" },
|
|
262
|
-
* { "type": "end" }
|
|
263
|
-
* ]
|
|
264
|
-
* }
|
|
265
|
-
* ```
|
|
266
|
-
*/
|
|
267
|
-
|
|
268
|
-
/**
|
|
269
|
-
* Example 8 — Map (dynamic iteration)
|
|
270
|
-
*
|
|
271
|
-
* @example
|
|
272
|
-
* ```json
|
|
273
|
-
* {
|
|
274
|
-
* "name": "批量审核",
|
|
275
|
-
* "steps": [
|
|
276
|
-
* { "id": "items", "prompt": "提取待审核项: {{input}}" },
|
|
277
|
-
* {
|
|
278
|
-
* "id": "results", "type": "map", "source": "items",
|
|
279
|
-
* "each": { "id": "auditor", "prompt": "审核: {{item}}" },
|
|
280
|
-
* "batch": 10, "concurrency": 3
|
|
281
|
-
* },
|
|
282
|
-
* { "id": "summary", "prompt": "总结: {{results}}" },
|
|
283
|
-
* { "type": "end" }
|
|
284
|
-
* ]
|
|
285
|
-
* }
|
|
286
|
-
* ```
|
|
287
|
-
*/
|
|
288
|
-
|
|
289
|
-
/**
|
|
290
|
-
* Example 9 — Map + reduce
|
|
291
|
-
*
|
|
292
|
-
* @example
|
|
293
|
-
* ```json
|
|
294
|
-
* {
|
|
295
|
-
* "name": "舆情分析",
|
|
296
|
-
* "steps": [
|
|
297
|
-
* { "id": "posts", "prompt": "抓取: {{input}}" },
|
|
298
|
-
* {
|
|
299
|
-
* "id": "sentiments", "type": "map", "source": "posts",
|
|
300
|
-
* "each": { "id": "sentiment", "prompt": "分析情感: {{item}}" },
|
|
301
|
-
* "reduce": { "id": "aggregator", "prompt": "汇总: {{sentiments}}" }
|
|
302
|
-
* },
|
|
303
|
-
* { "id": "report", "prompt": "报告: {{aggregator}}" },
|
|
304
|
-
* { "type": "end" }
|
|
305
|
-
* ]
|
|
306
|
-
* }
|
|
307
|
-
* ```
|
|
308
|
-
*/
|
|
309
|
-
|
|
310
|
-
/**
|
|
311
|
-
* Example 10 — Full pipeline (all types)
|
|
312
|
-
*
|
|
313
|
-
* @example
|
|
314
|
-
* ```json
|
|
315
|
-
* {
|
|
316
|
-
* "name": "智能客服",
|
|
317
|
-
* "steps": [
|
|
318
|
-
* { "id": "intent", "prompt": "分类: {{input}}" },
|
|
319
|
-
* {
|
|
320
|
-
* "type": "condition", "if": "intent",
|
|
321
|
-
* "then": [
|
|
322
|
-
* { "id": "kb", "prompt": "查知识库: {{input}}" },
|
|
323
|
-
* {
|
|
324
|
-
* "type": "condition", "if": "kb.confidence > 0.8",
|
|
325
|
-
* "then": { "id": "reply", "prompt": "直接回复: {{kb}}" },
|
|
326
|
-
* "else": [
|
|
327
|
-
* { "id": "pre_merge", "prompt": "准备合并" },
|
|
328
|
-
* { "type": "parallel", "steps": [
|
|
329
|
-
* { "id": "faq", "prompt": "FAQ: {{input}}" },
|
|
330
|
-
* { "id": "hist", "prompt": "历史: {{input}}" }
|
|
331
|
-
* ]},
|
|
332
|
-
* { "id": "merged", "prompt": "合并: FAQ={{faq}} 历史={{hist}}" },
|
|
333
|
-
* { "id": "review", "type": "human",
|
|
334
|
-
* "title": "转人工", "prompt": "请处理:\\n{{merged}}",
|
|
335
|
-
* "schema": { "type": "object", "properties": { "action": { "type": "string" } } }
|
|
336
|
-
* },
|
|
337
|
-
* { "id": "response", "prompt": "回复: {{review}}" }
|
|
338
|
-
* ]
|
|
339
|
-
* }
|
|
340
|
-
* ],
|
|
341
|
-
* "else": { "id": "clarify", "prompt": "请用户澄清" }
|
|
342
|
-
* },
|
|
343
|
-
* { "type": "end" }
|
|
344
|
-
* ]
|
|
345
|
-
* }
|
|
346
|
-
* ```
|
|
347
|
-
*/
|
|
@@ -31,7 +31,7 @@ export interface WorkflowRun {
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
export type StepType = 'task_delegation' | 'tool_call' | 'human_in_loop' | 'topology_transition' | 'agent' | 'human_feedback' | 'map' | 'input' | 'terminal';
|
|
34
|
-
export type StepStatus = 'running' | 'completed' | 'failed' | 'interrupted';
|
|
34
|
+
export type StepStatus = 'running' | 'completed' | 'failed' | 'interrupted' | 'skipped';
|
|
35
35
|
|
|
36
36
|
export interface RunStep {
|
|
37
37
|
id: string;
|
|
@@ -39,6 +39,8 @@ export interface RunStep {
|
|
|
39
39
|
tenantId: string;
|
|
40
40
|
stepType: StepType;
|
|
41
41
|
stepName: string;
|
|
42
|
+
/** Sub-agent thread_id for agent/map steps. null for input/terminal. */
|
|
43
|
+
threadId?: string | null;
|
|
42
44
|
edgeFrom?: string;
|
|
43
45
|
edgeTo?: string;
|
|
44
46
|
edgePurpose?: string;
|
|
@@ -74,6 +76,7 @@ export interface CreateRunStepRequest {
|
|
|
74
76
|
tenantId: string;
|
|
75
77
|
stepType: StepType;
|
|
76
78
|
stepName: string;
|
|
79
|
+
threadId?: string | null;
|
|
77
80
|
edgeFrom?: string;
|
|
78
81
|
edgeTo?: string;
|
|
79
82
|
edgePurpose?: string;
|
package/src/index.ts
CHANGED
|
@@ -31,7 +31,9 @@ export * from "./UserStoreProtocol";
|
|
|
31
31
|
export * from "./UserTenantLinkProtocol";
|
|
32
32
|
export * from "./WorkflowTrackingStoreProtocol";
|
|
33
33
|
export * from "./BindingProtocol";
|
|
34
|
+
export * from "./MenuProtocol";
|
|
34
35
|
export * from "./EvalStoreProtocol";
|
|
36
|
+
export * from "./TaskStoreProtocol";
|
|
35
37
|
|
|
36
38
|
export * from "./ChannelAdapterProtocol";
|
|
37
39
|
export * from "./A2AProtocol";
|