@mickorz/opencode-agentic-workflow 0.4.0 → 0.5.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.
Files changed (127) hide show
  1. package/README.md +306 -5
  2. package/dist/cli/config.d.ts +121 -0
  3. package/dist/cli/config.js +331 -0
  4. package/dist/cli/config.js.map +1 -0
  5. package/dist/cli/doctor.d.ts +5 -0
  6. package/dist/cli/doctor.js +141 -0
  7. package/dist/cli/doctor.js.map +1 -0
  8. package/dist/cli/index.d.ts +18 -0
  9. package/dist/cli/index.js +120 -0
  10. package/dist/cli/index.js.map +1 -0
  11. package/dist/cli/install.d.ts +19 -0
  12. package/dist/cli/install.js +135 -0
  13. package/dist/cli/install.js.map +1 -0
  14. package/dist/cli/uninstall.d.ts +16 -0
  15. package/dist/cli/uninstall.js +110 -0
  16. package/dist/cli/uninstall.js.map +1 -0
  17. package/dist/cli/update.d.ts +15 -0
  18. package/dist/cli/update.js +86 -0
  19. package/dist/cli/update.js.map +1 -0
  20. package/dist/core/index.d.ts +39 -0
  21. package/dist/core/index.js +38 -0
  22. package/dist/core/index.js.map +1 -0
  23. package/dist/observability/events.d.ts +43 -0
  24. package/dist/observability/events.js.map +1 -1
  25. package/dist/plugin/checkpoint-override.d.ts +7 -9
  26. package/dist/plugin/checkpoint-override.js +8 -14
  27. package/dist/plugin/checkpoint-override.js.map +1 -1
  28. package/dist/plugin/define-workflow.d.ts +33 -0
  29. package/dist/plugin/define-workflow.js +103 -0
  30. package/dist/plugin/define-workflow.js.map +1 -0
  31. package/dist/plugin/index.js +406 -26
  32. package/dist/plugin/index.js.map +1 -1
  33. package/dist/plugin/opencode-v2-executor.js +58 -46
  34. package/dist/plugin/opencode-v2-executor.js.map +1 -1
  35. package/dist/plugin/progress-board.d.ts +64 -0
  36. package/dist/plugin/progress-board.js +150 -0
  37. package/dist/plugin/progress-board.js.map +1 -0
  38. package/dist/plugin/progress-rpc.d.ts +390 -0
  39. package/dist/plugin/progress-rpc.js +318 -0
  40. package/dist/plugin/progress-rpc.js.map +1 -0
  41. package/dist/plugin/progress-view.d.ts +82 -0
  42. package/dist/plugin/progress-view.js +244 -0
  43. package/dist/plugin/progress-view.js.map +1 -0
  44. package/dist/plugin/run-sessions.d.ts +28 -0
  45. package/dist/plugin/run-sessions.js +46 -0
  46. package/dist/plugin/run-sessions.js.map +1 -0
  47. package/dist/plugin/tool-args.d.ts +15 -0
  48. package/dist/plugin/tool-args.js +28 -0
  49. package/dist/plugin/tool-args.js.map +1 -0
  50. package/dist/plugin/tui.d.ts +11 -4
  51. package/dist/plugin/tui.js +149 -5
  52. package/dist/plugin/tui.js.map +1 -1
  53. package/dist/plugin/workflow-control.d.ts +16 -0
  54. package/dist/plugin/workflow-control.js +85 -0
  55. package/dist/plugin/workflow-control.js.map +1 -0
  56. package/dist/plugin/workflow-schedule.d.ts +24 -0
  57. package/dist/plugin/workflow-schedule.js +97 -0
  58. package/dist/plugin/workflow-schedule.js.map +1 -0
  59. package/dist/quality/checkpoint.d.ts +5 -2
  60. package/dist/quality/checkpoint.js +11 -6
  61. package/dist/quality/checkpoint.js.map +1 -1
  62. package/dist/quality/verify.d.ts +21 -2
  63. package/dist/quality/verify.js +36 -14
  64. package/dist/quality/verify.js.map +1 -1
  65. package/dist/registry/definition.d.ts +12 -0
  66. package/dist/registry/definition.js.map +1 -1
  67. package/dist/registry/registry.d.ts +4 -0
  68. package/dist/registry/registry.js +20 -1
  69. package/dist/registry/registry.js.map +1 -1
  70. package/dist/registry/run-control.d.ts +27 -0
  71. package/dist/registry/run-control.js +51 -0
  72. package/dist/registry/run-control.js.map +1 -0
  73. package/dist/registry/runner.d.ts +29 -6
  74. package/dist/registry/runner.js +153 -35
  75. package/dist/registry/runner.js.map +1 -1
  76. package/dist/runtime/errors.d.ts +26 -0
  77. package/dist/runtime/errors.js +30 -0
  78. package/dist/runtime/errors.js.map +1 -1
  79. package/dist/runtime/executor.d.ts +22 -0
  80. package/dist/runtime/executor.js.map +1 -1
  81. package/dist/runtime/run-context.d.ts +44 -0
  82. package/dist/runtime/run-context.js +32 -0
  83. package/dist/runtime/run-context.js.map +1 -0
  84. package/dist/scheduler/cron.d.ts +29 -0
  85. package/dist/scheduler/cron.js +171 -0
  86. package/dist/scheduler/cron.js.map +1 -0
  87. package/dist/scheduler/service.d.ts +78 -0
  88. package/dist/scheduler/service.js +210 -0
  89. package/dist/scheduler/service.js.map +1 -0
  90. package/dist/scheduler/store.d.ts +26 -0
  91. package/dist/scheduler/store.js +94 -0
  92. package/dist/scheduler/store.js.map +1 -0
  93. package/dist/scheduler/types.d.ts +53 -0
  94. package/dist/scheduler/types.js +12 -0
  95. package/dist/scheduler/types.js.map +1 -0
  96. package/dist/state/journal.d.ts +23 -0
  97. package/dist/state/journal.js +2 -0
  98. package/dist/state/journal.js.map +1 -1
  99. package/dist/state/recorder.d.ts +67 -0
  100. package/dist/state/recorder.js +148 -2
  101. package/dist/state/recorder.js.map +1 -1
  102. package/dist/workflow/agent.d.ts +42 -1
  103. package/dist/workflow/agent.js +116 -6
  104. package/dist/workflow/agent.js.map +1 -1
  105. package/dist/workflow/judge-panel.d.ts +37 -0
  106. package/dist/workflow/judge-panel.js +66 -0
  107. package/dist/workflow/judge-panel.js.map +1 -0
  108. package/dist/workflow/pipeline.d.ts +21 -0
  109. package/dist/workflow/pipeline.js +71 -0
  110. package/dist/workflow/pipeline.js.map +1 -0
  111. package/dist/workflow/race.d.ts +16 -0
  112. package/dist/workflow/race.js +46 -0
  113. package/dist/workflow/race.js.map +1 -0
  114. package/dist/workflow/sequence.js +6 -0
  115. package/dist/workflow/sequence.js.map +1 -1
  116. package/dist/workflows/loader.d.ts +124 -0
  117. package/dist/workflows/loader.js +500 -0
  118. package/dist/workflows/loader.js.map +1 -0
  119. package/dist/workspace/ambient.d.ts +6 -4
  120. package/dist/workspace/ambient.js +10 -4
  121. package/dist/workspace/ambient.js.map +1 -1
  122. package/package.json +16 -6
  123. package/skills/workflow-authoring/SKILL.md +111 -0
  124. package/skills/workflow-optimize/SKILL.md +70 -0
  125. package/dist/workflows/index.d.ts +0 -19
  126. package/dist/workflows/index.js +0 -40
  127. package/dist/workflows/index.js.map +0 -1
@@ -3,19 +3,126 @@
3
3
  *
4
4
  * 不感知 ctx / OpenCode:只经由 requireExecutor() 拿到当前绑定的
5
5
  * AgentExecutor 并执行。P2.4 起派发 agent.started / completed / failed 事件。
6
+ *
7
+ * P1-4 调用级选项(v1 parity):
8
+ * - model:覆盖本次调用的子会话模型("providerID/modelId" 或对象),
9
+ * 经 AgentTask.model 透传,executor 以 task.model 优先于构造期默认
10
+ * - timeoutMs:单次尝试超时(Promise.race,超时抛 AgentTimeoutError);
11
+ * 超时不会中断底层会话(无 AbortSignal 注入点),只是不再等待——
12
+ * 与 run 控制的协作式停止同一诚实语义
13
+ * - retries / retryDelayMs:失败重试(对超时同样生效——每次尝试独立计时)
14
+ *
15
+ * 纪律:事件保持调用级一对 started/completed|failed(不按尝试拆分)。
6
16
  */
7
17
  import { requireExecutor } from "../runtime/engine.js";
18
+ import { currentRunContext } from "../runtime/run-context.js";
8
19
  import { emitEvent, preview } from "../observability/events.js";
9
20
  import { currentWorkspace } from "../workspace/ambient.js";
10
- export async function agent(prompt) {
21
+ import { validateArgs } from "../registry/schema.js";
22
+ /** 结构化输出解析/校验失败(配合 retries 可重试) */
23
+ export class AgentSchemaError extends Error {
24
+ constructor(message) {
25
+ super(message);
26
+ this.name = "AgentSchemaError";
27
+ }
28
+ }
29
+ /** 从子 agent 文本输出提取 JSON 值:直接解析,失败则截取首个 { 到最后一个 } */
30
+ function extractJson(output) {
31
+ const text = output.trim();
32
+ try {
33
+ return JSON.parse(text);
34
+ }
35
+ catch {
36
+ const start = text.indexOf("{");
37
+ const end = text.lastIndexOf("}");
38
+ if (start >= 0 && end > start) {
39
+ return JSON.parse(text.slice(start, end + 1));
40
+ }
41
+ throw new AgentSchemaError(`agent output is not valid JSON: "${text.slice(0, 80)}"`);
42
+ }
43
+ }
44
+ /** 单次尝试超时(步骤级失败、journal 可见;底层会话不被硬杀) */
45
+ export class AgentTimeoutError extends Error {
46
+ constructor(timeoutMs) {
47
+ super(`agent call timed out after ${timeoutMs}ms`);
48
+ this.name = "AgentTimeoutError";
49
+ }
50
+ }
51
+ function parseModelRef(model) {
52
+ if (typeof model !== "string")
53
+ return model;
54
+ const sep = model.indexOf("/");
55
+ if (sep <= 0 || sep === model.length - 1) {
56
+ throw new Error(`[agentic-workflow] invalid model "${model}": expected "providerID/modelId"`);
57
+ }
58
+ return { providerID: model.slice(0, sep), id: model.slice(sep + 1) };
59
+ }
60
+ async function withTimeout(run, timeoutMs) {
61
+ if (timeoutMs === undefined)
62
+ return run();
63
+ let timer;
64
+ try {
65
+ return await Promise.race([
66
+ run(),
67
+ new Promise((_, reject) => {
68
+ timer = setTimeout(() => reject(new AgentTimeoutError(timeoutMs)), timeoutMs);
69
+ }),
70
+ ]);
71
+ }
72
+ finally {
73
+ clearTimeout(timer);
74
+ }
75
+ }
76
+ async function withRetries(run, retries, delayMs) {
77
+ let lastError;
78
+ for (let attempt = 0; attempt <= retries; attempt++) {
79
+ if (attempt > 0 && delayMs > 0) {
80
+ await new Promise((resolve) => setTimeout(resolve, delayMs));
81
+ }
82
+ try {
83
+ return await run();
84
+ }
85
+ catch (error) {
86
+ lastError = error;
87
+ }
88
+ }
89
+ throw lastError;
90
+ }
91
+ export async function agent(prompt, options = {}) {
11
92
  const workspace = currentWorkspace();
12
- emitEvent({ type: "agent.started", promptPreview: preview(prompt) });
93
+ // P1-6 结构化输出 shim:schema 存在时给 prompt 追加 JSON 指令,
94
+ // 输出经解析 + validateArgs 校验后挂到 result.structured
95
+ const effectivePrompt = options.schema === undefined
96
+ ? prompt
97
+ : prompt +
98
+ "\n\nRespond with ONLY a JSON value matching this schema - no markdown fences, no commentary:\n" +
99
+ JSON.stringify(options.schema);
100
+ const task = {
101
+ prompt: effectivePrompt,
102
+ ...(options.model !== undefined ? { model: parseModelRef(options.model) } : {}),
103
+ ...(workspace ? { cwd: workspace.root } : {}),
104
+ };
105
+ const retries = options.retries ?? 0;
106
+ const retryDelayMs = options.retryDelayMs ?? 0;
107
+ // runId 标注(P2-8b):run 作用域内的调用可被 journal 侧聚合到 currentStep;
108
+ // 作用域外(inline 无 journal 等)省略
109
+ const runId = currentRunContext()?.runId;
110
+ emitEvent({ type: "agent.started", promptPreview: preview(prompt), ...(runId ? { runId } : {}) });
13
111
  const startedAt = Date.now();
14
112
  try {
15
- const result = await requireExecutor().execute({
16
- prompt,
17
- ...(workspace ? { cwd: workspace.root } : {}),
18
- });
113
+ const result = await withRetries(() => withTimeout(async () => {
114
+ const executed = await requireExecutor().execute(task);
115
+ // P1-6:解析+校验放进重试环内——违规输出与执行失败同等可重试
116
+ if (options.schema !== undefined) {
117
+ const parsed = extractJson(executed.output);
118
+ const violations = validateArgs(options.schema, parsed);
119
+ if (violations.length > 0) {
120
+ throw new AgentSchemaError(`agent output does not match schema: ${violations.join("; ")}`);
121
+ }
122
+ executed.structured = parsed;
123
+ }
124
+ return executed;
125
+ }, options.timeoutMs), retries, retryDelayMs);
19
126
  emitEvent({
20
127
  type: "agent.completed",
21
128
  durationMs: Date.now() - startedAt,
@@ -23,6 +130,8 @@ export async function agent(prompt) {
23
130
  usage: result.usage,
24
131
  costUSD: result.costUSD,
25
132
  model: result.model,
133
+ ...(result.sessionID !== undefined ? { sessionID: result.sessionID } : {}),
134
+ ...(runId ? { runId } : {}),
26
135
  });
27
136
  return result;
28
137
  }
@@ -31,6 +140,7 @@ export async function agent(prompt) {
31
140
  type: "agent.failed",
32
141
  durationMs: Date.now() - startedAt,
33
142
  error: error instanceof Error ? error.message : String(error),
143
+ ...(runId ? { runId } : {}),
34
144
  });
35
145
  throw error;
36
146
  }
@@ -1 +1 @@
1
- {"version":3,"file":"agent.js","sourceRoot":"","sources":["../../src/workflow/agent.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAA;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAE1D,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,MAAc;IACxC,MAAM,SAAS,GAAG,gBAAgB,EAAE,CAAA;IACpC,SAAS,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,aAAa,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;IACpE,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;IAC5B,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,eAAe,EAAE,CAAC,OAAO,CAAC;YAC7C,MAAM;YACN,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC9C,CAAC,CAAA;QACF,SAAS,CAAC;YACR,IAAI,EAAE,iBAAiB;YACvB,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;YAClC,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM;YAClC,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,KAAK,EAAE,MAAM,CAAC,KAAK;SACpB,CAAC,CAAA;QACF,OAAO,MAAM,CAAA;IACf,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,SAAS,CAAC;YACR,IAAI,EAAE,cAAc;YACpB,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;YAClC,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;SAC9D,CAAC,CAAA;QACF,MAAM,KAAK,CAAA;IACb,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"agent.js","sourceRoot":"","sources":["../../src/workflow/agent.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * judgePanel() —— 评审团打分选优(P1-5,v1-parity)
3
+ *
4
+ * N 个评委 agent 并发给每个候选打 0-10 分(按 rubric),候选均分排序,
5
+ * 最高分胜出;同分稳定取输入顺序靠前者(v1 同语义)。
6
+ *
7
+ * v2 无结构化输出(P1-6 前置调研未完成)——评委 prompt 要求「只回复数字」,
8
+ * 输出经正则解析首个数值;解析失败/超界 = 该评委失败(计入 judgeFailures、
9
+ * 不进均分,fail-loud 统计而非静默丢分)。
10
+ * 某候选全部评委失败 -> 该候选按 0 分参与排序(judgments 为空可辨别);
11
+ * 所有候选均无有效评分 -> 抛错(无法排序,绝不静默选第一个)。
12
+ *
13
+ * 候选间并发、单个候选的评委间并发;实际 LLM 并发由 executor 层信号量约束。
14
+ */
15
+ import { type AgentCallOptions } from "./agent.js";
16
+ export interface JudgePanelOptions {
17
+ /** 评委人数,默认 3(<1 归一为 1) */
18
+ judges?: number;
19
+ /** 评分标准(写进评委 prompt),默认 "overall quality and correctness" */
20
+ rubric?: string;
21
+ /** agent() 调用级选项透传(model/timeoutMs/retries,P1-4) */
22
+ agent?: AgentCallOptions;
23
+ }
24
+ export interface JudgeVerdict {
25
+ score: number;
26
+ raw: string;
27
+ }
28
+ export interface JudgedCandidate<T> {
29
+ index: number;
30
+ candidate: T;
31
+ /** 成功评委的均分(全部失败 = 0 且 judgments 为空) */
32
+ score: number;
33
+ judgments: JudgeVerdict[];
34
+ /** 失败评委数(agent 抛错或输出无法解析为 0-10 数值) */
35
+ judgeFailures: number;
36
+ }
37
+ export declare function judgePanel<T>(candidates: T[], options?: JudgePanelOptions): Promise<JudgedCandidate<T>>;
@@ -0,0 +1,66 @@
1
+ /**
2
+ * judgePanel() —— 评审团打分选优(P1-5,v1-parity)
3
+ *
4
+ * N 个评委 agent 并发给每个候选打 0-10 分(按 rubric),候选均分排序,
5
+ * 最高分胜出;同分稳定取输入顺序靠前者(v1 同语义)。
6
+ *
7
+ * v2 无结构化输出(P1-6 前置调研未完成)——评委 prompt 要求「只回复数字」,
8
+ * 输出经正则解析首个数值;解析失败/超界 = 该评委失败(计入 judgeFailures、
9
+ * 不进均分,fail-loud 统计而非静默丢分)。
10
+ * 某候选全部评委失败 -> 该候选按 0 分参与排序(judgments 为空可辨别);
11
+ * 所有候选均无有效评分 -> 抛错(无法排序,绝不静默选第一个)。
12
+ *
13
+ * 候选间并发、单个候选的评委间并发;实际 LLM 并发由 executor 层信号量约束。
14
+ */
15
+ import { agent } from "./agent.js";
16
+ import { parallel } from "./parallel.js";
17
+ const SCORE_PATTERN = /-?\d+(?:\.\d+)?/;
18
+ /** 从评委输出解析 0-10 分值;无法解析或超界返回 undefined */
19
+ function parseScore(raw) {
20
+ const match = raw.match(SCORE_PATTERN);
21
+ if (!match)
22
+ return undefined;
23
+ const value = Number(match[0]);
24
+ if (!Number.isFinite(value) || value < 0 || value > 10)
25
+ return undefined;
26
+ return value;
27
+ }
28
+ export async function judgePanel(candidates, options) {
29
+ const judgeSlots = Math.max(1, Math.floor(options?.judges ?? 3));
30
+ const rubric = options?.rubric ?? "overall quality and correctness";
31
+ if (!Array.isArray(candidates) || candidates.length === 0) {
32
+ throw new Error("judgePanel() requires a non-empty candidates array");
33
+ }
34
+ const judged = await parallel(candidates.map((candidate, index) => async () => {
35
+ const text = typeof candidate === "string" ? candidate : JSON.stringify(candidate);
36
+ const verdicts = await parallel(Array.from({ length: judgeSlots }, (_v, j) => async () => {
37
+ const result = await agent(`Rate the following candidate from 0 to 10 on: ${rubric}. ` +
38
+ `Reply with ONLY the numeric score (no words, no explanation).\n\nCandidate:\n${text}`, { ...options?.agent });
39
+ const score = parseScore(result.output);
40
+ if (score === undefined) {
41
+ throw new Error(`judge ${index + 1}.${j + 1} output is not a 0-10 number: "${result.output.slice(0, 80)}"`);
42
+ }
43
+ return { score, raw: result.output };
44
+ }), { onFailure: "partial" });
45
+ const judgments = verdicts.filter((v) => v !== undefined);
46
+ const judgeFailures = judgeSlots - judgments.length;
47
+ const score = judgments.length > 0
48
+ ? judgments.reduce((sum, v) => sum + v.score, 0) / judgments.length
49
+ : 0;
50
+ return { index, candidate, score, judgments, judgeFailures };
51
+ }));
52
+ // 最高均分;同分稳定取输入顺序靠前者
53
+ let best = judged[0];
54
+ for (const entry of judged) {
55
+ if (entry.score > best.score || (entry.score === best.score && entry.index < best.index)) {
56
+ best = entry;
57
+ }
58
+ }
59
+ const anyJudged = judged.some((entry) => entry.judgments.length > 0);
60
+ if (!anyJudged) {
61
+ throw new Error("judgePanel() could not rank: every candidate lost all judges " +
62
+ "(agent failures or unparseable scores); check judge model/output");
63
+ }
64
+ return best;
65
+ }
66
+ //# sourceMappingURL=judge-panel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"judge-panel.js","sourceRoot":"","sources":["../../src/workflow/judge-panel.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * pipeline() —— 多条目 × 多阶段流水线(P1-5,v1-parity)
3
+ *
4
+ * items 并发流经同一组 stages(顺序执行):每个条目 value = stage(value, original, index),
5
+ * 阶段间串联、条目间互不干扰(单条目失败不拖垮其他条目——由 onFailure 决定收口方式)。
6
+ *
7
+ * onFailure(与 sequence 同语义):
8
+ * "fail-fast"(默认):第一个失败条目即抛 WorkflowPipelineError,其余条目不再影响结果
9
+ * (已附加吞错处理,不产生 unhandled rejection)。
10
+ * "continue" :跑完全部条目;存在失败则最后抛 WorkflowPipelineError(聚合全部失败)。
11
+ *
12
+ * 空条目数组返回 [];空 stages 返回原条目(v1 同语义)。
13
+ * 并发不在此限流——实际 LLM 并发由 executor 层信号量统一约束。
14
+ */
15
+ export interface PipelineOptions {
16
+ /** 失败模式,默认 "fail-fast" */
17
+ onFailure?: "fail-fast" | "continue";
18
+ }
19
+ /** 阶段函数:入参(当前值, 原始条目, 条目下标),返回下一阶段值 */
20
+ export type PipelineStage<T> = (value: T, original: T, index: number) => Promise<T> | T;
21
+ export declare function pipeline<T>(items: T[], stages: Array<PipelineStage<T>>, options?: PipelineOptions): Promise<T[]>;
@@ -0,0 +1,71 @@
1
+ /**
2
+ * pipeline() —— 多条目 × 多阶段流水线(P1-5,v1-parity)
3
+ *
4
+ * items 并发流经同一组 stages(顺序执行):每个条目 value = stage(value, original, index),
5
+ * 阶段间串联、条目间互不干扰(单条目失败不拖垮其他条目——由 onFailure 决定收口方式)。
6
+ *
7
+ * onFailure(与 sequence 同语义):
8
+ * "fail-fast"(默认):第一个失败条目即抛 WorkflowPipelineError,其余条目不再影响结果
9
+ * (已附加吞错处理,不产生 unhandled rejection)。
10
+ * "continue" :跑完全部条目;存在失败则最后抛 WorkflowPipelineError(聚合全部失败)。
11
+ *
12
+ * 空条目数组返回 [];空 stages 返回原条目(v1 同语义)。
13
+ * 并发不在此限流——实际 LLM 并发由 executor 层信号量统一约束。
14
+ */
15
+ import { WorkflowPipelineError } from "../runtime/errors.js";
16
+ export async function pipeline(items, stages, options) {
17
+ const onFailure = options?.onFailure ?? "fail-fast";
18
+ if (items.length === 0)
19
+ return [];
20
+ if (stages.length === 0)
21
+ return [...items];
22
+ const runItem = async (item, index) => {
23
+ let value = item;
24
+ for (const stage of stages) {
25
+ value = await stage(value, item, index);
26
+ }
27
+ return value;
28
+ };
29
+ if (onFailure === "fail-fast") {
30
+ return new Promise((resolve, reject) => {
31
+ const results = new Array(items.length).fill(undefined);
32
+ let rejected = false;
33
+ let pending = items.length;
34
+ items.forEach((item, index) => {
35
+ Promise.resolve()
36
+ .then(() => runItem(item, index))
37
+ .then((value) => {
38
+ if (rejected)
39
+ return;
40
+ results[index] = value;
41
+ pending -= 1;
42
+ if (pending === 0)
43
+ resolve(results);
44
+ })
45
+ .catch((cause) => {
46
+ if (rejected)
47
+ return; // 已失败:吞掉后续错误,避免 unhandled rejection
48
+ rejected = true;
49
+ reject(new WorkflowPipelineError([{ index, error: cause }], results, "fail-fast"));
50
+ });
51
+ });
52
+ });
53
+ }
54
+ // continue:等全部条目落定,存在失败则聚合抛出
55
+ const settled = await Promise.allSettled(items.map((item, index) => runItem(item, index)));
56
+ const results = new Array(items.length).fill(undefined);
57
+ const failures = [];
58
+ settled.forEach((outcome, index) => {
59
+ if (outcome.status === "fulfilled") {
60
+ results[index] = outcome.value;
61
+ }
62
+ else {
63
+ failures.push({ index, error: outcome.reason });
64
+ }
65
+ });
66
+ if (failures.length > 0) {
67
+ throw new WorkflowPipelineError(failures, results, "continue");
68
+ }
69
+ return results;
70
+ }
71
+ //# sourceMappingURL=pipeline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../../src/workflow/pipeline.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * race() —— 首达取胜(P1-5,v1-parity)
3
+ *
4
+ * 并发启动全部分支,**首个成功**者胜出、整体 resolve;其余分支不再等待
5
+ * (无法硬杀进行中的 LLM 调用——与 run 控制/超时同一诚实语义,只有「不再等待」)。
6
+ * 全部分支失败 -> WorkflowRaceError(聚合全部原因;fail-loud,不塌缩 null)。
7
+ * 分支数组为空 = 结构性错误,直接抛。
8
+ *
9
+ * 已为所有分支附加吞错处理(胜出后迟到的失败/全败后的迟到成功均被忽略,
10
+ * 不产生 unhandled rejection)。
11
+ */
12
+ export interface RaceOptions {
13
+ /** 分支名(日志用,可选) */
14
+ names?: string[];
15
+ }
16
+ export declare function race<T>(branches: Array<() => Promise<T>>, options?: RaceOptions): Promise<T>;
@@ -0,0 +1,46 @@
1
+ /**
2
+ * race() —— 首达取胜(P1-5,v1-parity)
3
+ *
4
+ * 并发启动全部分支,**首个成功**者胜出、整体 resolve;其余分支不再等待
5
+ * (无法硬杀进行中的 LLM 调用——与 run 控制/超时同一诚实语义,只有「不再等待」)。
6
+ * 全部分支失败 -> WorkflowRaceError(聚合全部原因;fail-loud,不塌缩 null)。
7
+ * 分支数组为空 = 结构性错误,直接抛。
8
+ *
9
+ * 已为所有分支附加吞错处理(胜出后迟到的失败/全败后的迟到成功均被忽略,
10
+ * 不产生 unhandled rejection)。
11
+ */
12
+ import { WorkflowRaceError } from "../runtime/errors.js";
13
+ export async function race(branches, options) {
14
+ if (branches.length === 0) {
15
+ throw new Error("race() requires at least one branch");
16
+ }
17
+ return new Promise((resolve, reject) => {
18
+ let settled = false;
19
+ let failureCount = 0;
20
+ const failures = [];
21
+ branches.forEach((branch, index) => {
22
+ // 附加 catch:胜出/全败后迟到的落定一律忽略(吞错防 unhandled rejection)
23
+ Promise.resolve()
24
+ .then(branch)
25
+ .then((value) => {
26
+ if (settled)
27
+ return;
28
+ settled = true;
29
+ const name = options?.names?.[index];
30
+ console.log(`[agentic-workflow] race winner: #${index}${name ? ` (${name})` : ""}; ` +
31
+ `${branches.length - 1} loser(s) no longer awaited`);
32
+ resolve(value);
33
+ }, (cause) => {
34
+ if (settled)
35
+ return;
36
+ failures.push({ index, error: cause });
37
+ failureCount += 1;
38
+ if (failureCount === branches.length) {
39
+ settled = true;
40
+ reject(new WorkflowRaceError(failures));
41
+ }
42
+ });
43
+ });
44
+ });
45
+ }
46
+ //# sourceMappingURL=race.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"race.js","sourceRoot":"","sources":["../../src/workflow/race.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAOxD,MAAM,CAAC,KAAK,UAAU,IAAI,CACxB,QAAiC,EACjC,OAAqB;IAErB,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAA;IACxD,CAAC;IAED,OAAO,IAAI,OAAO,CAAI,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACxC,IAAI,OAAO,GAAG,KAAK,CAAA;QACnB,IAAI,YAAY,GAAG,CAAC,CAAA;QACpB,MAAM,QAAQ,GAA6C,EAAE,CAAA;QAE7D,QAAQ,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;YACjC,oDAAoD;YACpD,OAAO,CAAC,OAAO,EAAE;iBACd,IAAI,CAAC,MAAM,CAAC;iBACZ,IAAI,CACH,CAAC,KAAK,EAAE,EAAE;gBACR,IAAI,OAAO;oBAAE,OAAM;gBACnB,OAAO,GAAG,IAAI,CAAA;gBACd,MAAM,IAAI,GAAG,OAAO,EAAE,KAAK,EAAE,CAAC,KAAK,CAAC,CAAA;gBACpC,OAAO,CAAC,GAAG,CACT,oCAAoC,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI;oBACtE,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,6BAA6B,CACtD,CAAA;gBACD,OAAO,CAAC,KAAK,CAAC,CAAA;YAChB,CAAC,EACD,CAAC,KAAc,EAAE,EAAE;gBACjB,IAAI,OAAO;oBAAE,OAAM;gBACnB,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAA;gBACtC,YAAY,IAAI,CAAC,CAAA;gBACjB,IAAI,YAAY,KAAK,QAAQ,CAAC,MAAM,EAAE,CAAC;oBACrC,OAAO,GAAG,IAAI,CAAA;oBACd,MAAM,CAAC,IAAI,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAA;gBACzC,CAAC;YACH,CAAC,CACF,CAAA;QACL,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC"}
@@ -19,6 +19,7 @@
19
19
  import { WorkflowSequenceError, WorkflowStepError } from "../runtime/errors.js";
20
20
  import { emitEvent } from "../observability/events.js";
21
21
  import { RunJournal } from "../state/recorder.js";
22
+ import { RunAbortedError } from "../registry/run-control.js";
22
23
  function assertStepCount(journal, steps) {
23
24
  if (journal && journal.run.steps.length !== steps) {
24
25
  throw new Error(`[agentic-workflow] journal step count mismatch: journal ` +
@@ -42,6 +43,11 @@ async function runLoop(steps, options, journal, fromIndex, initialPrev) {
42
43
  emitEvent({ type: "step.completed", index: i, durationMs: Date.now() - stepStartedAt });
43
44
  }
44
45
  catch (cause) {
46
+ // P1-3 协作式停止:RunAbortedError 直接穿透——不收集、不标 step failed、
47
+ // 不把 run 收口为 failed(由 runner 统一收口为 aborted:主动停 ≠ 出错)
48
+ if (cause instanceof RunAbortedError) {
49
+ throw cause;
50
+ }
45
51
  const stepError = new WorkflowStepError(i, cause, options?.stepNames?.[i]);
46
52
  await journal?.stepFailed(i, cause);
47
53
  emitEvent({
@@ -1 +1 @@
1
- {"version":3,"file":"sequence.js","sourceRoot":"","sources":["../../src/workflow/sequence.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sequence.js","sourceRoot":"","sources":["../../src/workflow/sequence.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,124 @@
1
+ /**
2
+ * 声明式 workflow 装载器(P4)—— 用户自定义流程的 JSON 形态
3
+ *
4
+ * 装载契约(详见 dev-docs/planning/P4-custom-workflows.md):
5
+ * - 入口:.json 文件路径 或 目录(扫一层 *.json);相对项目目录
6
+ * - 步骤七类(互斥键):agent / checkpoint / verify / fileExists / subflow /
7
+ * pipeline(条目并发 fan-out,{{item}} 引用条目)/ race(≥2 提示竞速取首胜)
8
+ * - 模板:{{topic}}、{{args.x}}、{{steps.<name>}};pipeline 提示额外支持
9
+ * {{item}}(条目字面替换,先于通用模板解析);未知变量 = 步骤失败
10
+ * - 并发步骤的 resume 粒度:pipeline/race 各占一个 journal 步骤单元
11
+ * (completed 即整体跳过;中断重跑整步——与 sequence 前缀语义一致)
12
+ * - 错误语义:装载期文件级 skip+warn(不阻断其他文件与内置流程);
13
+ * 运行期步骤级 failed(走既有 journal/resume 语义)
14
+ *
15
+ * 纪律:本文件属于 Core 侧资产装载,禁止 import OpenCode API
16
+ * (架构不变量);路径解析基准由调用方(plugin)传入。
17
+ */
18
+ import type { AnyWorkflowDefinition } from "../registry/registry.js";
19
+ /** 步骤四类的声明形态(互斥键由校验保证) */
20
+ interface AgentStepDecl {
21
+ name: string;
22
+ agent: string;
23
+ /** P1-4 调用级选项(仅 agent 步可用) */
24
+ model?: string;
25
+ timeoutMs?: number;
26
+ retries?: number;
27
+ }
28
+ interface CheckpointStepDecl {
29
+ name: string;
30
+ checkpoint: string;
31
+ }
32
+ interface VerifyStepDecl {
33
+ name: string;
34
+ verify: {
35
+ artifact: string;
36
+ criteria?: string;
37
+ reviewers?: number;
38
+ label?: string;
39
+ /** P2-11:投票阈值 (0,1],缺省 1 = 全票 */
40
+ threshold?: number;
41
+ /** P2-11:多视角评审(一个 lens 一个评审员,覆盖 reviewers/criteria) */
42
+ lenses?: Array<{
43
+ name: string;
44
+ criteria: string;
45
+ }>;
46
+ };
47
+ }
48
+ interface FileExistsStepDecl {
49
+ name: string;
50
+ fileExists: string;
51
+ }
52
+ /** P2-9 子工作流步骤:subflow = 目标 flow id(模板);args 值支持模板 */
53
+ interface SubflowStepDecl {
54
+ name: string;
55
+ subflow: string;
56
+ args?: Record<string, string | number | boolean>;
57
+ }
58
+ /**
59
+ * 并发流水线步骤(声明式 pipeline):pipeline = 每条目提示模板({{item}} 引用条目,
60
+ * 其余变量走通用模板);items = 条目模板数组(每项解析后原样作为条目值)。
61
+ * 条目并发、单阶段(多阶段链用代码式 combinator);结果数组(与 items 对齐)
62
+ * 并入 state[outputAs ?? name]。
63
+ */
64
+ interface PipelineStepDecl {
65
+ name: string;
66
+ pipeline: string;
67
+ /** 条目(每项为模板) */
68
+ items: string[];
69
+ /** 结果并入 state 的键(缺省 = 步骤名) */
70
+ outputAs?: string;
71
+ /** 失败模式(与代码式 pipeline 同语义,缺省 fail-fast) */
72
+ onFailure?: "fail-fast" | "continue";
73
+ /** agent 调用级选项(每条目同规则透传) */
74
+ model?: string;
75
+ timeoutMs?: number;
76
+ retries?: number;
77
+ }
78
+ /**
79
+ * 竞速步骤(声明式 race):race = 竞速提示模板数组(≥2),并发起跑、
80
+ * 首个成功者输出并入 state[outputAs ?? name];全败抛 WorkflowRaceError。
81
+ */
82
+ interface RaceStepDecl {
83
+ name: string;
84
+ race: string[];
85
+ /** 结果并入 state 的键(缺省 = 步骤名) */
86
+ outputAs?: string;
87
+ }
88
+ type StepDecl = AgentStepDecl | CheckpointStepDecl | VerifyStepDecl | FileExistsStepDecl | SubflowStepDecl | PipelineStepDecl | RaceStepDecl;
89
+ export interface DeclarativeWorkflow {
90
+ id: string;
91
+ version?: string;
92
+ description?: string;
93
+ /** argsSchema(JSON Schema);缺省 = 仅 topic(工具恒传) */
94
+ args?: Record<string, unknown>;
95
+ steps: StepDecl[];
96
+ /** 输出模板;缺省 = 最后一个 agent 步的输出 */
97
+ output?: string;
98
+ }
99
+ /** 单文件校验:返回声明对象或错误文案(含文件名前缀) */
100
+ export declare function validateWorkflow(raw: unknown, file: string): {
101
+ ok: true;
102
+ value: DeclarativeWorkflow;
103
+ } | {
104
+ ok: false;
105
+ error: string;
106
+ };
107
+ /**
108
+ * 模板解析:{{topic}} / {{args.x}} / {{steps.<name>}}(允许空白)。
109
+ * 未知变量抛错(步骤级失败、journal 可见,绝不静默空串)。
110
+ */
111
+ export declare function resolveTemplate(template: string, args: Record<string, unknown>, stepOutputs: ReadonlyMap<string, string>): string;
112
+ /** P0-2:声明对象 -> 可注册 definition(workflow_define 内联定义复用同一转换) */
113
+ export declare function toDefinition(dw: DeclarativeWorkflow): AnyWorkflowDefinition;
114
+ /**
115
+ * 装载自定义流程(声明式 JSON + 代码式 JS 模块,P2-14 起统一入口)。
116
+ * 文件级错误 warn+跳过(与装载纪律一致:观测/装载不能成为主链路故障源)。
117
+ */
118
+ export declare function loadCustomWorkflows(entries: string[], baseDir: string, reservedIds?: string[]): Promise<{
119
+ definitions: AnyWorkflowDefinition[];
120
+ errors: string[];
121
+ }>;
122
+ /** @deprecated 旧名(P2-14 起装载范围扩展到代码流程),等价 loadCustomWorkflows */
123
+ export declare const loadDeclarativeWorkflows: typeof loadCustomWorkflows;
124
+ export {};