stageflow 0.9.0 → 0.12.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/README.md +1 -0
- package/dist/agent/activity.d.ts +9 -0
- package/dist/agent/agentBackend.d.ts +32 -0
- package/dist/agent/agentBackend.js +38 -0
- package/dist/agent/claudeActivity.d.ts +15 -0
- package/dist/agent/claudeActivity.js +58 -0
- package/dist/agent/claudeAdapter.d.ts +5 -0
- package/dist/agent/claudeAdapter.js +301 -0
- package/dist/agent/claudeSession.d.ts +18 -0
- package/dist/agent/claudeSession.js +54 -0
- package/dist/agent/claudeTools.d.ts +89 -0
- package/dist/agent/claudeTools.js +135 -0
- package/dist/agent/fakeAgent.js +24 -4
- package/dist/agent/piAdapter.d.ts +6 -3
- package/dist/agent/piAdapter.js +129 -21
- package/dist/agent/port.d.ts +50 -1
- package/dist/agent/resolveAgentPort.d.ts +26 -0
- package/dist/agent/resolveAgentPort.js +39 -0
- package/dist/cli/runCommand.js +2 -2
- package/dist/cli/runsCommand.d.ts +1 -1
- package/dist/cli/runsCommand.js +184 -2
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +11 -5
- package/dist/config/browseCatalog.js +1 -1
- package/dist/config/createPipeline.d.ts +2 -1
- package/dist/config/createPipeline.js +34 -9
- package/dist/config/createStage.js +14 -9
- package/dist/config/loadPipeline.js +10 -1
- package/dist/config/loadStage.js +138 -2
- package/dist/config/loadStageflowManifest.js +14 -1
- package/dist/config/mergePipelineIncludes.d.ts +1 -0
- package/dist/config/mergePipelineIncludes.js +14 -1
- package/dist/config/normalizePipelineStageEntry.d.ts +7 -2
- package/dist/config/normalizePipelineStageEntry.js +49 -6
- package/dist/config/parseCompletionContract.d.ts +8 -0
- package/dist/config/parseCompletionContract.js +218 -0
- package/dist/config/parsePreEmitChecks.d.ts +3 -0
- package/dist/config/parsePreEmitChecks.js +65 -0
- package/dist/config/pipelineNeeds.d.ts +19 -0
- package/dist/config/pipelineNeeds.js +151 -0
- package/dist/config/pipelineStageKeys.js +16 -1
- package/dist/config/resolveForkEmitContext.d.ts +6 -2
- package/dist/config/resolveForkEmitContext.js +9 -2
- package/dist/config/resolvePipelineDag.d.ts +2 -1
- package/dist/config/resolvePipelineDag.js +182 -39
- package/dist/config/validateCatalog.d.ts +1 -1
- package/dist/config/validateCompletionContract.d.ts +4 -0
- package/dist/config/validateCompletionContract.js +52 -0
- package/dist/envelope/check.d.ts +1 -1
- package/dist/envelope/check.js +86 -13
- package/dist/envelope/cloneForks.d.ts +1 -1
- package/dist/envelope/cloneForks.js +24 -9
- package/dist/envelope/feedbackLoop.d.ts +4 -0
- package/dist/envelope/feedbackLoop.js +31 -0
- package/dist/envelope/payloadSchema.d.ts +7 -1
- package/dist/envelope/payloadSchema.js +170 -13
- package/dist/envelope/preEmitChecks.d.ts +29 -0
- package/dist/envelope/preEmitChecks.js +57 -0
- package/dist/hitl/qaTrail.d.ts +25 -0
- package/dist/hitl/qaTrail.js +51 -0
- package/dist/mcp/catalogTools.js +4 -2
- package/dist/mcp/controlTools.js +72 -0
- package/dist/mcp/waitingGates.d.ts +2 -1
- package/dist/mcp/waitingGates.js +17 -1
- package/dist/package-meta.d.ts +1 -1
- package/dist/package-meta.js +1 -1
- package/dist/projection/projectRun.d.ts +4 -1
- package/dist/projection/projectRun.js +7 -0
- package/dist/prompt/feedbackLoopContext.d.ts +2 -0
- package/dist/prompt/feedbackLoopContext.js +17 -0
- package/dist/prompt/priorEnvelope.d.ts +2 -2
- package/dist/prompt/priorEnvelope.js +4 -1
- package/dist/runstore/pipelineDagSnapshot.d.ts +1 -0
- package/dist/runstore/pipelineDagSnapshot.js +51 -11
- package/dist/runstore/port.d.ts +185 -3
- package/dist/runstore/port.js +42 -3
- package/dist/runstore/runProjection.d.ts +7 -3
- package/dist/runstore/runProjection.js +30 -15
- package/dist/runstore/sqlite/SqliteRunStore.d.ts +25 -1
- package/dist/runstore/sqlite/SqliteRunStore.js +626 -8
- package/dist/runstore/sqlite/schema.d.ts +1 -1
- package/dist/runstore/sqlite/schema.js +99 -0
- package/dist/runstore/stageInstanceId.d.ts +1 -1
- package/dist/runstore/stageInstanceId.js +3 -2
- package/dist/runstore/trackProjection.js +59 -27
- package/dist/runstore/verificationHistory.d.ts +19 -0
- package/dist/runstore/verificationHistory.js +30 -0
- package/dist/runtime/cloneSchedule.d.ts +40 -4
- package/dist/runtime/cloneSchedule.js +212 -28
- package/dist/runtime/completionCheckRunner.d.ts +137 -0
- package/dist/runtime/completionCheckRunner.js +365 -0
- package/dist/runtime/completionCheckoutBaseline.d.ts +3 -0
- package/dist/runtime/completionCheckoutBaseline.js +44 -0
- package/dist/runtime/envelopeRouting.d.ts +10 -3
- package/dist/runtime/envelopeRouting.js +146 -5
- package/dist/runtime/feedbackLoopCoordinator.d.ts +74 -0
- package/dist/runtime/feedbackLoopCoordinator.js +446 -0
- package/dist/runtime/feedbackLoopDecision.d.ts +44 -0
- package/dist/runtime/feedbackLoopDecision.js +207 -0
- package/dist/runtime/feedbackLoopRoute.d.ts +5 -0
- package/dist/runtime/feedbackLoopRoute.js +13 -0
- package/dist/runtime/feedbackLoopSchedule.d.ts +38 -0
- package/dist/runtime/feedbackLoopSchedule.js +72 -0
- package/dist/runtime/forkGeneration.d.ts +72 -0
- package/dist/runtime/forkGeneration.js +295 -0
- package/dist/runtime/gitCheckoutCapability.d.ts +7 -0
- package/dist/runtime/gitCheckoutCapability.js +97 -0
- package/dist/runtime/manualRecoveryState.d.ts +40 -0
- package/dist/runtime/manualRecoveryState.js +73 -0
- package/dist/runtime/pipelineScheduler.d.ts +13 -1
- package/dist/runtime/pipelineScheduler.js +328 -45
- package/dist/runtime/replayLifecycle.d.ts +107 -0
- package/dist/runtime/replayLifecycle.js +168 -0
- package/dist/runtime/runManager.d.ts +54 -1
- package/dist/runtime/runManager.js +471 -6
- package/dist/runtime/runRetryCoordinator.d.ts +6 -1
- package/dist/runtime/runRetryCoordinator.js +43 -9
- package/dist/runtime/stageAttemptBootstrap.d.ts +3 -1
- package/dist/runtime/stageAttemptBootstrap.js +79 -1
- package/dist/runtime/stageProcessLauncher.d.ts +1 -1
- package/dist/runtime/stageRecovery.js +1 -1
- package/dist/runtime/stageRunner.d.ts +4 -1
- package/dist/runtime/stageRunner.js +29 -3
- package/dist/runtime/stageWorker.js +69 -2
- package/dist/runtime/stageWorkerProtocol.d.ts +1 -1
- package/dist/runtime/verifiedStageExecution.d.ts +29 -0
- package/dist/runtime/verifiedStageExecution.js +119 -0
- package/dist/server/bootstrap.js +1 -0
- package/dist/server/http.js +114 -0
- package/dist/server/operatorResults.js +2 -0
- package/dist/tools/askOperator.d.ts +161 -5
- package/dist/tools/askOperator.js +58 -25
- package/dist/tools/emitStageEnvelope.d.ts +12 -12
- package/dist/tools/emitStageEnvelope.js +112 -24
- package/dist/types/completion.d.ts +43 -0
- package/dist/types/completion.js +1 -0
- package/dist/types/envelope.d.ts +18 -0
- package/dist/types/forkChoice.d.ts +9 -4
- package/dist/types/forkChoice.js +1 -1
- package/dist/types/pipeline.d.ts +39 -2
- package/dist/types/preEmitCheck.d.ts +18 -0
- package/dist/types/preEmitCheck.js +1 -0
- package/dist/types/stage.d.ts +13 -0
- package/dist/types/stageflowManifest.d.ts +2 -0
- package/dist/ui/assets/index-CXGz4nL7.js +118 -0
- package/dist/ui/assets/{index-C3N7MXAC.css → index-uVHiae8s.css} +1 -1
- package/dist/ui/index.html +2 -2
- package/package.json +2 -1
- package/skills/stageflow-author/references/catalog-mapping.md +26 -2
- package/skills/stageflow-author/references/catalog-write-conventions.md +1 -1
- package/dist/ui/assets/index-CSoGDA3A.js +0 -118
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import type { FeedbackLoopContext, StageSessionMode } from "../agent/port.js";
|
|
2
|
+
import type { DeferredFeedbackSendBack, FeedbackLoopRecord, RunStore } from "../runstore/port.js";
|
|
3
|
+
import type { StageEnvelope } from "../types/envelope.js";
|
|
4
|
+
import type { ResolvedPipelineDag, ResolvedPipelineStageNode } from "../types/pipeline.js";
|
|
5
|
+
import { terminalizeCurrentFeedbackReplay } from "./feedbackLoopCoordinator.js";
|
|
6
|
+
import { type FeedbackScheduleState } from "./feedbackLoopSchedule.js";
|
|
7
|
+
export { terminalizeCurrentFeedbackReplay };
|
|
8
|
+
type StageScheduleState = "pending" | "active" | "waiting" | "succeeded" | "failed" | "skipped";
|
|
9
|
+
export type ScheduleProjection = {
|
|
10
|
+
dag: ResolvedPipelineDag;
|
|
11
|
+
states: Map<string, StageScheduleState>;
|
|
12
|
+
completedEnvelopes: Map<string, StageEnvelope>;
|
|
13
|
+
};
|
|
14
|
+
export type ReplayApplyResult = {
|
|
15
|
+
kind: "applied";
|
|
16
|
+
loopId: string;
|
|
17
|
+
replayId: string;
|
|
18
|
+
retiredSkippedStageIds: string[];
|
|
19
|
+
loop: FeedbackLoopRecord;
|
|
20
|
+
} | {
|
|
21
|
+
kind: "idempotent";
|
|
22
|
+
loopId: string;
|
|
23
|
+
replayId: string;
|
|
24
|
+
retiredSkippedStageIds: string[];
|
|
25
|
+
loop: FeedbackLoopRecord;
|
|
26
|
+
} | {
|
|
27
|
+
kind: "waiting_for_human";
|
|
28
|
+
loop: FeedbackLoopRecord;
|
|
29
|
+
deferred: DeferredFeedbackSendBack;
|
|
30
|
+
sourceStageId: string;
|
|
31
|
+
sourceAttempt: number;
|
|
32
|
+
} | {
|
|
33
|
+
kind: "rejected";
|
|
34
|
+
reason: string;
|
|
35
|
+
};
|
|
36
|
+
export type StageLaunchPrep = {
|
|
37
|
+
attempt: number;
|
|
38
|
+
sessionMode?: StageSessionMode;
|
|
39
|
+
priorAttempt?: number;
|
|
40
|
+
feedbackLoopContext?: FeedbackLoopContext;
|
|
41
|
+
};
|
|
42
|
+
export type ReplayScheduleHandle = {
|
|
43
|
+
readonly feedback: FeedbackScheduleState;
|
|
44
|
+
};
|
|
45
|
+
export declare function createReplaySchedule(): ReplayScheduleHandle;
|
|
46
|
+
export declare function isHeld(schedule: ReplayScheduleHandle, stageId: string): boolean;
|
|
47
|
+
export declare function launchFor(schedule: ReplayScheduleHandle, stageId: string): StageLaunchPrep | undefined;
|
|
48
|
+
export declare function launchAttemptFor(schedule: ReplayScheduleHandle, stageId: string): number | undefined;
|
|
49
|
+
export declare function clearLaunchPrep(schedule: ReplayScheduleHandle, stageId: string): void;
|
|
50
|
+
export declare function releaseHold(schedule: ReplayScheduleHandle): void;
|
|
51
|
+
export declare function activeReplayId(schedule: ReplayScheduleHandle): string | undefined;
|
|
52
|
+
export declare function activeSourceStageId(schedule: ReplayScheduleHandle): string | undefined;
|
|
53
|
+
export declare function activeLoopId(schedule: ReplayScheduleHandle): string | undefined;
|
|
54
|
+
export declare function cohortOverrideMap(schedule: ReplayScheduleHandle): ReadonlyMap<string, ReadonlySet<string>>;
|
|
55
|
+
export declare function noteActiveCohort(schedule: ReplayScheduleHandle, forkParent: string, cloneStageIds: readonly string[]): void;
|
|
56
|
+
export declare function applySendBack(options: {
|
|
57
|
+
store: RunStore;
|
|
58
|
+
runId: string;
|
|
59
|
+
sourceNode: ResolvedPipelineStageNode;
|
|
60
|
+
sourceAttempt: number;
|
|
61
|
+
envelope: StageEnvelope;
|
|
62
|
+
schedule: ReplayScheduleHandle;
|
|
63
|
+
projection: ScheduleProjection;
|
|
64
|
+
}): Promise<ReplayApplyResult>;
|
|
65
|
+
export declare function onRouteStageRunning(options: {
|
|
66
|
+
store: RunStore;
|
|
67
|
+
runId: string;
|
|
68
|
+
schedule: ReplayScheduleHandle;
|
|
69
|
+
stageId: string;
|
|
70
|
+
}): Promise<void>;
|
|
71
|
+
export declare function onRouteStageSucceeded(options: {
|
|
72
|
+
store: RunStore;
|
|
73
|
+
runId: string;
|
|
74
|
+
schedule: ReplayScheduleHandle;
|
|
75
|
+
stageId: string;
|
|
76
|
+
envelope: StageEnvelope;
|
|
77
|
+
}): Promise<void>;
|
|
78
|
+
export declare function onRouteStageFailed(options: {
|
|
79
|
+
store: RunStore;
|
|
80
|
+
runId: string;
|
|
81
|
+
schedule: ReplayScheduleHandle;
|
|
82
|
+
stageId: string;
|
|
83
|
+
}): Promise<void>;
|
|
84
|
+
export declare function hydrateFromStore(schedule: ReplayScheduleHandle, store: RunStore, runId: string, dag: ResolvedPipelineDag): Promise<{
|
|
85
|
+
loop: FeedbackLoopRecord;
|
|
86
|
+
replay: {
|
|
87
|
+
replay_id: string;
|
|
88
|
+
};
|
|
89
|
+
} | undefined>;
|
|
90
|
+
export declare function rebindRouteAttempts(schedule: ReplayScheduleHandle, store: RunStore, runId: string, overrides: ReadonlyMap<string, number>): Promise<void>;
|
|
91
|
+
export declare function onContinued(options: {
|
|
92
|
+
store: RunStore;
|
|
93
|
+
runId: string;
|
|
94
|
+
sourceStageId: string;
|
|
95
|
+
envelope: StageEnvelope;
|
|
96
|
+
schedule: ReplayScheduleHandle;
|
|
97
|
+
}): Promise<void>;
|
|
98
|
+
export declare function resolveDecision(options: {
|
|
99
|
+
store: RunStore;
|
|
100
|
+
runId: string;
|
|
101
|
+
decision: import("./feedbackLoopDecision.js").FeedbackLoopDecisionKind;
|
|
102
|
+
loopId?: string;
|
|
103
|
+
reason?: string;
|
|
104
|
+
schedule: ReplayScheduleHandle;
|
|
105
|
+
projection: ScheduleProjection;
|
|
106
|
+
sourceNode: ResolvedPipelineStageNode;
|
|
107
|
+
}): Promise<import("./feedbackLoopDecision.js").ResolveFeedbackLoopDecisionResult>;
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { acceptFeedbackSendBack, hydrateActiveFeedbackScheduleFromStore, markFeedbackLoopContinued, markFeedbackRouteStageFailed, markFeedbackRouteStageRunning, markFeedbackRouteStageSucceeded, rebindFeedbackRoutePassAttempts, terminalizeCurrentFeedbackReplay, } from "./feedbackLoopCoordinator.js";
|
|
2
|
+
import { postSourceStageIds } from "./feedbackLoopRoute.js";
|
|
3
|
+
import { applyFeedbackSendBackToSchedule, createFeedbackScheduleState, isFeedbackHeld, releaseFeedbackHold, } from "./feedbackLoopSchedule.js";
|
|
4
|
+
export { terminalizeCurrentFeedbackReplay };
|
|
5
|
+
export function createReplaySchedule() {
|
|
6
|
+
return { feedback: createFeedbackScheduleState() };
|
|
7
|
+
}
|
|
8
|
+
export function isHeld(schedule, stageId) {
|
|
9
|
+
return isFeedbackHeld(schedule.feedback, stageId);
|
|
10
|
+
}
|
|
11
|
+
export function launchFor(schedule, stageId) {
|
|
12
|
+
const attempt = schedule.feedback.launchAttemptByStageId.get(stageId);
|
|
13
|
+
if (attempt === undefined)
|
|
14
|
+
return undefined;
|
|
15
|
+
const sessionMode = schedule.feedback.sessionModeByStageId.get(stageId);
|
|
16
|
+
const priorAttempt = schedule.feedback.priorAttemptByStageId.get(stageId);
|
|
17
|
+
const feedbackLoopContext = schedule.feedback.contextsByStageId.get(stageId);
|
|
18
|
+
return {
|
|
19
|
+
attempt,
|
|
20
|
+
...(sessionMode !== undefined ? { sessionMode } : {}),
|
|
21
|
+
...(priorAttempt !== undefined ? { priorAttempt } : {}),
|
|
22
|
+
...(feedbackLoopContext !== undefined ? { feedbackLoopContext } : {}),
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
export function launchAttemptFor(schedule, stageId) {
|
|
26
|
+
return schedule.feedback.launchAttemptByStageId.get(stageId);
|
|
27
|
+
}
|
|
28
|
+
export function clearLaunchPrep(schedule, stageId) {
|
|
29
|
+
schedule.feedback.contextsByStageId.delete(stageId);
|
|
30
|
+
schedule.feedback.sessionModeByStageId.delete(stageId);
|
|
31
|
+
schedule.feedback.priorAttemptByStageId.delete(stageId);
|
|
32
|
+
schedule.feedback.launchAttemptByStageId.delete(stageId);
|
|
33
|
+
}
|
|
34
|
+
export function releaseHold(schedule) {
|
|
35
|
+
releaseFeedbackHold(schedule.feedback);
|
|
36
|
+
}
|
|
37
|
+
export function activeReplayId(schedule) {
|
|
38
|
+
return schedule.feedback.activeReplayId;
|
|
39
|
+
}
|
|
40
|
+
export function activeSourceStageId(schedule) {
|
|
41
|
+
return schedule.feedback.sourceStageId;
|
|
42
|
+
}
|
|
43
|
+
export function activeLoopId(schedule) {
|
|
44
|
+
return schedule.feedback.activeLoopId;
|
|
45
|
+
}
|
|
46
|
+
export function cohortOverrideMap(schedule) {
|
|
47
|
+
return schedule.feedback.activeCloneIdsByForkParent;
|
|
48
|
+
}
|
|
49
|
+
export function noteActiveCohort(schedule, forkParent, cloneStageIds) {
|
|
50
|
+
schedule.feedback.activeCloneIdsByForkParent.set(forkParent, new Set(cloneStageIds));
|
|
51
|
+
}
|
|
52
|
+
function armWaitingHold(schedule, dag, sourceStageId, loopId) {
|
|
53
|
+
if (schedule.feedback.activeHoldStageIds.size === 0) {
|
|
54
|
+
schedule.feedback.activeHoldStageIds = new Set(postSourceStageIds(dag, sourceStageId));
|
|
55
|
+
}
|
|
56
|
+
schedule.feedback.activeLoopId = loopId;
|
|
57
|
+
schedule.feedback.sourceStageId = sourceStageId;
|
|
58
|
+
}
|
|
59
|
+
function projectAccepted(schedule, projection, sourceId, accepted) {
|
|
60
|
+
return applyFeedbackSendBackToSchedule({
|
|
61
|
+
dag: projection.dag,
|
|
62
|
+
sourceId,
|
|
63
|
+
routeStageIds: accepted.routeStageIds,
|
|
64
|
+
states: projection.states,
|
|
65
|
+
completedEnvelopes: projection.completedEnvelopes,
|
|
66
|
+
feedback: schedule.feedback,
|
|
67
|
+
loopId: accepted.loop.loop_id,
|
|
68
|
+
replayId: accepted.replay.replay_id,
|
|
69
|
+
contextsByStageId: accepted.launch.contextsByStageId,
|
|
70
|
+
sessionModeByStageId: accepted.launch.sessionModeByStageId,
|
|
71
|
+
priorAttemptByStageId: accepted.launch.priorAttemptByStageId,
|
|
72
|
+
launchAttemptByStageId: accepted.launch.launchAttemptByStageId,
|
|
73
|
+
supersededCloneIds: accepted.launch.supersededCloneIds,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
export async function applySendBack(options) {
|
|
77
|
+
const accepted = await acceptFeedbackSendBack({
|
|
78
|
+
store: options.store,
|
|
79
|
+
runId: options.runId,
|
|
80
|
+
dag: options.projection.dag,
|
|
81
|
+
sourceNode: options.sourceNode,
|
|
82
|
+
sourceAttempt: options.sourceAttempt,
|
|
83
|
+
envelope: options.envelope,
|
|
84
|
+
});
|
|
85
|
+
if (accepted.kind === "rejected") {
|
|
86
|
+
return { kind: "rejected", reason: accepted.reason };
|
|
87
|
+
}
|
|
88
|
+
if (accepted.kind === "waiting_for_human") {
|
|
89
|
+
armWaitingHold(options.schedule, options.projection.dag, accepted.sourceStageId, accepted.loop.loop_id);
|
|
90
|
+
options.schedule.feedback.activeReplayId = undefined;
|
|
91
|
+
return {
|
|
92
|
+
kind: "waiting_for_human",
|
|
93
|
+
loop: accepted.loop,
|
|
94
|
+
deferred: accepted.deferred,
|
|
95
|
+
sourceStageId: accepted.sourceStageId,
|
|
96
|
+
sourceAttempt: accepted.sourceAttempt,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
const retiredSkippedStageIds = projectAccepted(options.schedule, options.projection, options.sourceNode.id, accepted);
|
|
100
|
+
return {
|
|
101
|
+
kind: accepted.kind === "accepted" ? "applied" : "idempotent",
|
|
102
|
+
loopId: accepted.loop.loop_id,
|
|
103
|
+
replayId: accepted.replay.replay_id,
|
|
104
|
+
retiredSkippedStageIds,
|
|
105
|
+
loop: accepted.loop,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
export async function onRouteStageRunning(options) {
|
|
109
|
+
await markFeedbackRouteStageRunning({
|
|
110
|
+
store: options.store,
|
|
111
|
+
runId: options.runId,
|
|
112
|
+
replayId: options.schedule.feedback.activeReplayId,
|
|
113
|
+
stageId: options.stageId,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
export async function onRouteStageSucceeded(options) {
|
|
117
|
+
await markFeedbackRouteStageSucceeded({
|
|
118
|
+
store: options.store,
|
|
119
|
+
runId: options.runId,
|
|
120
|
+
replayId: options.schedule.feedback.activeReplayId,
|
|
121
|
+
stageId: options.stageId,
|
|
122
|
+
envelope: options.envelope,
|
|
123
|
+
});
|
|
124
|
+
clearLaunchPrep(options.schedule, options.stageId);
|
|
125
|
+
}
|
|
126
|
+
export async function onRouteStageFailed(options) {
|
|
127
|
+
await markFeedbackRouteStageFailed(options.store, options.runId, options.schedule.feedback.activeReplayId, options.stageId);
|
|
128
|
+
}
|
|
129
|
+
export async function hydrateFromStore(schedule, store, runId, dag) {
|
|
130
|
+
return hydrateActiveFeedbackScheduleFromStore(store, runId, dag, schedule.feedback);
|
|
131
|
+
}
|
|
132
|
+
export async function rebindRouteAttempts(schedule, store, runId, overrides) {
|
|
133
|
+
const replayId = schedule.feedback.activeReplayId;
|
|
134
|
+
if (replayId === undefined || overrides.size === 0)
|
|
135
|
+
return;
|
|
136
|
+
await rebindFeedbackRoutePassAttempts(store, runId, replayId, overrides);
|
|
137
|
+
for (const [stageId, attempt] of overrides) {
|
|
138
|
+
if (!schedule.feedback.launchAttemptByStageId.has(stageId))
|
|
139
|
+
continue;
|
|
140
|
+
schedule.feedback.launchAttemptByStageId.set(stageId, attempt);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
export async function onContinued(options) {
|
|
144
|
+
await markFeedbackLoopContinued({
|
|
145
|
+
store: options.store,
|
|
146
|
+
runId: options.runId,
|
|
147
|
+
sourceStageId: options.sourceStageId,
|
|
148
|
+
envelope: options.envelope,
|
|
149
|
+
});
|
|
150
|
+
releaseHold(options.schedule);
|
|
151
|
+
}
|
|
152
|
+
export async function resolveDecision(options) {
|
|
153
|
+
const { resolveFeedbackLoopDecision } = await import("./feedbackLoopDecision.js");
|
|
154
|
+
return resolveFeedbackLoopDecision({
|
|
155
|
+
store: options.store,
|
|
156
|
+
runId: options.runId,
|
|
157
|
+
decision: options.decision,
|
|
158
|
+
loopId: options.loopId,
|
|
159
|
+
reason: options.reason,
|
|
160
|
+
schedule: {
|
|
161
|
+
dag: options.projection.dag,
|
|
162
|
+
sourceNode: options.sourceNode,
|
|
163
|
+
states: options.projection.states,
|
|
164
|
+
completedEnvelopes: options.projection.completedEnvelopes,
|
|
165
|
+
feedback: options.schedule.feedback,
|
|
166
|
+
},
|
|
167
|
+
});
|
|
168
|
+
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { AgentPort, OpaqueAnswer } from "../agent/port.js";
|
|
2
|
-
import type
|
|
2
|
+
import { type RunStore } from "../runstore/port.js";
|
|
3
3
|
import type { TaskFile } from "../types/task.js";
|
|
4
4
|
import { type PipelineRunResult } from "./pipelineRunner.js";
|
|
5
|
+
import { type FeedbackLoopDecisionKind } from "./feedbackLoopDecision.js";
|
|
5
6
|
import { type RetryStageResult } from "./runRetryCoordinator.js";
|
|
6
7
|
import { type StageExecutionMode } from "./stageConcurrency.js";
|
|
7
8
|
import { StageProcessLauncher } from "./stageProcessLauncher.js";
|
|
@@ -44,6 +45,24 @@ export type AbandonStageResult = {
|
|
|
44
45
|
reason: string;
|
|
45
46
|
status?: number;
|
|
46
47
|
};
|
|
48
|
+
export type DecideFeedbackLoopResult = {
|
|
49
|
+
ok: true;
|
|
50
|
+
effect: "extended" | "continued" | "abandoned";
|
|
51
|
+
loopId: string;
|
|
52
|
+
} | {
|
|
53
|
+
ok: false;
|
|
54
|
+
reason: string;
|
|
55
|
+
status?: number;
|
|
56
|
+
};
|
|
57
|
+
export type StopManualRecoveryResult = {
|
|
58
|
+
ok: true;
|
|
59
|
+
runId: string;
|
|
60
|
+
stageId: string;
|
|
61
|
+
} | {
|
|
62
|
+
ok: false;
|
|
63
|
+
reason: string;
|
|
64
|
+
status?: number;
|
|
65
|
+
};
|
|
47
66
|
export declare class RunManager {
|
|
48
67
|
private readonly options;
|
|
49
68
|
private readonly active;
|
|
@@ -51,6 +70,8 @@ export declare class RunManager {
|
|
|
51
70
|
private readonly provisionalIds;
|
|
52
71
|
private readonly resumeInFlight;
|
|
53
72
|
private readonly retryInFlight;
|
|
73
|
+
private readonly retryStartOwner;
|
|
74
|
+
private readonly retryStartWaiters;
|
|
54
75
|
private trackingGeneration;
|
|
55
76
|
private maxConcurrent;
|
|
56
77
|
private readonly maxActiveStagesPerRun;
|
|
@@ -99,6 +120,9 @@ export declare class RunManager {
|
|
|
99
120
|
reason: string;
|
|
100
121
|
}>;
|
|
101
122
|
}>;
|
|
123
|
+
resumeStalledSchedules(): Promise<Array<{
|
|
124
|
+
runId: string;
|
|
125
|
+
}>>;
|
|
102
126
|
abandonStage(runId: string, stageId: string): Promise<AbandonStageResult>;
|
|
103
127
|
startRun(input: StartTaskInput & {
|
|
104
128
|
pipeline: string;
|
|
@@ -111,6 +135,15 @@ export declare class RunManager {
|
|
|
111
135
|
}): Promise<StartRunResult>;
|
|
112
136
|
rerun(runId: string): Promise<StartRunResult>;
|
|
113
137
|
retryStage(runId: string, stageId: string): Promise<RetryStageResult>;
|
|
138
|
+
recoverManualStage(runId: string, stageId: string, guidance?: string): Promise<RetryStageResult>;
|
|
139
|
+
recoverManualStageUntilStop(runId: string, stageId: string, guidance?: string): Promise<{
|
|
140
|
+
ok: true;
|
|
141
|
+
pipeline: PipelineRunResult;
|
|
142
|
+
} | Extract<RetryStageResult, {
|
|
143
|
+
ok: false;
|
|
144
|
+
}>>;
|
|
145
|
+
private recoverManualStageInternal;
|
|
146
|
+
stopManualRecovery(runId: string, stageId: string): Promise<StopManualRecoveryResult>;
|
|
114
147
|
retryStageUntilStop(runId: string, stageId: string): Promise<{
|
|
115
148
|
ok: true;
|
|
116
149
|
pipeline: PipelineRunResult;
|
|
@@ -118,12 +151,31 @@ export declare class RunManager {
|
|
|
118
151
|
ok: false;
|
|
119
152
|
}>>;
|
|
120
153
|
private retryStageInternal;
|
|
154
|
+
private isStartRunWindingDown;
|
|
155
|
+
private awaitStartRunWindDown;
|
|
156
|
+
private raceRetryRootTimeout;
|
|
157
|
+
private claimRetryStart;
|
|
158
|
+
private releaseRetryStart;
|
|
159
|
+
private notifyRetryStartWaiters;
|
|
160
|
+
private waitForRetryCoordinatorOrOwnerRelease;
|
|
161
|
+
private manualRecoveryEligibility;
|
|
162
|
+
private blocksGenericRetry;
|
|
121
163
|
/**
|
|
122
164
|
* Deliver an operator answer for `(runId, stageId)` (KTD2 / KTD6).
|
|
123
165
|
* Same-process: unparks the live yield loop. After restart: reconstructs
|
|
124
166
|
* the stage session seam and continues that stage (KTD8).
|
|
125
167
|
*/
|
|
126
168
|
deliverAnswer(runId: string, stageId: string, opaqueAnswer: OpaqueAnswer): Promise<DeliverAnswerResult>;
|
|
169
|
+
/**
|
|
170
|
+
* Resolve a feedback-loop wait_for_human decision after the scheduler has
|
|
171
|
+
* exited waiting (host-down / HTTP / CLI). Persist-only resolve, then
|
|
172
|
+
* resume orchestration for extend/continue.
|
|
173
|
+
*/
|
|
174
|
+
decideFeedbackLoop(runId: string, stageId: string, input: {
|
|
175
|
+
decision: FeedbackLoopDecisionKind;
|
|
176
|
+
loopId?: string;
|
|
177
|
+
reason?: string;
|
|
178
|
+
}): Promise<DecideFeedbackLoopResult>;
|
|
127
179
|
private resumeViaSubprocess;
|
|
128
180
|
private reconstructAndContinue;
|
|
129
181
|
private reserveAndStartPipeline;
|
|
@@ -131,6 +183,7 @@ export declare class RunManager {
|
|
|
131
183
|
private tryReserve;
|
|
132
184
|
private clearReservation;
|
|
133
185
|
private track;
|
|
186
|
+
private tryResumeStalledSchedule;
|
|
134
187
|
/**
|
|
135
188
|
* Acquire active tracking + checkout lease for a restart resume before
|
|
136
189
|
* reconstruct starts. Over-max is allowed. Lease held by another run → fail closed.
|