@bastani/atomic 0.9.0-alpha.1 → 0.9.0-alpha.3
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/CHANGELOG.md +29 -0
- package/dist/builtin/cursor/CHANGELOG.md +6 -0
- package/dist/builtin/cursor/package.json +2 -2
- package/dist/builtin/intercom/CHANGELOG.md +6 -0
- package/dist/builtin/intercom/package.json +2 -2
- package/dist/builtin/mcp/CHANGELOG.md +6 -0
- package/dist/builtin/mcp/package.json +3 -3
- package/dist/builtin/subagents/CHANGELOG.md +6 -0
- package/dist/builtin/subagents/package.json +4 -4
- package/dist/builtin/web-access/CHANGELOG.md +6 -0
- package/dist/builtin/web-access/package.json +2 -2
- package/dist/builtin/workflows/CHANGELOG.md +19 -0
- package/dist/builtin/workflows/README.md +189 -122
- package/dist/builtin/workflows/builtin/deep-research-codebase.ts +30 -27
- package/dist/builtin/workflows/builtin/goal-ledger.ts +2 -0
- package/dist/builtin/workflows/builtin/goal-reports.ts +5 -0
- package/dist/builtin/workflows/builtin/goal-runner.ts +17 -20
- package/dist/builtin/workflows/builtin/goal-types.ts +2 -0
- package/dist/builtin/workflows/builtin/goal.d.ts +1 -0
- package/dist/builtin/workflows/builtin/goal.ts +40 -44
- package/dist/builtin/workflows/builtin/index.d.ts +1 -0
- package/dist/builtin/workflows/builtin/open-claude-design-runner.ts +16 -17
- package/dist/builtin/workflows/builtin/open-claude-design.d.ts +1 -0
- package/dist/builtin/workflows/builtin/open-claude-design.ts +42 -50
- package/dist/builtin/workflows/builtin/prompt-refinement.ts +102 -0
- package/dist/builtin/workflows/builtin/ralph-core.ts +6 -4
- package/dist/builtin/workflows/builtin/ralph-runner.ts +22 -24
- package/dist/builtin/workflows/builtin/ralph.d.ts +2 -0
- package/dist/builtin/workflows/builtin/ralph.ts +46 -41
- package/dist/builtin/workflows/package.json +2 -2
- package/dist/builtin/workflows/src/authoring/typebox-defaults.d.ts +41 -0
- package/dist/builtin/workflows/src/authoring/typebox-defaults.ts +217 -0
- package/dist/builtin/workflows/src/authoring/workflow.ts +184 -0
- package/dist/builtin/workflows/src/authoring.d.ts +14 -66
- package/dist/builtin/workflows/src/engine/graph-inference.ts +100 -0
- package/dist/builtin/workflows/src/engine/options.ts +40 -0
- package/dist/builtin/workflows/src/engine/primitives/chain.ts +29 -0
- package/dist/builtin/workflows/src/engine/primitives/exit.ts +2 -0
- package/dist/builtin/workflows/src/engine/primitives/parallel.ts +47 -0
- package/dist/builtin/workflows/src/engine/primitives/task.ts +108 -0
- package/dist/builtin/workflows/src/engine/primitives/ui.ts +41 -0
- package/dist/builtin/workflows/src/engine/primitives/workflow.ts +159 -0
- package/dist/builtin/workflows/src/engine/replay.ts +8 -0
- package/dist/builtin/workflows/src/engine/run.ts +356 -0
- package/dist/builtin/workflows/src/engine/runtime.ts +160 -0
- package/dist/builtin/workflows/src/extension/workflow-module-loader.ts +9 -3
- package/dist/builtin/workflows/src/extension/workflow-prompts.ts +3 -1
- package/dist/builtin/workflows/src/extension/workflow-schema.ts +0 -18
- package/dist/builtin/workflows/src/index.ts +0 -2
- package/dist/builtin/workflows/src/runs/background/runner.ts +6 -3
- package/dist/builtin/workflows/src/runs/foreground/executor-child-boundary.ts +3 -3
- package/dist/builtin/workflows/src/runs/foreground/executor-child-helpers.ts +4 -4
- package/dist/builtin/workflows/src/runs/foreground/executor-child-workflow.ts +1 -158
- package/dist/builtin/workflows/src/runs/foreground/executor-direct-helpers.ts +1 -1
- package/dist/builtin/workflows/src/runs/foreground/executor-outputs.ts +2 -2
- package/dist/builtin/workflows/src/runs/foreground/executor-prompt-nodes.ts +1 -1
- package/dist/builtin/workflows/src/runs/foreground/executor-run.ts +1 -359
- package/dist/builtin/workflows/src/runs/foreground/executor-scheduler.ts +1 -1
- package/dist/builtin/workflows/src/runs/foreground/executor-stage-call.ts +2 -5
- package/dist/builtin/workflows/src/runs/foreground/executor-stage-factory.ts +12 -4
- package/dist/builtin/workflows/src/runs/foreground/executor-stage-replay.ts +4 -3
- package/dist/builtin/workflows/src/runs/foreground/executor-stage-types.ts +9 -2
- package/dist/builtin/workflows/src/runs/foreground/executor-task-context.ts +2 -132
- package/dist/builtin/workflows/src/runs/foreground/executor-types.ts +2 -2
- package/dist/builtin/workflows/src/runs/shared/graph-inference.ts +2 -100
- package/dist/builtin/workflows/src/sdk-surface.ts +6 -9
- package/dist/builtin/workflows/src/shared/authoring-contract-stage.d.ts +9 -3
- package/dist/builtin/workflows/src/shared/authoring-contract-stage.ts +17 -3
- package/dist/builtin/workflows/src/shared/authoring-contract-ui.d.ts +3 -33
- package/dist/builtin/workflows/src/shared/authoring-contract-ui.ts +9 -81
- package/dist/builtin/workflows/src/shared/types.ts +25 -8
- package/dist/builtin/workflows/src/shared/workflow-authoring-types.d.ts +49 -0
- package/dist/builtin/workflows/src/shared/workflow-authoring-types.ts +84 -0
- package/dist/builtin/workflows/src/workflows/registry.ts +7 -3
- package/dist/core/agent-session-auto-compaction.d.ts.map +1 -1
- package/dist/core/agent-session-auto-compaction.js +6 -1
- package/dist/core/agent-session-auto-compaction.js.map +1 -1
- package/dist/core/agent-session-bash.d.ts.map +1 -1
- package/dist/core/agent-session-bash.js +0 -5
- package/dist/core/agent-session-bash.js.map +1 -1
- package/dist/core/agent-session-methods.d.ts +0 -2
- package/dist/core/agent-session-methods.d.ts.map +1 -1
- package/dist/core/agent-session-methods.js.map +1 -1
- package/dist/core/agent-session-services.d.ts +0 -1
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js +0 -1
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session-tool-registry.d.ts.map +1 -1
- package/dist/core/agent-session-tool-registry.js +0 -2
- package/dist/core/agent-session-tool-registry.js.map +1 -1
- package/dist/core/agent-session-types.d.ts +0 -2
- package/dist/core/agent-session-types.d.ts.map +1 -1
- package/dist/core/agent-session-types.js.map +1 -1
- package/dist/core/agent-session.d.ts +0 -2
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +0 -1
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/atomic-guide-command.d.ts.map +1 -1
- package/dist/core/atomic-guide-command.js +1 -1
- package/dist/core/atomic-guide-command.js.map +1 -1
- package/dist/core/extensions/loader-core.d.ts +1 -3
- package/dist/core/extensions/loader-core.d.ts.map +1 -1
- package/dist/core/extensions/loader-core.js +13 -6
- package/dist/core/extensions/loader-core.js.map +1 -1
- package/dist/core/extensions/loader-virtual-modules.d.ts +7 -1
- package/dist/core/extensions/loader-virtual-modules.d.ts.map +1 -1
- package/dist/core/extensions/loader-virtual-modules.js +34 -2
- package/dist/core/extensions/loader-virtual-modules.js.map +1 -1
- package/dist/core/extensions/loader.d.ts +2 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +2 -1
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/index.d.ts +0 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +0 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/model-registry-builtins.d.ts.map +1 -1
- package/dist/core/model-registry-builtins.js +6 -0
- package/dist/core/model-registry-builtins.js.map +1 -1
- package/dist/core/model-registry-schemas.d.ts +65 -13
- package/dist/core/model-registry-schemas.d.ts.map +1 -1
- package/dist/core/model-registry-schemas.js +10 -0
- package/dist/core/model-registry-schemas.js.map +1 -1
- package/dist/core/resource-loader-core.d.ts +1 -0
- package/dist/core/resource-loader-core.d.ts.map +1 -1
- package/dist/core/resource-loader-core.js +2 -0
- package/dist/core/resource-loader-core.js.map +1 -1
- package/dist/core/resource-loader-extensions.d.ts.map +1 -1
- package/dist/core/resource-loader-extensions.js +3 -3
- package/dist/core/resource-loader-extensions.js.map +1 -1
- package/dist/core/resource-loader-internals.d.ts +1 -0
- package/dist/core/resource-loader-internals.d.ts.map +1 -1
- package/dist/core/resource-loader-internals.js.map +1 -1
- package/dist/core/resource-loader-reload.d.ts.map +1 -1
- package/dist/core/resource-loader-reload.js +6 -2
- package/dist/core/resource-loader-reload.js.map +1 -1
- package/dist/core/sdk-exports.d.ts +1 -1
- package/dist/core/sdk-exports.d.ts.map +1 -1
- package/dist/core/sdk-exports.js.map +1 -1
- package/dist/core/sdk-types.d.ts +0 -3
- package/dist/core/sdk-types.d.ts.map +1 -1
- package/dist/core/sdk-types.js.map +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +0 -1
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager-history.d.ts.map +1 -1
- package/dist/core/session-manager-history.js +2 -1
- package/dist/core/session-manager-history.js.map +1 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +0 -1
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tools/bash.d.ts +0 -5
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +10 -11
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/edit-diff-preserve.d.ts +18 -0
- package/dist/core/tools/edit-diff-preserve.d.ts.map +1 -0
- package/dist/core/tools/edit-diff-preserve.js +85 -0
- package/dist/core/tools/edit-diff-preserve.js.map +1 -0
- package/dist/core/tools/edit-diff.d.ts +3 -2
- package/dist/core/tools/edit-diff.d.ts.map +1 -1
- package/dist/core/tools/edit-diff.js +15 -18
- package/dist/core/tools/edit-diff.js.map +1 -1
- package/dist/core/tools/index.d.ts +0 -1
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +0 -1
- package/dist/core/tools/index.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +2 -2
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/model-search.d.ts +5 -0
- package/dist/modes/interactive/model-search.d.ts.map +1 -1
- package/dist/modes/interactive/model-search.js +9 -0
- package/dist/modes/interactive/model-search.js.map +1 -1
- package/dist/utils/shell.d.ts +1 -0
- package/dist/utils/shell.d.ts.map +1 -1
- package/dist/utils/shell.js +12 -5
- package/dist/utils/shell.js.map +1 -1
- package/docs/custom-provider.md +4 -3
- package/docs/models.md +3 -2
- package/docs/packages.md +2 -2
- package/docs/quickstart.md +1 -1
- package/docs/sdk.md +2 -40
- package/docs/security.md +1 -1
- package/docs/workflows.md +991 -176
- package/package.json +5 -5
- package/dist/builtin/workflows/src/workflows/define-workflow.ts +0 -277
- package/dist/core/tools/bash-policy-compile.d.ts +0 -5
- package/dist/core/tools/bash-policy-compile.d.ts.map +0 -1
- package/dist/core/tools/bash-policy-compile.js +0 -241
- package/dist/core/tools/bash-policy-compile.js.map +0 -1
- package/dist/core/tools/bash-policy-evaluate.d.ts +0 -3
- package/dist/core/tools/bash-policy-evaluate.d.ts.map +0 -1
- package/dist/core/tools/bash-policy-evaluate.js +0 -92
- package/dist/core/tools/bash-policy-evaluate.js.map +0 -1
- package/dist/core/tools/bash-policy-format.d.ts +0 -5
- package/dist/core/tools/bash-policy-format.d.ts.map +0 -1
- package/dist/core/tools/bash-policy-format.js +0 -49
- package/dist/core/tools/bash-policy-format.js.map +0 -1
- package/dist/core/tools/bash-policy-parser.d.ts +0 -4
- package/dist/core/tools/bash-policy-parser.d.ts.map +0 -1
- package/dist/core/tools/bash-policy-parser.js +0 -155
- package/dist/core/tools/bash-policy-parser.js.map +0 -1
- package/dist/core/tools/bash-policy-segment.d.ts +0 -3
- package/dist/core/tools/bash-policy-segment.d.ts.map +0 -1
- package/dist/core/tools/bash-policy-segment.js +0 -275
- package/dist/core/tools/bash-policy-segment.js.map +0 -1
- package/dist/core/tools/bash-policy-shell.d.ts +0 -11
- package/dist/core/tools/bash-policy-shell.d.ts.map +0 -1
- package/dist/core/tools/bash-policy-shell.js +0 -267
- package/dist/core/tools/bash-policy-shell.js.map +0 -1
- package/dist/core/tools/bash-policy-types.d.ts +0 -146
- package/dist/core/tools/bash-policy-types.d.ts.map +0 -1
- package/dist/core/tools/bash-policy-types.js +0 -2
- package/dist/core/tools/bash-policy-types.js.map +0 -1
- package/dist/core/tools/bash-policy.d.ts +0 -6
- package/dist/core/tools/bash-policy.d.ts.map +0 -1
- package/dist/core/tools/bash-policy.js +0 -5
- package/dist/core/tools/bash-policy.js.map +0 -1
|
@@ -1,359 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import type {
|
|
3
|
-
WorkflowDefinition,
|
|
4
|
-
WorkflowInputValues,
|
|
5
|
-
WorkflowCustomUiFactory,
|
|
6
|
-
WorkflowCustomUiOptions,
|
|
7
|
-
WorkflowRunContext,
|
|
8
|
-
WorkflowUIContext,
|
|
9
|
-
} from "../../shared/types.js";
|
|
10
|
-
import type { WorkflowFailure } from "../../shared/workflow-failures.js";
|
|
11
|
-
import { classifyWorkflowFailure } from "../../shared/workflow-failures.js";
|
|
12
|
-
import { store as defaultStore } from "../../shared/store.js";
|
|
13
|
-
import { appendRunStart } from "../../shared/persistence-session-entries.js";
|
|
14
|
-
import { GraphFrontierTracker } from "../shared/graph-inference.js";
|
|
15
|
-
import { createRunLimiter } from "../shared/concurrency.js";
|
|
16
|
-
import { stageControlRegistry as defaultStageControlRegistry } from "./stage-control-registry.js";
|
|
17
|
-
import type { RunOpts, RunResult } from "./executor-types.js";
|
|
18
|
-
import { unknownErrorMessage, findWorkflowExitSignal, parentWorkflowExitAbortReason } from "./executor-abort.js";
|
|
19
|
-
import { createWorkflowExitManager } from "./executor-exit-manager.js";
|
|
20
|
-
import { resolveAndValidateInputs, resolveInputConcurrency, resolveInputRuntimeDefaults } from "./executor-inputs.js";
|
|
21
|
-
import { workflowCwdWithInputWorktree } from "./executor-direct-helpers.js";
|
|
22
|
-
import { createStageScheduler } from "./executor-scheduler.js";
|
|
23
|
-
import { createRunFinalizers } from "./executor-run-finalizers.js";
|
|
24
|
-
import { createWorkflowBoundaryFactory } from "./executor-child-boundary.js";
|
|
25
|
-
import { createWorkflowStageFactory } from "./executor-stage-factory.js";
|
|
26
|
-
import { createWorkflowTaskRunners } from "./executor-task-context.js";
|
|
27
|
-
import { createChildWorkflowRunner } from "./executor-child-workflow.js";
|
|
28
|
-
import { createContinuationReplayIndex } from "./executor-continuation.js";
|
|
29
|
-
import { buildPromptNodeUiAdapter } from "./executor-prompt-nodes.js";
|
|
30
|
-
import { makeHeadlessUnavailableUIContext, normalizeUIContext } from "./executor-hil.js";
|
|
31
|
-
import {
|
|
32
|
-
appendRunEndWhenRecorded,
|
|
33
|
-
assertWorkflowCreatedStage,
|
|
34
|
-
finalizeKilled,
|
|
35
|
-
finalizeKilledByFailure,
|
|
36
|
-
recordActiveBlockedFailure,
|
|
37
|
-
reconcileTerminalRunResult,
|
|
38
|
-
selectRunFailureDisposition,
|
|
39
|
-
} from "./executor-lifecycle.js";
|
|
40
|
-
import { assertWorkflowRunOutputs, normalizeWorkflowRunOutput } from "./executor-outputs.js";
|
|
41
|
-
import { isWorkflowDefinition, workflowDefinitionRequirementMessage } from "./executor-child-helpers.js";
|
|
42
|
-
|
|
43
|
-
function nextEventLoopTurn(): Promise<void> {
|
|
44
|
-
return new Promise((resolve) => setTimeout(resolve, 0));
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
function buildExitGatedUiContext(input: {
|
|
48
|
-
readonly opts: RunOpts;
|
|
49
|
-
readonly baseFromPromptNodes: () => WorkflowUIContext;
|
|
50
|
-
readonly throwIfWorkflowExitSelected: () => void;
|
|
51
|
-
}): WorkflowUIContext {
|
|
52
|
-
const base = input.opts.usePromptNodesForUi === true
|
|
53
|
-
? input.baseFromPromptNodes()
|
|
54
|
-
: input.opts.executionMode === "non_interactive" && input.opts.ui === undefined
|
|
55
|
-
? makeHeadlessUnavailableUIContext()
|
|
56
|
-
: normalizeUIContext(input.opts.ui);
|
|
57
|
-
return {
|
|
58
|
-
async input(promptText: string): Promise<string> {
|
|
59
|
-
input.throwIfWorkflowExitSelected();
|
|
60
|
-
return await base.input(promptText);
|
|
61
|
-
},
|
|
62
|
-
async confirm(message: string): Promise<boolean> {
|
|
63
|
-
input.throwIfWorkflowExitSelected();
|
|
64
|
-
return await base.confirm(message);
|
|
65
|
-
},
|
|
66
|
-
async select<T extends string>(message: string, options: readonly T[]): Promise<T> {
|
|
67
|
-
input.throwIfWorkflowExitSelected();
|
|
68
|
-
return await base.select(message, options);
|
|
69
|
-
},
|
|
70
|
-
async editor(initial?: string): Promise<string> {
|
|
71
|
-
input.throwIfWorkflowExitSelected();
|
|
72
|
-
return await base.editor(initial);
|
|
73
|
-
},
|
|
74
|
-
async custom<T>(factory: WorkflowCustomUiFactory<T>, options?: WorkflowCustomUiOptions): Promise<T> {
|
|
75
|
-
input.throwIfWorkflowExitSelected();
|
|
76
|
-
return await base.custom(factory, options);
|
|
77
|
-
},
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
export async function run<TInputs extends WorkflowInputValues>(
|
|
82
|
-
def: WorkflowDefinition<TInputs>,
|
|
83
|
-
inputs: Readonly<Record<string, unknown>>,
|
|
84
|
-
opts: RunOpts = {},
|
|
85
|
-
): Promise<RunResult> {
|
|
86
|
-
if (!isWorkflowDefinition(def)) throw new Error(workflowDefinitionRequirementMessage("run(definition, inputs)", def));
|
|
87
|
-
|
|
88
|
-
const activeStore = opts.store ?? defaultStore;
|
|
89
|
-
const adapters = opts.adapters ?? {};
|
|
90
|
-
if (opts.usePromptNodesForUi === true && opts.ui !== undefined) {
|
|
91
|
-
console.warn("atomic-workflows: usePromptNodesForUi ignores the provided RunOpts.ui adapter");
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
const depth = opts.depth ?? 0;
|
|
95
|
-
const maxDepth = opts.config?.maxDepth ?? 4;
|
|
96
|
-
if (depth >= maxDepth) {
|
|
97
|
-
return {
|
|
98
|
-
runId: opts.runId ?? crypto.randomUUID(),
|
|
99
|
-
status: "failed",
|
|
100
|
-
error: `atomic-workflows: maxDepth exceeded (max ${maxDepth})`,
|
|
101
|
-
stages: [],
|
|
102
|
-
};
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
const resolvedInputs = resolveAndValidateInputs(def.inputs, inputs, `workflow "${def.name}"`);
|
|
106
|
-
const runId = opts.runId ?? crypto.randomUUID();
|
|
107
|
-
const exitScope = Symbol(`workflow-exit:${runId}`);
|
|
108
|
-
const ownController = new AbortController();
|
|
109
|
-
const callerSignal = opts.signal;
|
|
110
|
-
if (callerSignal) {
|
|
111
|
-
if (callerSignal.aborted) ownController.abort(callerSignal.reason);
|
|
112
|
-
else callerSignal.addEventListener("abort", () => { ownController.abort(callerSignal.reason); }, { once: true });
|
|
113
|
-
}
|
|
114
|
-
const exit = createWorkflowExitManager({ runId, exitScope, controller: ownController });
|
|
115
|
-
|
|
116
|
-
const runSnapshot: RunSnapshot = {
|
|
117
|
-
id: runId,
|
|
118
|
-
name: def.name,
|
|
119
|
-
inputs: Object.freeze(resolvedInputs),
|
|
120
|
-
status: "running" as const,
|
|
121
|
-
stages: [],
|
|
122
|
-
startedAt: Date.now(),
|
|
123
|
-
...(opts.parentRun !== undefined ? {
|
|
124
|
-
parentRunId: opts.parentRun.runId,
|
|
125
|
-
parentStageId: opts.parentRun.stageId,
|
|
126
|
-
rootRunId: opts.parentRun.rootRunId,
|
|
127
|
-
} : {}),
|
|
128
|
-
...(opts.continuation !== undefined ? {
|
|
129
|
-
resumedFromRunId: opts.continuation.source.id,
|
|
130
|
-
resumeFromStageId: opts.continuation.resumeFromStageId,
|
|
131
|
-
} : {}),
|
|
132
|
-
};
|
|
133
|
-
|
|
134
|
-
const classifiedFailures = new Map<unknown, WorkflowFailure>();
|
|
135
|
-
const classifyExecutorFailure = (error: unknown): WorkflowFailure => {
|
|
136
|
-
const cached = classifiedFailures.get(error);
|
|
137
|
-
if (cached !== undefined) return cached;
|
|
138
|
-
let classified: WorkflowFailure;
|
|
139
|
-
try {
|
|
140
|
-
classified = classifyWorkflowFailure(error);
|
|
141
|
-
} catch {
|
|
142
|
-
classified = classifyWorkflowFailure(new Error(unknownErrorMessage(error)));
|
|
143
|
-
}
|
|
144
|
-
classifiedFailures.set(error, classified);
|
|
145
|
-
return classified;
|
|
146
|
-
};
|
|
147
|
-
|
|
148
|
-
activeStore.recordRunStart(runSnapshot);
|
|
149
|
-
if (!opts.signal) opts.cancellation?.register(runId, ownController);
|
|
150
|
-
opts.onRunStart?.(runSnapshot);
|
|
151
|
-
if (opts.persistence) {
|
|
152
|
-
appendRunStart(opts.persistence, {
|
|
153
|
-
runId,
|
|
154
|
-
name: def.name,
|
|
155
|
-
inputs: resolvedInputs,
|
|
156
|
-
...(runSnapshot.parentRunId !== undefined ? { parentRunId: runSnapshot.parentRunId } : {}),
|
|
157
|
-
...(runSnapshot.parentStageId !== undefined ? { parentStageId: runSnapshot.parentStageId } : {}),
|
|
158
|
-
...(runSnapshot.rootRunId !== undefined ? { rootRunId: runSnapshot.rootRunId } : {}),
|
|
159
|
-
...(runSnapshot.resumedFromRunId !== undefined ? { resumedFromRunId: runSnapshot.resumedFromRunId } : {}),
|
|
160
|
-
...(runSnapshot.resumeFromStageId !== undefined ? { resumeFromStageId: runSnapshot.resumeFromStageId } : {}),
|
|
161
|
-
ts: runSnapshot.startedAt,
|
|
162
|
-
});
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
const tracker = new GraphFrontierTracker();
|
|
166
|
-
const inputConcurrency = resolveInputConcurrency(def.inputs, resolvedInputs);
|
|
167
|
-
const inputRuntimeDefaults = resolveInputRuntimeDefaults(def, resolvedInputs);
|
|
168
|
-
const workflowInvocationCwd = opts.cwd ?? process.cwd();
|
|
169
|
-
let workflowCwd: string | undefined;
|
|
170
|
-
const resolveWorkflowCwd = (): string => {
|
|
171
|
-
workflowCwd ??= workflowCwdWithInputWorktree(inputRuntimeDefaults, workflowInvocationCwd);
|
|
172
|
-
return workflowCwd;
|
|
173
|
-
};
|
|
174
|
-
const limiter = createRunLimiter(inputConcurrency ?? opts.config?.defaultConcurrency);
|
|
175
|
-
const stageRegistry = opts.stageControlRegistry ?? defaultStageControlRegistry;
|
|
176
|
-
const replayIndex = createContinuationReplayIndex(opts.continuation);
|
|
177
|
-
const scheduler = createStageScheduler({
|
|
178
|
-
runId,
|
|
179
|
-
runSnapshot,
|
|
180
|
-
activeStore,
|
|
181
|
-
tracker,
|
|
182
|
-
stageRegistry: () => stageRegistry,
|
|
183
|
-
});
|
|
184
|
-
ownController.signal.addEventListener(
|
|
185
|
-
"abort",
|
|
186
|
-
() => scheduler.rejectReleaseBarriers(ownController.signal.reason ?? new Error("atomic-workflows: run aborted")),
|
|
187
|
-
{ once: true },
|
|
188
|
-
);
|
|
189
|
-
|
|
190
|
-
const finalizers = createRunFinalizers({
|
|
191
|
-
def,
|
|
192
|
-
runId,
|
|
193
|
-
runSnapshot,
|
|
194
|
-
activeStore,
|
|
195
|
-
opts,
|
|
196
|
-
classifyExecutorFailure,
|
|
197
|
-
drainWorkflowExitCleanups: exit.drainWorkflowExitCleanups,
|
|
198
|
-
});
|
|
199
|
-
const startWorkflowBoundaryStage = createWorkflowBoundaryFactory({
|
|
200
|
-
runId,
|
|
201
|
-
runSnapshot,
|
|
202
|
-
activeStore,
|
|
203
|
-
opts,
|
|
204
|
-
tracker,
|
|
205
|
-
replayIndex,
|
|
206
|
-
registerWorkflowExitCleanup: exit.registerWorkflowExitCleanup,
|
|
207
|
-
workflowExitSkippedReason: exit.workflowExitSkippedReason,
|
|
208
|
-
classifyExecutorFailure,
|
|
209
|
-
});
|
|
210
|
-
const workflowBoundaryReplayCounts = new Map<string, number>();
|
|
211
|
-
const nextWorkflowBoundaryReplayKey = (name: string): string => {
|
|
212
|
-
const next = (workflowBoundaryReplayCounts.get(name) ?? 0) + 1;
|
|
213
|
-
workflowBoundaryReplayCounts.set(name, next);
|
|
214
|
-
return `workflow:${name}:${next}`;
|
|
215
|
-
};
|
|
216
|
-
const stage = createWorkflowStageFactory({
|
|
217
|
-
runId,
|
|
218
|
-
activeStore,
|
|
219
|
-
opts,
|
|
220
|
-
adapters,
|
|
221
|
-
signal: ownController.signal,
|
|
222
|
-
tracker,
|
|
223
|
-
scheduler,
|
|
224
|
-
replayIndex,
|
|
225
|
-
limiter,
|
|
226
|
-
inputRuntimeDefaults,
|
|
227
|
-
workflowInvocationCwd,
|
|
228
|
-
stageRegistry,
|
|
229
|
-
exit,
|
|
230
|
-
classifyExecutorFailure,
|
|
231
|
-
});
|
|
232
|
-
const taskRunners = createWorkflowTaskRunners({
|
|
233
|
-
runId,
|
|
234
|
-
exit,
|
|
235
|
-
tracker,
|
|
236
|
-
inputRuntimeDefaults,
|
|
237
|
-
workflowInvocationCwd,
|
|
238
|
-
stage,
|
|
239
|
-
});
|
|
240
|
-
const workflow = createChildWorkflowRunner({
|
|
241
|
-
runId,
|
|
242
|
-
depth,
|
|
243
|
-
opts,
|
|
244
|
-
exit,
|
|
245
|
-
ownController,
|
|
246
|
-
resolveWorkflowCwd,
|
|
247
|
-
nextWorkflowBoundaryReplayKey,
|
|
248
|
-
startWorkflowBoundaryStage,
|
|
249
|
-
runWorkflow: run,
|
|
250
|
-
});
|
|
251
|
-
|
|
252
|
-
const ctx: WorkflowRunContext<TInputs> = {
|
|
253
|
-
inputs: resolvedInputs as TInputs,
|
|
254
|
-
get cwd() { return resolveWorkflowCwd(); },
|
|
255
|
-
exit: exit.exit,
|
|
256
|
-
ui: buildExitGatedUiContext({
|
|
257
|
-
opts,
|
|
258
|
-
throwIfWorkflowExitSelected: exit.throwIfWorkflowExitSelected,
|
|
259
|
-
baseFromPromptNodes: () => buildPromptNodeUiAdapter({
|
|
260
|
-
runId,
|
|
261
|
-
activeStore,
|
|
262
|
-
opts,
|
|
263
|
-
tracker,
|
|
264
|
-
replayIndex,
|
|
265
|
-
signal: ownController.signal,
|
|
266
|
-
throwIfWorkflowExitSelected: exit.throwIfWorkflowExitSelected,
|
|
267
|
-
registerWorkflowExitCleanup: exit.registerWorkflowExitCleanup,
|
|
268
|
-
workflowExitSkippedReason: exit.workflowExitSkippedReason,
|
|
269
|
-
preserveWorkflowExitSkippedReason: exit.preserveWorkflowExitSkippedReason,
|
|
270
|
-
classifyExecutorFailure,
|
|
271
|
-
}),
|
|
272
|
-
}),
|
|
273
|
-
stage,
|
|
274
|
-
task: taskRunners.task,
|
|
275
|
-
chain: taskRunners.chain,
|
|
276
|
-
parallel: taskRunners.parallel,
|
|
277
|
-
workflow,
|
|
278
|
-
};
|
|
279
|
-
|
|
280
|
-
try {
|
|
281
|
-
if (opts.deferWorkflowStart === true) {
|
|
282
|
-
await nextEventLoopTurn();
|
|
283
|
-
if (ownController.signal.aborted) {
|
|
284
|
-
const selectedExit = findWorkflowExitSignal(ownController.signal.reason, exitScope);
|
|
285
|
-
if (selectedExit !== undefined) return await finalizers.finalizeWorkflowExit(selectedExit);
|
|
286
|
-
const parentExit = parentWorkflowExitAbortReason(ownController.signal.reason);
|
|
287
|
-
if (parentExit !== undefined) return await finalizers.finalizeParentWorkflowExitCancellation(parentExit);
|
|
288
|
-
return finalizeKilled(runId, runSnapshot, activeStore, opts.persistence, opts.onRunEnd);
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
const rawResult = await def.run(ctx);
|
|
293
|
-
if (ownController.signal.aborted) {
|
|
294
|
-
const selectedExit = findWorkflowExitSignal(ownController.signal.reason, exitScope);
|
|
295
|
-
if (selectedExit !== undefined) return await finalizers.finalizeWorkflowExit(selectedExit);
|
|
296
|
-
const parentExit = parentWorkflowExitAbortReason(ownController.signal.reason);
|
|
297
|
-
if (parentExit !== undefined) return await finalizers.finalizeParentWorkflowExitCancellation(parentExit);
|
|
298
|
-
return finalizeKilled(runId, runSnapshot, activeStore, opts.persistence, opts.onRunEnd);
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
const result = normalizeWorkflowRunOutput(def.name, rawResult);
|
|
302
|
-
assertWorkflowRunOutputs(def.name, result, def.outputs);
|
|
303
|
-
assertWorkflowCreatedStage(runSnapshot);
|
|
304
|
-
const recorded = activeStore.recordRunEnd(runId, "completed", result);
|
|
305
|
-
appendRunEndWhenRecorded(opts.persistence, recorded, { runId, status: "completed", result, ts: Date.now() });
|
|
306
|
-
return reconcileTerminalRunResult(runId, runSnapshot, activeStore, { status: "completed", result }, opts.onRunEnd);
|
|
307
|
-
} catch (err) {
|
|
308
|
-
const selectedExit = findWorkflowExitSignal(err, exitScope) ?? findWorkflowExitSignal(ownController.signal.reason, exitScope);
|
|
309
|
-
if (selectedExit !== undefined) return await finalizers.finalizeWorkflowExit(selectedExit);
|
|
310
|
-
|
|
311
|
-
if (ownController.signal.aborted) {
|
|
312
|
-
const parentExit = parentWorkflowExitAbortReason(ownController.signal.reason);
|
|
313
|
-
if (parentExit !== undefined) return await finalizers.finalizeParentWorkflowExitCancellation(parentExit);
|
|
314
|
-
return finalizeKilled(runId, runSnapshot, activeStore, opts.persistence, opts.onRunEnd);
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
const failure = classifyExecutorFailure(err);
|
|
318
|
-
const metadata = selectRunFailureDisposition({
|
|
319
|
-
outerFailure: failure,
|
|
320
|
-
thrownError: err,
|
|
321
|
-
stages: runSnapshot.stages,
|
|
322
|
-
classifyFailure: classifyExecutorFailure,
|
|
323
|
-
});
|
|
324
|
-
|
|
325
|
-
if (metadata.failureDisposition === "terminal_killed") {
|
|
326
|
-
for (const failedStageId of metadata.failedStageIds) scheduler.blockKnownNonTerminalDescendants(failedStageId);
|
|
327
|
-
return finalizeKilledByFailure(runId, runSnapshot, activeStore, opts.persistence, opts.onRunEnd, { ...metadata, resumable: false });
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
if (metadata.failureDisposition === "active_blocked" && metadata.failedStageId !== undefined && metadata.failureRecoverability === "recoverable") {
|
|
331
|
-
for (const failedStageId of metadata.failedStageIds) scheduler.blockKnownNonTerminalDescendants(failedStageId);
|
|
332
|
-
return recordActiveBlockedFailure(runId, runSnapshot, activeStore, opts.persistence, {
|
|
333
|
-
...metadata,
|
|
334
|
-
failureRecoverability: "recoverable",
|
|
335
|
-
failedStageId: metadata.failedStageId,
|
|
336
|
-
resumable: true,
|
|
337
|
-
});
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
const recorded = activeStore.recordRunEnd(runId, "failed", undefined, metadata.errorMessage, metadata);
|
|
341
|
-
appendRunEndWhenRecorded(opts.persistence, recorded, {
|
|
342
|
-
runId,
|
|
343
|
-
status: "failed",
|
|
344
|
-
error: metadata.errorMessage,
|
|
345
|
-
failureKind: metadata.failureKind,
|
|
346
|
-
...(metadata.failureCode !== undefined ? { failureCode: metadata.failureCode } : {}),
|
|
347
|
-
...(metadata.failureRecoverability !== undefined ? { failureRecoverability: metadata.failureRecoverability } : {}),
|
|
348
|
-
...(metadata.failureDisposition !== undefined ? { failureDisposition: metadata.failureDisposition } : {}),
|
|
349
|
-
failureMessage: metadata.failureMessage,
|
|
350
|
-
...(metadata.failedStageId !== undefined ? { failedStageId: metadata.failedStageId } : {}),
|
|
351
|
-
resumable: metadata.resumable,
|
|
352
|
-
...(metadata.retryAfterMs !== undefined ? { retryAfterMs: metadata.retryAfterMs } : {}),
|
|
353
|
-
ts: Date.now(),
|
|
354
|
-
});
|
|
355
|
-
return reconcileTerminalRunResult(runId, runSnapshot, activeStore, { status: "failed", error: metadata.errorMessage }, opts.onRunEnd);
|
|
356
|
-
} finally {
|
|
357
|
-
opts.cancellation?.unregister(runId);
|
|
358
|
-
}
|
|
359
|
-
}
|
|
1
|
+
export { run } from "../../engine/run.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { RunSnapshot, StageSnapshot } from "../../shared/store-types.js";
|
|
2
2
|
import type { Store } from "../../shared/store.js";
|
|
3
|
-
import type { GraphFrontierTracker } from "
|
|
3
|
+
import type { GraphFrontierTracker } from "../../engine/graph-inference.js";
|
|
4
4
|
import type { StageControlRegistry } from "./stage-control-registry.js";
|
|
5
5
|
|
|
6
6
|
interface ReleaseBarrier {
|
|
@@ -112,10 +112,7 @@ export function createTrackedStageCaller(input: {
|
|
|
112
112
|
runtime.activeStore.recordStageStart(runtime.runId, runtime.stageSnapshot);
|
|
113
113
|
runtime.appendStageStartOnce();
|
|
114
114
|
|
|
115
|
-
|
|
116
|
-
const mcpDeny = input.options?.mcp?.deny ?? null;
|
|
117
|
-
const hasMcpScope = mcpAllow !== null || mcpDeny !== null;
|
|
118
|
-
if (runtime.opts.mcp && hasMcpScope) runtime.opts.mcp.setScope(runtime.stageId, mcpAllow, mcpDeny);
|
|
115
|
+
runtime.mcpScope.apply();
|
|
119
116
|
|
|
120
117
|
try {
|
|
121
118
|
const abortSession = (): void => {
|
|
@@ -183,7 +180,7 @@ export function createTrackedStageCaller(input: {
|
|
|
183
180
|
}
|
|
184
181
|
throw err;
|
|
185
182
|
} finally {
|
|
186
|
-
|
|
183
|
+
runtime.mcpScope.clear();
|
|
187
184
|
runtime.captureStageSessionMeta();
|
|
188
185
|
runtime.finalizeStageSnapshot();
|
|
189
186
|
if (runtime.state.stageClosedByWorkflowExit || runtime.exit.currentWorkflowExitAbortReason() !== undefined) {
|
|
@@ -7,10 +7,11 @@ import { appendStageEnd, appendStageStart } from "../../shared/persistence-sessi
|
|
|
7
7
|
import { elapsedStageMs } from "../../shared/timing.js";
|
|
8
8
|
import type { WorkflowFailure } from "../../shared/workflow-failures.js";
|
|
9
9
|
import type { ConcurrencyLimiter } from "../shared/concurrency.js";
|
|
10
|
-
import type { GraphFrontierTracker } from "
|
|
10
|
+
import type { GraphFrontierTracker } from "../../engine/graph-inference.js";
|
|
11
|
+
import type { EngineStageRuntimeOptions } from "../../engine/options.js";
|
|
11
12
|
import { createStageContext as createInnerStageContext, type InternalStageContext, type StageAdapters } from "./stage-runner.js";
|
|
12
13
|
import type { StageControlRegistry } from "./stage-control-registry.js";
|
|
13
|
-
import type {
|
|
14
|
+
import type { ParallelFailFastScope } from "./executor-types.js";
|
|
14
15
|
import type { WorkflowExitManager } from "./executor-exit-manager.js";
|
|
15
16
|
import type { ContinuationReplayIndex } from "./executor-continuation.js";
|
|
16
17
|
import { sameStringSet } from "./executor-continuation.js";
|
|
@@ -19,7 +20,7 @@ import { isTerminalStage } from "./executor-scheduler.js";
|
|
|
19
20
|
import { stageReplayFields } from "./executor-lifecycle.js";
|
|
20
21
|
import { askUserQuestionToolEvent, toolResultHasChatAnswer } from "./executor-hil.js";
|
|
21
22
|
import { createReplayStageContext } from "./executor-stage-replay.js";
|
|
22
|
-
import type { LiveStageMutableState, LiveStageRuntime, StageContextWithMeta } from "./executor-stage-types.js";
|
|
23
|
+
import type { LiveStageMutableState, LiveStageRuntime, StageContextWithMeta, StageMcpScope } from "./executor-stage-types.js";
|
|
23
24
|
import { createStageControlHandle } from "./executor-stage-control.js";
|
|
24
25
|
import { createTrackedStageCaller } from "./executor-stage-call.js";
|
|
25
26
|
import { createStageContext } from "./executor-stage-context.js";
|
|
@@ -28,7 +29,7 @@ import { stageOptionsWithGitWorktree, stageOptionsWithInputDefaults } from "./ex
|
|
|
28
29
|
export function createWorkflowStageFactory(input: {
|
|
29
30
|
readonly runId: string;
|
|
30
31
|
readonly activeStore: Store;
|
|
31
|
-
readonly opts:
|
|
32
|
+
readonly opts: EngineStageRuntimeOptions;
|
|
32
33
|
readonly adapters: StageAdapters;
|
|
33
34
|
readonly signal: AbortSignal;
|
|
34
35
|
readonly tracker: GraphFrontierTracker;
|
|
@@ -40,6 +41,7 @@ export function createWorkflowStageFactory(input: {
|
|
|
40
41
|
readonly stageRegistry: StageControlRegistry;
|
|
41
42
|
readonly exit: WorkflowExitManager;
|
|
42
43
|
readonly classifyExecutorFailure: (error: unknown) => WorkflowFailure;
|
|
44
|
+
readonly createMcpScope: (stageId: string, options: StageOptions | undefined) => StageMcpScope;
|
|
43
45
|
}): (name: string, options?: StageOptions, stageFailFastScope?: ParallelFailFastScope) => StageContextWithMeta {
|
|
44
46
|
return (name: string, options?: StageOptions, stageFailFastScope?: ParallelFailFastScope): StageContextWithMeta => {
|
|
45
47
|
input.exit.throwIfWorkflowExitSelected();
|
|
@@ -287,6 +289,7 @@ export function createWorkflowStageFactory(input: {
|
|
|
287
289
|
signal: input.signal,
|
|
288
290
|
exit: input.exit,
|
|
289
291
|
classifyExecutorFailure: input.classifyExecutorFailure,
|
|
292
|
+
mcpScope: input.createMcpScope(stageId, options),
|
|
290
293
|
...(stageFailFastScope !== undefined ? { stageFailFastScope } : {}),
|
|
291
294
|
state,
|
|
292
295
|
unregisterStageHandle: () => {},
|
|
@@ -317,6 +320,11 @@ export function createWorkflowStageFactory(input: {
|
|
|
317
320
|
const blockedBy = input.scheduler.blockingAncestorFor(stageSnapshot);
|
|
318
321
|
if (blockedBy !== undefined) input.scheduler.blockStageUntilCascadeRelease(stageSnapshot, blockedBy);
|
|
319
322
|
|
|
323
|
+
// Parallel fail-fast and workflow-exit cleanup can both target a live stage.
|
|
324
|
+
// The first terminal path owns the snapshot: finalization unregisters
|
|
325
|
+
// workflow-exit cleanup and removes the stage from the fail-fast active set.
|
|
326
|
+
// Later paths must not overwrite the terminal skippedReason; they only abort
|
|
327
|
+
// and release idempotent live handles.
|
|
320
328
|
const skipForParallelFailFast = (): void => {
|
|
321
329
|
if (isTerminalStage(stageSnapshot)) return;
|
|
322
330
|
markSkippedForParallelFailFast();
|
|
@@ -2,9 +2,10 @@ import type { StageSnapshot } from "../../shared/store-types.js";
|
|
|
2
2
|
import type { Store } from "../../shared/store.js";
|
|
3
3
|
import { appendStageEnd, appendStageStart } from "../../shared/persistence-session-entries.js";
|
|
4
4
|
import { elapsedStageMs } from "../../shared/timing.js";
|
|
5
|
-
import type { GraphFrontierTracker } from "
|
|
5
|
+
import type { GraphFrontierTracker } from "../../engine/graph-inference.js";
|
|
6
|
+
import type { EngineStageRuntimeOptions } from "../../engine/options.js";
|
|
6
7
|
import type { InternalStageContext } from "./stage-runner.js";
|
|
7
|
-
import type {
|
|
8
|
+
import type { WorkflowExitCleanup } from "./executor-types.js";
|
|
8
9
|
import { stageReplayFields } from "./executor-lifecycle.js";
|
|
9
10
|
|
|
10
11
|
export function createReplayStageContext(input: {
|
|
@@ -14,7 +15,7 @@ export function createReplayStageContext(input: {
|
|
|
14
15
|
readonly stageSnapshot: StageSnapshot;
|
|
15
16
|
readonly replaySource: StageSnapshot;
|
|
16
17
|
readonly activeStore: Store;
|
|
17
|
-
readonly opts:
|
|
18
|
+
readonly opts: EngineStageRuntimeOptions;
|
|
18
19
|
readonly tracker: GraphFrontierTracker;
|
|
19
20
|
readonly registerWorkflowExitCleanup: (stageId: string, cleanup: WorkflowExitCleanup) => () => void;
|
|
20
21
|
readonly workflowExitSkippedReason: (reason?: string) => string;
|
|
@@ -3,10 +3,16 @@ import type { Store } from "../../shared/store.js";
|
|
|
3
3
|
import type { StageContext } from "../../shared/types.js";
|
|
4
4
|
import type { InternalStageContext } from "./stage-runner.js";
|
|
5
5
|
import type { StageControlRegistry } from "./stage-control-registry.js";
|
|
6
|
-
import type {
|
|
6
|
+
import type { ParallelFailFastScope } from "./executor-types.js";
|
|
7
7
|
import type { StageScheduler } from "./executor-scheduler.js";
|
|
8
8
|
import type { WorkflowExitManager } from "./executor-exit-manager.js";
|
|
9
9
|
import type { WorkflowFailure } from "../../shared/workflow-failures.js";
|
|
10
|
+
import type { EngineStageRuntimeOptions } from "../../engine/options.js";
|
|
11
|
+
|
|
12
|
+
export interface StageMcpScope {
|
|
13
|
+
apply(): void;
|
|
14
|
+
clear(): void;
|
|
15
|
+
}
|
|
10
16
|
|
|
11
17
|
export interface LiveStageMutableState {
|
|
12
18
|
activeAskUserQuestionAnonymousCalls: number;
|
|
@@ -27,12 +33,13 @@ export interface LiveStageRuntime {
|
|
|
27
33
|
readonly stageSnapshot: StageSnapshot;
|
|
28
34
|
readonly innerCtx: InternalStageContext;
|
|
29
35
|
readonly activeStore: Store;
|
|
30
|
-
readonly opts:
|
|
36
|
+
readonly opts: EngineStageRuntimeOptions;
|
|
31
37
|
readonly stageRegistry: StageControlRegistry;
|
|
32
38
|
readonly scheduler: StageScheduler;
|
|
33
39
|
readonly signal: AbortSignal;
|
|
34
40
|
readonly exit: WorkflowExitManager;
|
|
35
41
|
readonly classifyExecutorFailure: (error: unknown) => WorkflowFailure;
|
|
42
|
+
readonly mcpScope: StageMcpScope;
|
|
36
43
|
readonly stageFailFastScope?: ParallelFailFastScope;
|
|
37
44
|
readonly state: LiveStageMutableState;
|
|
38
45
|
unregisterStageHandle: () => void;
|
|
@@ -1,132 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import type { WorkflowExitManager } from "./executor-exit-manager.js";
|
|
4
|
-
import type { ParallelFailFastScope, ParallelFailFastStage } from "./executor-types.js";
|
|
5
|
-
import { findWorkflowExitSignal } from "./executor-abort.js";
|
|
6
|
-
import {
|
|
7
|
-
applyTaskContext,
|
|
8
|
-
chainStepPrompt,
|
|
9
|
-
parallelFallbackTask,
|
|
10
|
-
replaceTaskPlaceholder,
|
|
11
|
-
structuredTaskOutputText,
|
|
12
|
-
taskOptionsFromStep,
|
|
13
|
-
taskPrevious,
|
|
14
|
-
taskPrompt,
|
|
15
|
-
taskPromptOptions,
|
|
16
|
-
taskReadInstruction,
|
|
17
|
-
taskStageOptions,
|
|
18
|
-
taskWithSharedDefaults,
|
|
19
|
-
truncateTaskOutput,
|
|
20
|
-
} from "./executor-task-prompts.js";
|
|
21
|
-
import { cleanupPreparedWorktrees, collectWorktreeDiffs, mapParallelSteps, prepareDirectWorktrees, stageOptionsWithGitWorktree, stageOptionsWithInputDefaults } from "./executor-direct-helpers.js";
|
|
22
|
-
import type { InternalStageContext } from "./stage-runner.js";
|
|
23
|
-
|
|
24
|
-
export interface WorkflowTaskRunners {
|
|
25
|
-
task(name: string, options: WorkflowTaskOptions, stageFailFastScope?: ParallelFailFastScope): Promise<WorkflowTaskResult>;
|
|
26
|
-
chain(steps: readonly WorkflowTaskStep[], options?: WorkflowChainOptions): Promise<WorkflowTaskResult[]>;
|
|
27
|
-
parallel(steps: readonly WorkflowTaskStep[], options?: WorkflowParallelOptions): Promise<WorkflowTaskResult[]>;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export function createWorkflowTaskRunners(input: {
|
|
31
|
-
readonly runId: string;
|
|
32
|
-
readonly exit: WorkflowExitManager;
|
|
33
|
-
readonly tracker: GraphFrontierTracker;
|
|
34
|
-
readonly inputRuntimeDefaults: Partial<StageOptions>;
|
|
35
|
-
readonly workflowInvocationCwd: string;
|
|
36
|
-
readonly stage: (name: string, options?: StageOptions, scope?: ParallelFailFastScope) => StageContext;
|
|
37
|
-
}): WorkflowTaskRunners {
|
|
38
|
-
const task = async (name: string, options: WorkflowTaskOptions, stageFailFastScope?: ParallelFailFastScope): Promise<WorkflowTaskResult> => {
|
|
39
|
-
input.exit.throwIfWorkflowExitSelected();
|
|
40
|
-
const runTaskOnce = async (taskOptions: WorkflowTaskOptions): Promise<WorkflowTaskResult> => {
|
|
41
|
-
input.exit.throwIfWorkflowExitSelected();
|
|
42
|
-
const resolvedTaskOptions = stageOptionsWithGitWorktree(stageOptionsWithInputDefaults(taskOptions, input.inputRuntimeDefaults), input.workflowInvocationCwd) ?? taskOptions;
|
|
43
|
-
const stage = input.stage(name, taskStageOptions(resolvedTaskOptions), stageFailFastScope);
|
|
44
|
-
const rawOutput = await stage.prompt(
|
|
45
|
-
applyTaskContext(`${taskReadInstruction(resolvedTaskOptions)}${taskPrompt(resolvedTaskOptions)}`, taskPrevious(resolvedTaskOptions)),
|
|
46
|
-
taskPromptOptions(resolvedTaskOptions),
|
|
47
|
-
);
|
|
48
|
-
const structured = typeof rawOutput === "string" ? undefined : rawOutput;
|
|
49
|
-
const text = truncateTaskOutput(structuredTaskOutputText(rawOutput), resolvedTaskOptions.maxOutput);
|
|
50
|
-
const sessionId = (() => {
|
|
51
|
-
try {
|
|
52
|
-
return stage.sessionId;
|
|
53
|
-
} catch {
|
|
54
|
-
return undefined;
|
|
55
|
-
}
|
|
56
|
-
})();
|
|
57
|
-
const stageMeta = (stage as InternalStageContext).__modelFallbackMeta?.() ?? {};
|
|
58
|
-
return {
|
|
59
|
-
name,
|
|
60
|
-
stageName: name,
|
|
61
|
-
text,
|
|
62
|
-
...(structured !== undefined ? { structured } : {}),
|
|
63
|
-
...(sessionId !== undefined ? { sessionId } : {}),
|
|
64
|
-
...(stage.sessionFile !== undefined ? { sessionFile: stage.sessionFile } : {}),
|
|
65
|
-
...(stageMeta.model !== undefined ? { model: stageMeta.model } : {}),
|
|
66
|
-
...(stageMeta.fastMode === true ? { fastMode: stageMeta.fastMode } : {}),
|
|
67
|
-
...(stageMeta.attemptedModels !== undefined ? { attemptedModels: stageMeta.attemptedModels } : {}),
|
|
68
|
-
...(stageMeta.modelAttempts !== undefined ? { modelAttempts: stageMeta.modelAttempts } : {}),
|
|
69
|
-
...(stageMeta.warnings !== undefined ? { warnings: stageMeta.warnings } : {}),
|
|
70
|
-
};
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
if (options.worktree !== true) return runTaskOnce(options);
|
|
74
|
-
const prepared = prepareDirectWorktrees(
|
|
75
|
-
[{ ...options, name }],
|
|
76
|
-
{ ...options, worktree: true },
|
|
77
|
-
`${input.runId}-${name}-${crypto.randomUUID()}`,
|
|
78
|
-
name,
|
|
79
|
-
);
|
|
80
|
-
const preparedTask = prepared.tasks[0]!;
|
|
81
|
-
try {
|
|
82
|
-
const result = await runTaskOnce(preparedTask);
|
|
83
|
-
const worktreeDiffs = collectWorktreeDiffs(prepared, options.artifacts !== false);
|
|
84
|
-
return worktreeDiffs.artifacts.length === 0
|
|
85
|
-
? result
|
|
86
|
-
: { ...result, artifacts: [...(result.artifacts ?? []), ...worktreeDiffs.artifacts] };
|
|
87
|
-
} finally {
|
|
88
|
-
cleanupPreparedWorktrees(prepared);
|
|
89
|
-
}
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
const chain = async (steps: readonly WorkflowTaskStep[], options: WorkflowChainOptions = {}): Promise<WorkflowTaskResult[]> => {
|
|
93
|
-
input.exit.throwIfWorkflowExitSelected();
|
|
94
|
-
const results: WorkflowTaskResult[] = [];
|
|
95
|
-
for (let index = 0; index < steps.length; index += 1) {
|
|
96
|
-
input.exit.throwIfWorkflowExitSelected();
|
|
97
|
-
const step = steps[index]!;
|
|
98
|
-
const explicitPrevious = taskPrevious(step);
|
|
99
|
-
const previous = explicitPrevious ?? (index > 0 ? results[index - 1] : undefined);
|
|
100
|
-
const prompt = replaceTaskPlaceholder(chainStepPrompt(step, index), options.task ?? "");
|
|
101
|
-
results.push(await task(step.name, taskWithSharedDefaults(taskOptionsFromStep(step, prompt, previous), options)));
|
|
102
|
-
}
|
|
103
|
-
return results;
|
|
104
|
-
};
|
|
105
|
-
|
|
106
|
-
const parallel = async (steps: readonly WorkflowTaskStep[], options: WorkflowParallelOptions = {}): Promise<WorkflowTaskResult[]> => {
|
|
107
|
-
input.exit.throwIfWorkflowExitSelected();
|
|
108
|
-
const fallback = parallelFallbackTask(steps, options);
|
|
109
|
-
const failFastEnabled = options.failFast !== false;
|
|
110
|
-
const parallelScope: ParallelFailFastScope = {
|
|
111
|
-
failed: false,
|
|
112
|
-
activeStages: new Map<string, ParallelFailFastStage>(),
|
|
113
|
-
parentIds: Object.freeze(input.tracker.currentParents()),
|
|
114
|
-
};
|
|
115
|
-
return mapParallelSteps(steps, options.concurrency, options.failFast, async (step) => {
|
|
116
|
-
input.exit.throwIfWorkflowExitSelected();
|
|
117
|
-
const prompt = replaceTaskPlaceholder(step.prompt ?? step.task ?? fallback, options.task ?? fallback);
|
|
118
|
-
return await task(step.name, taskWithSharedDefaults(taskOptionsFromStep(step, prompt, taskPrevious(step)), options), parallelScope);
|
|
119
|
-
}, (error) => {
|
|
120
|
-
if (!failFastEnabled) return;
|
|
121
|
-
parallelScope.failed = true;
|
|
122
|
-
parallelScope.firstFailure = error;
|
|
123
|
-
for (const stage of parallelScope.activeStages.values()) stage.skip();
|
|
124
|
-
}, {
|
|
125
|
-
beforeDequeue: input.exit.throwIfWorkflowExitSelected,
|
|
126
|
-
beforeMap: input.exit.throwIfWorkflowExitSelected,
|
|
127
|
-
isControlSignal: (error) => findWorkflowExitSignal(error, input.exit.exitScope) !== undefined,
|
|
128
|
-
});
|
|
129
|
-
};
|
|
130
|
-
|
|
131
|
-
return { task, chain, parallel };
|
|
132
|
-
}
|
|
1
|
+
export { createWorkflowTaskRunners } from "../../engine/primitives/task.js";
|
|
2
|
+
export type { WorkflowTaskRunners } from "../../engine/primitives/task.js";
|
|
@@ -82,10 +82,10 @@ export interface RunOpts extends Omit<AuthoringContract.RunOpts, "adapters" | "s
|
|
|
82
82
|
onRunEnd?: (runId: string, status: RunStatus, result?: WorkflowOutputValues, error?: string, exitReason?: string) => void;
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
export interface RunResult {
|
|
85
|
+
export interface RunResult<TOutputs extends WorkflowOutputValues = WorkflowOutputValues> {
|
|
86
86
|
readonly runId: string;
|
|
87
87
|
readonly status: RunStatus;
|
|
88
|
-
readonly result?:
|
|
88
|
+
readonly result?: Partial<TOutputs>;
|
|
89
89
|
readonly error?: string;
|
|
90
90
|
/** True when the run reached its terminal status through ctx.exit(). */
|
|
91
91
|
readonly exited?: boolean;
|