@agent-phonon/protocol 0.3.0 → 0.6.0
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/schemas/capabilities.d.ts +9 -0
- package/dist/schemas/capabilities.d.ts.map +1 -1
- package/dist/schemas/capabilities.js +7 -0
- package/dist/schemas/capabilities.js.map +1 -1
- package/dist/schemas/discovery.d.ts +26 -0
- package/dist/schemas/discovery.d.ts.map +1 -1
- package/dist/schemas/methods.d.ts +676 -35
- package/dist/schemas/methods.d.ts.map +1 -1
- package/dist/schemas/methods.js +8 -1
- package/dist/schemas/methods.js.map +1 -1
- package/dist/schemas/stream.d.ts +192 -16
- package/dist/schemas/stream.d.ts.map +1 -1
- package/dist/schemas/stream.js +9 -0
- package/dist/schemas/stream.js.map +1 -1
- package/dist/schemas/workflow.d.ts +1555 -46
- package/dist/schemas/workflow.d.ts.map +1 -1
- package/dist/schemas/workflow.js +266 -17
- package/dist/schemas/workflow.js.map +1 -1
- package/package.json +1 -1
- package/src/schemas/capabilities.ts +7 -0
- package/src/schemas/methods.ts +8 -0
- package/src/schemas/stream.ts +9 -0
- package/src/schemas/workflow.ts +306 -18
package/src/schemas/workflow.ts
CHANGED
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { AgentId, ProjectId, SessionId, Timestamp } from "./common.js";
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* L3 Orchestration Protocol (workflow.*)
|
|
6
|
+
*
|
|
7
|
+
* Locked design (2026-06-23 v0.4 + v0.5 review):
|
|
8
|
+
* - L3 编排是 L1 session 的 wrapper,不重新发明 session 概念。
|
|
9
|
+
* - Node 创建出来的 L1 session 的所有 stream.event 自动带 workflowId / nodeId / role
|
|
10
|
+
* 字段(见 stream.ts),服务端按这些字段筛选/区分。
|
|
11
|
+
* workflow.event **不重复承载** session 流,只负责工作流级元事件。
|
|
12
|
+
* - phonon 只提供通用底层能力。category / wisdom 这类业务由上层 server 自行实现。
|
|
13
|
+
*/
|
|
14
|
+
|
|
4
15
|
const ModelId = z.string().min(1);
|
|
5
16
|
const TurnId = z.string().min(1);
|
|
6
17
|
const ClientRequestId = z.string().min(1);
|
|
@@ -8,12 +19,25 @@ const ClientRequestId = z.string().min(1);
|
|
|
8
19
|
export const WorkflowId = z.string().min(1);
|
|
9
20
|
export const WorkflowNodeId = z.string().min(1);
|
|
10
21
|
export const WorkflowEdgeId = z.string().min(1);
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Role 字段说明(review v0.5):
|
|
25
|
+
* role 是这个 agent 在当前 workflow 中扮演的角色,由调用方自由定义。
|
|
26
|
+
* phonon 只做透传 + 在 stream.event / workflow.event 里回显,不解析其语义。
|
|
27
|
+
* 常见示例:"executor" / "worker" / "reviewer" / "coder" / "planner" / "chairman" / "participant"
|
|
28
|
+
* 上层服务可以把 role 映射到 category / system prompt / 模型选择,phonon 不感知。
|
|
29
|
+
*/
|
|
11
30
|
export const WorkflowRoleId = z.string().min(1);
|
|
12
31
|
|
|
32
|
+
// ---------------------------------------------------------------------------
|
|
33
|
+
// Node / Edge / Plan
|
|
34
|
+
// ---------------------------------------------------------------------------
|
|
35
|
+
|
|
13
36
|
export const WorkflowNode = z.object({
|
|
14
37
|
nodeId: WorkflowNodeId,
|
|
15
38
|
agent: AgentId,
|
|
16
39
|
model: ModelId,
|
|
40
|
+
/** 该节点在 workflow 中扮演的角色(由调用方定义,phonon 仅回显)。 */
|
|
17
41
|
role: WorkflowRoleId.optional(),
|
|
18
42
|
input: z.string().optional(),
|
|
19
43
|
systemPrompt: z.string().optional(),
|
|
@@ -21,6 +45,32 @@ export const WorkflowNode = z.object({
|
|
|
21
45
|
sessionId: SessionId.optional(),
|
|
22
46
|
agentConfig: z.record(z.unknown()).optional(),
|
|
23
47
|
metadata: z.record(z.unknown()).optional(),
|
|
48
|
+
|
|
49
|
+
// ===== 执行环境(v0.6 改造。62026-06-23。不兼容旧 worktreeId 句柄语义)=====
|
|
50
|
+
/**
|
|
51
|
+
* 此节点跑在哪个 project。不传默认继承 workflow 级 project。
|
|
52
|
+
* project + workflow 级都没传,phonon 拒接。
|
|
53
|
+
*/
|
|
54
|
+
project: ProjectId.optional(),
|
|
55
|
+
/**
|
|
56
|
+
* 隔离 key。调用方自定义的任意字符串。
|
|
57
|
+
* - 不传 → 该节点跑在 project 主目录
|
|
58
|
+
* - 传了 → phonon 按 (projectId, worktreeId) 复合键维护隔离 worktree:
|
|
59
|
+
* • 同一 workflow 内首次看到 → 创建 worktree(branch 名 phonon 自动生成)
|
|
60
|
+
* • 同一 workflow 内后续节点用同一 key → 复用同一 worktree
|
|
61
|
+
* • 不跨 workflow 复用(下次 workflow.run 同名 key 是新 worktree)
|
|
62
|
+
* - workflow 终态时 phonon 尝试自动清理:git status 干净则 worktree remove;dirty 则保留
|
|
63
|
+
* 且发 workflow.status payload warn。创出的 branch 一律不删。
|
|
64
|
+
*/
|
|
65
|
+
worktreeId: z.string().optional(),
|
|
66
|
+
/**
|
|
67
|
+
* Git branch。意义联动 worktreeId:
|
|
68
|
+
* - 不传 worktreeId 传 branch → 在 project 主目录先 `git checkout <branch>` 再跑(对主目录有副作用,法定调用方负责)
|
|
69
|
+
* - 传 worktreeId 首次传 branch → 作为新 worktree 的 base branch(从它检出)
|
|
70
|
+
* - 传 worktreeId 未传 branch 首次 → 从 project 当前 branch 检出
|
|
71
|
+
* - worktreeId 复用时 branch 被忽略(worktree 已存在)
|
|
72
|
+
*/
|
|
73
|
+
branch: z.string().optional(),
|
|
24
74
|
});
|
|
25
75
|
export type WorkflowNode = z.infer<typeof WorkflowNode>;
|
|
26
76
|
|
|
@@ -49,35 +99,155 @@ export const WorkflowCommunicationGraph = z.object({
|
|
|
49
99
|
});
|
|
50
100
|
export type WorkflowCommunicationGraph = z.infer<typeof WorkflowCommunicationGraph>;
|
|
51
101
|
|
|
102
|
+
export const WorkflowExecutorNode = WorkflowNode.extend({
|
|
103
|
+
role: z.literal("executor").default("executor"),
|
|
104
|
+
});
|
|
105
|
+
export type WorkflowExecutorNode = z.infer<typeof WorkflowExecutorNode>;
|
|
106
|
+
|
|
52
107
|
export const WorkflowGraphPlan = z.object({
|
|
53
108
|
mode: z.literal("graph"),
|
|
54
|
-
executor:
|
|
55
|
-
nodeId: WorkflowNodeId,
|
|
56
|
-
agent: AgentId,
|
|
57
|
-
model: ModelId,
|
|
58
|
-
role: z.literal("executor").default("executor"),
|
|
59
|
-
systemPrompt: z.string().optional(),
|
|
60
|
-
agentConfig: z.record(z.unknown()).optional(),
|
|
61
|
-
}),
|
|
109
|
+
executor: WorkflowExecutorNode,
|
|
62
110
|
workers: z.array(WorkflowNode).min(1),
|
|
63
111
|
communicationGraph: WorkflowCommunicationGraph,
|
|
64
112
|
});
|
|
65
113
|
export type WorkflowGraphPlan = z.infer<typeof WorkflowGraphPlan>;
|
|
66
114
|
|
|
67
|
-
|
|
115
|
+
// ---------------------------------------------------------------------------
|
|
116
|
+
// Discussion plan (review v0.5 借鉴 4,对应 Foreman _run_discuss_rounds)
|
|
117
|
+
//
|
|
118
|
+
// N 个 agent 平等参与多轮讨论,chairman 控场决定何时终止。
|
|
119
|
+
// 与 graph 模式根本区别:没有路由 + 没有主从;所有 participant 每轮并行发言。
|
|
120
|
+
// ---------------------------------------------------------------------------
|
|
121
|
+
|
|
122
|
+
export const WorkflowDiscussionPlan = z.object({
|
|
123
|
+
mode: z.literal("discussion"),
|
|
124
|
+
/** 主题(initial input) — 所有 participant 第一轮收到这个。 */
|
|
125
|
+
topic: z.string(),
|
|
126
|
+
/** 参与者列表(无主从)。 */
|
|
127
|
+
participants: z.array(WorkflowNode).min(2),
|
|
128
|
+
/** Chairman 必须是 participants 之一的 nodeId,每轮所有 participant 发完它再 review + 决定续/停。 */
|
|
129
|
+
chairman: WorkflowNodeId,
|
|
130
|
+
termination: z
|
|
131
|
+
.object({
|
|
132
|
+
/** chairman 输出含该信号则终止。 */
|
|
133
|
+
chairmanSignal: z.string().default("[DISCUSS_END]"),
|
|
134
|
+
/** 硬上限。 */
|
|
135
|
+
maxRounds: z.number().int().positive().default(10),
|
|
136
|
+
/** 自然达成共识的检测字符串(任一 participant 输出含此则终止,可选)。 */
|
|
137
|
+
consensusSignal: z.string().optional(),
|
|
138
|
+
})
|
|
139
|
+
.default({}),
|
|
140
|
+
});
|
|
141
|
+
export type WorkflowDiscussionPlan = z.infer<typeof WorkflowDiscussionPlan>;
|
|
142
|
+
|
|
143
|
+
export const WorkflowPlan = z.discriminatedUnion("mode", [
|
|
144
|
+
WorkflowDagPlan,
|
|
145
|
+
WorkflowGraphPlan,
|
|
146
|
+
WorkflowDiscussionPlan,
|
|
147
|
+
]);
|
|
68
148
|
export type WorkflowPlan = z.infer<typeof WorkflowPlan>;
|
|
69
149
|
|
|
70
|
-
|
|
150
|
+
// ---------------------------------------------------------------------------
|
|
151
|
+
// Status enums
|
|
152
|
+
// ---------------------------------------------------------------------------
|
|
153
|
+
|
|
154
|
+
export const WorkflowStatus = z.enum([
|
|
155
|
+
"queued",
|
|
156
|
+
"running",
|
|
157
|
+
"completed",
|
|
158
|
+
"failed",
|
|
159
|
+
"cancelled",
|
|
160
|
+
"timeout",
|
|
161
|
+
]);
|
|
71
162
|
export type WorkflowStatus = z.infer<typeof WorkflowStatus>;
|
|
72
163
|
|
|
73
|
-
export const WorkflowNodeStatus = z.enum([
|
|
164
|
+
export const WorkflowNodeStatus = z.enum([
|
|
165
|
+
"pending",
|
|
166
|
+
"ready",
|
|
167
|
+
"running",
|
|
168
|
+
"completed",
|
|
169
|
+
"failed",
|
|
170
|
+
"skipped",
|
|
171
|
+
"cancelled",
|
|
172
|
+
]);
|
|
74
173
|
export type WorkflowNodeStatus = z.infer<typeof WorkflowNodeStatus>;
|
|
75
174
|
|
|
175
|
+
// ---------------------------------------------------------------------------
|
|
176
|
+
// Execution policy
|
|
177
|
+
// ---------------------------------------------------------------------------
|
|
178
|
+
|
|
179
|
+
export const WorkflowPolicy = z
|
|
180
|
+
.object({
|
|
181
|
+
timeoutSeconds: z.number().int().positive().optional(),
|
|
182
|
+
perNodeTimeoutSeconds: z.number().int().positive().optional(),
|
|
183
|
+
onNodeFailure: z.enum(["fail_workflow", "skip_dependents", "continue"]).default("fail_workflow"),
|
|
184
|
+
maxParallel: z.number().int().positive().optional(),
|
|
185
|
+
})
|
|
186
|
+
.partial();
|
|
187
|
+
export type WorkflowPolicy = z.infer<typeof WorkflowPolicy>;
|
|
188
|
+
|
|
189
|
+
// ---------------------------------------------------------------------------
|
|
190
|
+
// Shared context (review v0.5 借鉴 3:通用共享上下文,不是 SSOT)
|
|
191
|
+
//
|
|
192
|
+
// phonon 在每个 node create 时把 sharedContext 注入到 systemPrompt(追加形式)。
|
|
193
|
+
// 文件路径会被 phonon 解析为 workspace 内绝对路径(受 policy 沙箱保护)。
|
|
194
|
+
// 文件不存在则跳过该文件,不阻塞 workflow。
|
|
195
|
+
// ---------------------------------------------------------------------------
|
|
196
|
+
|
|
197
|
+
export const WorkflowSharedContext = z.object({
|
|
198
|
+
/** 直接文本:phonon 原样追加到每个 node 的 systemPrompt。 */
|
|
199
|
+
text: z.string().optional(),
|
|
200
|
+
/** workspace 相对路径列表(受 policy 沙箱);phonon 读取后拼成 markdown 段追加到 systemPrompt。 */
|
|
201
|
+
files: z.array(z.string()).optional(),
|
|
202
|
+
/** 注入位置:prepend 在最前,append 在最后,默认 append。 */
|
|
203
|
+
placement: z.enum(["prepend", "append"]).default("append"),
|
|
204
|
+
});
|
|
205
|
+
export type WorkflowSharedContext = z.infer<typeof WorkflowSharedContext>;
|
|
206
|
+
|
|
207
|
+
// ---------------------------------------------------------------------------
|
|
208
|
+
// Resume (review v0.5 借鉴 2:checkpoint + 断点续跑)
|
|
209
|
+
// ---------------------------------------------------------------------------
|
|
210
|
+
|
|
211
|
+
export const WorkflowResumeFrom = z.object({
|
|
212
|
+
/** 要恢复的 workflowId(必须先前 run 过,并有 checkpoint)。 */
|
|
213
|
+
workflowId: WorkflowId,
|
|
214
|
+
/**
|
|
215
|
+
* 起点策略:
|
|
216
|
+
* - "last_success_dependents" : 从最后成功节点的下游开始(DAG 默认)
|
|
217
|
+
* - "failed_node" : 重跑失败的那个 node(其他成功 node 不重做)
|
|
218
|
+
* - "node:<nodeId>" : 显式指定从某 node 开始
|
|
219
|
+
*/
|
|
220
|
+
strategy: z.union([
|
|
221
|
+
z.literal("last_success_dependents"),
|
|
222
|
+
z.literal("failed_node"),
|
|
223
|
+
z.string().regex(/^node:/),
|
|
224
|
+
]).default("failed_node"),
|
|
225
|
+
/** 可选:重置某些 node 的状态(让它们重跑),覆盖默认策略。 */
|
|
226
|
+
rerunNodes: z.array(WorkflowNodeId).optional(),
|
|
227
|
+
});
|
|
228
|
+
export type WorkflowResumeFrom = z.infer<typeof WorkflowResumeFrom>;
|
|
229
|
+
|
|
230
|
+
// ---------------------------------------------------------------------------
|
|
231
|
+
// workflow.run
|
|
232
|
+
// ---------------------------------------------------------------------------
|
|
233
|
+
|
|
76
234
|
export const WorkflowRunParams = z.object({
|
|
77
|
-
|
|
235
|
+
/**
|
|
236
|
+
* 默认 project。可以省略,但如果某个 node 也没传 project,phonon 会拒接。
|
|
237
|
+
* v0.6 起改为可选,支持每个 node 跳不同 project 的跨项目编排场景。
|
|
238
|
+
*/
|
|
239
|
+
project: ProjectId.optional(),
|
|
240
|
+
/** 默认隔离 key;node 未传 worktreeId 时继承该值。含义及复用规则同 WorkflowNode.worktreeId。 */
|
|
78
241
|
worktreeId: z.string().optional(),
|
|
242
|
+
/** 默认 branch;node 未传 branch 时继承。含义同 WorkflowNode.branch。 */
|
|
243
|
+
branch: z.string().optional(),
|
|
79
244
|
plan: WorkflowPlan,
|
|
80
245
|
input: z.string().optional(),
|
|
246
|
+
policy: WorkflowPolicy.optional(),
|
|
247
|
+
/** 共享上下文(v0.5 新增)。 */
|
|
248
|
+
sharedContext: WorkflowSharedContext.optional(),
|
|
249
|
+
/** 断点续跑(v0.5 新增)。传入则跳过 plan 重新规划,从 checkpoint 恢复。 */
|
|
250
|
+
resumeFrom: WorkflowResumeFrom.optional(),
|
|
81
251
|
clientRequestId: ClientRequestId.optional(),
|
|
82
252
|
metadata: z.record(z.unknown()).optional(),
|
|
83
253
|
});
|
|
@@ -87,11 +257,26 @@ export const WorkflowRunResult = z.object({
|
|
|
87
257
|
workflowId: WorkflowId,
|
|
88
258
|
status: WorkflowStatus,
|
|
89
259
|
createdAt: Timestamp,
|
|
260
|
+
/** 是否走的 resume 路径。 */
|
|
261
|
+
resumed: z.boolean().default(false),
|
|
90
262
|
});
|
|
91
263
|
export type WorkflowRunResult = z.infer<typeof WorkflowRunResult>;
|
|
92
264
|
|
|
93
|
-
|
|
94
|
-
|
|
265
|
+
// ---------------------------------------------------------------------------
|
|
266
|
+
// Node runtime state
|
|
267
|
+
// ---------------------------------------------------------------------------
|
|
268
|
+
|
|
269
|
+
export const WorkflowNodeResult = z.object({
|
|
270
|
+
text: z.string().optional(),
|
|
271
|
+
status: z.enum(["completed", "interrupted", "aborted", "failed", "timeout"]),
|
|
272
|
+
usage: z
|
|
273
|
+
.object({
|
|
274
|
+
inputTokens: z.number().int().nonnegative().optional(),
|
|
275
|
+
outputTokens: z.number().int().nonnegative().optional(),
|
|
276
|
+
})
|
|
277
|
+
.optional(),
|
|
278
|
+
});
|
|
279
|
+
export type WorkflowNodeResult = z.infer<typeof WorkflowNodeResult>;
|
|
95
280
|
|
|
96
281
|
export const WorkflowNodeRuntime = z.object({
|
|
97
282
|
nodeId: WorkflowNodeId,
|
|
@@ -104,19 +289,33 @@ export const WorkflowNodeRuntime = z.object({
|
|
|
104
289
|
startedAt: Timestamp.optional(),
|
|
105
290
|
completedAt: Timestamp.optional(),
|
|
106
291
|
error: z.string().optional(),
|
|
292
|
+
result: WorkflowNodeResult.optional(),
|
|
293
|
+
/** 该节点完成的轮次计数(discussion 用;DAG/Graph 一次执行 = 1)。 */
|
|
294
|
+
iterations: z.number().int().nonnegative().optional(),
|
|
107
295
|
});
|
|
108
296
|
export type WorkflowNodeRuntime = z.infer<typeof WorkflowNodeRuntime>;
|
|
109
297
|
|
|
298
|
+
// ---------------------------------------------------------------------------
|
|
299
|
+
// workflow.status / list / cancel
|
|
300
|
+
// ---------------------------------------------------------------------------
|
|
301
|
+
|
|
302
|
+
export const WorkflowStatusParams = z.object({ workflowId: WorkflowId });
|
|
303
|
+
export type WorkflowStatusParams = z.infer<typeof WorkflowStatusParams>;
|
|
304
|
+
|
|
110
305
|
export const WorkflowStatusResult = z.object({
|
|
111
306
|
workflowId: WorkflowId,
|
|
112
307
|
status: WorkflowStatus,
|
|
113
|
-
project
|
|
114
|
-
|
|
308
|
+
/** workflow 默认 project;v0.6 起可选。 */
|
|
309
|
+
project: ProjectId.optional(),
|
|
310
|
+
mode: z.enum(["dag", "graph", "discussion"]),
|
|
115
311
|
nodes: z.array(WorkflowNodeRuntime),
|
|
116
312
|
createdAt: Timestamp,
|
|
117
313
|
updatedAt: Timestamp,
|
|
118
314
|
completedAt: Timestamp.optional(),
|
|
119
315
|
error: z.string().optional(),
|
|
316
|
+
finalText: z.string().optional(),
|
|
317
|
+
/** 是否可 resume:phonon 持有该 workflow 的 checkpoint。 */
|
|
318
|
+
resumable: z.boolean().default(false),
|
|
120
319
|
});
|
|
121
320
|
export type WorkflowStatusResult = z.infer<typeof WorkflowStatusResult>;
|
|
122
321
|
|
|
@@ -127,17 +326,37 @@ export type WorkflowCancelResult = z.infer<typeof WorkflowCancelResult>;
|
|
|
127
326
|
|
|
128
327
|
export const WorkflowListParams = z.object({
|
|
129
328
|
status: WorkflowStatus.optional(),
|
|
329
|
+
projectId: ProjectId.optional(),
|
|
330
|
+
since: Timestamp.optional(),
|
|
331
|
+
until: Timestamp.optional(),
|
|
130
332
|
limit: z.number().int().positive().max(100).default(50).optional(),
|
|
131
333
|
cursor: z.string().optional(),
|
|
132
334
|
});
|
|
133
335
|
export type WorkflowListParams = z.infer<typeof WorkflowListParams>;
|
|
134
|
-
export const WorkflowListResult = z.object({
|
|
336
|
+
export const WorkflowListResult = z.object({
|
|
337
|
+
workflows: z.array(WorkflowStatusResult),
|
|
338
|
+
nextCursor: z.string().optional(),
|
|
339
|
+
});
|
|
135
340
|
export type WorkflowListResult = z.infer<typeof WorkflowListResult>;
|
|
136
341
|
|
|
342
|
+
// ---------------------------------------------------------------------------
|
|
343
|
+
// workflow.event
|
|
344
|
+
// v0.5 新增事件类型:round.started / round.completed / discussion.terminated
|
|
345
|
+
// (为 Discussion 模式准备;DAG/Graph 不发这些)
|
|
346
|
+
// ---------------------------------------------------------------------------
|
|
347
|
+
|
|
137
348
|
export const WorkflowEvent = z.object({
|
|
138
349
|
workflowId: WorkflowId,
|
|
139
350
|
seq: z.number().int().nonnegative(),
|
|
140
|
-
type: z.enum([
|
|
351
|
+
type: z.enum([
|
|
352
|
+
"workflow.status",
|
|
353
|
+
"node.status",
|
|
354
|
+
"edge.route",
|
|
355
|
+
"executor.decision",
|
|
356
|
+
"round.started", // discussion / graph iteration 轮次开始
|
|
357
|
+
"round.completed", // 一轮所有参与者发完
|
|
358
|
+
"discussion.terminated", // discussion 终止(含理由)
|
|
359
|
+
]),
|
|
141
360
|
nodeId: WorkflowNodeId.optional(),
|
|
142
361
|
sessionId: SessionId.optional(),
|
|
143
362
|
turnId: TurnId.optional(),
|
|
@@ -145,7 +364,76 @@ export const WorkflowEvent = z.object({
|
|
|
145
364
|
model: ModelId.optional(),
|
|
146
365
|
role: WorkflowRoleId.optional(),
|
|
147
366
|
status: z.union([WorkflowStatus, WorkflowNodeStatus]).optional(),
|
|
367
|
+
result: WorkflowNodeResult.optional(),
|
|
368
|
+
/** 自由载荷。常见字段:iteration, from, to, reason, terminationReason 等。 */
|
|
148
369
|
payload: z.record(z.unknown()).optional(),
|
|
149
370
|
timestamp: Timestamp,
|
|
150
371
|
});
|
|
151
372
|
export type WorkflowEvent = z.infer<typeof WorkflowEvent>;
|
|
373
|
+
|
|
374
|
+
// ---------------------------------------------------------------------------
|
|
375
|
+
// workflow.ack
|
|
376
|
+
// ---------------------------------------------------------------------------
|
|
377
|
+
|
|
378
|
+
export const WorkflowAckParams = z.object({
|
|
379
|
+
workflowId: WorkflowId,
|
|
380
|
+
lastSeq: z.number().int().nonnegative(),
|
|
381
|
+
});
|
|
382
|
+
export type WorkflowAckParams = z.infer<typeof WorkflowAckParams>;
|
|
383
|
+
|
|
384
|
+
// ---------------------------------------------------------------------------
|
|
385
|
+
// Routing directive — v0.5 升级为判别联合(review 借鉴 1)
|
|
386
|
+
//
|
|
387
|
+
// Executor agent 在输出里 emit fenced JSON / structured block,phonon 解析后
|
|
388
|
+
// 升级成内部动作。新增 feedback / reply / done 三种语义,比单一 route 表达力强。
|
|
389
|
+
//
|
|
390
|
+
// kind 缺省时回退为 workflow.route(向后兼容 0.4 行为)。
|
|
391
|
+
// 兼容前缀:```phonon.workflow.* / ```workflow.*。
|
|
392
|
+
// ---------------------------------------------------------------------------
|
|
393
|
+
|
|
394
|
+
/** route:派新任务给目标 worker(v0.4 既有语义)。 */
|
|
395
|
+
export const WorkflowRouteDirective = z.object({
|
|
396
|
+
kind: z.literal("workflow.route"),
|
|
397
|
+
to: z.union([WorkflowNodeId, z.array(WorkflowNodeId).min(1)]),
|
|
398
|
+
message: z.string(),
|
|
399
|
+
reason: z.string().optional(),
|
|
400
|
+
metadata: z.record(z.unknown()).optional(),
|
|
401
|
+
});
|
|
402
|
+
export type WorkflowRouteDirective = z.infer<typeof WorkflowRouteDirective>;
|
|
403
|
+
|
|
404
|
+
/** feedback:让目标 worker 基于上次输出返工修订(显式语义,区分于新任务)。 */
|
|
405
|
+
export const WorkflowFeedbackDirective = z.object({
|
|
406
|
+
kind: z.literal("workflow.feedback"),
|
|
407
|
+
to: WorkflowNodeId,
|
|
408
|
+
message: z.string(),
|
|
409
|
+
reason: z.string().optional(),
|
|
410
|
+
metadata: z.record(z.unknown()).optional(),
|
|
411
|
+
});
|
|
412
|
+
export type WorkflowFeedbackDirective = z.infer<typeof WorkflowFeedbackDirective>;
|
|
413
|
+
|
|
414
|
+
/** reply:模拟键盘输入(应答目标 agent 卡住的交互提示,如 [Y/n])。 */
|
|
415
|
+
export const WorkflowReplyDirective = z.object({
|
|
416
|
+
kind: z.literal("workflow.reply"),
|
|
417
|
+
to: WorkflowNodeId,
|
|
418
|
+
/** 应答内容(通常 1-2 字符:"Y"/"n"/"y" 等)。 */
|
|
419
|
+
keystroke: z.string(),
|
|
420
|
+
reason: z.string().optional(),
|
|
421
|
+
});
|
|
422
|
+
export type WorkflowReplyDirective = z.infer<typeof WorkflowReplyDirective>;
|
|
423
|
+
|
|
424
|
+
/** done:显式宣告 workflow 完成。 */
|
|
425
|
+
export const WorkflowDoneDirective = z.object({
|
|
426
|
+
kind: z.literal("workflow.done"),
|
|
427
|
+
/** 最终总结文本,作为 workflow.finalText。 */
|
|
428
|
+
finalSummary: z.string().optional(),
|
|
429
|
+
reason: z.string().optional(),
|
|
430
|
+
});
|
|
431
|
+
export type WorkflowDoneDirective = z.infer<typeof WorkflowDoneDirective>;
|
|
432
|
+
|
|
433
|
+
export const WorkflowRoutingDirective = z.discriminatedUnion("kind", [
|
|
434
|
+
WorkflowRouteDirective,
|
|
435
|
+
WorkflowFeedbackDirective,
|
|
436
|
+
WorkflowReplyDirective,
|
|
437
|
+
WorkflowDoneDirective,
|
|
438
|
+
]);
|
|
439
|
+
export type WorkflowRoutingDirective = z.infer<typeof WorkflowRoutingDirective>;
|