agent-nuvira 3.1.1 → 3.2.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/agents/agents/reasoner.d.ts +8 -0
- package/dist/agents/agents/reasoner.d.ts.map +1 -1
- package/dist/agents/agents/reasoner.js +53 -2
- package/dist/agents/agents/reasoner.js.map +1 -1
- package/dist/agents/agents/writer.d.ts +24 -0
- package/dist/agents/agents/writer.d.ts.map +1 -1
- package/dist/agents/agents/writer.js +194 -0
- package/dist/agents/agents/writer.js.map +1 -1
- package/dist/agents/composite-plan.d.ts +143 -0
- package/dist/agents/composite-plan.d.ts.map +1 -0
- package/dist/agents/composite-plan.js +399 -0
- package/dist/agents/composite-plan.js.map +1 -0
- package/dist/agents/long-form-plan.d.ts +156 -0
- package/dist/agents/long-form-plan.d.ts.map +1 -0
- package/dist/agents/long-form-plan.js +274 -0
- package/dist/agents/long-form-plan.js.map +1 -0
- package/dist/agents/orchestrator.d.ts +107 -0
- package/dist/agents/orchestrator.d.ts.map +1 -1
- package/dist/agents/orchestrator.js +501 -35
- package/dist/agents/orchestrator.js.map +1 -1
- package/dist/agents/prompt-assembly.d.ts +8 -0
- package/dist/agents/prompt-assembly.d.ts.map +1 -1
- package/dist/agents/prompt-assembly.js +17 -0
- package/dist/agents/prompt-assembly.js.map +1 -1
- package/dist/cli/chat.d.ts +27 -0
- package/dist/cli/chat.d.ts.map +1 -1
- package/dist/cli/chat.js +133 -8
- package/dist/cli/chat.js.map +1 -1
- package/dist/cli/execute.d.ts +12 -0
- package/dist/cli/execute.d.ts.map +1 -1
- package/dist/cli/execute.js +105 -2
- package/dist/cli/execute.js.map +1 -1
- package/dist/cli/models.d.ts.map +1 -1
- package/dist/cli/models.js +10 -0
- package/dist/cli/models.js.map +1 -1
- package/dist/cli/nlu.d.ts +8 -0
- package/dist/cli/nlu.d.ts.map +1 -1
- package/dist/cli/nlu.js +57 -0
- package/dist/cli/nlu.js.map +1 -1
- package/dist/cli/trace.d.ts.map +1 -1
- package/dist/cli/trace.js +27 -0
- package/dist/cli/trace.js.map +1 -1
- package/dist/gateway/gateway-log.d.ts +1 -1
- package/dist/gateway/gateway-log.d.ts.map +1 -1
- package/dist/gateway/gateway-log.js.map +1 -1
- package/dist/gateway/registry.d.ts +116 -1
- package/dist/gateway/registry.d.ts.map +1 -1
- package/dist/gateway/registry.js +575 -52
- package/dist/gateway/registry.js.map +1 -1
- package/dist/inference/model-entitlement.d.ts +46 -0
- package/dist/inference/model-entitlement.d.ts.map +1 -0
- package/dist/inference/model-entitlement.js +98 -0
- package/dist/inference/model-entitlement.js.map +1 -0
- package/dist/inference/tool-call-utils.d.ts.map +1 -1
- package/dist/inference/tool-call-utils.js +70 -1
- package/dist/inference/tool-call-utils.js.map +1 -1
- package/dist/learning/autonomy-policy.d.ts +334 -0
- package/dist/learning/autonomy-policy.d.ts.map +1 -0
- package/dist/learning/autonomy-policy.js +500 -0
- package/dist/learning/autonomy-policy.js.map +1 -0
- package/dist/learning/credential-fingerprint.d.ts +58 -0
- package/dist/learning/credential-fingerprint.d.ts.map +1 -0
- package/dist/learning/credential-fingerprint.js +126 -0
- package/dist/learning/credential-fingerprint.js.map +1 -0
- package/dist/learning/deferred-task.d.ts +159 -0
- package/dist/learning/deferred-task.d.ts.map +1 -0
- package/dist/learning/deferred-task.js +451 -0
- package/dist/learning/deferred-task.js.map +1 -0
- package/dist/learning/deliverable-class.d.ts +130 -0
- package/dist/learning/deliverable-class.d.ts.map +1 -0
- package/dist/learning/deliverable-class.js +432 -0
- package/dist/learning/deliverable-class.js.map +1 -0
- package/dist/learning/long-form.d.ts +252 -0
- package/dist/learning/long-form.d.ts.map +1 -0
- package/dist/learning/long-form.js +510 -0
- package/dist/learning/long-form.js.map +1 -0
- package/dist/learning/model-first-router.d.ts +17 -0
- package/dist/learning/model-first-router.d.ts.map +1 -1
- package/dist/learning/model-first-router.js +35 -0
- package/dist/learning/model-first-router.js.map +1 -1
- package/dist/learning/model-registry.d.ts +96 -4
- package/dist/learning/model-registry.d.ts.map +1 -1
- package/dist/learning/model-registry.js +128 -6
- package/dist/learning/model-registry.js.map +1 -1
- package/dist/learning/model-warmup.d.ts +97 -2
- package/dist/learning/model-warmup.d.ts.map +1 -1
- package/dist/learning/model-warmup.js +165 -60
- package/dist/learning/model-warmup.js.map +1 -1
- package/dist/learning/prompt-layers.d.ts +61 -0
- package/dist/learning/prompt-layers.d.ts.map +1 -0
- package/dist/learning/prompt-layers.js +140 -0
- package/dist/learning/prompt-layers.js.map +1 -0
- package/dist/learning/provider-limits.d.ts +66 -0
- package/dist/learning/provider-limits.d.ts.map +1 -0
- package/dist/learning/provider-limits.js +184 -0
- package/dist/learning/provider-limits.js.map +1 -0
- package/dist/learning/reasoning-trace.d.ts +36 -1
- package/dist/learning/reasoning-trace.d.ts.map +1 -1
- package/dist/learning/reasoning-trace.js +36 -2
- package/dist/learning/reasoning-trace.js.map +1 -1
- package/dist/learning/resilient-call.d.ts +36 -1
- package/dist/learning/resilient-call.d.ts.map +1 -1
- package/dist/learning/resilient-call.js +118 -8
- package/dist/learning/resilient-call.js.map +1 -1
- package/dist/learning/unattended-job.d.ts +293 -0
- package/dist/learning/unattended-job.d.ts.map +1 -0
- package/dist/learning/unattended-job.js +544 -0
- package/dist/learning/unattended-job.js.map +1 -0
- package/dist/learning/unattended-progress.d.ts +95 -0
- package/dist/learning/unattended-progress.d.ts.map +1 -0
- package/dist/learning/unattended-progress.js +147 -0
- package/dist/learning/unattended-progress.js.map +1 -0
- package/dist/learning/working-state.d.ts +109 -0
- package/dist/learning/working-state.d.ts.map +1 -0
- package/dist/learning/working-state.js +244 -0
- package/dist/learning/working-state.js.map +1 -0
- package/dist/nlu/conversation-gate.d.ts +46 -0
- package/dist/nlu/conversation-gate.d.ts.map +1 -1
- package/dist/nlu/conversation-gate.js +73 -6
- package/dist/nlu/conversation-gate.js.map +1 -1
- package/dist/nlu/intent-confirm.d.ts +82 -0
- package/dist/nlu/intent-confirm.d.ts.map +1 -0
- package/dist/nlu/intent-confirm.js +146 -0
- package/dist/nlu/intent-confirm.js.map +1 -0
- package/dist/nlu/learnings.d.ts +101 -0
- package/dist/nlu/learnings.d.ts.map +1 -0
- package/dist/nlu/learnings.js +283 -0
- package/dist/nlu/learnings.js.map +1 -0
- package/dist/tools/coding-tools.d.ts.map +1 -1
- package/dist/tools/coding-tools.js +95 -19
- package/dist/tools/coding-tools.js.map +1 -1
- package/dist/tools/edit-verification.d.ts +125 -0
- package/dist/tools/edit-verification.d.ts.map +1 -0
- package/dist/tools/edit-verification.js +237 -0
- package/dist/tools/edit-verification.js.map +1 -0
- package/dist/tools/git-tool.d.ts.map +1 -1
- package/dist/tools/git-tool.js +37 -4
- package/dist/tools/git-tool.js.map +1 -1
- package/dist/tools/registry.d.ts +30 -2
- package/dist/tools/registry.d.ts.map +1 -1
- package/dist/tools/registry.js +40 -11
- package/dist/tools/registry.js.map +1 -1
- package/dist/tools/run-cli.d.ts.map +1 -1
- package/dist/tools/run-cli.js +40 -13
- package/dist/tools/run-cli.js.map +1 -1
- package/dist/tools/run-terminal.d.ts +6 -1
- package/dist/tools/run-terminal.d.ts.map +1 -1
- package/dist/tools/run-terminal.js +158 -18
- package/dist/tools/run-terminal.js.map +1 -1
- package/dist/tools/tool-loop.d.ts +35 -0
- package/dist/tools/tool-loop.d.ts.map +1 -1
- package/dist/tools/tool-loop.js +157 -3
- package/dist/tools/tool-loop.js.map +1 -1
- package/dist/web-dashboard/chat-console.d.ts +35 -0
- package/dist/web-dashboard/chat-console.d.ts.map +1 -1
- package/dist/web-dashboard/chat-console.js +97 -18
- package/dist/web-dashboard/chat-console.js.map +1 -1
- package/dist/web-dashboard/chat-retry.d.ts +143 -0
- package/dist/web-dashboard/chat-retry.d.ts.map +1 -0
- package/dist/web-dashboard/chat-retry.js +227 -0
- package/dist/web-dashboard/chat-retry.js.map +1 -0
- package/dist/web-dashboard/server.d.ts +17 -0
- package/dist/web-dashboard/server.d.ts.map +1 -1
- package/dist/web-dashboard/server.js +200 -9
- package/dist/web-dashboard/server.js.map +1 -1
- package/dist/web-dashboard/src/types.d.ts +81 -4
- package/dist/web-dashboard/src/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/web-dashboard/public/assets/{index-CQW0qv1r.js → index-kCUkORm7.js} +27 -27
- package/src/web-dashboard/public/assets/index-kCUkORm7.js.map +1 -0
- package/src/web-dashboard/public/index.html +1 -1
- package/src/web-dashboard/public/assets/index-CQW0qv1r.js.map +0 -1
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Composite planning — phased plans for deliverables that are more than one
|
|
3
|
+
* thing (enterprise-grade hardening, G12).
|
|
4
|
+
*
|
|
5
|
+
* WHY THIS EXISTS. The audit fixed "a story is not a program" (G7/G8) and the
|
|
6
|
+
* next class of ask showed the same shape one level up:
|
|
7
|
+
*
|
|
8
|
+
* "develop a web-based book (interactive, with voice assistance)"
|
|
9
|
+
* "build the app from this plan — it's a phased build, take the time you need"
|
|
10
|
+
*
|
|
11
|
+
* Both are AUTHORED work AND software, and a single-class planner can only fail
|
|
12
|
+
* one half of them:
|
|
13
|
+
* - plan it as prose and the site never appears — the user asked for a web
|
|
14
|
+
* book and got a markdown file;
|
|
15
|
+
* - plan it as code and the book never appears — the exact non-delivery the
|
|
16
|
+
* original audit found, where the agent built a machine to write the story
|
|
17
|
+
* instead of writing the story.
|
|
18
|
+
*
|
|
19
|
+
* The answer is not a better single answer; it is PHASES. `buildCompositePlan`
|
|
20
|
+
* emits the phases in dependency order, with the hard rule encoded: SHAPE first
|
|
21
|
+
* (so the content has somewhere to land), then CONTENT, then the EXPERIENCE
|
|
22
|
+
* layer, then optional SERVICES, then VERIFICATION.
|
|
23
|
+
*
|
|
24
|
+
* TWO DESIGN CALLS WORTH STATING
|
|
25
|
+
*
|
|
26
|
+
* 1. CONTENT IS NOT LAST, AND IT IS NOT OPTIONAL. A site scaffold is one
|
|
27
|
+
* small step; the book is dozens of units. Reserving the experience layer
|
|
28
|
+
* for the end means a run that stalls early still leaves real chapters on
|
|
29
|
+
* disk — which is what makes the work RESUMABLE rather than a half-built
|
|
30
|
+
* shell.
|
|
31
|
+
* 2. AN OPTIONAL SERVICE MUST NEVER GATE THE DELIVERABLE. When the ask names
|
|
32
|
+
* Python/voice/TTS, the plan does create the script — but the web layer is
|
|
33
|
+
* required to work without it (browser speech), so the deliverable is
|
|
34
|
+
* complete the moment it is opened. A page that needs `pip install` before
|
|
35
|
+
* it says a word is not enterprise-grade; it is a dependency the user never
|
|
36
|
+
* agreed to maintain.
|
|
37
|
+
*/
|
|
38
|
+
import type { TaskStep } from './agent.js';
|
|
39
|
+
import { type DeliverableVerdict, type Substrate } from '../learning/deliverable-class.js';
|
|
40
|
+
import { type LongFormJob } from '../learning/long-form.js';
|
|
41
|
+
import { type ProseUnit } from './long-form-plan.js';
|
|
42
|
+
/** What a phase is for. Drives ordering, naming and reporting. */
|
|
43
|
+
export type PhaseKind = 'scaffold' | 'content' | 'interactivity' | 'assets' | 'verify';
|
|
44
|
+
/** One stage of a composite deliverable. */
|
|
45
|
+
export interface CompositePhase {
|
|
46
|
+
/** Stable id, e.g. `phase-1-scaffold`. */
|
|
47
|
+
id: string;
|
|
48
|
+
kind: PhaseKind;
|
|
49
|
+
/** Short label for the board/report, e.g. "Shape the site". */
|
|
50
|
+
title: string;
|
|
51
|
+
/** The steps that implement this phase, already dependency-wired. */
|
|
52
|
+
steps: TaskStep[];
|
|
53
|
+
}
|
|
54
|
+
/** The plan for a composite ask. */
|
|
55
|
+
export interface CompositePlan {
|
|
56
|
+
/** Phases in execution order. */
|
|
57
|
+
phases: CompositePhase[];
|
|
58
|
+
/** Every step, flattened and wired (this is what becomes the task plan). */
|
|
59
|
+
steps: TaskStep[];
|
|
60
|
+
/** `proseUnit` per step id, consumed by the writer via metadata. */
|
|
61
|
+
proseUnits: Map<string, ProseUnit>;
|
|
62
|
+
/**
|
|
63
|
+
* The long-form ledger job backing the content phase.
|
|
64
|
+
*
|
|
65
|
+
* Always present: a composite plan only exists when it contains authored
|
|
66
|
+
* content (see `buildCompositePlan`), and the ledger is how that content's
|
|
67
|
+
* progress is measured and resumed.
|
|
68
|
+
*/
|
|
69
|
+
job: LongFormJob;
|
|
70
|
+
/** Honest one-line progress, shown to the user. */
|
|
71
|
+
progressLine: string;
|
|
72
|
+
/**
|
|
73
|
+
* Files that must ALL exist before the deliverable counts as finished.
|
|
74
|
+
*
|
|
75
|
+
* The unattended runner uses this to MEASURE completion instead of trusting
|
|
76
|
+
* a batch that reported success — the same "ran ≠ worked" rule G1/G2/G3
|
|
77
|
+
* apply to single edits.
|
|
78
|
+
*/
|
|
79
|
+
expectedArtifacts: string[];
|
|
80
|
+
/** One line describing what the user is getting. */
|
|
81
|
+
deliverableSummary: string;
|
|
82
|
+
/** Which substrates this plan covers (for logs/traces). */
|
|
83
|
+
substrates: Substrate[];
|
|
84
|
+
/**
|
|
85
|
+
* Steps that CREATE files from scratch — shape, experience layer, services.
|
|
86
|
+
*
|
|
87
|
+
* The orchestrator routes these to the ONE-SHOT writer rather than the
|
|
88
|
+
* tool-calling one. The tool-calling writer exists for the read→edit→verify
|
|
89
|
+
* loop, and there is nothing to read in a directory that does not exist yet:
|
|
90
|
+
* in the live run the tool-calling writer returned zero file changes for the
|
|
91
|
+
* site scaffold and the whole pipeline died on its first step. Writing a new
|
|
92
|
+
* file from nothing is exactly what the one-shot writer's contract (complete
|
|
93
|
+
* file contents in `filepath:` blocks) is for.
|
|
94
|
+
*/
|
|
95
|
+
creationStepIds: string[];
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* The deterministic end-to-end check for a composite deliverable.
|
|
99
|
+
*
|
|
100
|
+
* Generated by US, not written by the model, for the same reason the assembly
|
|
101
|
+
* of a book is pure concatenation: the thing that decides whether the work is
|
|
102
|
+
* done must not be part of the work being judged. It runs as a `runner` step
|
|
103
|
+
* whose non-zero exit FAILS the phase, so the run reports an honest "not
|
|
104
|
+
* delivered" instead of a green summary over a missing site.
|
|
105
|
+
*
|
|
106
|
+
* It asserts the two facts a user would check in the first ten seconds:
|
|
107
|
+
* 1. every artifact the deliverable promises exists on disk;
|
|
108
|
+
* 2. for a web deliverable, the site actually enumerates the chapters —
|
|
109
|
+
* a reader that cannot see chapter 12 has not presented chapter 12.
|
|
110
|
+
*/
|
|
111
|
+
export declare function buildVerifyCommand(input: {
|
|
112
|
+
artifacts: string[];
|
|
113
|
+
/** The site's own directory, when there is a web layer to check. */
|
|
114
|
+
siteDir?: string;
|
|
115
|
+
/** The directory the site must read its chapters from. */
|
|
116
|
+
chaptersDir?: string;
|
|
117
|
+
}): string;
|
|
118
|
+
/**
|
|
119
|
+
* Plan a hybrid ask as phases, or return `null` when the ask is not one.
|
|
120
|
+
*
|
|
121
|
+
* Returning null for every single-substrate goal is deliberate: this module
|
|
122
|
+
* must be invisible to the existing code path, or it would change how ordinary
|
|
123
|
+
* software and ordinary prose are planned — both of which work today.
|
|
124
|
+
*/
|
|
125
|
+
export declare function buildCompositePlan(input: {
|
|
126
|
+
goal: string;
|
|
127
|
+
workingDir: string;
|
|
128
|
+
/** Units of prose to plan for this run. */
|
|
129
|
+
limit?: number;
|
|
130
|
+
/** Reuse an already-computed verdict (the orchestrator has one). */
|
|
131
|
+
verdict?: DeliverableVerdict;
|
|
132
|
+
}): CompositePlan | null;
|
|
133
|
+
/**
|
|
134
|
+
* The honest progress line for a composite job, derived from the ledger.
|
|
135
|
+
*
|
|
136
|
+
* Reported as units AND phases, because "3 of 5 phases" is meaningless when the
|
|
137
|
+
* content phase is 36 of 39 chapters: the user asked for a book, so the book's
|
|
138
|
+
* own completion is the number that matters.
|
|
139
|
+
*/
|
|
140
|
+
export declare function compositeProgressLine(job: LongFormJob, extra?: string): string;
|
|
141
|
+
/** Phase labels in execution order (for reports and traces). */
|
|
142
|
+
export declare function phaseSummary(plan: CompositePlan): string;
|
|
143
|
+
//# sourceMappingURL=composite-plan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"composite-plan.d.ts","sourceRoot":"","sources":["../../src/agents/composite-plan.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAIH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAA2C,KAAK,kBAAkB,EAAE,KAAK,SAAS,EAAE,MAAM,kCAAkC,CAAC;AACpI,OAAO,EAIL,KAAK,WAAW,EACjB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAqB,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAIxE,kEAAkE;AAClE,MAAM,MAAM,SAAS,GAAG,UAAU,GAAG,SAAS,GAAG,eAAe,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAEvF,4CAA4C;AAC5C,MAAM,WAAW,cAAc;IAC7B,0CAA0C;IAC1C,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,SAAS,CAAC;IAChB,+DAA+D;IAC/D,KAAK,EAAE,MAAM,CAAC;IACd,qEAAqE;IACrE,KAAK,EAAE,QAAQ,EAAE,CAAC;CACnB;AAED,oCAAoC;AACpC,MAAM,WAAW,aAAa;IAC5B,iCAAiC;IACjC,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,4EAA4E;IAC5E,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,oEAAoE;IACpE,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACnC;;;;;;OAMG;IACH,GAAG,EAAE,WAAW,CAAC;IACjB,mDAAmD;IACnD,YAAY,EAAE,MAAM,CAAC;IACrB;;;;;;OAMG;IACH,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,oDAAoD;IACpD,kBAAkB,EAAE,MAAM,CAAC;IAC3B,2DAA2D;IAC3D,UAAU,EAAE,SAAS,EAAE,CAAC;IACxB;;;;;;;;;;OAUG;IACH,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AA4CD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE;IACxC,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,oEAAoE;IACpE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,0DAA0D;IAC1D,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,GAAG,MAAM,CAsCT;AA2LD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,2CAA2C;IAC3C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oEAAoE;IACpE,OAAO,CAAC,EAAE,kBAAkB,CAAC;CAC9B,GAAG,aAAa,GAAG,IAAI,CAiHvB;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,WAAW,EAAE,KAAK,SAAK,GAAG,MAAM,CAG1E;AAED,gEAAgE;AAChE,wBAAgB,YAAY,CAAC,IAAI,EAAE,aAAa,GAAG,MAAM,CAExD"}
|
|
@@ -0,0 +1,399 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Composite planning — phased plans for deliverables that are more than one
|
|
3
|
+
* thing (enterprise-grade hardening, G12).
|
|
4
|
+
*
|
|
5
|
+
* WHY THIS EXISTS. The audit fixed "a story is not a program" (G7/G8) and the
|
|
6
|
+
* next class of ask showed the same shape one level up:
|
|
7
|
+
*
|
|
8
|
+
* "develop a web-based book (interactive, with voice assistance)"
|
|
9
|
+
* "build the app from this plan — it's a phased build, take the time you need"
|
|
10
|
+
*
|
|
11
|
+
* Both are AUTHORED work AND software, and a single-class planner can only fail
|
|
12
|
+
* one half of them:
|
|
13
|
+
* - plan it as prose and the site never appears — the user asked for a web
|
|
14
|
+
* book and got a markdown file;
|
|
15
|
+
* - plan it as code and the book never appears — the exact non-delivery the
|
|
16
|
+
* original audit found, where the agent built a machine to write the story
|
|
17
|
+
* instead of writing the story.
|
|
18
|
+
*
|
|
19
|
+
* The answer is not a better single answer; it is PHASES. `buildCompositePlan`
|
|
20
|
+
* emits the phases in dependency order, with the hard rule encoded: SHAPE first
|
|
21
|
+
* (so the content has somewhere to land), then CONTENT, then the EXPERIENCE
|
|
22
|
+
* layer, then optional SERVICES, then VERIFICATION.
|
|
23
|
+
*
|
|
24
|
+
* TWO DESIGN CALLS WORTH STATING
|
|
25
|
+
*
|
|
26
|
+
* 1. CONTENT IS NOT LAST, AND IT IS NOT OPTIONAL. A site scaffold is one
|
|
27
|
+
* small step; the book is dozens of units. Reserving the experience layer
|
|
28
|
+
* for the end means a run that stalls early still leaves real chapters on
|
|
29
|
+
* disk — which is what makes the work RESUMABLE rather than a half-built
|
|
30
|
+
* shell.
|
|
31
|
+
* 2. AN OPTIONAL SERVICE MUST NEVER GATE THE DELIVERABLE. When the ask names
|
|
32
|
+
* Python/voice/TTS, the plan does create the script — but the web layer is
|
|
33
|
+
* required to work without it (browser speech), so the deliverable is
|
|
34
|
+
* complete the moment it is opened. A page that needs `pip install` before
|
|
35
|
+
* it says a word is not enterprise-grade; it is a dependency the user never
|
|
36
|
+
* agreed to maintain.
|
|
37
|
+
*/
|
|
38
|
+
import { existsSync } from 'node:fs';
|
|
39
|
+
import { resolve } from 'node:path';
|
|
40
|
+
import { classifyDeliverable, describeSubstrates } from '../learning/deliverable-class.js';
|
|
41
|
+
import { MAX_UNITS_PER_RUN, formatProgress, } from '../learning/long-form.js';
|
|
42
|
+
import { buildLongFormPlan } from './long-form-plan.js';
|
|
43
|
+
// ─── Project shape ──────────────────────────────────────────────────────────
|
|
44
|
+
/** Where a composite web deliverable puts its presentation layer. */
|
|
45
|
+
const SITE_DIR = 'site';
|
|
46
|
+
/** Where a composite authored deliverable puts its prose. */
|
|
47
|
+
const CONTENT_DIR = 'content';
|
|
48
|
+
/** Where optional service scripts live. */
|
|
49
|
+
const TOOLS_DIR = 'tools';
|
|
50
|
+
/** The document the prose phase assembles. */
|
|
51
|
+
const BOOK_PATH = `${CONTENT_DIR}/book.md`;
|
|
52
|
+
/** Per-unit prose files, so the web layer can enumerate them predictably. */
|
|
53
|
+
const CHAPTERS_DIR = `${CONTENT_DIR}/chapters`;
|
|
54
|
+
/** The site's entry point and its supporting files. */
|
|
55
|
+
const SITE_FILES = [`${SITE_DIR}/index.html`, `${SITE_DIR}/styles.css`, `${SITE_DIR}/reader.js`];
|
|
56
|
+
/** The generated chapter index the reader consumes. */
|
|
57
|
+
const CHAPTER_INDEX = `${SITE_DIR}/chapters.js`;
|
|
58
|
+
/** The optional high-quality narration service. */
|
|
59
|
+
const NARRATION_SCRIPT = `${TOOLS_DIR}/narrate.py`;
|
|
60
|
+
/** A dependency-free export/build helper, for asks that named a runtime. */
|
|
61
|
+
const EXPORT_SCRIPT = `${TOOLS_DIR}/export.mjs`;
|
|
62
|
+
// ─── Helpers ────────────────────────────────────────────────────────────────
|
|
63
|
+
/** JSON literal for embedding in a generated command. */
|
|
64
|
+
function jsArray(values) {
|
|
65
|
+
return `[${values.map((v) => `'${v.replace(/\\/g, '\\\\').replace(/'/g, "\\'")}'`).join(',')}]`;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* A JS single-quoted string literal for embedding in the generated command.
|
|
69
|
+
*
|
|
70
|
+
* NOT a shell-quoted argument: the command runs inside `node -e "…"`, so a
|
|
71
|
+
* shell-quoted `"site"` has its quotes consumed by the shell and the script
|
|
72
|
+
* then sees a bare identifier (`ReferenceError: site is not defined`). The
|
|
73
|
+
* value has to arrive at Node as JS source, so it is rendered as one.
|
|
74
|
+
*/
|
|
75
|
+
function jsString(value) {
|
|
76
|
+
return `'${value.replace(/\\/g, '\\\\').replace(/'/g, "\\'")}'`;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* The deterministic end-to-end check for a composite deliverable.
|
|
80
|
+
*
|
|
81
|
+
* Generated by US, not written by the model, for the same reason the assembly
|
|
82
|
+
* of a book is pure concatenation: the thing that decides whether the work is
|
|
83
|
+
* done must not be part of the work being judged. It runs as a `runner` step
|
|
84
|
+
* whose non-zero exit FAILS the phase, so the run reports an honest "not
|
|
85
|
+
* delivered" instead of a green summary over a missing site.
|
|
86
|
+
*
|
|
87
|
+
* It asserts the two facts a user would check in the first ten seconds:
|
|
88
|
+
* 1. every artifact the deliverable promises exists on disk;
|
|
89
|
+
* 2. for a web deliverable, the site actually enumerates the chapters —
|
|
90
|
+
* a reader that cannot see chapter 12 has not presented chapter 12.
|
|
91
|
+
*/
|
|
92
|
+
export function buildVerifyCommand(input) {
|
|
93
|
+
const artifacts = jsArray(input.artifacts);
|
|
94
|
+
const siteDir = input.siteDir ?? '';
|
|
95
|
+
const chaptersDir = jsString(input.chaptersDir ?? '');
|
|
96
|
+
const checksSite = !!input.siteDir && !!input.chaptersDir;
|
|
97
|
+
// ── What the site check asserts, and why it is shaped this way ──────────
|
|
98
|
+
// It asserts the site ENUMERATES a chapters directory instead of hard-coding
|
|
99
|
+
// a list. The tempting stronger check — "does the site source mention each
|
|
100
|
+
// chapter FILE" — is wrong: a correct reader lists the directory at load time
|
|
101
|
+
// and therefore names NO chapter file in its source, so that check would fail
|
|
102
|
+
// exactly the implementation we asked for. Proving chapter 12 renders needs a
|
|
103
|
+
// browser, which a runner step does not have. So we assert what is genuinely
|
|
104
|
+
// verifiable: every promised file exists, and the site reads its content from
|
|
105
|
+
// the chapters directory rather than embedding it.
|
|
106
|
+
const siteScan = checksSite
|
|
107
|
+
? `const roots=[];const walk=d=>{for(const e of fs.readdirSync(d,{withFileTypes:true})){const p=path.join(d,e.name);if(e.isDirectory())walk(p);else roots.push(p)}};` +
|
|
108
|
+
`if(fs.existsSync(${jsString(siteDir)}))walk(${jsString(siteDir)});` +
|
|
109
|
+
`const blob=roots.map(p=>fs.readFileSync(p,'utf8')).join(String.fromCharCode(10));` +
|
|
110
|
+
`const enumerates=blob.includes(${chaptersDir});`
|
|
111
|
+
: '';
|
|
112
|
+
const siteCheck = checksSite
|
|
113
|
+
? `if(!enumerates){console.error('THE SITE DOES NOT READ ITS CHAPTERS FROM '+${chaptersDir});process.exit(1)}`
|
|
114
|
+
: '';
|
|
115
|
+
const success = checksSite
|
|
116
|
+
? `'OK: '+need.length+' artifact(s) present and the site reads its chapters from '+${chaptersDir}`
|
|
117
|
+
: `'OK: '+need.length+' artifact(s) present'`;
|
|
118
|
+
return (`node -e "const fs=require('fs');const path=require('path');` +
|
|
119
|
+
`const need=${artifacts};` +
|
|
120
|
+
`const missing=need.filter(p=>!fs.existsSync(p));` +
|
|
121
|
+
siteScan +
|
|
122
|
+
siteCheck +
|
|
123
|
+
`if(missing.length){` +
|
|
124
|
+
`console.error('MISSING FILES: '+missing.join(', '));` +
|
|
125
|
+
`process.exit(1)}` +
|
|
126
|
+
`console.log(${success})"`).trim();
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Is this step's deliverable already on disk?
|
|
130
|
+
*
|
|
131
|
+
* A satisfied step is NOT planned again, and the second reason is the sharp
|
|
132
|
+
* one: re-running a scaffold wastes tokens, and an idempotent writer that
|
|
133
|
+
* correctly reports "no changes needed" is then marked as having FAILED its
|
|
134
|
+
* expected files — a false failure that burned a whole repair budget on the
|
|
135
|
+
* second run of the live composite test. A continuation must plan only what is
|
|
136
|
+
* left to do.
|
|
137
|
+
*/
|
|
138
|
+
function alreadySatisfied(step, workingDir) {
|
|
139
|
+
const files = step.expectedFiles ?? [];
|
|
140
|
+
if (files.length === 0)
|
|
141
|
+
return false;
|
|
142
|
+
return files.every((f) => existsSync(resolve(workingDir, f)));
|
|
143
|
+
}
|
|
144
|
+
/** A step that runs a deterministic command (the runner extracts backticks). */
|
|
145
|
+
function runStep(id, description, command, dependsOn) {
|
|
146
|
+
return {
|
|
147
|
+
id,
|
|
148
|
+
description: `${description} Run: \`${command}\``,
|
|
149
|
+
agentType: 'runner',
|
|
150
|
+
dependsOn,
|
|
151
|
+
status: 'pending',
|
|
152
|
+
complexity: 'simple',
|
|
153
|
+
routingHints: { runSerially: true },
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
/** A step that writes files. */
|
|
157
|
+
function writeStep(input) {
|
|
158
|
+
return {
|
|
159
|
+
id: input.id,
|
|
160
|
+
description: input.description,
|
|
161
|
+
agentType: 'writer',
|
|
162
|
+
dependsOn: input.dependsOn,
|
|
163
|
+
status: 'pending',
|
|
164
|
+
complexity: input.complexity ?? 'complex',
|
|
165
|
+
expectedFiles: input.expectedFiles,
|
|
166
|
+
routingHints: { runSerially: true },
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
// ─── Phase builders ─────────────────────────────────────────────────────────
|
|
170
|
+
/** Phase 1 — the shape the content will land in. */
|
|
171
|
+
function scaffoldPhase(substrates) {
|
|
172
|
+
if (!substrates.includes('web'))
|
|
173
|
+
return null;
|
|
174
|
+
return {
|
|
175
|
+
id: 'phase-1-scaffold',
|
|
176
|
+
kind: 'scaffold',
|
|
177
|
+
title: 'Shape the site',
|
|
178
|
+
steps: [
|
|
179
|
+
writeStep({
|
|
180
|
+
id: 'scaffold-site',
|
|
181
|
+
description: `Create the static site that will read and present the book: ${SITE_FILES.join(', ')}. ` +
|
|
182
|
+
'The entry point must work by opening the HTML file directly from disk — no build step, no server, no package install. ' +
|
|
183
|
+
`The reader must load the written content from the ${CHAPTERS_DIR}/ directory at runtime and render one chapter at a time ` +
|
|
184
|
+
'with previous/next navigation and a table of contents. Include a "Read aloud" control that uses the browser\'s built-in ' +
|
|
185
|
+
'speech synthesis so narration works with nothing installed. Keep styling self-contained in the CSS file; no external CDNs.',
|
|
186
|
+
expectedFiles: SITE_FILES,
|
|
187
|
+
dependsOn: [],
|
|
188
|
+
}),
|
|
189
|
+
],
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
/** Phase 2 — the content itself, via the bounded long-form engine. */
|
|
193
|
+
function contentPhase(input) {
|
|
194
|
+
const prose = buildLongFormPlan({
|
|
195
|
+
goal: input.goal,
|
|
196
|
+
workingDir: input.workingDir,
|
|
197
|
+
limit: input.limit,
|
|
198
|
+
assumeAuthored: true,
|
|
199
|
+
docPath: BOOK_PATH,
|
|
200
|
+
dir: CHAPTERS_DIR,
|
|
201
|
+
});
|
|
202
|
+
if (!prose)
|
|
203
|
+
return null;
|
|
204
|
+
// The first unit must wait for the scaffold only when there IS one; a prose
|
|
205
|
+
// unit's own chain already serializes the rest of the batch.
|
|
206
|
+
const steps = prose.steps.map((step, i) => ({
|
|
207
|
+
...step,
|
|
208
|
+
dependsOn: i === 0 ? [...input.dependsOn] : step.dependsOn,
|
|
209
|
+
}));
|
|
210
|
+
return {
|
|
211
|
+
phase: { id: 'phase-2-content', kind: 'content', title: 'Write the content', steps },
|
|
212
|
+
job: prose.job,
|
|
213
|
+
proseUnits: prose.units,
|
|
214
|
+
progressLine: prose.progressLine,
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
/** Phase 3 — the experience layer that makes the content usable. */
|
|
218
|
+
function interactivityPhase(input) {
|
|
219
|
+
const steps = [
|
|
220
|
+
writeStep({
|
|
221
|
+
id: 'site-chapter-index',
|
|
222
|
+
description: `Create ${CHAPTER_INDEX}: a small module that lists every chapter file in ${CHAPTERS_DIR}/ ` +
|
|
223
|
+
'in reading order, with a display title for each (derived from the file name), so the reader can build its ' +
|
|
224
|
+
'table of contents and navigation without a server. It must enumerate the directory contents at load time ' +
|
|
225
|
+
'rather than hard-coding a count.' +
|
|
226
|
+
(input.wantsNarration
|
|
227
|
+
? ' Also wire the "Read aloud" button to the browser speech synthesis API with play/pause, and make the page ' +
|
|
228
|
+
'note that an optional higher-quality narration script is available for those who want it.'
|
|
229
|
+
: ''),
|
|
230
|
+
expectedFiles: [CHAPTER_INDEX],
|
|
231
|
+
dependsOn: input.dependsOn,
|
|
232
|
+
complexity: 'moderate',
|
|
233
|
+
}),
|
|
234
|
+
];
|
|
235
|
+
return { id: 'phase-3-interactivity', kind: 'interactivity', title: 'Make it interactive', steps };
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Phase 4 — optional services.
|
|
239
|
+
*
|
|
240
|
+
* The narration script is generated but NOT wired as a requirement, and the
|
|
241
|
+
* phase never fails the run on its own: a missing Python interpreter must not
|
|
242
|
+
* cost the user their book (see the module header).
|
|
243
|
+
*/
|
|
244
|
+
function assetsPhase(input) {
|
|
245
|
+
const wantsNarration = input.substrates.includes('python') || /audio|narrat|voice|speech|tts|listen|read\s+aloud/i.test(input.goal);
|
|
246
|
+
const steps = [];
|
|
247
|
+
if (wantsNarration) {
|
|
248
|
+
steps.push(writeStep({
|
|
249
|
+
id: 'tools-narrate',
|
|
250
|
+
description: `Create ${NARRATION_SCRIPT}: an optional high-quality narration generator for this book. It must list the ` +
|
|
251
|
+
`chapters, synthesise speech for each into an audio file next to it, and require only standard third-party ` +
|
|
252
|
+
'libraries (gTTS or edge-tts), detecting which is installed and explaining what to install when neither is. ' +
|
|
253
|
+
'It must NOT be required for the site to work — the site narrates through the browser without it.',
|
|
254
|
+
expectedFiles: [NARRATION_SCRIPT],
|
|
255
|
+
dependsOn: input.dependsOn,
|
|
256
|
+
complexity: 'moderate',
|
|
257
|
+
}));
|
|
258
|
+
}
|
|
259
|
+
if (input.substrates.includes('python') && !wantsNarration) {
|
|
260
|
+
steps.push(writeStep({
|
|
261
|
+
id: 'tools-export',
|
|
262
|
+
description: `Create ${EXPORT_SCRIPT}: a dependency-free Node build helper that assembles the finished document from its ` +
|
|
263
|
+
'per-unit files into a single file and reports the word and page counts, so the deliverable can be rebuilt ' +
|
|
264
|
+
'after any edit without an LLM.',
|
|
265
|
+
expectedFiles: [EXPORT_SCRIPT],
|
|
266
|
+
dependsOn: input.dependsOn,
|
|
267
|
+
complexity: 'moderate',
|
|
268
|
+
}));
|
|
269
|
+
}
|
|
270
|
+
if (steps.length === 0)
|
|
271
|
+
return null;
|
|
272
|
+
return { id: 'phase-4-assets', kind: 'assets', title: 'Optional services', steps };
|
|
273
|
+
}
|
|
274
|
+
// ─── Entry point ────────────────────────────────────────────────────────────
|
|
275
|
+
/**
|
|
276
|
+
* Plan a hybrid ask as phases, or return `null` when the ask is not one.
|
|
277
|
+
*
|
|
278
|
+
* Returning null for every single-substrate goal is deliberate: this module
|
|
279
|
+
* must be invisible to the existing code path, or it would change how ordinary
|
|
280
|
+
* software and ordinary prose are planned — both of which work today.
|
|
281
|
+
*/
|
|
282
|
+
export function buildCompositePlan(input) {
|
|
283
|
+
const verdict = input.verdict ?? classifyDeliverable(input.goal);
|
|
284
|
+
// Only hybrid asks take this path. An authored-only ask stays with
|
|
285
|
+
// `buildLongFormPlan`; a software-only ask stays with the code planner.
|
|
286
|
+
if (!verdict.composite)
|
|
287
|
+
return null;
|
|
288
|
+
// And the hybrid must actually contain authored content. "A React app with a
|
|
289
|
+
// Python backend" is multi-substrate but it is a SOFTWARE ask, and the code
|
|
290
|
+
// planner already plans those correctly.
|
|
291
|
+
if (!verdict.substrates.includes('prose'))
|
|
292
|
+
return null;
|
|
293
|
+
const substrates = verdict.substrates;
|
|
294
|
+
const limit = Math.max(1, input.limit ?? MAX_UNITS_PER_RUN);
|
|
295
|
+
const phases = [];
|
|
296
|
+
const scaffold = scaffoldPhase(substrates);
|
|
297
|
+
if (scaffold) {
|
|
298
|
+
// Pruned BEFORE the content phase is built, not after: the content must not
|
|
299
|
+
// declare a dependency on a step that is about to be dropped from the plan.
|
|
300
|
+
// (Live evidence: on the second run the scaffold was satisfied and pruned,
|
|
301
|
+
// but unit 1 still depended on `scaffold-site` — the scheduler found zero
|
|
302
|
+
// runnable steps and the whole continuation failed at planning.)
|
|
303
|
+
scaffold.steps = scaffold.steps.filter((s) => !alreadySatisfied(s, input.workingDir));
|
|
304
|
+
if (scaffold.steps.length > 0)
|
|
305
|
+
phases.push(scaffold);
|
|
306
|
+
}
|
|
307
|
+
const content = contentPhase({
|
|
308
|
+
goal: input.goal,
|
|
309
|
+
workingDir: input.workingDir,
|
|
310
|
+
limit,
|
|
311
|
+
dependsOn: scaffold && scaffold.steps.length > 0 ? scaffold.steps.map((s) => s.id) : [],
|
|
312
|
+
});
|
|
313
|
+
// Authored content is the point of a composite ask that includes prose. If
|
|
314
|
+
// the long-form engine cannot plan it at all, the hybrid cannot be delivered
|
|
315
|
+
// honestly — bail out to the ordinary path rather than planning a shell.
|
|
316
|
+
if (!content)
|
|
317
|
+
return null;
|
|
318
|
+
phases.push(content.phase);
|
|
319
|
+
// Everything after the content depends on the LAST content step: the site
|
|
320
|
+
// must be able to enumerate finished chapters, and the narration script
|
|
321
|
+
// should see real files.
|
|
322
|
+
const lastContentStep = content.phase.steps[content.phase.steps.length - 1]?.id;
|
|
323
|
+
const afterContent = lastContentStep ? [lastContentStep] : [];
|
|
324
|
+
if (substrates.includes('web')) {
|
|
325
|
+
phases.push(interactivityPhase({
|
|
326
|
+
goal: input.goal,
|
|
327
|
+
job: content.job,
|
|
328
|
+
dependsOn: afterContent,
|
|
329
|
+
wantsNarration: substrates.includes('python') || /audio|narrat|voice|speech|tts/i.test(input.goal),
|
|
330
|
+
}));
|
|
331
|
+
}
|
|
332
|
+
const assets = assetsPhase({ substrates, dependsOn: afterContent, goal: input.goal });
|
|
333
|
+
if (assets)
|
|
334
|
+
phases.push(assets);
|
|
335
|
+
// ── Verification, generated by us ───────────────────────────────────────
|
|
336
|
+
const chapterPaths = content.job.sections.map((s) => s.path);
|
|
337
|
+
// Captured BEFORE pruning: a satisfied step is not planned again, but its
|
|
338
|
+
// files are still part of what the deliverable promises — completion is
|
|
339
|
+
// measured against this list either way.
|
|
340
|
+
const expectedArtifacts = [
|
|
341
|
+
BOOK_PATH,
|
|
342
|
+
...chapterPaths,
|
|
343
|
+
...(substrates.includes('web') ? [...SITE_FILES, CHAPTER_INDEX] : []),
|
|
344
|
+
...(assets ? assets.steps.flatMap((s) => s.expectedFiles ?? []) : []),
|
|
345
|
+
];
|
|
346
|
+
// ── Plan only what is LEFT ──────────────────────────────────────────────
|
|
347
|
+
// A presentation-layer step whose files already exist is dropped, so a
|
|
348
|
+
// continuation goes straight to the unfinished content instead of rewriting a
|
|
349
|
+
// site that is already correct.
|
|
350
|
+
for (const phase of phases) {
|
|
351
|
+
if (phase.kind === 'content' || phase.kind === 'verify')
|
|
352
|
+
continue;
|
|
353
|
+
phase.steps = phase.steps.filter((s) => !alreadySatisfied(s, input.workingDir));
|
|
354
|
+
}
|
|
355
|
+
const planned = phases.filter((p) => p.steps.length > 0);
|
|
356
|
+
const verifyDependsOn = planned.flatMap((p) => p.steps.map((s) => s.id));
|
|
357
|
+
const verify = {
|
|
358
|
+
id: 'phase-5-verify',
|
|
359
|
+
kind: 'verify',
|
|
360
|
+
title: 'Verify the whole deliverable',
|
|
361
|
+
steps: [
|
|
362
|
+
runStep('verify-deliverable', 'Verify the whole deliverable end to end: every promised file exists on disk, and the site reads its chapters from the content directory.', buildVerifyCommand({
|
|
363
|
+
artifacts: expectedArtifacts,
|
|
364
|
+
...(substrates.includes('web') ? { siteDir: SITE_DIR, chaptersDir: CHAPTERS_DIR } : {}),
|
|
365
|
+
}), verifyDependsOn),
|
|
366
|
+
],
|
|
367
|
+
};
|
|
368
|
+
planned.push(verify);
|
|
369
|
+
const steps = planned.flatMap((p) => p.steps);
|
|
370
|
+
return {
|
|
371
|
+
phases: planned,
|
|
372
|
+
steps,
|
|
373
|
+
proseUnits: content.proseUnits,
|
|
374
|
+
job: content.job,
|
|
375
|
+
progressLine: content.progressLine,
|
|
376
|
+
expectedArtifacts,
|
|
377
|
+
substrates,
|
|
378
|
+
creationStepIds: planned
|
|
379
|
+
.filter((p) => p.kind === 'scaffold' || p.kind === 'interactivity' || p.kind === 'assets')
|
|
380
|
+
.flatMap((p) => p.steps.map((s) => s.id)),
|
|
381
|
+
deliverableSummary: `${describeSubstrates(verdict)} — ${steps.length} step(s) across ${planned.length} phase(s), ${content.job.sections.length} content units`,
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* The honest progress line for a composite job, derived from the ledger.
|
|
386
|
+
*
|
|
387
|
+
* Reported as units AND phases, because "3 of 5 phases" is meaningless when the
|
|
388
|
+
* content phase is 36 of 39 chapters: the user asked for a book, so the book's
|
|
389
|
+
* own completion is the number that matters.
|
|
390
|
+
*/
|
|
391
|
+
export function compositeProgressLine(job, extra = '') {
|
|
392
|
+
const suffix = extra ? ` · ${extra}` : '';
|
|
393
|
+
return `${formatProgress(job)}${suffix}`;
|
|
394
|
+
}
|
|
395
|
+
/** Phase labels in execution order (for reports and traces). */
|
|
396
|
+
export function phaseSummary(plan) {
|
|
397
|
+
return plan.phases.map((p) => `${p.title} (${p.steps.length})`).join(' → ');
|
|
398
|
+
}
|
|
399
|
+
//# sourceMappingURL=composite-plan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"composite-plan.js","sourceRoot":"","sources":["../../src/agents/composite-plan.ts"],"names":[],"mappings":"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"}
|