substrate-ai 0.20.64 → 0.20.65
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/adapter-registry-BbVWH3Yv.js +4 -0
- package/dist/cli/index.js +93 -24
- package/dist/{decision-router-BA__VYIp.js → decision-router-DblHY8se.js} +1 -1
- package/dist/{decisions-4F91LrVD.js → decisions-DilHo99V.js} +2 -2
- package/dist/{dist-W2emvN3F.js → dist-K_RRWnBX.js} +2 -2
- package/dist/{errors-CKFu8YI9.js → errors-pSiZbn6e.js} +2 -2
- package/dist/{experimenter-BgpUcUaW.js → experimenter-DT9v2Pto.js} +1 -1
- package/dist/health-DC3y-sR6.js +1715 -0
- package/dist/health-qhtWYh49.js +8 -0
- package/dist/index-c924O9mj.d.ts +1432 -0
- package/dist/index.d.ts +56 -735
- package/dist/index.js +2 -2
- package/dist/interactive-prompt-C7wpE4z4.js +183 -0
- package/dist/{health-DudlnqXd.js → manifest-read-DDkXC3L_.js} +120 -2012
- package/dist/modules/interactive-prompt/index.d.ts +86 -0
- package/dist/modules/interactive-prompt/index.js +6 -0
- package/dist/recovery-engine-BKGBeBnW.js +281 -0
- package/dist/{routing-0ykvBl_4.js → routing-CzF0p6lI.js} +2 -2
- package/dist/run-DX95j4_D.js +14 -0
- package/dist/{run-CCxsv-9M.js → run-DzB4rgkj.js} +224 -31
- package/dist/src/modules/decision-router/index.js +1 -1
- package/dist/src/modules/recovery-engine/index.d.ts +1101 -0
- package/dist/src/modules/recovery-engine/index.js +5 -0
- package/dist/{upgrade-OFeC_NIx.js → upgrade-DxzQ1nss.js} +3 -3
- package/dist/{upgrade-aW7GYL2F.js → upgrade-MP9XzrI6.js} +2 -2
- package/dist/version-manager-impl-GZDUBt0Q.js +4 -0
- package/dist/work-graph-repository-DZyJv5pV.js +265 -0
- package/package.json +1 -1
- package/dist/adapter-registry-k7ZX3Bz6.js +0 -4
- package/dist/health-CLNmnZiw.js +0 -6
- package/dist/run-ChxsPICN.js +0 -10
- package/dist/version-manager-impl-BCSf5E3j.js +0 -4
- /package/dist/{decisions-C0pz9Clx.js → decisions-CzSIEeGP.js} +0 -0
- /package/dist/{routing-CcBOCuC9.js → routing-DFxoKHDt.js} +0 -0
- /package/dist/{version-manager-impl-FH4TTnXm.js → version-manager-impl-qFBiO4Eh.js} +0 -0
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
//#region src/modules/interactive-prompt/index.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Interactive Prompt — Phase D Story 54-3 (2026-04-05): original spec.
|
|
4
|
+
* Epic 72: Decision Router that triggers prompts (Story 72-1 / 72-2).
|
|
5
|
+
* Story 73-1: Recovery Engine that the prompt collects responses for.
|
|
6
|
+
*
|
|
7
|
+
* Presents an interactive numbered-choice prompt when the Decision Router halts
|
|
8
|
+
* execution, and writes a filesystem notification file before prompting so
|
|
9
|
+
* external monitors can detect the halt immediately.
|
|
10
|
+
*
|
|
11
|
+
* Non-interactive mode (SUBSTRATE_NON_INTERACTIVE=true or
|
|
12
|
+
* decisionContext.nonInteractive=true) bypasses stdin, applies the default
|
|
13
|
+
* action, and emits a decision:halt-skipped-non-interactive event for audit.
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Context provided to the interactive prompt when a halt is triggered.
|
|
17
|
+
* Consumed by the Recovery Engine (Story 73-1) to route the operator's choice.
|
|
18
|
+
*/
|
|
19
|
+
interface DecisionContext {
|
|
20
|
+
/** Pipeline run ID — resolved from manifest-read if not provided. */
|
|
21
|
+
runId?: string;
|
|
22
|
+
/** Decision type that triggered the halt (e.g., 'cost-ceiling-exhausted'). */
|
|
23
|
+
decisionType: string;
|
|
24
|
+
/** Severity of the halt (e.g., 'critical', 'fatal'). */
|
|
25
|
+
severity: string;
|
|
26
|
+
/** Human-readable summary of the halt condition to display to the operator. */
|
|
27
|
+
summary: string;
|
|
28
|
+
/** Default action to apply if operator presses Enter or is in non-interactive mode. */
|
|
29
|
+
defaultAction: string;
|
|
30
|
+
/** List of choice labels (e.g., ['retry', 'abort']). Used in the notification file. */
|
|
31
|
+
choices: string[];
|
|
32
|
+
/** When true, bypass stdin and return defaultAction immediately (AC4). */
|
|
33
|
+
nonInteractive?: boolean;
|
|
34
|
+
/** Optional event emitter callback for decision:halt-skipped-non-interactive. */
|
|
35
|
+
onHaltSkipped?: (payload: HaltSkippedPayload) => void;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Payload emitted when a halt is skipped under non-interactive mode (AC4).
|
|
39
|
+
* Matches OrchestratorEvents['decision:halt-skipped-non-interactive'].
|
|
40
|
+
*/
|
|
41
|
+
interface HaltSkippedPayload {
|
|
42
|
+
runId: string;
|
|
43
|
+
decisionType: string;
|
|
44
|
+
severity: string;
|
|
45
|
+
defaultAction: string;
|
|
46
|
+
reason: string;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* The operator's chosen action, returned by runInteractivePrompt.
|
|
50
|
+
* Maps choice 1–4 to the corresponding action string.
|
|
51
|
+
*/
|
|
52
|
+
type OperatorAction = string | 'retry-with-custom-context' | 'propose-re-scope' | 'abort-run';
|
|
53
|
+
/**
|
|
54
|
+
* Shape written to .substrate/notifications/<runId>-<timestamp>.json.
|
|
55
|
+
* Exported so callers (e.g., report.ts) can parse typed notifications.
|
|
56
|
+
*/
|
|
57
|
+
interface HaltNotification {
|
|
58
|
+
runId: string;
|
|
59
|
+
timestamp: string;
|
|
60
|
+
decisionType: string;
|
|
61
|
+
severity: string;
|
|
62
|
+
context: Record<string, unknown>;
|
|
63
|
+
choices: string[];
|
|
64
|
+
operatorChoice: string | null;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Run the interactive prompt for a Decision Router halt.
|
|
68
|
+
*
|
|
69
|
+
* Workflow:
|
|
70
|
+
* 1. Resolve run ID (from context or manifest-read.ts).
|
|
71
|
+
* 2. Write notification file BEFORE prompting (AC5).
|
|
72
|
+
* 3. If non-interactive mode, emit halt-skipped event and return default (AC4).
|
|
73
|
+
* 4. If stdin is not a TTY, log warning and treat as non-interactive (defensive).
|
|
74
|
+
* 5. Render the numbered-choice prompt (AC2).
|
|
75
|
+
* 6. Read one line from stdin via readline.createInterface (AC3).
|
|
76
|
+
* 7. Parse and return the chosen action.
|
|
77
|
+
* 8. Update notification file with the operator's choice (AC5).
|
|
78
|
+
*
|
|
79
|
+
* @param decisionContext - Decision context from the Decision Router halt.
|
|
80
|
+
* @returns The operator's chosen action string.
|
|
81
|
+
*/
|
|
82
|
+
declare function runInteractivePrompt(decisionContext: DecisionContext): Promise<string>; //#endregion
|
|
83
|
+
|
|
84
|
+
//# sourceMappingURL=index.d.ts.map
|
|
85
|
+
export { DecisionContext, HaltNotification, HaltSkippedPayload, OperatorAction, runInteractivePrompt };
|
|
86
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
import { createLogger } from "./logger-KeHncl-f.js";
|
|
2
|
+
import { WorkGraphRepository } from "./work-graph-repository-DZyJv5pV.js";
|
|
3
|
+
import { randomUUID } from "node:crypto";
|
|
4
|
+
|
|
5
|
+
//#region src/modules/recovery-engine/index.ts
|
|
6
|
+
const logger = createLogger("recovery-engine");
|
|
7
|
+
/**
|
|
8
|
+
* Root causes that map to Tier A (auto-retry) when retry budget is available.
|
|
9
|
+
* Transient failures that can be resolved by re-dispatching with additional context.
|
|
10
|
+
*/
|
|
11
|
+
const RETRY_ROOT_CAUSES = new Set([
|
|
12
|
+
"build-failure",
|
|
13
|
+
"test-coverage-gap",
|
|
14
|
+
"ac-missing-evidence",
|
|
15
|
+
"missing-import"
|
|
16
|
+
]);
|
|
17
|
+
/**
|
|
18
|
+
* Root causes that always map to Tier B (re-scope proposal) regardless of budget.
|
|
19
|
+
* Structural failures that cannot be resolved by retrying the same approach.
|
|
20
|
+
*/
|
|
21
|
+
const PROPOSE_ROOT_CAUSES = new Set([
|
|
22
|
+
"scope-violation",
|
|
23
|
+
"fundamental-design-error",
|
|
24
|
+
"cross-story-contract-mismatch"
|
|
25
|
+
]);
|
|
26
|
+
/**
|
|
27
|
+
* Root causes that map to Tier C (halt) — requires operator intervention.
|
|
28
|
+
*/
|
|
29
|
+
const HALT_ROOT_CAUSES = new Set([
|
|
30
|
+
"halt-policy",
|
|
31
|
+
"irreversible",
|
|
32
|
+
"security-violation",
|
|
33
|
+
"data-loss-risk"
|
|
34
|
+
]);
|
|
35
|
+
/**
|
|
36
|
+
* Classify a failure into a recovery action tier.
|
|
37
|
+
*
|
|
38
|
+
* Pure function — no imports from I/O modules, no side effects.
|
|
39
|
+
* The action handler (`runRecoveryEngine`) owns all I/O.
|
|
40
|
+
*
|
|
41
|
+
* Classification rules:
|
|
42
|
+
* 1. HALT root causes → 'halt' always
|
|
43
|
+
* 2. PROPOSE root causes → 'propose' always (structural, not retry-able)
|
|
44
|
+
* 3. RETRY root causes:
|
|
45
|
+
* - budget.remaining > 0 → 'retry'
|
|
46
|
+
* - budget.remaining <= 0 → 'propose' (exhausted, escalate)
|
|
47
|
+
* 4. Unknown root cause → 'propose' (safe default)
|
|
48
|
+
*
|
|
49
|
+
* @param failure - Failure with rootCause field
|
|
50
|
+
* @param budget - Retry budget with remaining count
|
|
51
|
+
* @returns 'retry' | 'propose' | 'halt'
|
|
52
|
+
*/
|
|
53
|
+
function classifyRecoveryAction(failure, budget) {
|
|
54
|
+
const { rootCause } = failure;
|
|
55
|
+
if (HALT_ROOT_CAUSES.has(rootCause) || rootCause.startsWith("halt-")) return "halt";
|
|
56
|
+
if (PROPOSE_ROOT_CAUSES.has(rootCause)) return "propose";
|
|
57
|
+
if (RETRY_ROOT_CAUSES.has(rootCause)) {
|
|
58
|
+
if (budget.remaining > 0) return "retry";
|
|
59
|
+
return "propose";
|
|
60
|
+
}
|
|
61
|
+
return "propose";
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Query work-graph dependency edges to find stories that depend on any
|
|
65
|
+
* proposed story. Used for Tier B back-pressure when NOT in linear mode.
|
|
66
|
+
*
|
|
67
|
+
* @param proposedStoryKeys - Story keys currently in pending_proposals
|
|
68
|
+
* @param pendingStoryKeys - Story keys still pending / dispatching
|
|
69
|
+
* @param adapter - DatabaseAdapter for wg_stories / story_dependencies
|
|
70
|
+
* @returns { pause: string[], continue: string[] }
|
|
71
|
+
*/
|
|
72
|
+
async function computeDependencyAwarePause(proposedStoryKeys, pendingStoryKeys, adapter) {
|
|
73
|
+
if (pendingStoryKeys.length === 0) return {
|
|
74
|
+
pause: [],
|
|
75
|
+
continue: []
|
|
76
|
+
};
|
|
77
|
+
try {
|
|
78
|
+
const wgRepo = new WorkGraphRepository(adapter);
|
|
79
|
+
const deps = await wgRepo.getDependencyEdges();
|
|
80
|
+
const proposedSet = new Set(proposedStoryKeys);
|
|
81
|
+
const pause = [];
|
|
82
|
+
const continueKeys = [];
|
|
83
|
+
for (const pendingKey of pendingStoryKeys) {
|
|
84
|
+
const blockers = deps.filter((d) => d.story_key === pendingKey).map((d) => d.depends_on);
|
|
85
|
+
const isBlocked = blockers.some((b) => proposedSet.has(b));
|
|
86
|
+
if (isBlocked) pause.push(pendingKey);
|
|
87
|
+
else continueKeys.push(pendingKey);
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
pause,
|
|
91
|
+
continue: continueKeys
|
|
92
|
+
};
|
|
93
|
+
} catch (err) {
|
|
94
|
+
logger.warn({ err: err instanceof Error ? err.message : String(err) }, "Work-graph dependency query failed — falling back to pause-all for back-pressure");
|
|
95
|
+
return {
|
|
96
|
+
pause: pendingStoryKeys,
|
|
97
|
+
continue: []
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Recovery Engine action handler.
|
|
103
|
+
*
|
|
104
|
+
* Consumes a halt decision (failure + budget) and applies tiered recovery:
|
|
105
|
+
*
|
|
106
|
+
* Tier A (retry): emits recovery:tier-a-retry, returns enriched prompt for re-dispatch.
|
|
107
|
+
* Tier B (propose): appends Proposal to RunManifest.pending_proposals, applies back-pressure.
|
|
108
|
+
* Tier C (halt): emits recovery:tier-c-halt, returns halt action for Decision Router.
|
|
109
|
+
*
|
|
110
|
+
* Safety valve: if pending_proposals.length >= 5 after any Tier B append,
|
|
111
|
+
* emits pipeline:halted-pending-proposals and returns halt-entire-run.
|
|
112
|
+
*
|
|
113
|
+
* Back-pressure:
|
|
114
|
+
* >= 2 proposals + work graph: pauses dependent stories, continues independent ones.
|
|
115
|
+
* >= 2 proposals + linear mode: pauses ALL remaining dispatches.
|
|
116
|
+
*
|
|
117
|
+
* Idempotency: re-invoking on a story already in pending_proposals is a no-op
|
|
118
|
+
* (handled inside RunManifest.appendProposal via storyKey deduplication).
|
|
119
|
+
*
|
|
120
|
+
* Canonical helper discipline: all manifest reads/writes via RunManifest class.
|
|
121
|
+
* No direct JSON file access. No new aggregate manifest formats.
|
|
122
|
+
*
|
|
123
|
+
* @param input - Recovery engine input (see RecoveryEngineInput)
|
|
124
|
+
* @returns Recovery action result for the orchestrator to act on
|
|
125
|
+
*/
|
|
126
|
+
async function runRecoveryEngine(input) {
|
|
127
|
+
const { runId, storyKey, failure, budget, bus, manifest, adapter, engine, pendingStoryKeys = [] } = input;
|
|
128
|
+
const action = classifyRecoveryAction(failure, budget);
|
|
129
|
+
if (action === "retry") {
|
|
130
|
+
const attempt = budget.max - budget.remaining + 1;
|
|
131
|
+
const retryBudgetRemaining = budget.remaining - 1;
|
|
132
|
+
const diagnosisParts = [];
|
|
133
|
+
if (failure.diagnosis) diagnosisParts.push(`## Recovery Diagnosis\n\n${failure.diagnosis}`);
|
|
134
|
+
if (failure.findings && failure.findings.length > 0) diagnosisParts.push(`## Prior Attempt Findings\n\n${failure.findings.map((f, i) => `${i + 1}. ${typeof f === "string" ? f : JSON.stringify(f)}`).join("\n")}`);
|
|
135
|
+
const enrichedPrompt = diagnosisParts.length > 0 ? diagnosisParts.join("\n\n") + "\n\n---\n\n" : void 0;
|
|
136
|
+
bus.emit("recovery:tier-a-retry", {
|
|
137
|
+
runId,
|
|
138
|
+
storyKey,
|
|
139
|
+
rootCause: failure.rootCause,
|
|
140
|
+
attempt,
|
|
141
|
+
retryBudgetRemaining
|
|
142
|
+
});
|
|
143
|
+
logger.info({
|
|
144
|
+
runId,
|
|
145
|
+
storyKey,
|
|
146
|
+
rootCause: failure.rootCause,
|
|
147
|
+
attempt,
|
|
148
|
+
retryBudgetRemaining
|
|
149
|
+
}, "Recovery Engine: Tier A retry dispatched");
|
|
150
|
+
return {
|
|
151
|
+
action: "retry",
|
|
152
|
+
attempt,
|
|
153
|
+
retryBudgetRemaining,
|
|
154
|
+
...enrichedPrompt !== void 0 ? { enrichedPrompt } : {}
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
if (action === "halt") {
|
|
158
|
+
bus.emit("recovery:tier-c-halt", {
|
|
159
|
+
runId,
|
|
160
|
+
storyKey,
|
|
161
|
+
rootCause: failure.rootCause
|
|
162
|
+
});
|
|
163
|
+
logger.warn({
|
|
164
|
+
runId,
|
|
165
|
+
storyKey,
|
|
166
|
+
rootCause: failure.rootCause
|
|
167
|
+
}, "Recovery Engine: Tier C halt — operator intervention required");
|
|
168
|
+
return { action: "halt" };
|
|
169
|
+
}
|
|
170
|
+
const attempts = budget.max - budget.remaining;
|
|
171
|
+
const suggestedAction = buildSuggestedAction(failure.rootCause, storyKey);
|
|
172
|
+
const blastRadius = [];
|
|
173
|
+
const proposal = {
|
|
174
|
+
id: randomUUID(),
|
|
175
|
+
created_at: new Date().toISOString(),
|
|
176
|
+
description: `Recovery Engine: ${failure.rootCause} on story ${storyKey} after ${attempts} attempt(s)`,
|
|
177
|
+
type: "escalate",
|
|
178
|
+
story_key: storyKey,
|
|
179
|
+
storyKey,
|
|
180
|
+
rootCause: failure.rootCause,
|
|
181
|
+
attempts,
|
|
182
|
+
suggestedAction,
|
|
183
|
+
blastRadius
|
|
184
|
+
};
|
|
185
|
+
await manifest.appendProposal(proposal).catch((err) => {
|
|
186
|
+
logger.warn({
|
|
187
|
+
err: err instanceof Error ? err.message : String(err),
|
|
188
|
+
storyKey
|
|
189
|
+
}, "Recovery Engine: appendProposal failed — pipeline continues");
|
|
190
|
+
});
|
|
191
|
+
let pendingProposals = [];
|
|
192
|
+
try {
|
|
193
|
+
const manifestData = await manifest.read();
|
|
194
|
+
pendingProposals = manifestData.pending_proposals;
|
|
195
|
+
} catch (err) {
|
|
196
|
+
logger.warn({ err: err instanceof Error ? err.message : String(err) }, "Recovery Engine: manifest read failed after appendProposal");
|
|
197
|
+
}
|
|
198
|
+
const pendingProposalsCount = pendingProposals.length;
|
|
199
|
+
if (pendingProposalsCount >= 5) {
|
|
200
|
+
bus.emit("pipeline:halted-pending-proposals", {
|
|
201
|
+
runId,
|
|
202
|
+
pendingProposalsCount
|
|
203
|
+
});
|
|
204
|
+
logger.error({
|
|
205
|
+
runId,
|
|
206
|
+
pendingProposalsCount
|
|
207
|
+
}, "Recovery Engine: safety valve triggered — >= 5 pending proposals, halting run");
|
|
208
|
+
return {
|
|
209
|
+
action: "halt-entire-run",
|
|
210
|
+
pendingProposalsCount
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
bus.emit("recovery:tier-b-proposal", {
|
|
214
|
+
runId,
|
|
215
|
+
storyKey,
|
|
216
|
+
rootCause: failure.rootCause,
|
|
217
|
+
attempts,
|
|
218
|
+
suggestedAction,
|
|
219
|
+
blastRadius
|
|
220
|
+
});
|
|
221
|
+
logger.info({
|
|
222
|
+
runId,
|
|
223
|
+
storyKey,
|
|
224
|
+
rootCause: failure.rootCause,
|
|
225
|
+
pendingProposalsCount
|
|
226
|
+
}, "Recovery Engine: Tier B proposal appended");
|
|
227
|
+
if (pendingProposalsCount >= 2) {
|
|
228
|
+
const isLinearMode = engine === "linear";
|
|
229
|
+
if (isLinearMode) {
|
|
230
|
+
logger.info({
|
|
231
|
+
runId,
|
|
232
|
+
pendingProposalsCount
|
|
233
|
+
}, "Recovery Engine: linear mode back-pressure — pausing all pending dispatches");
|
|
234
|
+
return {
|
|
235
|
+
action: "propose",
|
|
236
|
+
storyKey,
|
|
237
|
+
pendingProposalsCount,
|
|
238
|
+
pauseAll: true
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
const proposedStoryKeys = pendingProposals.map((p) => p.storyKey ?? p.story_key).filter((k) => k !== void 0);
|
|
242
|
+
const { pause, continue: continueKeys } = await computeDependencyAwarePause(proposedStoryKeys, pendingStoryKeys, adapter);
|
|
243
|
+
logger.info({
|
|
244
|
+
runId,
|
|
245
|
+
pendingProposalsCount,
|
|
246
|
+
pause,
|
|
247
|
+
continue: continueKeys
|
|
248
|
+
}, "Recovery Engine: work-graph back-pressure computed");
|
|
249
|
+
return {
|
|
250
|
+
action: "propose",
|
|
251
|
+
storyKey,
|
|
252
|
+
pendingProposalsCount,
|
|
253
|
+
pause,
|
|
254
|
+
continue: continueKeys
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
return {
|
|
258
|
+
action: "propose",
|
|
259
|
+
storyKey,
|
|
260
|
+
pendingProposalsCount
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Build a human-readable suggested action for the operator based on root cause.
|
|
265
|
+
*/
|
|
266
|
+
function buildSuggestedAction(rootCause, storyKey) {
|
|
267
|
+
switch (rootCause) {
|
|
268
|
+
case "scope-violation": return `Split story ${storyKey} into smaller stories with narrower scope`;
|
|
269
|
+
case "fundamental-design-error": return `Revisit the architecture for story ${storyKey} — design approach is not viable`;
|
|
270
|
+
case "cross-story-contract-mismatch": return `Reconcile interface contracts for story ${storyKey} with dependent stories`;
|
|
271
|
+
case "build-failure": return `Fix build errors for story ${storyKey} — retry budget exhausted`;
|
|
272
|
+
case "test-coverage-gap": return `Add missing test coverage for story ${storyKey}`;
|
|
273
|
+
case "ac-missing-evidence": return `Story ${storyKey} lacks acceptance criteria evidence — revisit scope or provide evidence`;
|
|
274
|
+
case "missing-import": return `Fix missing import dependencies for story ${storyKey}`;
|
|
275
|
+
default: return `Manual review required for story ${storyKey}: ${rootCause}`;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
//#endregion
|
|
280
|
+
export { classifyRecoveryAction, runRecoveryEngine };
|
|
281
|
+
//# sourceMappingURL=recovery-engine-BKGBeBnW.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ModelRoutingConfigSchema, ProviderPolicySchema, RoutingConfigError, RoutingRecommender, RoutingResolver, RoutingTelemetry, RoutingTokenAccumulator, RoutingTuner, TASK_TYPE_PHASE_MAP, getModelTier, loadModelRoutingConfig } from "./dist-
|
|
2
|
-
import "./routing-
|
|
1
|
+
import { ModelRoutingConfigSchema, ProviderPolicySchema, RoutingConfigError, RoutingRecommender, RoutingResolver, RoutingTelemetry, RoutingTokenAccumulator, RoutingTuner, TASK_TYPE_PHASE_MAP, getModelTier, loadModelRoutingConfig } from "./dist-K_RRWnBX.js";
|
|
2
|
+
import "./routing-DFxoKHDt.js";
|
|
3
3
|
|
|
4
4
|
export { loadModelRoutingConfig };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import "./health-DC3y-sR6.js";
|
|
2
|
+
import "./logger-KeHncl-f.js";
|
|
3
|
+
import "./helpers-CElYrONe.js";
|
|
4
|
+
import "./dist-K_RRWnBX.js";
|
|
5
|
+
import "./manifest-read-DDkXC3L_.js";
|
|
6
|
+
import { normalizeGraphSummaryToStatus, registerRunCommand, resolveMaxReviewCycles, resolveProbeAuthorStateIntegrating, runRunAction, wireNdjsonEmitter } from "./run-DzB4rgkj.js";
|
|
7
|
+
import "./routing-DFxoKHDt.js";
|
|
8
|
+
import "./work-graph-repository-DZyJv5pV.js";
|
|
9
|
+
import "./decisions-CzSIEeGP.js";
|
|
10
|
+
import "./decision-router-DblHY8se.js";
|
|
11
|
+
import "./interactive-prompt-C7wpE4z4.js";
|
|
12
|
+
import "./recovery-engine-BKGBeBnW.js";
|
|
13
|
+
|
|
14
|
+
export { runRunAction };
|