返回 CodeWhale
wf_a3_partial_failure_synthesis.workflow.js
根目录 / docs / examples / dogfood-automatic / wf_a3_partial_failure_synthesis.workflow.js
1 /**
2 * #4131 WF-A3 — partial failure + synthesis.
3 *
4 * parallel() uses all-settled semantics: a failed slot becomes null; the run
5 * continues so a synthesizer can still produce an operator summary.
6 *
7 * Run: /workflow run docs/examples/dogfood-automatic/wf_a3_partial_failure_synthesis.workflow.js
8 *
9 * For pure VM proof without model spend, use workflow-js unit tests:
10 * cargo test -p codewhale-workflow-js --locked parallel_fan_out_maps_one_failure_to_null_slot
11 */
12 export default async function () {
13 phase("Parallel scouts");
14 const slots = await parallel([
15 () =>
16 task({
17 description: "Healthy scout A",
18 label: "scout-a",
19 type: "explore",
20 prompt: "Return the string READY_A. Read-only.",
21 }),
22 // Give this child an intentionally tiny budget so it starts, then fails
23 // deterministically at the runtime boundary. A model refusal is still a
24 // successful transport-level completion, while response-schema failures
25 // intentionally abort the whole workflow so they remain loud.
26 () =>
27 task({
28 description: "Deliberately failing scout B",
29 label: "scout-b-fail",
30 type: "explore",
31 tokenBudget: 1,
32 prompt:
33 "Inspect Cargo.toml and return a detailed workspace summary. This child intentionally has a one-token budget so parallel() exercises a failed null slot.",
34 }),
35 () =>
36 task({
37 description: "Healthy scout C",
38 label: "scout-c",
39 type: "explore",
40 prompt: "Return the string READY_C. Read-only.",
41 }),
42 ]);
43
44 phase("Synthesize");
45 const surviving = (slots || []).filter((s) => s != null);
46 const summary = await task({
47 description: "Synthesize from surviving parallel slots",
48 label: "synthesizer",
49 type: "general",
50 prompt: [
51 "Build one operator-facing summary from the surviving scout results.",
52 "Explicitly note which parallel slot failed or returned null.",
53 `slot_count=${(slots || []).length} surviving=${surviving.length}`,
54 "slots_json:",
55 JSON.stringify(slots),
56 ].join("\n"),
57 });
58
59 return {
60 scenario: "WF-A3",
61 slots,
62 surviving_count: surviving.length,
63 summary,
64 };
65 }
66
66 lines JAVASCRIPT