@cat-factory/orchestration 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.
Files changed (182) hide show
  1. package/LICENSE +21 -0
  2. package/dist/container.d.ts +460 -0
  3. package/dist/container.d.ts.map +1 -0
  4. package/dist/container.js +657 -0
  5. package/dist/container.js.map +1 -0
  6. package/dist/index.d.ts +29 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +31 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/modules/board/BoardService.d.ts +125 -0
  11. package/dist/modules/board/BoardService.d.ts.map +1 -0
  12. package/dist/modules/board/BoardService.js +496 -0
  13. package/dist/modules/board/BoardService.js.map +1 -0
  14. package/dist/modules/board/board.logic.d.ts +17 -0
  15. package/dist/modules/board/board.logic.d.ts.map +1 -0
  16. package/dist/modules/board/board.logic.js +51 -0
  17. package/dist/modules/board/board.logic.js.map +1 -0
  18. package/dist/modules/boardScan/BoardScanService.d.ts +35 -0
  19. package/dist/modules/boardScan/BoardScanService.d.ts.map +1 -0
  20. package/dist/modules/boardScan/BoardScanService.js +91 -0
  21. package/dist/modules/boardScan/BoardScanService.js.map +1 -0
  22. package/dist/modules/boardScan/board-scan.logic.d.ts +10 -0
  23. package/dist/modules/boardScan/board-scan.logic.d.ts.map +1 -0
  24. package/dist/modules/boardScan/board-scan.logic.js +26 -0
  25. package/dist/modules/boardScan/board-scan.logic.js.map +1 -0
  26. package/dist/modules/bootstrap/BootstrapService.d.ts +114 -0
  27. package/dist/modules/bootstrap/BootstrapService.d.ts.map +1 -0
  28. package/dist/modules/bootstrap/BootstrapService.js +516 -0
  29. package/dist/modules/bootstrap/BootstrapService.js.map +1 -0
  30. package/dist/modules/clarity/ClarityReviewService.d.ts +48 -0
  31. package/dist/modules/clarity/ClarityReviewService.d.ts.map +1 -0
  32. package/dist/modules/clarity/ClarityReviewService.js +63 -0
  33. package/dist/modules/clarity/ClarityReviewService.js.map +1 -0
  34. package/dist/modules/clarity/clarity.logic.d.ts +36 -0
  35. package/dist/modules/clarity/clarity.logic.d.ts.map +1 -0
  36. package/dist/modules/clarity/clarity.logic.js +98 -0
  37. package/dist/modules/clarity/clarity.logic.js.map +1 -0
  38. package/dist/modules/estimation/estimate.logic.d.ts +11 -0
  39. package/dist/modules/estimation/estimate.logic.d.ts.map +1 -0
  40. package/dist/modules/estimation/estimate.logic.js +37 -0
  41. package/dist/modules/estimation/estimate.logic.js.map +1 -0
  42. package/dist/modules/execution/AgentContextBuilder.d.ts +114 -0
  43. package/dist/modules/execution/AgentContextBuilder.d.ts.map +1 -0
  44. package/dist/modules/execution/AgentContextBuilder.js +316 -0
  45. package/dist/modules/execution/AgentContextBuilder.js.map +1 -0
  46. package/dist/modules/execution/CompanionController.d.ts +60 -0
  47. package/dist/modules/execution/CompanionController.d.ts.map +1 -0
  48. package/dist/modules/execution/CompanionController.js +216 -0
  49. package/dist/modules/execution/CompanionController.js.map +1 -0
  50. package/dist/modules/execution/ExecutionService.d.ts +874 -0
  51. package/dist/modules/execution/ExecutionService.d.ts.map +1 -0
  52. package/dist/modules/execution/ExecutionService.js +2921 -0
  53. package/dist/modules/execution/ExecutionService.js.map +1 -0
  54. package/dist/modules/execution/MergeResolver.d.ts +34 -0
  55. package/dist/modules/execution/MergeResolver.d.ts.map +1 -0
  56. package/dist/modules/execution/MergeResolver.js +81 -0
  57. package/dist/modules/execution/MergeResolver.js.map +1 -0
  58. package/dist/modules/execution/ReviewGateController.d.ts +163 -0
  59. package/dist/modules/execution/ReviewGateController.d.ts.map +1 -0
  60. package/dist/modules/execution/ReviewGateController.js +251 -0
  61. package/dist/modules/execution/ReviewGateController.js.map +1 -0
  62. package/dist/modules/execution/TesterController.d.ts +61 -0
  63. package/dist/modules/execution/TesterController.d.ts.map +1 -0
  64. package/dist/modules/execution/TesterController.js +215 -0
  65. package/dist/modules/execution/TesterController.js.map +1 -0
  66. package/dist/modules/execution/advance.d.ts +84 -0
  67. package/dist/modules/execution/advance.d.ts.map +1 -0
  68. package/dist/modules/execution/advance.js +2 -0
  69. package/dist/modules/execution/advance.js.map +1 -0
  70. package/dist/modules/execution/artifact-review.logic.d.ts +25 -0
  71. package/dist/modules/execution/artifact-review.logic.d.ts.map +1 -0
  72. package/dist/modules/execution/artifact-review.logic.js +39 -0
  73. package/dist/modules/execution/artifact-review.logic.js.map +1 -0
  74. package/dist/modules/execution/ci.logic.d.ts +101 -0
  75. package/dist/modules/execution/ci.logic.d.ts.map +1 -0
  76. package/dist/modules/execution/ci.logic.js +117 -0
  77. package/dist/modules/execution/ci.logic.js.map +1 -0
  78. package/dist/modules/execution/drive.d.ts +47 -0
  79. package/dist/modules/execution/drive.d.ts.map +1 -0
  80. package/dist/modules/execution/drive.js +112 -0
  81. package/dist/modules/execution/drive.js.map +1 -0
  82. package/dist/modules/execution/gates.d.ts +97 -0
  83. package/dist/modules/execution/gates.d.ts.map +1 -0
  84. package/dist/modules/execution/gates.js +2 -0
  85. package/dist/modules/execution/gates.js.map +1 -0
  86. package/dist/modules/execution/individualVendors.logic.d.ts +22 -0
  87. package/dist/modules/execution/individualVendors.logic.d.ts.map +1 -0
  88. package/dist/modules/execution/individualVendors.logic.js +33 -0
  89. package/dist/modules/execution/individualVendors.logic.js.map +1 -0
  90. package/dist/modules/execution/job.logic.d.ts +52 -0
  91. package/dist/modules/execution/job.logic.d.ts.map +1 -0
  92. package/dist/modules/execution/job.logic.js +56 -0
  93. package/dist/modules/execution/job.logic.js.map +1 -0
  94. package/dist/modules/execution/release.logic.d.ts +43 -0
  95. package/dist/modules/execution/release.logic.d.ts.map +1 -0
  96. package/dist/modules/execution/release.logic.js +49 -0
  97. package/dist/modules/execution/release.logic.js.map +1 -0
  98. package/dist/modules/execution/retry.logic.d.ts +40 -0
  99. package/dist/modules/execution/retry.logic.d.ts.map +1 -0
  100. package/dist/modules/execution/retry.logic.js +83 -0
  101. package/dist/modules/execution/retry.logic.js.map +1 -0
  102. package/dist/modules/execution/stepGating.logic.d.ts +15 -0
  103. package/dist/modules/execution/stepGating.logic.d.ts.map +1 -0
  104. package/dist/modules/execution/stepGating.logic.js +29 -0
  105. package/dist/modules/execution/stepGating.logic.js.map +1 -0
  106. package/dist/modules/execution/stepResolvers.d.ts +41 -0
  107. package/dist/modules/execution/stepResolvers.d.ts.map +1 -0
  108. package/dist/modules/execution/stepResolvers.js +2 -0
  109. package/dist/modules/execution/stepResolvers.js.map +1 -0
  110. package/dist/modules/execution/tester-infra.logic.d.ts +42 -0
  111. package/dist/modules/execution/tester-infra.logic.d.ts.map +1 -0
  112. package/dist/modules/execution/tester-infra.logic.js +46 -0
  113. package/dist/modules/execution/tester-infra.logic.js.map +1 -0
  114. package/dist/modules/merge/MergePresetService.d.ts +32 -0
  115. package/dist/modules/merge/MergePresetService.d.ts.map +1 -0
  116. package/dist/modules/merge/MergePresetService.js +109 -0
  117. package/dist/modules/merge/MergePresetService.js.map +1 -0
  118. package/dist/modules/modelDefaults/ModelDefaultsService.d.ts +22 -0
  119. package/dist/modules/modelDefaults/ModelDefaultsService.d.ts.map +1 -0
  120. package/dist/modules/modelDefaults/ModelDefaultsService.js +28 -0
  121. package/dist/modules/modelDefaults/ModelDefaultsService.js.map +1 -0
  122. package/dist/modules/notifications/NotificationService.d.ts +74 -0
  123. package/dist/modules/notifications/NotificationService.d.ts.map +1 -0
  124. package/dist/modules/notifications/NotificationService.js +131 -0
  125. package/dist/modules/notifications/NotificationService.js.map +1 -0
  126. package/dist/modules/observability/LlmObservabilityService.d.ts +121 -0
  127. package/dist/modules/observability/LlmObservabilityService.d.ts.map +1 -0
  128. package/dist/modules/observability/LlmObservabilityService.js +140 -0
  129. package/dist/modules/observability/LlmObservabilityService.js.map +1 -0
  130. package/dist/modules/observability/observability.logic.d.ts +57 -0
  131. package/dist/modules/observability/observability.logic.d.ts.map +1 -0
  132. package/dist/modules/observability/observability.logic.js +186 -0
  133. package/dist/modules/observability/observability.logic.js.map +1 -0
  134. package/dist/modules/pipelines/PipelineService.d.ts +54 -0
  135. package/dist/modules/pipelines/PipelineService.d.ts.map +1 -0
  136. package/dist/modules/pipelines/PipelineService.js +226 -0
  137. package/dist/modules/pipelines/PipelineService.js.map +1 -0
  138. package/dist/modules/pipelines/pipelineShape.d.ts +53 -0
  139. package/dist/modules/pipelines/pipelineShape.d.ts.map +1 -0
  140. package/dist/modules/pipelines/pipelineShape.js +74 -0
  141. package/dist/modules/pipelines/pipelineShape.js.map +1 -0
  142. package/dist/modules/recurring/RecurringPipelineService.d.ts +76 -0
  143. package/dist/modules/recurring/RecurringPipelineService.d.ts.map +1 -0
  144. package/dist/modules/recurring/RecurringPipelineService.js +295 -0
  145. package/dist/modules/recurring/RecurringPipelineService.js.map +1 -0
  146. package/dist/modules/recurring/TrackerSettingsService.d.ts +16 -0
  147. package/dist/modules/recurring/TrackerSettingsService.d.ts.map +1 -0
  148. package/dist/modules/recurring/TrackerSettingsService.js +30 -0
  149. package/dist/modules/recurring/TrackerSettingsService.js.map +1 -0
  150. package/dist/modules/recurring/schedule.logic.d.ts +14 -0
  151. package/dist/modules/recurring/schedule.logic.d.ts.map +1 -0
  152. package/dist/modules/recurring/schedule.logic.js +85 -0
  153. package/dist/modules/recurring/schedule.logic.js.map +1 -0
  154. package/dist/modules/releaseHealth/ReleaseHealthService.d.ts +38 -0
  155. package/dist/modules/releaseHealth/ReleaseHealthService.d.ts.map +1 -0
  156. package/dist/modules/releaseHealth/ReleaseHealthService.js +96 -0
  157. package/dist/modules/releaseHealth/ReleaseHealthService.js.map +1 -0
  158. package/dist/modules/requirements/RequirementReviewService.d.ts +48 -0
  159. package/dist/modules/requirements/RequirementReviewService.d.ts.map +1 -0
  160. package/dist/modules/requirements/RequirementReviewService.js +83 -0
  161. package/dist/modules/requirements/RequirementReviewService.js.map +1 -0
  162. package/dist/modules/requirements/requirements.logic.d.ts +93 -0
  163. package/dist/modules/requirements/requirements.logic.d.ts.map +1 -0
  164. package/dist/modules/requirements/requirements.logic.js +203 -0
  165. package/dist/modules/requirements/requirements.logic.js.map +1 -0
  166. package/dist/modules/review/IterativeReviewService.d.ts +175 -0
  167. package/dist/modules/review/IterativeReviewService.d.ts.map +1 -0
  168. package/dist/modules/review/IterativeReviewService.js +327 -0
  169. package/dist/modules/review/IterativeReviewService.js.map +1 -0
  170. package/dist/modules/serviceFragmentDefaults/ServiceFragmentDefaultsService.d.ts +20 -0
  171. package/dist/modules/serviceFragmentDefaults/ServiceFragmentDefaultsService.d.ts.map +1 -0
  172. package/dist/modules/serviceFragmentDefaults/ServiceFragmentDefaultsService.js +26 -0
  173. package/dist/modules/serviceFragmentDefaults/ServiceFragmentDefaultsService.js.map +1 -0
  174. package/dist/modules/services/ServiceMountService.d.ts +48 -0
  175. package/dist/modules/services/ServiceMountService.d.ts.map +1 -0
  176. package/dist/modules/services/ServiceMountService.js +90 -0
  177. package/dist/modules/services/ServiceMountService.js.map +1 -0
  178. package/dist/modules/settings/WorkspaceSettingsService.d.ts +22 -0
  179. package/dist/modules/settings/WorkspaceSettingsService.d.ts.map +1 -0
  180. package/dist/modules/settings/WorkspaceSettingsService.js +50 -0
  181. package/dist/modules/settings/WorkspaceSettingsService.js.map +1 -0
  182. package/package.json +41 -0
@@ -0,0 +1,316 @@
1
+ import { CODE_AWARE_TRAIT, hasTrait } from '@cat-factory/agents';
2
+ import { getFragment } from '@cat-factory/prompt-fragments';
3
+ /**
4
+ * The `revision` slice of an agent context when a step is being re-run with feedback
5
+ * — either a human's "request changes" on its approval gate, or a downstream
6
+ * companion's automatic rework (`step.rework`). The companion path wins when both are
7
+ * present. Empty object when neither applies (no revision context).
8
+ */
9
+ export function buildRevisionContext(step) {
10
+ const source = step.rework
11
+ ? {
12
+ previousProposal: step.rework.previousProposal,
13
+ feedback: step.rework.feedback,
14
+ comments: step.rework.comments,
15
+ }
16
+ : step.approval?.status === 'changes_requested'
17
+ ? {
18
+ previousProposal: step.approval.proposal,
19
+ feedback: step.approval.feedback ?? '',
20
+ comments: step.approval.comments,
21
+ }
22
+ : undefined;
23
+ if (!source)
24
+ return {};
25
+ return {
26
+ revision: {
27
+ previousProposal: source.previousProposal,
28
+ feedback: source.feedback,
29
+ ...(source.comments?.length
30
+ ? {
31
+ comments: source.comments.map((c) => ({
32
+ ...(c.quotedSource ? { quotedSource: c.quotedSource } : {}),
33
+ body: c.body,
34
+ })),
35
+ }
36
+ : {}),
37
+ },
38
+ };
39
+ }
40
+ /**
41
+ * Assembles the {@link AgentRunContext} for a pipeline step from the run + block state:
42
+ * the (possibly reworked) requirements, linked docs/tracker issues, the live environment,
43
+ * the service-frame config, the best-practice fragments, prior step outputs, recorded
44
+ * decisions and any revision feedback. Pure inputs → output (it only reads repositories),
45
+ * extracted out of `ExecutionService` so the engine stays a thin state machine. Also the
46
+ * single home for service-frame resolution (`resolveServiceFrameId`/`resolveServiceConfig`),
47
+ * which a few other engine paths reuse.
48
+ */
49
+ export class AgentContextBuilder {
50
+ deps;
51
+ constructor(deps) {
52
+ this.deps = deps;
53
+ }
54
+ /** Assemble the {@link AgentRunContext} for a step from the run + block state. */
55
+ async buildContext(workspaceId, instance, step, isFinalStep, block) {
56
+ // When a block's requirements have been reworked, that standardized document is
57
+ // the single source of truth for every agent step: it already folds in the
58
+ // description plus the linked docs / tracker issues, so it REPLACES the
59
+ // description and the (now-redundant) doc/task context. Reviews are only ever run
60
+ // on task blocks, so skip the lookup entirely for frames/modules — that keeps the
61
+ // extra read off every container/frame step rather than on the whole hot path.
62
+ // A converged clarity (bug-report triage) report substitutes downstream exactly like a
63
+ // reworked requirements doc. When both exist on one task the requirements doc — which
64
+ // runs after clarity and is the more refined artifact — takes precedence.
65
+ const reworked = block.level === 'task'
66
+ ? ((await this.resolveReworkedRequirements(workspaceId, block.id)) ??
67
+ (await this.resolveClarifiedBrief(workspaceId, block.id)))
68
+ : null;
69
+ const description = reworked ?? block.description;
70
+ const contextDocs = reworked ? [] : await this.resolveContextDocs(workspaceId, block.id);
71
+ const contextTasks = reworked ? [] : await this.resolveContextTasks(workspaceId, block.id);
72
+ const environment = await this.resolveEnvironment(workspaceId, block.id);
73
+ const service = await this.resolveServiceConfig(workspaceId, block);
74
+ const priorOutputs = instance.steps
75
+ .slice(0, instance.currentStep)
76
+ .filter((s) => s.output)
77
+ .map((s) => ({ agentKind: s.agentKind, output: s.output }));
78
+ // Resolve the best-practice fragments to inject for this step. `code-aware` kinds
79
+ // get the running service's selected fragments unioned with the block's own pins;
80
+ // other kinds keep only their block pins. Recorded on the step for observability.
81
+ const resolved = await this.resolveFragments(workspaceId, step, block);
82
+ return {
83
+ agentKind: step.agentKind,
84
+ pipelineName: instance.pipelineName,
85
+ workspaceId,
86
+ executionId: instance.id,
87
+ // Carry the run initiator so the container executor can lease their OWN personal
88
+ // (individual-usage) subscription for the step. Null on system/dev runs.
89
+ ...(instance.initiatedBy != null ? { initiatedByUserId: instance.initiatedBy } : {}),
90
+ stepIndex: instance.currentStep,
91
+ isFinalStep,
92
+ // Consensus config for this step (copied onto the step at run start). Read only
93
+ // by the optional consensus executor, which decides — possibly gated on the
94
+ // block estimate below — whether to run the multi-model process. Absent ⇒ standard.
95
+ ...(step.consensus ? { consensus: step.consensus } : {}),
96
+ block: {
97
+ id: block.id,
98
+ title: block.title,
99
+ type: block.type,
100
+ description,
101
+ fragmentIds: block.fragmentIds,
102
+ ...(resolved ? { resolvedFragments: resolved.fragments } : {}),
103
+ modelId: block.modelId,
104
+ ...(block.agentConfig ? { agentConfig: block.agentConfig } : {}),
105
+ ...(block.pullRequest ? { pullRequest: block.pullRequest } : {}),
106
+ ...(contextDocs.length ? { contextDocs } : {}),
107
+ ...(contextTasks.length ? { contextTasks } : {}),
108
+ // The task-estimator's triage, when produced earlier in this run — the
109
+ // consensus executor's gating input.
110
+ ...(block.estimate ? { estimate: block.estimate } : {}),
111
+ },
112
+ ...(environment ? { environment } : {}),
113
+ ...(service ? { service } : {}),
114
+ priorOutputs,
115
+ decisions: instance.steps
116
+ .filter((s, i) => i < instance.currentStep && s.decision?.chosen)
117
+ .map((s) => ({ question: s.decision.question, chosen: s.decision.chosen })),
118
+ resolvedDecision: step.decision?.chosen
119
+ ? { question: step.decision.question, chosen: step.decision.chosen }
120
+ : null,
121
+ // A re-run triggered either by a human "Request changes" on this step's
122
+ // approval gate OR by a downstream companion looping it back for rework: hand
123
+ // the agent its previous proposal plus the feedback so it revises rather than
124
+ // starting over. The companion's automatic rework (`step.rework`) and the
125
+ // human's gate feedback share one revision shape; the companion path takes
126
+ // precedence when both are present.
127
+ ...buildRevisionContext(step),
128
+ };
129
+ }
130
+ /** The service-frame id for a block (walks up frame → module → task; cycle-guarded). */
131
+ async resolveServiceFrameId(workspaceId, blockId) {
132
+ let current = await this.deps.blockRepository.get(workspaceId, blockId);
133
+ // Bounded walk (the tree is at most frame → module → task) guarded against cycles.
134
+ for (let i = 0; current && i < 8; i++) {
135
+ if (current.level === 'frame' || !current.parentId)
136
+ return current.id;
137
+ current = await this.deps.blockRepository.get(workspaceId, current.parentId);
138
+ }
139
+ return current?.id ?? null;
140
+ }
141
+ /**
142
+ * Resolve the service-level (frame) configuration for a run's block — the
143
+ * Tester's local-infra docker-compose path / "no infra" flag and the provisioning
144
+ * provider + instance size — by walking up to the service frame. When the frame
145
+ * pins no cloud provider it inherits the owning account's `defaultCloudProvider`
146
+ * (so the account-level default actually reaches dispatch, not just the UI).
147
+ * Returns undefined when no frame carries any of these settings, so callers can
148
+ * spread it conditionally onto the agent context.
149
+ */
150
+ async resolveServiceConfig(workspaceId, block) {
151
+ const frame = block.level === 'frame'
152
+ ? block
153
+ : await this.resolveServiceFrameId(workspaceId, block.id).then((id) => id ? this.deps.blockRepository.get(workspaceId, id) : null);
154
+ if (!frame)
155
+ return undefined;
156
+ const service = {};
157
+ if (frame.testComposePath)
158
+ service.testComposePath = frame.testComposePath;
159
+ if (frame.noInfraDependencies)
160
+ service.noInfraDependencies = frame.noInfraDependencies;
161
+ if (frame.cloudProvider)
162
+ service.cloudProvider = frame.cloudProvider;
163
+ else {
164
+ // No per-service override: fall back to the owning account's default provider
165
+ // so a pool/local deployment honours the account-level choice at dispatch.
166
+ const accountDefault = await this.resolveAccountDefaultProvider(workspaceId);
167
+ if (accountDefault)
168
+ service.cloudProvider = accountDefault;
169
+ }
170
+ if (frame.instanceSize)
171
+ service.instanceSize = frame.instanceSize;
172
+ return Object.keys(service).length ? service : undefined;
173
+ }
174
+ /**
175
+ * The owning account's `defaultCloudProvider`, or undefined when the workspace
176
+ * has no account or the account pins no default (so the transport keeps its own).
177
+ */
178
+ async resolveAccountDefaultProvider(workspaceId) {
179
+ const workspace = await this.deps.workspaceRepository.get(workspaceId);
180
+ if (!workspace?.accountId)
181
+ return undefined;
182
+ const account = await this.deps.accountRepository.get(workspace.accountId);
183
+ return account?.defaultCloudProvider;
184
+ }
185
+ /**
186
+ * The reworked ("incorporated") requirements for a block — the standard-format
187
+ * document the requirements-rework step produced — or `null` when the feature is
188
+ * unwired or the block has no incorporated review yet. Used both to substitute the
189
+ * agent context for every step and to feed the spec-writer.
190
+ */
191
+ async resolveReworkedRequirements(workspaceId, blockId) {
192
+ if (!this.deps.requirementReviews)
193
+ return null;
194
+ const review = await this.deps.requirementReviews.getByBlock(workspaceId, blockId);
195
+ if (review?.status === 'incorporated' && review.incorporatedRequirements) {
196
+ return review.incorporatedRequirements;
197
+ }
198
+ return null;
199
+ }
200
+ /**
201
+ * The clarified bug report for a block — the standard-format document the clarity-rework
202
+ * step produced — or `null` when the feature is unwired or the block has no incorporated
203
+ * clarity review yet. The clarity mirror of {@link resolveReworkedRequirements}.
204
+ */
205
+ async resolveClarifiedBrief(workspaceId, blockId) {
206
+ if (!this.deps.clarityReviews)
207
+ return null;
208
+ const review = await this.deps.clarityReviews.getByBlock(workspaceId, blockId);
209
+ if (review?.status === 'incorporated' && review.clarifiedReport) {
210
+ return review.clarifiedReport;
211
+ }
212
+ return null;
213
+ }
214
+ /**
215
+ * Resolve the best-practice fragments to fold into a step's system prompt. Service
216
+ * fragments reach an agent ONLY when its kind carries the `code-aware` trait: those
217
+ * kinds get the running SERVICE's selected fragments (the frame's
218
+ * `serviceFragmentIds`, seeded from the workspace default and editable per service)
219
+ * unioned with the block's own manual pins, resolved against the universal pool. A
220
+ * non-code-aware kind returns null so `composeBlockSystemPrompt` falls back to the
221
+ * block's own `fragmentIds` unchanged. Records the selected ids on the step for
222
+ * observability; never throws (a lookup failure degrades to the block pins).
223
+ */
224
+ async resolveFragments(workspaceId, step, block) {
225
+ if (!hasTrait(step.agentKind, CODE_AWARE_TRAIT))
226
+ return null;
227
+ try {
228
+ const serviceIds = await this.resolveServiceFragmentIds(workspaceId, block);
229
+ // Service standards first, then the block's own pins; deduped, stable order.
230
+ const ids = [];
231
+ const seen = new Set();
232
+ for (const id of [...serviceIds, ...(block.fragmentIds ?? [])]) {
233
+ if (seen.has(id))
234
+ continue;
235
+ seen.add(id);
236
+ ids.push(id);
237
+ }
238
+ const fragments = ids
239
+ .map((id) => {
240
+ const fragment = getFragment(id);
241
+ return fragment ? { id, body: fragment.body } : null;
242
+ })
243
+ .filter((f) => f !== null);
244
+ if (fragments.length === 0)
245
+ return null;
246
+ step.selectedFragmentIds = fragments.map((f) => f.id);
247
+ return { fragments };
248
+ }
249
+ catch {
250
+ // Resolution must never wedge a run; fall back to the block's own pins.
251
+ return null;
252
+ }
253
+ }
254
+ /**
255
+ * The selected best-practice fragment ids of the block's owning service frame. Walks
256
+ * up from the block we already hold (bounded: frame → module → task, cycle-guarded),
257
+ * reading the frame's `serviceFragmentIds` — without re-fetching the block in hand or
258
+ * fetching the frame twice.
259
+ */
260
+ async resolveServiceFragmentIds(workspaceId, block) {
261
+ let current = block;
262
+ for (let i = 0; current && i < 8; i++) {
263
+ if (current.level === 'frame' || !current.parentId)
264
+ return current.serviceFragmentIds ?? [];
265
+ current = await this.deps.blockRepository.get(workspaceId, current.parentId);
266
+ }
267
+ return [];
268
+ }
269
+ /**
270
+ * Resolve documents (from any source) linked to the running block into compact
271
+ * agent context. A no-op unless the document-source integration is wired (the
272
+ * repository is an optional dependency), so the engine stays unchanged when it
273
+ * is off.
274
+ */
275
+ async resolveContextDocs(workspaceId, blockId) {
276
+ if (!this.deps.documents)
277
+ return [];
278
+ const docs = await this.deps.documents.listByBlock(workspaceId, blockId);
279
+ return docs.map((d) => ({ title: d.title, url: d.url, excerpt: d.excerpt }));
280
+ }
281
+ /**
282
+ * Resolve tracker issues (from any source) linked to the running block into
283
+ * structured agent context. A no-op unless the task-source integration is
284
+ * wired (the repository is an optional dependency), so the engine stays
285
+ * unchanged when it is off.
286
+ */
287
+ async resolveContextTasks(workspaceId, blockId) {
288
+ if (!this.deps.tasks)
289
+ return [];
290
+ const tasks = await this.deps.tasks.listByBlock(workspaceId, blockId);
291
+ return tasks.map((t) => ({
292
+ key: t.externalId,
293
+ url: t.url,
294
+ title: t.title,
295
+ status: t.status,
296
+ type: t.type,
297
+ assignee: t.assignee,
298
+ priority: t.priority,
299
+ labels: t.labels,
300
+ description: t.description,
301
+ comments: t.comments,
302
+ }));
303
+ }
304
+ /**
305
+ * Resolve the live ephemeral environment provisioned for the running block
306
+ * into compact agent context. A no-op unless the environment integration is
307
+ * wired (the provisioning service is an optional dependency), so the engine
308
+ * stays unchanged when it is off.
309
+ */
310
+ async resolveEnvironment(workspaceId, blockId) {
311
+ if (!this.deps.environmentProvisioning)
312
+ return null;
313
+ return this.deps.environmentProvisioning.resolveForBlock(workspaceId, blockId);
314
+ }
315
+ }
316
+ //# sourceMappingURL=AgentContextBuilder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AgentContextBuilder.js","sourceRoot":"","sources":["../../../src/modules/execution/AgentContextBuilder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ import type { AgentRunContext, AgentRunResult, Block, ExecutionInstance, IdGenerator, PipelineStep } from '@cat-factory/kernel';
2
+ import type { SpendService } from '@cat-factory/spend';
3
+ import type { AdvanceOptions, AdvanceResult } from './advance.js';
4
+ import type { AgentContextBuilder } from './AgentContextBuilder.js';
5
+ /**
6
+ * The engine flow-control operations the companion loop drives. These stay on
7
+ * `ExecutionService` (they are the shared state-machine primitives, reused by the human
8
+ * "request changes" path and the iteration-cap resolution) and are injected here so the
9
+ * companion evaluation can live in its own unit without duplicating them.
10
+ */
11
+ export interface CompanionControllerDeps {
12
+ contextBuilder: AgentContextBuilder;
13
+ spend: SpendService;
14
+ idGenerator: IdGenerator;
15
+ previewStepModel: (context: AgentRunContext) => Promise<string | undefined>;
16
+ runAgent: (context: AgentRunContext, options: AdvanceOptions) => Promise<AgentRunResult>;
17
+ finishStep: (step: PipelineStep) => void;
18
+ startStep: (step: PipelineStep) => void;
19
+ pauseStepForInput: (step: PipelineStep) => void;
20
+ updateBlockProgress: (workspaceId: string, instance: ExecutionInstance, status: 'in_progress' | 'blocked') => Promise<void>;
21
+ persistInstance: (workspaceId: string, instance: ExecutionInstance) => Promise<void>;
22
+ emitInstance: (workspaceId: string, instance: ExecutionInstance) => Promise<void>;
23
+ stopRunContainer: (workspaceId: string, instance: ExecutionInstance) => Promise<void>;
24
+ finalizeBlock: (workspaceId: string, instance: ExecutionInstance, confidence: number | undefined) => Promise<void>;
25
+ parkStepOnDecision: (workspaceId: string, instance: ExecutionInstance, step: PipelineStep, proposal?: string) => Promise<AdvanceResult>;
26
+ raiseDecisionRequired: (workspaceId: string, instance: ExecutionInstance) => Promise<void>;
27
+ loopCompanionProducer: (instance: ExecutionInstance, companionIndex: number, rework: NonNullable<PipelineStep['rework']>) => void;
28
+ }
29
+ /**
30
+ * Drives a companion (reviewer / spec-companion / architect-companion) step: it runs the
31
+ * companion as a normal inline LLM step, parses its rating JSON (with one repair retry), and
32
+ * acts on the verdict —
33
+ * - at/above threshold → finish; a gated companion raises the human approval gate on the
34
+ * producer's output, else the run advances.
35
+ * - below, budget left → loop the producer back with the feedback folded in (the automatic
36
+ * analogue of "request changes").
37
+ * - below, budget spent → park on the iteration-cap gate for a human (one more round /
38
+ * proceed / stop & reset), NOT a failure.
39
+ * An unparseable verdict (even after the repair retry) fails the run (`companion_rejected`)
40
+ * rather than silently passing. Extracted out of `ExecutionService`; the shared step-graph
41
+ * primitives it calls (`loopCompanionProducer`, the parking gate, the block/instance writes)
42
+ * stay on the engine and are injected via {@link CompanionControllerDeps}.
43
+ */
44
+ export declare class CompanionController {
45
+ private readonly deps;
46
+ constructor(deps: CompanionControllerDeps);
47
+ evaluate(workspaceId: string, instance: ExecutionInstance, step: PipelineStep, block: Block, isFinalStep: boolean, options: AdvanceOptions): Promise<AdvanceResult>;
48
+ /**
49
+ * Run a companion step and parse its JSON verdict, with ONE repair retry when the
50
+ * first reply doesn't parse (truncated, or wrapped in prose `extractJson` can't
51
+ * recover). The retry runs only when there is a producer to grade (`gradable`) — with
52
+ * none there is nothing to assess, so a malformed reply is irrelevant. Returns the
53
+ * parsed assessment (or `undefined` if even the repair failed) and the LAST call's
54
+ * result, with usage summed across both calls so the caller's single `spend.record`
55
+ * prices the whole thing. A still-unparseable verdict is handled by the caller (it
56
+ * surfaces to a human rather than passing), so this never wedges the run.
57
+ */
58
+ private runWithRepair;
59
+ }
60
+ //# sourceMappingURL=CompanionController.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CompanionController.d.ts","sourceRoot":"","sources":["../../../src/modules/execution/CompanionController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EAEd,KAAK,EACL,iBAAiB,EACjB,WAAW,EACX,YAAY,EACb,MAAM,qBAAqB,CAAA;AAO5B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAEtD,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AACjE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAwBnE;;;;;GAKG;AACH,MAAM,WAAW,uBAAuB;IACtC,cAAc,EAAE,mBAAmB,CAAA;IACnC,KAAK,EAAE,YAAY,CAAA;IACnB,WAAW,EAAE,WAAW,CAAA;IACxB,gBAAgB,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;IAC3E,QAAQ,EAAE,CAAC,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,cAAc,KAAK,OAAO,CAAC,cAAc,CAAC,CAAA;IACxF,UAAU,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAAA;IACxC,SAAS,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAAA;IACvC,iBAAiB,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAAA;IAC/C,mBAAmB,EAAE,CACnB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,iBAAiB,EAC3B,MAAM,EAAE,aAAa,GAAG,SAAS,KAC9B,OAAO,CAAC,IAAI,CAAC,CAAA;IAClB,eAAe,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,iBAAiB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACpF,YAAY,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,iBAAiB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACjF,gBAAgB,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,iBAAiB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACrF,aAAa,EAAE,CACb,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,iBAAiB,EAC3B,UAAU,EAAE,MAAM,GAAG,SAAS,KAC3B,OAAO,CAAC,IAAI,CAAC,CAAA;IAClB,kBAAkB,EAAE,CAClB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,iBAAiB,EAC3B,IAAI,EAAE,YAAY,EAClB,QAAQ,CAAC,EAAE,MAAM,KACd,OAAO,CAAC,aAAa,CAAC,CAAA;IAC3B,qBAAqB,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,iBAAiB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1F,qBAAqB,EAAE,CACrB,QAAQ,EAAE,iBAAiB,EAC3B,cAAc,EAAE,MAAM,EACtB,MAAM,EAAE,WAAW,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,KACxC,IAAI,CAAA;CACV;AAED;;;;;;;;;;;;;;GAcG;AACH,qBAAa,mBAAmB;IAClB,OAAO,CAAC,QAAQ,CAAC,IAAI;IAAjC,YAA6B,IAAI,EAAE,uBAAuB,EAAI;IAExD,QAAQ,CACZ,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,iBAAiB,EAC3B,IAAI,EAAE,YAAY,EAClB,KAAK,EAAE,KAAK,EACZ,WAAW,EAAE,OAAO,EACpB,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,aAAa,CAAC,CA6JxB;IAED;;;;;;;;;OASG;YACW,aAAa;CAiB5B"}
@@ -0,0 +1,216 @@
1
+ import { DEFAULT_COMPANION_MAX_ATTEMPTS, parseCompanionAssessment, } from '@cat-factory/contracts';
2
+ import { companionFor, companionTargets } from '@cat-factory/agents';
3
+ import { extractJson } from '../requirements/requirements.logic.js';
4
+ /** Parse a companion's JSON verdict from a model reply, or `undefined` if it won't parse. */
5
+ function parseCompanionOrUndefined(output) {
6
+ try {
7
+ return parseCompanionAssessment(extractJson(output ?? ''));
8
+ }
9
+ catch {
10
+ return undefined;
11
+ }
12
+ }
13
+ /** Sum the token usage of two model calls (for the companion's repair retry). */
14
+ function sumUsage(a, b) {
15
+ if (!a)
16
+ return b;
17
+ if (!b)
18
+ return a;
19
+ return {
20
+ inputTokens: a.inputTokens + b.inputTokens,
21
+ outputTokens: a.outputTokens + b.outputTokens,
22
+ };
23
+ }
24
+ /**
25
+ * Drives a companion (reviewer / spec-companion / architect-companion) step: it runs the
26
+ * companion as a normal inline LLM step, parses its rating JSON (with one repair retry), and
27
+ * acts on the verdict —
28
+ * - at/above threshold → finish; a gated companion raises the human approval gate on the
29
+ * producer's output, else the run advances.
30
+ * - below, budget left → loop the producer back with the feedback folded in (the automatic
31
+ * analogue of "request changes").
32
+ * - below, budget spent → park on the iteration-cap gate for a human (one more round /
33
+ * proceed / stop & reset), NOT a failure.
34
+ * An unparseable verdict (even after the repair retry) fails the run (`companion_rejected`)
35
+ * rather than silently passing. Extracted out of `ExecutionService`; the shared step-graph
36
+ * primitives it calls (`loopCompanionProducer`, the parking gate, the block/instance writes)
37
+ * stay on the engine and are injected via {@link CompanionControllerDeps}.
38
+ */
39
+ export class CompanionController {
40
+ deps;
41
+ constructor(deps) {
42
+ this.deps = deps;
43
+ }
44
+ async evaluate(workspaceId, instance, step, block, isFinalStep, options) {
45
+ const targets = companionTargets(step.agentKind);
46
+ // The nearest earlier step whose kind this companion reviews (the producer).
47
+ let producerIndex = -1;
48
+ for (let i = instance.currentStep - 1; i >= 0; i--) {
49
+ if (targets.includes(instance.steps[i].agentKind)) {
50
+ producerIndex = i;
51
+ break;
52
+ }
53
+ }
54
+ // Run the companion as a normal inline LLM step: its prompt asks for the rating
55
+ // JSON and `priorOutputs` already carries the producer's output for it to grade.
56
+ const context = await this.deps.contextBuilder.buildContext(workspaceId, instance, step, isFinalStep, block);
57
+ const previewModel = await this.deps.previewStepModel(context);
58
+ if (previewModel && previewModel !== step.model)
59
+ step.model = previewModel;
60
+ // Run the companion, parsing its JSON verdict with ONE repair retry when the first
61
+ // reply doesn't parse (truncated / wrapped in prose). Only retried when there is a
62
+ // producer to grade. `result` carries the LAST call's output + the summed usage.
63
+ const { assessment, result } = await this.runWithRepair(context, options, producerIndex >= 0);
64
+ if (result.usage) {
65
+ await this.deps.spend.record({
66
+ workspaceId,
67
+ executionId: instance.id,
68
+ agentKind: step.agentKind,
69
+ model: result.model ?? 'unknown',
70
+ usage: result.usage,
71
+ });
72
+ }
73
+ if (result.model)
74
+ step.model = result.model;
75
+ const companion = step.companion ?? {
76
+ threshold: companionFor(step.agentKind)?.defaultThreshold ?? 0.8,
77
+ maxAttempts: DEFAULT_COMPANION_MAX_ATTEMPTS,
78
+ attempts: 0,
79
+ verdicts: [],
80
+ };
81
+ const feedback = assessment?.summary ?? '';
82
+ // There IS a producer to grade but the companion's own verdict never parsed (even
83
+ // after the repair retry): do NOT silently treat that as a perfect pass. That is the
84
+ // bug where a truncated reviewer reply surfaced as "100% ≥ 80%" and dropped a real
85
+ // review. Surface it for a human instead, recording the raw reply as the detail.
86
+ if (producerIndex >= 0 && !assessment) {
87
+ step.output = result.output || '';
88
+ step.companion = companion;
89
+ await this.deps.persistInstance(workspaceId, instance);
90
+ // Hand the precise classification + the raw reply (the whole point of the failure,
91
+ // for triage) to the driver's single `failRun` funnel. Do NOT fail the run here as
92
+ // well: a second `failRun` from the driver would clobber this rich record with a
93
+ // generic `job_failed` ("the implementation container reported a failure", no
94
+ // detail), which is exactly the misleading surface this path is meant to avoid.
95
+ return {
96
+ kind: 'job_failed',
97
+ failureKind: 'companion_rejected',
98
+ error: `Companion "${step.agentKind}" did not return a parseable assessment (its reply ` +
99
+ `was truncated or malformed) after a repair retry.`,
100
+ detail: (result.output ?? '').slice(0, 2000) || undefined,
101
+ };
102
+ }
103
+ // The score to judge: the parsed rating when there is a producer to grade, else a
104
+ // perfect score (no producer of this companion's target kind precedes it, so there
105
+ // is genuinely nothing to grade and the run advances).
106
+ const rating = assessment && producerIndex >= 0 ? assessment.rating : 1;
107
+ // The FIRST review batch ALWAYS loops the producer back when it raised any comments,
108
+ // regardless of rating; the configured threshold only governs the SECOND pass onward.
109
+ // `attempts` counts automatic reworks, so it is 0 on the first batch. Applies to every
110
+ // companion (reviewer / spec-companion / architect-companion). Gated on a real producer
111
+ // so the loop-back below always has a step to re-run.
112
+ const firstBatch = companion.attempts === 0;
113
+ const hasComments = producerIndex >= 0 && (assessment?.comments?.length ?? 0) > 0;
114
+ const passed = firstBatch && hasComments ? false : rating >= companion.threshold;
115
+ // Append this cycle's standardized verdict (the same shape the requirements-rework
116
+ // gate stores) so the whole correction sequence is visible, not just the latest.
117
+ companion.verdicts.push({
118
+ rating,
119
+ threshold: companion.threshold,
120
+ passed,
121
+ feedback,
122
+ });
123
+ step.companion = companion;
124
+ step.output = feedback || result.output || '';
125
+ // PASS: the producer cleared the bar (and was not force-looped on its first batch).
126
+ if (passed) {
127
+ this.deps.finishStep(step);
128
+ step.progress = 1;
129
+ // A gated companion now raises the HUMAN approval gate on the producer's output
130
+ // (the human reviews what the companion just cleared). Never on the final step.
131
+ if (step.requiresApproval && !isFinalStep && step.approval?.status !== 'approved') {
132
+ const producer = producerIndex >= 0 ? instance.steps[producerIndex] : undefined;
133
+ step.approval = {
134
+ id: this.deps.idGenerator.next('appr'),
135
+ status: 'pending',
136
+ proposal: producer?.output ?? step.output,
137
+ };
138
+ this.deps.pauseStepForInput(step);
139
+ instance.status = 'blocked';
140
+ await this.deps.updateBlockProgress(workspaceId, instance, 'blocked');
141
+ await this.deps.persistInstance(workspaceId, instance);
142
+ await this.deps.emitInstance(workspaceId, instance);
143
+ return { kind: 'awaiting_decision', decisionId: step.approval.id };
144
+ }
145
+ if (isFinalStep) {
146
+ instance.status = 'done';
147
+ await this.deps.finalizeBlock(workspaceId, instance, undefined);
148
+ await this.deps.persistInstance(workspaceId, instance);
149
+ await this.deps.emitInstance(workspaceId, instance);
150
+ await this.deps.stopRunContainer(workspaceId, instance);
151
+ return { kind: 'done' };
152
+ }
153
+ instance.currentStep += 1;
154
+ const next = instance.steps[instance.currentStep];
155
+ if (next)
156
+ this.deps.startStep(next);
157
+ await this.deps.updateBlockProgress(workspaceId, instance, 'in_progress');
158
+ await this.deps.persistInstance(workspaceId, instance);
159
+ await this.deps.emitInstance(workspaceId, instance);
160
+ return { kind: 'continue' };
161
+ }
162
+ // BELOW THRESHOLD, automatic budget spent → DON'T get stuck. Park on a human
163
+ // decision (one more round / proceed anyway / stop & reset) — the same iteration-cap
164
+ // surface the requirements reviewer uses at its cap. Only AUTOMATIC reworks count
165
+ // against the budget (`attempts`); human "request changes" cycles on a gated
166
+ // companion re-run the producer without consuming it. `step.output` already holds the
167
+ // companion's latest feedback; the `exceeded` flag + the parked approval gate let the
168
+ // SPA render the three choices (resolved via `resolveCompanionExceeded`).
169
+ if (companion.attempts >= companion.maxAttempts) {
170
+ companion.exceeded = true;
171
+ step.companion = companion;
172
+ await this.deps.raiseDecisionRequired(workspaceId, instance);
173
+ return this.deps.parkStepOnDecision(workspaceId, instance, step, step.output ?? '');
174
+ }
175
+ // NOT PASSED, budget left → loop the producer back with the feedback folded in (the
176
+ // automatic analogue of a human "request changes"). Reached either below threshold or
177
+ // on the forced first-batch loop. `producerIndex` is guaranteed >= 0 here: a forced
178
+ // loop requires comments on a real producer, and a below-threshold rating requires a
179
+ // parsed verdict against a producer (otherwise rating defaulted to 1 and we passed).
180
+ const producer = instance.steps[producerIndex];
181
+ this.deps.loopCompanionProducer(instance, instance.currentStep, {
182
+ previousProposal: producer.output ?? '',
183
+ feedback: assessment?.summary ?? '',
184
+ ...(assessment?.comments?.length ? { comments: assessment.comments } : {}),
185
+ });
186
+ await this.deps.updateBlockProgress(workspaceId, instance, 'in_progress');
187
+ await this.deps.persistInstance(workspaceId, instance);
188
+ await this.deps.emitInstance(workspaceId, instance);
189
+ return { kind: 'continue' };
190
+ }
191
+ /**
192
+ * Run a companion step and parse its JSON verdict, with ONE repair retry when the
193
+ * first reply doesn't parse (truncated, or wrapped in prose `extractJson` can't
194
+ * recover). The retry runs only when there is a producer to grade (`gradable`) — with
195
+ * none there is nothing to assess, so a malformed reply is irrelevant. Returns the
196
+ * parsed assessment (or `undefined` if even the repair failed) and the LAST call's
197
+ * result, with usage summed across both calls so the caller's single `spend.record`
198
+ * prices the whole thing. A still-unparseable verdict is handled by the caller (it
199
+ * surfaces to a human rather than passing), so this never wedges the run.
200
+ */
201
+ async runWithRepair(context, options, gradable) {
202
+ const first = await this.deps.runAgent(context, options);
203
+ const parsed = parseCompanionOrUndefined(first.output);
204
+ if (parsed || !gradable)
205
+ return { assessment: parsed, result: first };
206
+ // The first reply didn't parse. Re-run the same grading step once more; with the
207
+ // companion's raised output budget this almost always clears a one-off truncation.
208
+ const second = await this.deps.runAgent(context, options);
209
+ const repaired = parseCompanionOrUndefined(second.output);
210
+ return {
211
+ assessment: repaired,
212
+ result: { ...second, usage: sumUsage(first.usage, second.usage) },
213
+ };
214
+ }
215
+ }
216
+ //# sourceMappingURL=CompanionController.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CompanionController.js","sourceRoot":"","sources":["../../../src/modules/execution/CompanionController.ts"],"names":[],"mappings":"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"}