@bastani/atomic 0.9.40 → 0.9.41-alpha.2
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 +75 -0
- package/README.md +1 -1
- package/dist/builtin/intercom/CHANGELOG.md +12 -0
- package/dist/builtin/intercom/README.md +1 -1
- package/dist/builtin/intercom/broker/broker.ts +24 -21
- package/dist/builtin/intercom/broker/client.ts +97 -6
- package/dist/builtin/intercom/broker/list-reply.ts +53 -0
- package/dist/builtin/intercom/index.bundle.mjs +278 -46
- package/dist/builtin/intercom/package.json +2 -2
- package/dist/builtin/intercom/recoverable-disconnect.ts +27 -1
- package/dist/builtin/intercom/types.ts +8 -1
- package/dist/builtin/mcp/package.json +1 -1
- package/dist/builtin/subagents/CHANGELOG.md +14 -0
- package/dist/builtin/subagents/README.md +14 -0
- package/dist/builtin/subagents/package.json +3 -3
- package/dist/builtin/subagents/src/extension/index.bundle.mjs +99 -19
- package/dist/builtin/web-access/package.json +2 -2
- package/dist/builtin/workflows/CHANGELOG.md +33 -0
- package/dist/builtin/workflows/README.md +2 -0
- package/dist/builtin/workflows/builtin/adversarial-verification.js +2 -2
- package/dist/builtin/workflows/builtin/{chunk-qjqn389g.js → chunk-2jfst7e4.js} +72 -10
- package/dist/builtin/workflows/builtin/{chunk-4bwtzyjq.js → chunk-49kkbdpr.js} +1 -1
- package/dist/builtin/workflows/builtin/{chunk-qdd897wm.js → chunk-apagcs4r.js} +1 -1
- package/dist/builtin/workflows/builtin/{chunk-454hz1qt.js → chunk-dcxscfnb.js} +1 -1
- package/dist/builtin/workflows/builtin/{chunk-bjva9j5k.js → chunk-hx8v4p97.js} +1 -1
- package/dist/builtin/workflows/builtin/{chunk-85mx6wcf.js → chunk-k5q3t7je.js} +1 -1
- package/dist/builtin/workflows/builtin/{chunk-8kkv04hz.js → chunk-n2gkzkty.js} +1 -1
- package/dist/builtin/workflows/builtin/{chunk-y45tkftg.js → chunk-txbc93t6.js} +1 -1
- package/dist/builtin/workflows/builtin/{chunk-x0vvjyzg.js → chunk-w4xp1w1f.js} +1 -1
- package/dist/builtin/workflows/builtin/{chunk-5eh0brtd.js → chunk-z3pajrfs.js} +1 -1
- package/dist/builtin/workflows/builtin/classify-and-act.js +2 -2
- package/dist/builtin/workflows/builtin/fan-out-and-synthesize.js +2 -2
- package/dist/builtin/workflows/builtin/generate-and-filter.js +2 -2
- package/dist/builtin/workflows/builtin/goal.js +2 -2
- package/dist/builtin/workflows/builtin/index.js +10 -10
- package/dist/builtin/workflows/builtin/loop-until-done.js +2 -2
- package/dist/builtin/workflows/builtin/open-claude-design.js +2 -2
- package/dist/builtin/workflows/builtin/ralph.js +2 -2
- package/dist/builtin/workflows/builtin/tournament.js +2 -2
- package/dist/builtin/workflows/package.json +2 -2
- package/dist/builtin/workflows/src/authoring.d.ts +1 -1
- package/dist/builtin/workflows/src/durable/journal/internal.d.ts +16 -0
- package/dist/builtin/workflows/src/durable/journal/legacy-journal-tables.d.ts +9 -0
- package/dist/builtin/workflows/src/durable/journal/sql-run-journal.d.ts +6 -0
- package/dist/builtin/workflows/src/extension/index.bundle.mjs +950 -116
- package/dist/builtin/workflows/src/index.js +806 -131
- package/dist/builtin/workflows/src/shared/authoring-contract-stage.d.ts +17 -1
- package/dist/cli/credential-print.d.ts.map +1 -1
- package/dist/cli/credential-print.js +1 -1
- package/dist/cli/credential-print.js.map +1 -1
- package/dist/config.d.ts +1 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +1 -0
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session-extension-bindings.d.ts +2 -1
- package/dist/core/agent-session-extension-bindings.d.ts.map +1 -1
- package/dist/core/agent-session-extension-bindings.js +33 -18
- package/dist/core/agent-session-extension-bindings.js.map +1 -1
- package/dist/core/agent-session-methods.d.ts +2 -1
- 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-prompt.d.ts.map +1 -1
- package/dist/core/agent-session-prompt.js +114 -21
- package/dist/core/agent-session-prompt.js.map +1 -1
- package/dist/core/agent-session-runtime.d.ts +1 -1
- package/dist/core/agent-session-runtime.d.ts.map +1 -1
- package/dist/core/agent-session-runtime.js +6 -0
- package/dist/core/agent-session-runtime.js.map +1 -1
- package/dist/core/agent-session-state.d.ts +19 -1
- package/dist/core/agent-session-state.d.ts.map +1 -1
- package/dist/core/agent-session-state.js +41 -6
- package/dist/core/agent-session-state.js.map +1 -1
- package/dist/core/auth-storage-backends.d.ts +3 -1
- package/dist/core/auth-storage-backends.d.ts.map +1 -1
- package/dist/core/auth-storage-backends.js +79 -12
- package/dist/core/auth-storage-backends.js.map +1 -1
- package/dist/core/client-identity.d.ts +8 -0
- package/dist/core/client-identity.d.ts.map +1 -0
- package/dist/core/client-identity.js +16 -0
- package/dist/core/client-identity.js.map +1 -0
- package/dist/core/compaction/planner-outcome.d.ts.map +1 -1
- package/dist/core/compaction/planner-outcome.js +2 -1
- package/dist/core/compaction/planner-outcome.js.map +1 -1
- package/dist/core/execution-model-router.d.ts +18 -0
- package/dist/core/execution-model-router.d.ts.map +1 -1
- package/dist/core/execution-model-router.js +14 -8
- package/dist/core/execution-model-router.js.map +1 -1
- package/dist/core/extension-oauth-refresh-rejection.d.ts +12 -0
- package/dist/core/extension-oauth-refresh-rejection.d.ts.map +1 -0
- package/dist/core/extension-oauth-refresh-rejection.js +70 -0
- package/dist/core/extension-oauth-refresh-rejection.js.map +1 -0
- package/dist/core/extension-startup-failure.d.ts +30 -0
- package/dist/core/extension-startup-failure.d.ts.map +1 -0
- package/dist/core/extension-startup-failure.js +62 -0
- package/dist/core/extension-startup-failure.js.map +1 -0
- package/dist/core/extensions/context-types.d.ts +2 -0
- package/dist/core/extensions/context-types.d.ts.map +1 -1
- package/dist/core/extensions/context-types.js.map +1 -1
- package/dist/core/extensions/provider-types.d.ts +2 -0
- package/dist/core/extensions/provider-types.d.ts.map +1 -1
- package/dist/core/extensions/provider-types.js.map +1 -1
- package/dist/core/extensions/runner-context.d.ts +1 -0
- package/dist/core/extensions/runner-context.d.ts.map +1 -1
- package/dist/core/extensions/runner-context.js +8 -0
- package/dist/core/extensions/runner-context.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +1 -0
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +3 -0
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/runtime-types.d.ts +1 -0
- package/dist/core/extensions/runtime-types.d.ts.map +1 -1
- package/dist/core/extensions/runtime-types.js.map +1 -1
- package/dist/core/extensions/workflow-run-control-hub.d.ts +1 -0
- package/dist/core/extensions/workflow-run-control-hub.d.ts.map +1 -1
- package/dist/core/extensions/workflow-run-control-hub.js +3 -0
- package/dist/core/extensions/workflow-run-control-hub.js.map +1 -1
- package/dist/core/extensions/workflow-run-control.d.ts +8 -0
- package/dist/core/extensions/workflow-run-control.d.ts.map +1 -1
- package/dist/core/extensions/workflow-run-control.js.map +1 -1
- package/dist/core/model-config.d.ts +28 -0
- package/dist/core/model-config.d.ts.map +1 -1
- package/dist/core/model-fallback-failures.d.ts.map +1 -1
- package/dist/core/model-fallback-failures.js +12 -0
- package/dist/core/model-fallback-failures.js.map +1 -1
- package/dist/core/model-resolver-defaults.js +1 -1
- package/dist/core/model-resolver-defaults.js.map +1 -1
- package/dist/core/model-runtime-streaming.d.ts.map +1 -1
- package/dist/core/model-runtime-streaming.js +9 -3
- package/dist/core/model-runtime-streaming.js.map +1 -1
- package/dist/core/model-runtime.d.ts +5 -0
- package/dist/core/model-runtime.d.ts.map +1 -1
- package/dist/core/model-runtime.js +6 -0
- package/dist/core/model-runtime.js.map +1 -1
- package/dist/core/provider-composer-internal.d.ts +8 -6
- package/dist/core/provider-composer-internal.d.ts.map +1 -1
- package/dist/core/provider-composer-internal.js +21 -8
- package/dist/core/provider-composer-internal.js.map +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +12 -4
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/storage/session/sql-session-store.d.ts +35 -0
- package/dist/core/storage/session/sql-session-store.d.ts.map +1 -1
- package/dist/core/storage/session/sql-session-store.js +158 -42
- package/dist/core/storage/session/sql-session-store.js.map +1 -1
- package/dist/core/structured-output/deadline.d.ts +40 -0
- package/dist/core/structured-output/deadline.d.ts.map +1 -0
- package/dist/core/structured-output/deadline.js +110 -0
- package/dist/core/structured-output/deadline.js.map +1 -0
- package/dist/core/structured-output/index.d.ts.map +1 -1
- package/dist/core/structured-output/index.js +103 -47
- package/dist/core/structured-output/index.js.map +1 -1
- package/dist/core/structured-output/rejection-detail.d.ts +9 -0
- package/dist/core/structured-output/rejection-detail.d.ts.map +1 -0
- package/dist/core/structured-output/rejection-detail.js +129 -0
- package/dist/core/structured-output/rejection-detail.js.map +1 -0
- package/dist/core/structured-output/types.d.ts +8 -1
- package/dist/core/structured-output/types.d.ts.map +1 -1
- package/dist/core/structured-output/types.js.map +1 -1
- package/dist/core/tasks/completion.d.ts +7 -1
- package/dist/core/tasks/completion.d.ts.map +1 -1
- package/dist/core/tasks/completion.js +28 -6
- package/dist/core/tasks/completion.js.map +1 -1
- package/dist/core/tasks/contracts.d.ts +6 -1
- package/dist/core/tasks/contracts.d.ts.map +1 -1
- package/dist/core/tasks/contracts.js.map +1 -1
- package/dist/core/tasks/pause.d.ts +2 -1
- package/dist/core/tasks/pause.d.ts.map +1 -1
- package/dist/core/tasks/pause.js +3 -2
- package/dist/core/tasks/pause.js.map +1 -1
- package/dist/core/tools/bash-pty-native.d.ts.map +1 -1
- package/dist/core/tools/bash-pty-native.js +10 -5
- package/dist/core/tools/bash-pty-native.js.map +1 -1
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +16 -32
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/grep.js +1 -1
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/kill.d.ts.map +1 -1
- package/dist/core/tools/kill.js +17 -3
- package/dist/core/tools/kill.js.map +1 -1
- package/dist/core/tools/shell-task-render.d.ts +55 -0
- package/dist/core/tools/shell-task-render.d.ts.map +1 -0
- package/dist/core/tools/shell-task-render.js +123 -0
- package/dist/core/tools/shell-task-render.js.map +1 -0
- package/dist/core/tools/shell-task-status.d.ts +52 -0
- package/dist/core/tools/shell-task-status.d.ts.map +1 -0
- package/dist/core/tools/shell-task-status.js +184 -0
- package/dist/core/tools/shell-task-status.js.map +1 -0
- package/dist/core/tools/structured-output.d.ts +5 -0
- package/dist/core/tools/structured-output.d.ts.map +1 -1
- package/dist/core/tools/structured-output.js +3 -0
- package/dist/core/tools/structured-output.js.map +1 -1
- package/dist/extensions/codemode/execute.d.ts.map +1 -1
- package/dist/extensions/codemode/execute.js +134 -57
- package/dist/extensions/codemode/execute.js.map +1 -1
- package/dist/extensions/mcp/config.d.ts.map +1 -1
- package/dist/extensions/mcp/config.js +3 -2
- package/dist/extensions/mcp/config.js.map +1 -1
- package/dist/index-extensions.d.ts +1 -0
- package/dist/index-extensions.d.ts.map +1 -1
- package/dist/index-extensions.js +3 -0
- package/dist/index-extensions.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +19 -6
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/task-row.d.ts.map +1 -1
- package/dist/modes/interactive/components/task-row.js +11 -1
- package/dist/modes/interactive/components/task-row.js.map +1 -1
- package/dist/modes/interactive/interactive-auth-routing.js +12 -10
- package/dist/modes/interactive/interactive-auth-routing.js.map +1 -1
- package/dist/modes/interactive/interactive-extension-custom-ui.js +20 -30
- package/dist/modes/interactive/interactive-extension-custom-ui.js.map +1 -1
- package/dist/modes/interactive/interactive-extension-dialogs.js +23 -96
- package/dist/modes/interactive/interactive-extension-dialogs.js.map +1 -1
- package/dist/modes/interactive/interactive-extension-runtime.js +7 -8
- package/dist/modes/interactive/interactive-extension-runtime.js.map +1 -1
- package/dist/modes/interactive/interactive-input-handling.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-input-handling.js +27 -4
- package/dist/modes/interactive/interactive-input-handling.js.map +1 -1
- package/dist/modes/interactive/interactive-mode-base.d.ts +20 -10
- package/dist/modes/interactive/interactive-mode-base.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode-base.js +40 -5
- package/dist/modes/interactive/interactive-mode-base.js.map +1 -1
- package/dist/modes/interactive/interactive-mode-deps.d.ts +1 -1
- package/dist/modes/interactive/interactive-mode-deps.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode-deps.js +1 -1
- package/dist/modes/interactive/interactive-mode-deps.js.map +1 -1
- package/dist/modes/interactive/interactive-mode-surface.d.ts +2 -4
- package/dist/modes/interactive/interactive-mode-surface.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode-surface.js.map +1 -1
- package/dist/modes/interactive/interactive-mode-types.d.ts +4 -1
- package/dist/modes/interactive/interactive-mode-types.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode-types.js.map +1 -1
- package/dist/modes/interactive/interactive-prompt-restore.d.ts +3 -0
- package/dist/modes/interactive/interactive-prompt-restore.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-prompt-restore.js +9 -1
- package/dist/modes/interactive/interactive-prompt-restore.js.map +1 -1
- package/dist/modes/interactive/interactive-prompt-turn.js +30 -2
- package/dist/modes/interactive/interactive-prompt-turn.js.map +1 -1
- package/dist/modes/interactive/interactive-queueing.js +43 -8
- package/dist/modes/interactive/interactive-queueing.js.map +1 -1
- package/dist/modes/interactive/interactive-startup.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-startup.js +12 -3
- package/dist/modes/interactive/interactive-startup.js.map +1 -1
- package/dist/modes/interactive/theme/color-utils.d.ts +6 -1
- package/dist/modes/interactive/theme/color-utils.d.ts.map +1 -1
- package/dist/modes/interactive/theme/color-utils.js +39 -17
- package/dist/modes/interactive/theme/color-utils.js.map +1 -1
- package/dist/modes/interactive/theme/theme-class.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme-class.js +2 -2
- package/dist/modes/interactive/theme/theme-class.js.map +1 -1
- package/dist/modes/interactive/theme/theme-tokens.d.ts +6 -0
- package/dist/modes/interactive/theme/theme-tokens.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme-tokens.js +7 -3
- package/dist/modes/interactive/theme/theme-tokens.js.map +1 -1
- package/dist/modes/interactive-engine/isolated-auth.d.ts +3 -0
- package/dist/modes/interactive-engine/isolated-auth.d.ts.map +1 -1
- package/dist/modes/interactive-engine/isolated-auth.js +13 -1
- package/dist/modes/interactive-engine/isolated-auth.js.map +1 -1
- package/dist/modes/interactive-engine/isolated-runtime.d.ts.map +1 -1
- package/dist/modes/interactive-engine/isolated-runtime.js +11 -2
- package/dist/modes/interactive-engine/isolated-runtime.js.map +1 -1
- package/dist/modes/interactive-engine/remote-model-catalog.d.ts +8 -0
- package/dist/modes/interactive-engine/remote-model-catalog.d.ts.map +1 -1
- package/dist/modes/interactive-engine/remote-model-catalog.js +54 -0
- package/dist/modes/interactive-engine/remote-model-catalog.js.map +1 -1
- package/dist/modes/rpc/rpc-command-handler.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-command-handler.js +4 -13
- package/dist/modes/rpc/rpc-command-handler.js.map +1 -1
- package/dist/modes/rpc/rpc-model-catalog.d.ts +9 -0
- package/dist/modes/rpc/rpc-model-catalog.d.ts.map +1 -0
- package/dist/modes/rpc/rpc-model-catalog.js +19 -0
- package/dist/modes/rpc/rpc-model-catalog.js.map +1 -0
- package/dist/modes/rpc/rpc-provider-auth.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-provider-auth.js +2 -6
- package/dist/modes/rpc/rpc-provider-auth.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +6 -0
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/utils/changelog.d.ts +6 -0
- package/dist/utils/changelog.d.ts.map +1 -1
- package/dist/utils/changelog.js +11 -0
- package/dist/utils/changelog.js.map +1 -1
- package/dist/utils/clipboard.d.ts.map +1 -1
- package/dist/utils/clipboard.js +4 -0
- package/dist/utils/clipboard.js.map +1 -1
- package/dist/utils/tools-manager.d.ts.map +1 -1
- package/dist/utils/tools-manager.js +3 -2
- package/dist/utils/tools-manager.js.map +1 -1
- package/docs/background-tasks.md +5 -3
- package/docs/codemode.md +2 -2
- package/docs/custom-provider/oauth.md +42 -1
- package/docs/custom-provider/registration.md +2 -0
- package/docs/environment-variables.md +1 -0
- package/docs/extensions/api-reference.md +3 -4
- package/docs/extensions/authoring.md +1 -1
- package/docs/extensions/events.md +1 -1
- package/docs/models-configuration.md +9 -0
- package/docs/models.md +3 -1
- package/docs/providers.md +4 -4
- package/docs/rpc/protocol.md +4 -2
- package/docs/sdk/reference.md +2 -0
- package/docs/sdk/structured-decisions.md +7 -5
- package/docs/sdk.md +5 -2
- package/docs/settings.md +4 -2
- package/docs/subagents/reference.md +1 -1
- package/docs/subagents.md +15 -1
- package/docs/themes/reference.md +3 -1
- package/docs/usage.md +3 -1
- package/docs/workflows/api-reference.md +28 -0
- package/docs/workflows/authoring.md +1 -1
- package/docs/workflows/operations.md +2 -2
- package/npm-shrinkwrap.json +67 -54
- package/package.json +6 -6
- package/schemas/models.schema.json +21 -0
- package/dist/core/provider-attribution.d.ts +0 -4
- package/dist/core/provider-attribution.d.ts.map +0 -1
- package/dist/core/provider-attribution.js +0 -87
- package/dist/core/provider-attribution.js.map +0 -1
|
@@ -38933,10 +38933,23 @@ function runIndicatorStatus(run, allRuns = [run]) {
|
|
|
38933
38933
|
}
|
|
38934
38934
|
return status;
|
|
38935
38935
|
}
|
|
38936
|
+
function createRunIndicatorStatusResolver(allRuns) {
|
|
38937
|
+
let runsWithPendingDescendants;
|
|
38938
|
+
return (run) => {
|
|
38939
|
+
const status = effectiveRunStatus(run);
|
|
38940
|
+
if (TERMINAL_OR_BLOCKED.has(status))
|
|
38941
|
+
return status;
|
|
38942
|
+
if (runHasPendingInput(run))
|
|
38943
|
+
return "awaiting_input";
|
|
38944
|
+
runsWithPendingDescendants ??= ancestorsOfPendingInputRuns(allRuns);
|
|
38945
|
+
return runsWithPendingDescendants.has(run.id) ? "awaiting_input" : status;
|
|
38946
|
+
};
|
|
38947
|
+
}
|
|
38936
38948
|
function resolveRunIndicatorStatuses(runs, allRuns) {
|
|
38949
|
+
const statusOf = createRunIndicatorStatusResolver(allRuns);
|
|
38937
38950
|
const statuses = {};
|
|
38938
38951
|
for (const run of runs)
|
|
38939
|
-
statuses[run.id] =
|
|
38952
|
+
statuses[run.id] = statusOf(run);
|
|
38940
38953
|
return statuses;
|
|
38941
38954
|
}
|
|
38942
38955
|
function runHasPendingInput(run) {
|
|
@@ -38944,6 +38957,30 @@ function runHasPendingInput(run) {
|
|
|
38944
38957
|
return true;
|
|
38945
38958
|
return run.stages.some((stage) => stage.status === "awaiting_input" || stage.awaitingInputSince !== undefined || stage.pendingPrompt !== undefined || stage.inputRequest !== undefined);
|
|
38946
38959
|
}
|
|
38960
|
+
function ancestorsOfPendingInputRuns(allRuns) {
|
|
38961
|
+
const runsById = new Map(allRuns.map((candidate) => [candidate.id, candidate]));
|
|
38962
|
+
const ancestors = new Set;
|
|
38963
|
+
for (const candidate of allRuns) {
|
|
38964
|
+
if (TERMINAL_OR_BLOCKED.has(effectiveRunStatus(candidate)) || !runHasPendingInput(candidate))
|
|
38965
|
+
continue;
|
|
38966
|
+
const mark = (ancestorId) => {
|
|
38967
|
+
if (ancestorId !== candidate.id)
|
|
38968
|
+
ancestors.add(ancestorId);
|
|
38969
|
+
};
|
|
38970
|
+
if (candidate.rootRunId !== undefined)
|
|
38971
|
+
mark(candidate.rootRunId);
|
|
38972
|
+
const visited = new Set;
|
|
38973
|
+
let current = candidate;
|
|
38974
|
+
while (current !== undefined && current.parentRunId !== undefined) {
|
|
38975
|
+
mark(current.parentRunId);
|
|
38976
|
+
if (visited.has(current.id))
|
|
38977
|
+
break;
|
|
38978
|
+
visited.add(current.id);
|
|
38979
|
+
current = runsById.get(current.parentRunId);
|
|
38980
|
+
}
|
|
38981
|
+
}
|
|
38982
|
+
return ancestors;
|
|
38983
|
+
}
|
|
38947
38984
|
function runBelongsTo(candidate, ancestor, runsById) {
|
|
38948
38985
|
if (candidate.rootRunId === ancestor.id)
|
|
38949
38986
|
return true;
|
|
@@ -38960,16 +38997,58 @@ function runBelongsTo(candidate, ancestor, runsById) {
|
|
|
38960
38997
|
return false;
|
|
38961
38998
|
}
|
|
38962
38999
|
|
|
39000
|
+
// dist/builtin/workflows/src/shared/run-order.ts
|
|
39001
|
+
var ACTIVE_RANK = {
|
|
39002
|
+
awaiting_input: 0,
|
|
39003
|
+
blocked: 0,
|
|
39004
|
+
running: 1,
|
|
39005
|
+
paused: 2
|
|
39006
|
+
};
|
|
39007
|
+
var OTHER_ACTIVE_RANK = 3;
|
|
39008
|
+
var TERMINAL_RANK = {
|
|
39009
|
+
blocked: 0,
|
|
39010
|
+
failed: 1,
|
|
39011
|
+
killed: 1,
|
|
39012
|
+
cancelled: 2,
|
|
39013
|
+
skipped: 3,
|
|
39014
|
+
completed: 4
|
|
39015
|
+
};
|
|
39016
|
+
var OTHER_TERMINAL_RANK = 5;
|
|
39017
|
+
function isQuitRun(run) {
|
|
39018
|
+
return run.endedAt === undefined && run.status === "paused" && run.exitReason === "quit";
|
|
39019
|
+
}
|
|
39020
|
+
function statusRank(run, statusOf) {
|
|
39021
|
+
if (run.endedAt !== undefined)
|
|
39022
|
+
return TERMINAL_RANK[statusOf(run)] ?? OTHER_TERMINAL_RANK;
|
|
39023
|
+
if (isQuitRun(run))
|
|
39024
|
+
return ACTIVE_RANK.paused ?? OTHER_ACTIVE_RANK;
|
|
39025
|
+
return ACTIVE_RANK[statusOf(run)] ?? OTHER_ACTIVE_RANK;
|
|
39026
|
+
}
|
|
39027
|
+
function sortRunsByStatus(items, runOf, statusOf) {
|
|
39028
|
+
return items.map((item) => {
|
|
39029
|
+
const run = runOf(item);
|
|
39030
|
+
return { item, run, rank: statusRank(run, statusOf) };
|
|
39031
|
+
}).sort((a, b) => {
|
|
39032
|
+
const aEnded = a.run.endedAt !== undefined;
|
|
39033
|
+
if (aEnded !== (b.run.endedAt !== undefined))
|
|
39034
|
+
return aEnded ? 1 : -1;
|
|
39035
|
+
const rankDelta = a.rank - b.rank;
|
|
39036
|
+
if (rankDelta !== 0)
|
|
39037
|
+
return rankDelta;
|
|
39038
|
+
return aEnded ? (b.run.endedAt ?? 0) - (a.run.endedAt ?? 0) : b.run.startedAt - a.run.startedAt;
|
|
39039
|
+
}).map((entry) => entry.item);
|
|
39040
|
+
}
|
|
39041
|
+
|
|
38963
39042
|
// dist/builtin/workflows/src/tui/status-list.ts
|
|
38964
39043
|
var STAGE_LABEL_BUDGET = 24;
|
|
38965
|
-
function
|
|
39044
|
+
function isQuitRun2(run) {
|
|
38966
39045
|
return run.endedAt === undefined && run.status === "paused" && run.exitReason === "quit";
|
|
38967
39046
|
}
|
|
38968
39047
|
function renderStatusList(runs, opts = {}) {
|
|
38969
39048
|
const now = opts.now ?? Date.now();
|
|
38970
39049
|
const width = effectiveWidth2(opts.width);
|
|
38971
39050
|
const cardWidth = Math.max(20, width - 4);
|
|
38972
|
-
const sorted = sortRuns(runs);
|
|
39051
|
+
const sorted = sortRuns(runs, opts);
|
|
38973
39052
|
const resolveBoundarySegments = opts.resolveBoundarySegments ?? ((runId) => workflowBoundarySegments(runs, runId));
|
|
38974
39053
|
const counts = countBuckets(runs);
|
|
38975
39054
|
const subtitle = `${sorted.length} run${sorted.length === 1 ? "" : "s"}`;
|
|
@@ -39094,12 +39173,12 @@ function pendingStageLine(line, width, theme) {
|
|
|
39094
39173
|
function runAccent(run, theme, indicatorStatus) {
|
|
39095
39174
|
if (!theme)
|
|
39096
39175
|
return "#000000";
|
|
39097
|
-
if (
|
|
39176
|
+
if (isQuitRun2(run))
|
|
39098
39177
|
return theme.warning;
|
|
39099
39178
|
return statusColor(indicatorStatus, theme);
|
|
39100
39179
|
}
|
|
39101
39180
|
function runTrailing(run, theme) {
|
|
39102
|
-
if (
|
|
39181
|
+
if (isQuitRun2(run))
|
|
39103
39182
|
return { text: "○ quit", fg: theme?.warning };
|
|
39104
39183
|
switch (effectiveRunStatus(run)) {
|
|
39105
39184
|
case "completed":
|
|
@@ -39128,7 +39207,7 @@ function runCardMeta(run, now) {
|
|
|
39128
39207
|
const total = run.stages.length;
|
|
39129
39208
|
const done = run.stages.filter((s) => s.status === "completed" || s.status === "failed" || s.status === "skipped").length;
|
|
39130
39209
|
const ago = run.endedAt !== undefined ? `${fmtDuration(now - run.endedAt)} ago` : run.startedAt != null ? fmtDuration(elapsedRunMs(run, now)) : undefined;
|
|
39131
|
-
if (
|
|
39210
|
+
if (isQuitRun2(run))
|
|
39132
39211
|
return run.resumable === false ? "not resumable" : "resumable via /workflow resume";
|
|
39133
39212
|
if (effectiveRunStatus(run) === "running") {
|
|
39134
39213
|
if (isChain)
|
|
@@ -39242,7 +39321,7 @@ function countBuckets(runs) {
|
|
|
39242
39321
|
const c = { active: 0, paused: 0, quit: 0, completed: 0, blocked: 0, failed: 0, pending: 0 };
|
|
39243
39322
|
for (const r of runs) {
|
|
39244
39323
|
const status = effectiveRunStatus(r);
|
|
39245
|
-
if (
|
|
39324
|
+
if (isQuitRun2(r))
|
|
39246
39325
|
c.quit++;
|
|
39247
39326
|
else if (r.endedAt === undefined) {
|
|
39248
39327
|
if (status === "pending")
|
|
@@ -39304,11 +39383,9 @@ function plainBadges(c) {
|
|
|
39304
39383
|
out.push({ text: `⊘ ${c.failed}` });
|
|
39305
39384
|
return out;
|
|
39306
39385
|
}
|
|
39307
|
-
function sortRuns(runs) {
|
|
39308
|
-
const
|
|
39309
|
-
|
|
39310
|
-
const byStart = (a, b) => (b.startedAt ?? 0) - (a.startedAt ?? 0);
|
|
39311
|
-
return [...[...active].sort(byStart), ...[...ended].sort(byStart)];
|
|
39386
|
+
function sortRuns(runs, opts) {
|
|
39387
|
+
const statusOf = createRunIndicatorStatusResolver(opts.allRuns ?? runs);
|
|
39388
|
+
return sortRunsByStatus(runs, (run) => run, (run) => opts.indicatorStatuses?.[run.id] ?? statusOf(run));
|
|
39312
39389
|
}
|
|
39313
39390
|
function renderStatusHintRows(id, theme, width) {
|
|
39314
39391
|
const budget = Math.max(1, width - 4);
|
|
@@ -39350,7 +39427,7 @@ function emptyStateLine(theme) {
|
|
|
39350
39427
|
return ` ${hexToAnsi(theme.dim)}no workflow runs in current session${RESET}`;
|
|
39351
39428
|
}
|
|
39352
39429
|
function statusIconForRun(run, indicatorStatus) {
|
|
39353
|
-
if (
|
|
39430
|
+
if (isQuitRun2(run))
|
|
39354
39431
|
return statusIcon("pending");
|
|
39355
39432
|
return statusIcon(indicatorStatus);
|
|
39356
39433
|
}
|
|
@@ -50249,7 +50326,7 @@ function isDisplayablePrompt(message) {
|
|
|
50249
50326
|
function isTerminalOrBlockedRun(run) {
|
|
50250
50327
|
return TERMINAL_OR_BLOCKED2.has(effectiveRunStatus(run)) || run.endedAt !== undefined;
|
|
50251
50328
|
}
|
|
50252
|
-
function
|
|
50329
|
+
function isQuitRun3(run) {
|
|
50253
50330
|
return run.endedAt === undefined && run.status === "paused" && run.exitReason === "quit";
|
|
50254
50331
|
}
|
|
50255
50332
|
function hasLiveAncestry(candidate, visibleRun, runsById) {
|
|
@@ -50265,7 +50342,7 @@ function hasLiveAncestry(candidate, visibleRun, runsById) {
|
|
|
50265
50342
|
return false;
|
|
50266
50343
|
const parent = runsById.get(parentRunId);
|
|
50267
50344
|
const boundary = parent?.stages.find((stage) => stage.id === parentStageId);
|
|
50268
|
-
if (parent === undefined || isTerminalOrBlockedRun(parent) ||
|
|
50345
|
+
if (parent === undefined || isTerminalOrBlockedRun(parent) || isQuitRun3(parent) || boundary === undefined || boundary.status !== "running" && boundary.status !== "awaiting_input") {
|
|
50269
50346
|
return false;
|
|
50270
50347
|
}
|
|
50271
50348
|
current = parent;
|
|
@@ -50273,12 +50350,12 @@ function hasLiveAncestry(candidate, visibleRun, runsById) {
|
|
|
50273
50350
|
return true;
|
|
50274
50351
|
}
|
|
50275
50352
|
function visibleRunTreeMembers(visibleRun, allRuns) {
|
|
50276
|
-
if (isTerminalOrBlockedRun(visibleRun) ||
|
|
50353
|
+
if (isTerminalOrBlockedRun(visibleRun) || isQuitRun3(visibleRun))
|
|
50277
50354
|
return [];
|
|
50278
50355
|
const runsById = new Map;
|
|
50279
50356
|
const ambiguousRunIds = new Set;
|
|
50280
50357
|
for (const candidate of allRuns) {
|
|
50281
|
-
if (isTerminalOrBlockedRun(candidate) ||
|
|
50358
|
+
if (isTerminalOrBlockedRun(candidate) || isQuitRun3(candidate))
|
|
50282
50359
|
continue;
|
|
50283
50360
|
if (runsById.has(candidate.id))
|
|
50284
50361
|
ambiguousRunIds.add(candidate.id);
|
|
@@ -50291,7 +50368,7 @@ function visibleRunTreeMembers(visibleRun, allRuns) {
|
|
|
50291
50368
|
return [];
|
|
50292
50369
|
const members = [visibleRun];
|
|
50293
50370
|
for (const candidate of allRuns) {
|
|
50294
|
-
if (isTerminalOrBlockedRun(candidate) ||
|
|
50371
|
+
if (isTerminalOrBlockedRun(candidate) || isQuitRun3(candidate))
|
|
50295
50372
|
continue;
|
|
50296
50373
|
if (candidate.id === visibleRun.id || ambiguousRunIds.has(candidate.id))
|
|
50297
50374
|
continue;
|
|
@@ -50361,7 +50438,7 @@ function runPromptOccurrenceForStage(run, stage, prompt) {
|
|
|
50361
50438
|
return descriptorOccurrence(run, stage.id, prompt.id, message, isDisplayablePrompt(message));
|
|
50362
50439
|
}
|
|
50363
50440
|
function pendingInputOccurrences(run) {
|
|
50364
|
-
if (isTerminalOrBlockedRun(run) ||
|
|
50441
|
+
if (isTerminalOrBlockedRun(run) || isQuitRun3(run))
|
|
50365
50442
|
return [];
|
|
50366
50443
|
const occurrences = run.pendingPrompt === undefined ? [] : [runPromptOccurrence(run, run.pendingPrompt)];
|
|
50367
50444
|
return occurrences.concat(stagePromptOccurrences(run));
|
|
@@ -50404,17 +50481,17 @@ function formatDuration(ms) {
|
|
|
50404
50481
|
const rmin = minutes % 60;
|
|
50405
50482
|
return `${hours}h${rmin > 0 ? ` ${rmin}m` : ""}`;
|
|
50406
50483
|
}
|
|
50407
|
-
function
|
|
50484
|
+
function isQuitRun4(run) {
|
|
50408
50485
|
return run.endedAt === undefined && run.status === "paused" && run.exitReason === "quit";
|
|
50409
50486
|
}
|
|
50410
50487
|
function isActive(run) {
|
|
50411
|
-
return run.endedAt === undefined && !
|
|
50488
|
+
return run.endedAt === undefined && !isQuitRun4(run);
|
|
50412
50489
|
}
|
|
50413
50490
|
function recentlyEnded(run, now) {
|
|
50414
50491
|
return run.endedAt !== undefined && now - run.endedAt <= RECENT_ENDED_WINDOW_MS;
|
|
50415
50492
|
}
|
|
50416
50493
|
function recentlyQuit(run, now) {
|
|
50417
|
-
return
|
|
50494
|
+
return isQuitRun4(run) && run.quitAt !== undefined && now - run.quitAt <= RECENT_ENDED_WINDOW_MS;
|
|
50418
50495
|
}
|
|
50419
50496
|
function subtreeAwaitsInput(root, allRuns) {
|
|
50420
50497
|
return runIndicatorStatus(root, allRuns) === "awaiting_input";
|
|
@@ -50423,7 +50500,7 @@ function countRuns(runs, allRuns = runs) {
|
|
|
50423
50500
|
const counts = { active: 0, paused: 0, quit: 0, done: 0, blocked: 0, failed: 0, awaiting: 0 };
|
|
50424
50501
|
for (const r of runs) {
|
|
50425
50502
|
const status = effectiveRunStatus(r);
|
|
50426
|
-
if (
|
|
50503
|
+
if (isQuitRun4(r))
|
|
50427
50504
|
counts.quit++;
|
|
50428
50505
|
else if (status === "blocked")
|
|
50429
50506
|
counts.blocked++;
|
|
@@ -50435,7 +50512,7 @@ function countRuns(runs, allRuns = runs) {
|
|
|
50435
50512
|
counts.done++;
|
|
50436
50513
|
else if (status === "failed" || status === "killed")
|
|
50437
50514
|
counts.failed++;
|
|
50438
|
-
if (r.endedAt === undefined && !
|
|
50515
|
+
if (r.endedAt === undefined && !isQuitRun4(r) && subtreeAwaitsInput(r, allRuns))
|
|
50439
50516
|
counts.awaiting++;
|
|
50440
50517
|
}
|
|
50441
50518
|
return counts;
|
|
@@ -50448,7 +50525,7 @@ function nextWidgetRefreshDelayMs(snap, now = Date.now()) {
|
|
|
50448
50525
|
for (const run of display) {
|
|
50449
50526
|
if (run.endedAt !== undefined) {
|
|
50450
50527
|
delays.push(Math.max(1, run.endedAt + RECENT_ENDED_WINDOW_MS - now + 1));
|
|
50451
|
-
} else if (
|
|
50528
|
+
} else if (isQuitRun4(run) && run.quitAt !== undefined) {
|
|
50452
50529
|
delays.push(Math.max(1, run.quitAt + RECENT_ENDED_WINDOW_MS - now + 1));
|
|
50453
50530
|
}
|
|
50454
50531
|
}
|
|
@@ -50468,12 +50545,12 @@ function selectDisplayRuns(snap, now) {
|
|
|
50468
50545
|
return [...sort(active), ...sort(recent)];
|
|
50469
50546
|
}
|
|
50470
50547
|
function statusGlyph2(run, allRuns) {
|
|
50471
|
-
if (
|
|
50548
|
+
if (isQuitRun4(run))
|
|
50472
50549
|
return statusIcon("pending");
|
|
50473
50550
|
return statusIcon(runIndicatorStatus(run, allRuns));
|
|
50474
50551
|
}
|
|
50475
50552
|
function statusFg(run, theme, allRuns) {
|
|
50476
|
-
if (
|
|
50553
|
+
if (isQuitRun4(run))
|
|
50477
50554
|
return theme.warning;
|
|
50478
50555
|
const indicatorStatus = runIndicatorStatus(run, allRuns);
|
|
50479
50556
|
if (indicatorStatus === "awaiting_input")
|
|
@@ -50559,7 +50636,7 @@ function metaLine(run, expandGraph, now, width = Number.POSITIVE_INFINITY, resol
|
|
|
50559
50636
|
if (run.endedAt !== undefined) {
|
|
50560
50637
|
return elapsedLabel(run, now);
|
|
50561
50638
|
}
|
|
50562
|
-
if (
|
|
50639
|
+
if (isQuitRun4(run))
|
|
50563
50640
|
return run.resumable === false ? "quit · not resumable" : "quit · resumable via /workflow resume";
|
|
50564
50641
|
if (effectiveRunStatus(run) === "blocked")
|
|
50565
50642
|
return "blocked · resumable via /workflow resume";
|
|
@@ -50708,8 +50785,8 @@ function buildThemedWidgetLines(snap, piTheme, width = 120, now = Date.now(), la
|
|
|
50708
50785
|
const displayCounts = countRuns(display, snap.runs);
|
|
50709
50786
|
const visibleCounts = {
|
|
50710
50787
|
active: display.filter((r) => r.endedAt === undefined && effectiveRunStatus(r) === "running").length,
|
|
50711
|
-
paused: display.filter((r) => r.endedAt === undefined && effectiveRunStatus(r) === "paused" && !
|
|
50712
|
-
quit: display.filter(
|
|
50788
|
+
paused: display.filter((r) => r.endedAt === undefined && effectiveRunStatus(r) === "paused" && !isQuitRun4(r)).length,
|
|
50789
|
+
quit: display.filter(isQuitRun4).length,
|
|
50713
50790
|
done: display.filter((r) => r.endedAt !== undefined && ["completed", "skipped", "cancelled"].includes(effectiveRunStatus(r))).length,
|
|
50714
50791
|
blocked: display.filter((r) => effectiveRunStatus(r) === "blocked").length,
|
|
50715
50792
|
failed: display.filter((r) => r.endedAt !== undefined && ["failed", "killed"].includes(effectiveRunStatus(r))).length,
|
|
@@ -50734,7 +50811,7 @@ function buildThemedWidgetLines(snap, piTheme, width = 120, now = Date.now(), la
|
|
|
50734
50811
|
for (let i = 0;i < display.length; i++) {
|
|
50735
50812
|
const run = display[i];
|
|
50736
50813
|
const affordance = pendingInputAffordance(run, snap.runs);
|
|
50737
|
-
const runLines = !
|
|
50814
|
+
const runLines = !isQuitRun4(run) && affordance !== undefined ? awaitingRunLines(run, now, themed ? graphTheme : undefined, snap.runs, affordance, bodyWidth, expandGraph) : themed ? themedRunLines(run, now, graphTheme, snap.runs, width, expandGraph) : plainRunLines(run, now, snap.runs, width, expandGraph);
|
|
50738
50815
|
body.push(...runLines);
|
|
50739
50816
|
layout?.runs.push({
|
|
50740
50817
|
id: run.id,
|
|
@@ -52374,7 +52451,7 @@ function compareDraftSourceOrder(left, right) {
|
|
|
52374
52451
|
function runTopologyFor(drafts, tools) {
|
|
52375
52452
|
return drafts.find((draft) => draft.topology?.run !== undefined)?.topology?.run ?? tools.find((checkpoint) => checkpoint.topology?.run !== undefined)?.topology?.run;
|
|
52376
52453
|
}
|
|
52377
|
-
function validateRunGroups(grouped, rootRunId, tools, checkpoints) {
|
|
52454
|
+
function validateRunGroups(grouped, rootRunId, tools, checkpoints, allowPendingChildren = false) {
|
|
52378
52455
|
const toolsFor = (runId) => tools.filter((checkpoint) => (checkpoint.topology?.run?.runId ?? rootRunId) === runId);
|
|
52379
52456
|
const owners = new Map;
|
|
52380
52457
|
const syntheticChildIds = new Set;
|
|
@@ -52386,6 +52463,11 @@ function validateRunGroups(grouped, rootRunId, tools, checkpoints) {
|
|
|
52386
52463
|
if (childRunId === parentRunId || owners.has(childRunId))
|
|
52387
52464
|
return false;
|
|
52388
52465
|
if (!grouped.has(childRunId)) {
|
|
52466
|
+
if (allowPendingChildren && isPendingChildBoundary(draft, parentRunId, childRunId, rootRunId) && !childScopedEvidenceExists(checkpoints, draft.replayKey, childRunId)) {
|
|
52467
|
+
syntheticChildIds.add(childRunId);
|
|
52468
|
+
owners.set(childRunId, draft);
|
|
52469
|
+
continue;
|
|
52470
|
+
}
|
|
52389
52471
|
if (!isSyntheticExitedChild(draft, parentRunId, childRunId, rootRunId) || childScopedEvidenceExists(checkpoints, draft.replayKey, childRunId))
|
|
52390
52472
|
return false;
|
|
52391
52473
|
syntheticChildIds.add(childRunId);
|
|
@@ -52418,6 +52500,10 @@ function validateRunGroups(grouped, rootRunId, tools, checkpoints) {
|
|
|
52418
52500
|
}
|
|
52419
52501
|
return true;
|
|
52420
52502
|
}
|
|
52503
|
+
function isPendingChildBoundary(draft, parentRunId, childRunId, rootRunId) {
|
|
52504
|
+
const boundary = draft.topology?.boundary;
|
|
52505
|
+
return workflowChildFromDraft(draft) === undefined && boundary?.event === "start" && boundary.status === "running" && boundary.child.runId === childRunId && boundary.child.parentRunId === parentRunId && boundary.child.parentStageId === draft.topology?.stageId && boundary.child.rootRunId === rootRunId;
|
|
52506
|
+
}
|
|
52421
52507
|
function isSyntheticExitedChild(draft, parentRunId, childRunId, rootRunId) {
|
|
52422
52508
|
const child = workflowChildFromDraft(draft);
|
|
52423
52509
|
const boundary = draft.topology?.boundary;
|
|
@@ -53060,6 +53146,13 @@ class PromptReservationState {
|
|
|
53060
53146
|
|
|
53061
53147
|
// dist/builtin/workflows/src/durable/journal/internal.ts
|
|
53062
53148
|
var JOURNAL_READ_PAGE_SIZE = 256;
|
|
53149
|
+
var versionReaders = new WeakMap;
|
|
53150
|
+
function registerRunJournalVersions(journal, versions) {
|
|
53151
|
+
versionReaders.set(journal, versions);
|
|
53152
|
+
}
|
|
53153
|
+
function runJournalVersions(journal) {
|
|
53154
|
+
return versionReaders.get(journal);
|
|
53155
|
+
}
|
|
53063
53156
|
|
|
53064
53157
|
// dist/builtin/workflows/src/durable/journal/values.ts
|
|
53065
53158
|
function validateText(field, value2) {
|
|
@@ -53405,6 +53498,8 @@ class JournalDurableBackend {
|
|
|
53405
53498
|
persistent;
|
|
53406
53499
|
projection = createJournalProjection();
|
|
53407
53500
|
sequences = new Map;
|
|
53501
|
+
foldedAt = new Map;
|
|
53502
|
+
catalogToken;
|
|
53408
53503
|
leases = new Map;
|
|
53409
53504
|
executions = new Map;
|
|
53410
53505
|
executionContext = new AsyncLocalStorage;
|
|
@@ -53448,7 +53543,7 @@ class JournalDurableBackend {
|
|
|
53448
53543
|
try {
|
|
53449
53544
|
this.ensureOpen();
|
|
53450
53545
|
if (requiresActiveExecution)
|
|
53451
|
-
this.assertExecutionActive(
|
|
53546
|
+
this.assertExecutionActive();
|
|
53452
53547
|
} catch (error) {
|
|
53453
53548
|
return Promise.reject(error);
|
|
53454
53549
|
}
|
|
@@ -53501,6 +53596,7 @@ class JournalDurableBackend {
|
|
|
53501
53596
|
this.projection.applyWorkflowSnapshot({ ...handle, pendingStageMessages: messages });
|
|
53502
53597
|
}
|
|
53503
53598
|
this.sequences.set(entry.runId, entry.seq);
|
|
53599
|
+
this.foldedAt.set(entry.runId, entry.at);
|
|
53504
53600
|
}
|
|
53505
53601
|
*entries(runId, fromSeq) {
|
|
53506
53602
|
return yield* invoke(async () => {
|
|
@@ -53514,6 +53610,7 @@ class JournalDurableBackend {
|
|
|
53514
53610
|
const entries = yield* this.entries(runId);
|
|
53515
53611
|
this.projection.deleteWorkflow(runId);
|
|
53516
53612
|
this.sequences.delete(runId);
|
|
53613
|
+
this.foldedAt.delete(runId);
|
|
53517
53614
|
this.prompts.delete(runId);
|
|
53518
53615
|
for (const entry of entries)
|
|
53519
53616
|
this.fold(entry);
|
|
@@ -53526,7 +53623,7 @@ class JournalDurableBackend {
|
|
|
53526
53623
|
}
|
|
53527
53624
|
*current(runId) {
|
|
53528
53625
|
this.ensureOpen();
|
|
53529
|
-
this.assertExecutionActive(
|
|
53626
|
+
this.assertExecutionActive(true);
|
|
53530
53627
|
yield* this.refresh(runId);
|
|
53531
53628
|
if (this.projection.getWorkflow(runId) === undefined)
|
|
53532
53629
|
return;
|
|
@@ -53545,14 +53642,14 @@ class JournalDurableBackend {
|
|
|
53545
53642
|
if (this.state === "closed" || this.state === "closing" && !this.mutationContext.getStore())
|
|
53546
53643
|
throw new JournalBackendClosedError;
|
|
53547
53644
|
}
|
|
53548
|
-
assertExecutionActive(
|
|
53645
|
+
assertExecutionActive(admitted = false) {
|
|
53549
53646
|
for (const [executionRunId, execution] of this.executionContext.getStore() ?? [])
|
|
53550
53647
|
if (execution.retired && !(admitted && this.mutationContext.getStore()?.has(execution)))
|
|
53551
|
-
throw new JournalExecutionRetiredError(
|
|
53648
|
+
throw new JournalExecutionRetiredError(executionRunId);
|
|
53552
53649
|
}
|
|
53553
53650
|
*ownership(runId) {
|
|
53554
53651
|
this.ensureOpen();
|
|
53555
|
-
this.assertExecutionActive(
|
|
53652
|
+
this.assertExecutionActive(true);
|
|
53556
53653
|
const lost = this.lost.get(runId);
|
|
53557
53654
|
if (lost)
|
|
53558
53655
|
throw lost;
|
|
@@ -53612,7 +53709,7 @@ class JournalDurableBackend {
|
|
|
53612
53709
|
return this.serialize(input.workflowId, () => this.register(input));
|
|
53613
53710
|
}
|
|
53614
53711
|
*register(input) {
|
|
53615
|
-
this.assertExecutionActive(
|
|
53712
|
+
this.assertExecutionActive(true);
|
|
53616
53713
|
this.ensureOpen();
|
|
53617
53714
|
const header = {
|
|
53618
53715
|
runId: input.workflowId,
|
|
@@ -53836,11 +53933,36 @@ class JournalDurableBackend {
|
|
|
53836
53933
|
}
|
|
53837
53934
|
hydrateResumableWorkflows() {
|
|
53838
53935
|
return this.serialize(this.catalogQueue, () => invoke(async () => {
|
|
53839
|
-
const
|
|
53840
|
-
|
|
53841
|
-
await this.
|
|
53936
|
+
const journal = runJournalVersions(this.journal);
|
|
53937
|
+
if (journal === undefined) {
|
|
53938
|
+
const runs = await this.journal.listRuns();
|
|
53939
|
+
for (const runId of new Set([...this.sequences.keys(), ...runs.map((run) => run.runId)]))
|
|
53940
|
+
await this.hydrateWorkflow(runId);
|
|
53941
|
+
return;
|
|
53942
|
+
}
|
|
53943
|
+
const token = await journal.changeToken();
|
|
53944
|
+
if (token === this.catalogToken)
|
|
53945
|
+
return;
|
|
53946
|
+
const versions = await journal.runVersions();
|
|
53947
|
+
for (const runId of new Set([...this.sequences.keys(), ...versions.keys()]))
|
|
53948
|
+
await this.serialize(runId, () => this.catchUp(runId, versions.get(runId)), false);
|
|
53949
|
+
this.catalogToken = token;
|
|
53842
53950
|
}));
|
|
53843
53951
|
}
|
|
53952
|
+
*catchUp(runId, version) {
|
|
53953
|
+
const folded = this.sequences.get(runId) ?? 0;
|
|
53954
|
+
if (version !== undefined && version.seq === folded && version.at === (this.foldedAt.get(runId) ?? 0))
|
|
53955
|
+
return;
|
|
53956
|
+
if (version !== undefined && folded > 0 && version.seq > folded) {
|
|
53957
|
+
const entries = yield* this.entries(runId, folded);
|
|
53958
|
+
if (entries[0]?.seq === folded && entries[0].at === this.foldedAt.get(runId)) {
|
|
53959
|
+
for (const entry of entries)
|
|
53960
|
+
this.fold(entry);
|
|
53961
|
+
return;
|
|
53962
|
+
}
|
|
53963
|
+
}
|
|
53964
|
+
yield* this.rebuild(runId);
|
|
53965
|
+
}
|
|
53844
53966
|
async prepareWorkflowCatalog() {
|
|
53845
53967
|
await this.hydrateResumableWorkflows();
|
|
53846
53968
|
return this.projection.prepareWorkflowCatalog();
|
|
@@ -53858,6 +53980,7 @@ class JournalDurableBackend {
|
|
|
53858
53980
|
}
|
|
53859
53981
|
this.leases.delete(runId);
|
|
53860
53982
|
this.sequences.delete(runId);
|
|
53983
|
+
this.foldedAt.delete(runId);
|
|
53861
53984
|
this.prompts.delete(runId);
|
|
53862
53985
|
this.projection.deleteWorkflow(runId);
|
|
53863
53986
|
}
|
|
@@ -53950,7 +54073,7 @@ class JournalDurableBackend {
|
|
|
53950
54073
|
}
|
|
53951
54074
|
async withWorkflowLease(runId, action) {
|
|
53952
54075
|
this.ensureOpen();
|
|
53953
|
-
this.assertExecutionActive(
|
|
54076
|
+
this.assertExecutionActive();
|
|
53954
54077
|
const context = this.executionContext.getStore();
|
|
53955
54078
|
const active = this.executions.get(runId);
|
|
53956
54079
|
if (active !== undefined && context?.get(runId) !== active)
|
|
@@ -53985,7 +54108,7 @@ class JournalDurableBackend {
|
|
|
53985
54108
|
return this.serialize(runId, () => this.release(runId, execution), false);
|
|
53986
54109
|
}
|
|
53987
54110
|
releaseWorkflow(runId) {
|
|
53988
|
-
this.assertExecutionActive(
|
|
54111
|
+
this.assertExecutionActive();
|
|
53989
54112
|
return this.serialize(runId, () => this.release(runId));
|
|
53990
54113
|
}
|
|
53991
54114
|
*release(runId, execution) {
|
|
@@ -54078,6 +54201,10 @@ var LEGACY_COLUMNS = {
|
|
|
54078
54201
|
var PENDING_LEGACY_RUNS = `SELECT ${JOURNAL_COLUMNS.runId}, ${JOURNAL_COLUMNS.headerJson}, ${JOURNAL_COLUMNS.status} FROM ${JOURNAL_TABLES.runs}
|
|
54079
54202
|
WHERE ${JOURNAL_COLUMNS.runId} NOT IN (SELECT ${JOURNAL_COLUMNS.runId} FROM ${CURRENT.runs})
|
|
54080
54203
|
AND ${JOURNAL_COLUMNS.runId} NOT IN (SELECT ${JOURNAL_COLUMNS.runId} FROM ${CURRENT.legacyDeleted})`;
|
|
54204
|
+
function latestEventColumns(events, runs) {
|
|
54205
|
+
const latest = (column) => `COALESCE((SELECT ${column} FROM ${events} AS latest WHERE latest.${JOURNAL_COLUMNS.runId} = ${runs}.${JOURNAL_COLUMNS.runId} ORDER BY latest.${JOURNAL_COLUMNS.seq} DESC LIMIT 1), 0) AS ${column}`;
|
|
54206
|
+
return `${latest(JOURNAL_COLUMNS.seq)}, ${latest(JOURNAL_COLUMNS.at)}`;
|
|
54207
|
+
}
|
|
54081
54208
|
async function hasLegacyTable(tx, table) {
|
|
54082
54209
|
const columns = await tx.all("SELECT name FROM pragma_table_info(?)", JOURNAL_TABLES[table]);
|
|
54083
54210
|
const names = new Set(columns.map((column) => column.name));
|
|
@@ -54111,6 +54238,9 @@ class LegacyJournalRuns {
|
|
|
54111
54238
|
async find(executor, runId) {
|
|
54112
54239
|
return executor.get(`${PENDING_LEGACY_RUNS} AND ${JOURNAL_COLUMNS.runId} = ?`, runId);
|
|
54113
54240
|
}
|
|
54241
|
+
async versions(executor) {
|
|
54242
|
+
return executor.all(`SELECT pending.${JOURNAL_COLUMNS.runId}, ${latestEventColumns(JOURNAL_TABLES.events, "pending")} FROM (${PENDING_LEGACY_RUNS}) AS pending`);
|
|
54243
|
+
}
|
|
54114
54244
|
async events(executor, runId, fromSeq, limit) {
|
|
54115
54245
|
return executor.all(`SELECT ${LEGACY_COLUMNS.events.join(", ")} FROM ${JOURNAL_TABLES.events} WHERE ${JOURNAL_COLUMNS.runId} = ? AND ${JOURNAL_COLUMNS.seq} >= ? ORDER BY ${JOURNAL_COLUMNS.seq} LIMIT ?`, runId, fromSeq, limit);
|
|
54116
54246
|
}
|
|
@@ -54161,6 +54291,10 @@ class SqlRunJournal {
|
|
|
54161
54291
|
this.database = database;
|
|
54162
54292
|
this.tables = tables;
|
|
54163
54293
|
this.legacy = legacy;
|
|
54294
|
+
registerRunJournalVersions(this, {
|
|
54295
|
+
changeToken: () => this.changeToken(),
|
|
54296
|
+
runVersions: () => this.runVersions()
|
|
54297
|
+
});
|
|
54164
54298
|
}
|
|
54165
54299
|
static async open(database, options = {}) {
|
|
54166
54300
|
const t = renderStorageIdentifiers2("journal", JOURNAL_TABLES, options.prefix);
|
|
@@ -54259,6 +54393,27 @@ class SqlRunJournal {
|
|
|
54259
54393
|
return [...rows, ...legacy].map((row) => ({ ...JSON.parse(row[JOURNAL_COLUMNS.headerJson]), status: row[JOURNAL_COLUMNS.status] })).sort((left, right) => left.runId < right.runId ? -1 : left.runId > right.runId ? 1 : 0);
|
|
54260
54394
|
});
|
|
54261
54395
|
}
|
|
54396
|
+
async changeToken() {
|
|
54397
|
+
this.assertOpen();
|
|
54398
|
+
return this.operation(async () => {
|
|
54399
|
+
const row = await this.database.get(`SELECT data_version, total_changes() AS changes,
|
|
54400
|
+
(SELECT count(*) FROM ${this.tables.runs}) AS runs,
|
|
54401
|
+
(SELECT max(rowid) FROM ${this.tables.events}) AS last_event
|
|
54402
|
+
FROM pragma_data_version`);
|
|
54403
|
+
return JSON.stringify(Object.values(row ?? {}).map(String));
|
|
54404
|
+
});
|
|
54405
|
+
}
|
|
54406
|
+
async runVersions() {
|
|
54407
|
+
this.assertOpen();
|
|
54408
|
+
return this.operation(async () => {
|
|
54409
|
+
const rows = await this.database.all(`SELECT runs.${JOURNAL_COLUMNS.runId}, ${latestEventColumns(this.tables.events, "runs")} FROM ${this.tables.runs} AS runs`);
|
|
54410
|
+
const legacy = await this.legacy?.versions(this.database) ?? [];
|
|
54411
|
+
return new Map([...rows, ...legacy].map((row) => [
|
|
54412
|
+
row[JOURNAL_COLUMNS.runId],
|
|
54413
|
+
{ seq: journalCounter(row[JOURNAL_COLUMNS.runId], "seq", row[JOURNAL_COLUMNS.seq]), at: Number(row[JOURNAL_COLUMNS.at]) }
|
|
54414
|
+
]));
|
|
54415
|
+
});
|
|
54416
|
+
}
|
|
54262
54417
|
async requireRun(tx, runId) {
|
|
54263
54418
|
if (await tx.get(`SELECT ${JOURNAL_COLUMNS.runId} FROM ${this.tables.runs} WHERE ${JOURNAL_COLUMNS.runId} = ?`, runId))
|
|
54264
54419
|
return;
|
|
@@ -55656,6 +55811,10 @@ function deriveInputFields(schema) {
|
|
|
55656
55811
|
|
|
55657
55812
|
// dist/builtin/workflows/src/runs/shared/validate-inputs.ts
|
|
55658
55813
|
import { Value as Value2 } from "typebox/value";
|
|
55814
|
+
function firstSchemaError(def, value2, kind) {
|
|
55815
|
+
const first = [...Value2.Errors(def, value2)][0];
|
|
55816
|
+
return first === undefined ? `does not match ${kind} schema` : first.message;
|
|
55817
|
+
}
|
|
55659
55818
|
function validateInputs(schema, inputs) {
|
|
55660
55819
|
const errors = [];
|
|
55661
55820
|
for (const key of Object.keys(inputs)) {
|
|
@@ -55684,12 +55843,16 @@ function validateInputs(schema, inputs) {
|
|
|
55684
55843
|
if (typeof value2 !== "number" || !Number.isFinite(value2)) {
|
|
55685
55844
|
errors.push({ key, reason: `expected finite number, got ${workflowSerializableTypeName(value2)}` });
|
|
55686
55845
|
hasTypeError = true;
|
|
55846
|
+
} else if (!Value2.Check(def, value2)) {
|
|
55847
|
+
errors.push({ key, reason: firstSchemaError(def, value2, kind) });
|
|
55687
55848
|
}
|
|
55688
55849
|
break;
|
|
55689
55850
|
case "integer":
|
|
55690
55851
|
if (typeof value2 !== "number" || !Number.isInteger(value2)) {
|
|
55691
55852
|
errors.push({ key, reason: `expected integer, got ${workflowSerializableTypeName(value2)}` });
|
|
55692
55853
|
hasTypeError = true;
|
|
55854
|
+
} else if (!Value2.Check(def, value2)) {
|
|
55855
|
+
errors.push({ key, reason: firstSchemaError(def, value2, kind) });
|
|
55693
55856
|
}
|
|
55694
55857
|
break;
|
|
55695
55858
|
case "boolean":
|
|
@@ -55860,6 +56023,20 @@ function resolve_budget(layers) {
|
|
|
55860
56023
|
var DEFAULT_WORKFLOW_HEARTBEAT_INTERVAL_MINUTES = 15;
|
|
55861
56024
|
var WORKFLOW_HEARTBEAT_CUSTOM_TYPE = "workflows:workflow-heartbeat";
|
|
55862
56025
|
|
|
56026
|
+
// dist/builtin/workflows/src/shared/workflow-source.ts
|
|
56027
|
+
var WORKFLOW_SOURCES = new WeakMap;
|
|
56028
|
+
var OWN_MODULE_PATH = normalizeStackPath(import.meta.url);
|
|
56029
|
+
function isWorkflowRuntimeModule(path) {
|
|
56030
|
+
const normalized = normalizeStackPath(path);
|
|
56031
|
+
return normalized === OWN_MODULE_PATH || isWorkflowRuntimeFrame(normalized);
|
|
56032
|
+
}
|
|
56033
|
+
function recordWorkflowSource(definition, path) {
|
|
56034
|
+
WORKFLOW_SOURCES.set(definition, path);
|
|
56035
|
+
}
|
|
56036
|
+
function workflowSource(definition) {
|
|
56037
|
+
return WORKFLOW_SOURCES.get(definition);
|
|
56038
|
+
}
|
|
56039
|
+
|
|
55863
56040
|
// dist/builtin/workflows/src/workflows/identity.ts
|
|
55864
56041
|
function normalizeWorkflowName(name) {
|
|
55865
56042
|
if (!name || typeof name !== "string") {
|
|
@@ -55907,8 +56084,10 @@ function isWorkflowAuthoringImplementationFrame(filePath) {
|
|
|
55907
56084
|
return false;
|
|
55908
56085
|
return normalized.includes("/packages/workflows/") || normalized.includes("/dist/builtin/workflows/") || normalized.includes("/.atomic/agent/extensions/workflows/");
|
|
55909
56086
|
}
|
|
55910
|
-
function
|
|
55911
|
-
const
|
|
56087
|
+
function callerSourcePath(entry) {
|
|
56088
|
+
const capture = new Error;
|
|
56089
|
+
Error.captureStackTrace(capture, entry);
|
|
56090
|
+
const stack = capture.stack;
|
|
55912
56091
|
if (stack === undefined)
|
|
55913
56092
|
return;
|
|
55914
56093
|
for (const line of stack.split(`
|
|
@@ -55918,14 +56097,18 @@ function workflowNameFromCaller() {
|
|
|
55918
56097
|
continue;
|
|
55919
56098
|
if (isWorkflowAuthoringImplementationFrame(filePath))
|
|
55920
56099
|
continue;
|
|
55921
|
-
|
|
55922
|
-
if (base.length > 0)
|
|
55923
|
-
return base;
|
|
56100
|
+
return isWorkflowRuntimeModule(filePath) ? undefined : filePath;
|
|
55924
56101
|
}
|
|
55925
56102
|
return;
|
|
55926
56103
|
}
|
|
55927
|
-
function
|
|
55928
|
-
|
|
56104
|
+
function workflowNameFromSourcePath(filePath) {
|
|
56105
|
+
if (filePath === undefined)
|
|
56106
|
+
return;
|
|
56107
|
+
const base = basename(filePath.replace(/\\/g, "/")).replace(/\.[cm]?[jt]sx?$/, "");
|
|
56108
|
+
return base.length > 0 ? base : undefined;
|
|
56109
|
+
}
|
|
56110
|
+
function resolveWorkflowName(name, sourcePath) {
|
|
56111
|
+
const resolved = name ?? workflowNameFromSourcePath(sourcePath);
|
|
55929
56112
|
if (resolved === undefined) {
|
|
55930
56113
|
throw new TypeError("workflow: name must be provided when caller filename cannot be inferred");
|
|
55931
56114
|
}
|
|
@@ -55961,7 +56144,8 @@ function workflow(spec) {
|
|
|
55961
56144
|
throw new TypeError("workflow: heartbeatIntervalMinutes must be a non-negative finite number");
|
|
55962
56145
|
}
|
|
55963
56146
|
assertWorkflowBudget(spec.budget, "workflow: budget");
|
|
55964
|
-
const
|
|
56147
|
+
const source = callerSourcePath(workflow);
|
|
56148
|
+
const name = resolveWorkflowName(spec.name, source);
|
|
55965
56149
|
const normalizedName = normalizeWorkflowName(name);
|
|
55966
56150
|
requireNonEmptyString(normalizedName, "normalized name");
|
|
55967
56151
|
const frozenInputs = freezeSchemaMap(spec.inputs ?? {});
|
|
@@ -55983,6 +56167,8 @@ function workflow(spec) {
|
|
|
55983
56167
|
run
|
|
55984
56168
|
};
|
|
55985
56169
|
const branded = stampWorkflowDefinition(definition);
|
|
56170
|
+
if (source !== undefined)
|
|
56171
|
+
recordWorkflowSource(branded, source);
|
|
55986
56172
|
return Object.freeze(branded);
|
|
55987
56173
|
}
|
|
55988
56174
|
|
|
@@ -60197,7 +60383,12 @@ async function mapParallelSteps(steps, concurrency, failFast, mapper, onFirstFai
|
|
|
60197
60383
|
if (selectedFailure !== undefined)
|
|
60198
60384
|
throw selectedFailure;
|
|
60199
60385
|
}
|
|
60200
|
-
|
|
60386
|
+
const aggregate = new AggregateError(failures.map((failure) => failure.error), `atomic-workflows: ${failures.length} parallel ${failures.length === 1 ? "step" : "steps"} failed`);
|
|
60387
|
+
if (failFastEnabled)
|
|
60388
|
+
throw aggregate;
|
|
60389
|
+
const failedIndexes = new Set(failures.map((failure) => failure.index));
|
|
60390
|
+
const partialResults = Array.from({ length: steps.length }, (_, index) => failedIndexes.has(index) ? undefined : results[index]);
|
|
60391
|
+
throw Object.assign(aggregate, { partialResults });
|
|
60201
60392
|
}
|
|
60202
60393
|
return results;
|
|
60203
60394
|
}
|
|
@@ -61672,13 +61863,24 @@ class ConcurrencyLimiter {
|
|
|
61672
61863
|
get queued() {
|
|
61673
61864
|
return this._queue.length;
|
|
61674
61865
|
}
|
|
61675
|
-
acquire() {
|
|
61866
|
+
acquire(signal) {
|
|
61867
|
+
if (signal?.aborted)
|
|
61868
|
+
return Promise.reject(signal.reason);
|
|
61676
61869
|
if (this._running < this.limit) {
|
|
61677
61870
|
this._running++;
|
|
61678
61871
|
return Promise.resolve();
|
|
61679
61872
|
}
|
|
61680
|
-
return new Promise((resolve) => {
|
|
61681
|
-
|
|
61873
|
+
return new Promise((resolve, reject) => {
|
|
61874
|
+
const grant = () => {
|
|
61875
|
+
signal?.removeEventListener("abort", onAbort);
|
|
61876
|
+
resolve();
|
|
61877
|
+
};
|
|
61878
|
+
const onAbort = () => {
|
|
61879
|
+
this._queue.splice(this._queue.indexOf(grant), 1);
|
|
61880
|
+
reject(signal?.reason);
|
|
61881
|
+
};
|
|
61882
|
+
this._queue.push(grant);
|
|
61883
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
61682
61884
|
});
|
|
61683
61885
|
}
|
|
61684
61886
|
release() {
|
|
@@ -61689,8 +61891,8 @@ class ConcurrencyLimiter {
|
|
|
61689
61891
|
this._running--;
|
|
61690
61892
|
}
|
|
61691
61893
|
}
|
|
61692
|
-
async run(fn) {
|
|
61693
|
-
await this.acquire();
|
|
61894
|
+
async run(fn, signal) {
|
|
61895
|
+
await this.acquire(signal);
|
|
61694
61896
|
try {
|
|
61695
61897
|
return await fn();
|
|
61696
61898
|
} finally {
|
|
@@ -63415,6 +63617,7 @@ function createWorkflowExitManager(input) {
|
|
|
63415
63617
|
...outputSnapshot !== undefined ? { outputSnapshot } : {},
|
|
63416
63618
|
...validationError !== undefined ? { validationError } : {}
|
|
63417
63619
|
}));
|
|
63620
|
+
input.onExitSelected?.(selectedExit);
|
|
63418
63621
|
input.controller.abort(selectedExit);
|
|
63419
63622
|
runWorkflowExitCleanups(reason);
|
|
63420
63623
|
throw selectedExit;
|
|
@@ -64226,14 +64429,40 @@ function createChildWorkflowRunner(input) {
|
|
|
64226
64429
|
}
|
|
64227
64430
|
};
|
|
64228
64431
|
}
|
|
64432
|
+
// dist/builtin/workflows/src/shared/error-with-causes.ts
|
|
64433
|
+
var MAX_CAUSE_DEPTH = 5;
|
|
64434
|
+
function describeErrorWithCauses(error) {
|
|
64435
|
+
const messages = [];
|
|
64436
|
+
const visited = new Set;
|
|
64437
|
+
let current = error;
|
|
64438
|
+
for (let depth = 0;current !== undefined && depth < MAX_CAUSE_DEPTH && !visited.has(current); depth++) {
|
|
64439
|
+
visited.add(current);
|
|
64440
|
+
const message = current instanceof Error ? current.message : String(current);
|
|
64441
|
+
if (!messages.includes(message))
|
|
64442
|
+
messages.push(message);
|
|
64443
|
+
current = current instanceof Error ? current.cause : undefined;
|
|
64444
|
+
}
|
|
64445
|
+
return messages.join(": ");
|
|
64446
|
+
}
|
|
64447
|
+
|
|
64229
64448
|
// dist/builtin/workflows/src/engine/run-durable-finalize.ts
|
|
64230
64449
|
async function finalizeDurableTerminalStatus(input) {
|
|
64450
|
+
try {
|
|
64451
|
+
await commitDurableTerminalStatus(input);
|
|
64452
|
+
} catch (error) {
|
|
64453
|
+
if (input.store !== undefined)
|
|
64454
|
+
recordDurableEndingFailure(input.store, input.runSnapshot, error);
|
|
64455
|
+
throw error;
|
|
64456
|
+
}
|
|
64457
|
+
}
|
|
64458
|
+
async function commitDurableTerminalStatus(input) {
|
|
64231
64459
|
if (!input.isRoot)
|
|
64232
64460
|
return;
|
|
64233
64461
|
const status = effectiveRunStatus(input.runSnapshot);
|
|
64234
64462
|
const isExitTerminal = input.runSnapshot.exited === true && status !== "running";
|
|
64235
64463
|
const isBlocked = status === "blocked" && (input.runSnapshot.endedAt !== undefined || input.runSnapshot.blockedAt !== undefined);
|
|
64236
|
-
|
|
64464
|
+
const isUncommittedCompletion = status === "completed" && input.terminalStatusCommitted === false;
|
|
64465
|
+
if (status !== "failed" && status !== "killed" && !isExitTerminal && !isBlocked && !isUncommittedCompletion)
|
|
64237
64466
|
return;
|
|
64238
64467
|
const durableStatus = toDurableStatus(status);
|
|
64239
64468
|
if (durableStatus !== undefined) {
|
|
@@ -64243,7 +64472,7 @@ async function finalizeDurableTerminalStatus(input) {
|
|
|
64243
64472
|
if (input.runSnapshot.result !== undefined)
|
|
64244
64473
|
throw error;
|
|
64245
64474
|
}
|
|
64246
|
-
if (durableStatus === "failed" || durableStatus === "blocked") {
|
|
64475
|
+
if (durableStatus === "failed" || durableStatus === "blocked" || isUncommittedCompletion) {
|
|
64247
64476
|
await recordRunTimingCheckpointAsync(input.durableBackend, input.runSnapshot);
|
|
64248
64477
|
}
|
|
64249
64478
|
const failure = durableStatus === "failed" ? {
|
|
@@ -64261,6 +64490,16 @@ async function finalizeDurableTerminalStatus(input) {
|
|
|
64261
64490
|
await input.durableBackend.commitWorkflowStatus(input.runId, durableStatus, undefined, input.runSnapshot.resumable, failure);
|
|
64262
64491
|
}
|
|
64263
64492
|
}
|
|
64493
|
+
function recordDurableEndingFailure(store, runSnapshot, error) {
|
|
64494
|
+
const detail = describeErrorWithCauses(error);
|
|
64495
|
+
store.recordNotice({
|
|
64496
|
+
id: `workflow-durable-ending-failed:${runSnapshot.id}`,
|
|
64497
|
+
runId: runSnapshot.id,
|
|
64498
|
+
level: "error",
|
|
64499
|
+
message: `Workflow "${runSnapshot.name}" ended ${runSnapshot.status}, but its final state could not be saved to the workflow journal: ${detail}. Readers of the journal may report it as crashed.`,
|
|
64500
|
+
createdAt: Date.now()
|
|
64501
|
+
});
|
|
64502
|
+
}
|
|
64264
64503
|
function toDurableStatus(status) {
|
|
64265
64504
|
switch (status) {
|
|
64266
64505
|
case "completed":
|
|
@@ -64648,6 +64887,402 @@ function deferStageUntilRunRelease(input) {
|
|
|
64648
64887
|
};
|
|
64649
64888
|
}
|
|
64650
64889
|
|
|
64890
|
+
// dist/builtin/workflows/src/engine/run-rejection-boundary.ts
|
|
64891
|
+
import { AsyncLocalStorage as AsyncLocalStorage3 } from "node:async_hooks";
|
|
64892
|
+
import { inspect } from "node:util";
|
|
64893
|
+
var EVENT = "unhandledRejection";
|
|
64894
|
+
var BOUNDARY_KEY = Symbol.for("atomic-workflows/run-rejection-boundary@5");
|
|
64895
|
+
var FLAG = "--unhandled-rejections";
|
|
64896
|
+
var MAX_CAUSE_DEPTH2 = 8;
|
|
64897
|
+
var MAX_PRIMITIVES_PER_RUN = 64;
|
|
64898
|
+
var MAX_STOP_STRINGS = 64;
|
|
64899
|
+
var ENDED_RUN_GRACE_MS = 30000;
|
|
64900
|
+
var NATIVE_REPORTING_MODES = new Set(["throw", "warn-with-error-code"]);
|
|
64901
|
+
function boundaryBag() {
|
|
64902
|
+
return globalThis;
|
|
64903
|
+
}
|
|
64904
|
+
function sharedBoundary() {
|
|
64905
|
+
const bag = boundaryBag();
|
|
64906
|
+
const existing = bag[BOUNDARY_KEY];
|
|
64907
|
+
if (existing !== undefined && existing.version === 5)
|
|
64908
|
+
return existing;
|
|
64909
|
+
const created = {
|
|
64910
|
+
version: 5,
|
|
64911
|
+
store: new AsyncLocalStorage3,
|
|
64912
|
+
owners: new WeakMap,
|
|
64913
|
+
promises: new WeakMap,
|
|
64914
|
+
scopes: new Set,
|
|
64915
|
+
runs: new Map,
|
|
64916
|
+
ended: new Map,
|
|
64917
|
+
stops: new Set,
|
|
64918
|
+
listener: undefined
|
|
64919
|
+
};
|
|
64920
|
+
bag[BOUNDARY_KEY] = created;
|
|
64921
|
+
return created;
|
|
64922
|
+
}
|
|
64923
|
+
function isObject(value2) {
|
|
64924
|
+
return typeof value2 === "object" && value2 !== null || typeof value2 === "function";
|
|
64925
|
+
}
|
|
64926
|
+
function isPrimitive(value2) {
|
|
64927
|
+
return !isObject(value2);
|
|
64928
|
+
}
|
|
64929
|
+
function safeField3(value2, key) {
|
|
64930
|
+
try {
|
|
64931
|
+
return value2[key];
|
|
64932
|
+
} catch {
|
|
64933
|
+
return;
|
|
64934
|
+
}
|
|
64935
|
+
}
|
|
64936
|
+
function strongerEffect(left, right) {
|
|
64937
|
+
return left === "fail-run" || right === "fail-run" ? "fail-run" : "ignore";
|
|
64938
|
+
}
|
|
64939
|
+
function addAttribution(into, scope, effect) {
|
|
64940
|
+
into.set(scope, strongerEffect(into.get(scope), effect));
|
|
64941
|
+
}
|
|
64942
|
+
function recordedOwners(boundary, reason) {
|
|
64943
|
+
const owners = new Map;
|
|
64944
|
+
let stopped = false;
|
|
64945
|
+
const seen = new Set;
|
|
64946
|
+
const pending = [{ value: reason, depth: 0 }];
|
|
64947
|
+
while (pending.length > 0) {
|
|
64948
|
+
const { value: value2, depth } = pending.pop();
|
|
64949
|
+
if (depth > MAX_CAUSE_DEPTH2)
|
|
64950
|
+
continue;
|
|
64951
|
+
if (isPrimitive(value2)) {
|
|
64952
|
+
if (depth === 0 || value2 !== undefined && value2 !== null) {
|
|
64953
|
+
for (const scope of boundary.scopes) {
|
|
64954
|
+
const entry = scope.primitives.get(value2);
|
|
64955
|
+
if (entry !== undefined)
|
|
64956
|
+
addAttribution(owners, scope, entry.effect);
|
|
64957
|
+
}
|
|
64958
|
+
if (typeof value2 === "string" && boundary.stops.has(value2))
|
|
64959
|
+
stopped = true;
|
|
64960
|
+
}
|
|
64961
|
+
continue;
|
|
64962
|
+
}
|
|
64963
|
+
if (seen.has(value2))
|
|
64964
|
+
continue;
|
|
64965
|
+
seen.add(value2);
|
|
64966
|
+
for (const [scope, effect] of boundary.owners.get(value2) ?? [])
|
|
64967
|
+
addAttribution(owners, scope, effect);
|
|
64968
|
+
pending.push({ value: safeField3(value2, "cause"), depth: depth + 1 });
|
|
64969
|
+
const errors = safeField3(value2, "errors");
|
|
64970
|
+
if (Array.isArray(errors))
|
|
64971
|
+
for (const entry of errors)
|
|
64972
|
+
pending.push({ value: entry, depth: depth + 1 });
|
|
64973
|
+
}
|
|
64974
|
+
return { owners, stopped };
|
|
64975
|
+
}
|
|
64976
|
+
function pruneEndedSources(boundary) {
|
|
64977
|
+
const now = Date.now();
|
|
64978
|
+
for (const [source, trees] of boundary.ended) {
|
|
64979
|
+
for (const [rootRunId, endedAt] of trees)
|
|
64980
|
+
if (now - endedAt > ENDED_RUN_GRACE_MS)
|
|
64981
|
+
trees.delete(rootRunId);
|
|
64982
|
+
if (trees.size === 0)
|
|
64983
|
+
boundary.ended.delete(source);
|
|
64984
|
+
}
|
|
64985
|
+
}
|
|
64986
|
+
function recordEndedRun(boundary, scope) {
|
|
64987
|
+
if (scope.source === undefined)
|
|
64988
|
+
return;
|
|
64989
|
+
const trees = boundary.ended.get(scope.source) ?? new Map;
|
|
64990
|
+
trees.set(scope.rootRunId, Date.now());
|
|
64991
|
+
boundary.ended.set(scope.source, trees);
|
|
64992
|
+
}
|
|
64993
|
+
function endedInAnotherRunTree(boundary, source, live) {
|
|
64994
|
+
for (const endedRoot of boundary.ended.get(source)?.keys() ?? [])
|
|
64995
|
+
if (endedRoot !== live.rootRunId)
|
|
64996
|
+
return true;
|
|
64997
|
+
return false;
|
|
64998
|
+
}
|
|
64999
|
+
function recognizedSources(boundary) {
|
|
65000
|
+
pruneEndedSources(boundary);
|
|
65001
|
+
const sources = new Set(boundary.ended.keys());
|
|
65002
|
+
for (const scope of boundary.scopes)
|
|
65003
|
+
if (scope.live && scope.source !== undefined)
|
|
65004
|
+
sources.add(scope.source);
|
|
65005
|
+
return sources;
|
|
65006
|
+
}
|
|
65007
|
+
function authoringSource(reason, sources) {
|
|
65008
|
+
if (sources.size === 0 || !isObject(reason))
|
|
65009
|
+
return;
|
|
65010
|
+
const stack = safeField3(reason, "stack");
|
|
65011
|
+
if (typeof stack !== "string")
|
|
65012
|
+
return;
|
|
65013
|
+
for (const line of stack.split(`
|
|
65014
|
+
`)) {
|
|
65015
|
+
if (!line.trimStart().startsWith("at "))
|
|
65016
|
+
continue;
|
|
65017
|
+
const path = parsePromptStackFrame(line)?.normalizedPath;
|
|
65018
|
+
if (path === undefined)
|
|
65019
|
+
continue;
|
|
65020
|
+
if (isWorkflowRuntimeModule(path))
|
|
65021
|
+
return;
|
|
65022
|
+
if (/\/node_modules\//.test(path))
|
|
65023
|
+
continue;
|
|
65024
|
+
if (sources.has(path))
|
|
65025
|
+
return path;
|
|
65026
|
+
}
|
|
65027
|
+
return;
|
|
65028
|
+
}
|
|
65029
|
+
function hasAncestorIn(scope, candidates) {
|
|
65030
|
+
for (let ancestor = scope.parent;ancestor !== undefined; ancestor = ancestor.parent) {
|
|
65031
|
+
if (candidates.has(ancestor))
|
|
65032
|
+
return true;
|
|
65033
|
+
}
|
|
65034
|
+
return false;
|
|
65035
|
+
}
|
|
65036
|
+
function outermostLiveRuns(boundary, source) {
|
|
65037
|
+
const matching = new Set;
|
|
65038
|
+
for (const scope of boundary.scopes)
|
|
65039
|
+
if (scope.live && scope.source === source)
|
|
65040
|
+
matching.add(scope);
|
|
65041
|
+
const outermost = new Set;
|
|
65042
|
+
for (const scope of matching)
|
|
65043
|
+
if (!hasAncestorIn(scope, matching))
|
|
65044
|
+
outermost.add(scope);
|
|
65045
|
+
return outermost;
|
|
65046
|
+
}
|
|
65047
|
+
function runOfSource(boundary, source) {
|
|
65048
|
+
const [only, ...others] = outermostLiveRuns(boundary, source);
|
|
65049
|
+
if (only === undefined)
|
|
65050
|
+
return new Map;
|
|
65051
|
+
if (others.length > 0 || only.sharedSource)
|
|
65052
|
+
return;
|
|
65053
|
+
if (endedInAnotherRunTree(boundary, source, only))
|
|
65054
|
+
return;
|
|
65055
|
+
return new Map([[only, "fail-run"]]);
|
|
65056
|
+
}
|
|
65057
|
+
function markSharedSource(boundary, source) {
|
|
65058
|
+
const runs = outermostLiveRuns(boundary, source);
|
|
65059
|
+
if (runs.size > 1)
|
|
65060
|
+
for (const run of runs)
|
|
65061
|
+
run.sharedSource = true;
|
|
65062
|
+
}
|
|
65063
|
+
function rejectingRun(boundary, recorded, promise, scoped) {
|
|
65064
|
+
const tracked = promise === undefined ? undefined : boundary.promises.get(promise);
|
|
65065
|
+
if (tracked !== undefined && recorded.has(tracked))
|
|
65066
|
+
return tracked;
|
|
65067
|
+
if (scoped !== undefined && recorded.has(scoped))
|
|
65068
|
+
return scoped;
|
|
65069
|
+
return;
|
|
65070
|
+
}
|
|
65071
|
+
function attribute(boundary, reason, promise) {
|
|
65072
|
+
const { owners: recorded, stopped } = recordedOwners(boundary, reason);
|
|
65073
|
+
const scoped = boundary.store.getStore();
|
|
65074
|
+
if (recorded.size > 1) {
|
|
65075
|
+
const rejecting = rejectingRun(boundary, recorded, promise, scoped);
|
|
65076
|
+
if (rejecting !== undefined)
|
|
65077
|
+
return new Map([[rejecting, recorded.get(rejecting) ?? "fail-run"]]);
|
|
65078
|
+
}
|
|
65079
|
+
if (recorded.size > 0)
|
|
65080
|
+
return recorded;
|
|
65081
|
+
if (stopped)
|
|
65082
|
+
return new Map;
|
|
65083
|
+
if (scoped !== undefined && boundary.scopes.has(scoped))
|
|
65084
|
+
return new Map([[scoped, "fail-run"]]);
|
|
65085
|
+
const origin = authoringSource(reason, recognizedSources(boundary));
|
|
65086
|
+
if (origin === undefined)
|
|
65087
|
+
return;
|
|
65088
|
+
if (scoped !== undefined)
|
|
65089
|
+
return new Map([[scoped, "ignore"]]);
|
|
65090
|
+
return runOfSource(boundary, origin);
|
|
65091
|
+
}
|
|
65092
|
+
function unhandledRejectionError(reason) {
|
|
65093
|
+
return Object.assign(new Error("This error originated either by throwing inside of an async function without a catch block, " + `or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason "${inspect(reason)}".`), { code: "ERR_UNHANDLED_REJECTION" });
|
|
65094
|
+
}
|
|
65095
|
+
function unhandledRejectionsMode() {
|
|
65096
|
+
const args = [...(process.env.NODE_OPTIONS ?? "").split(/\s+/), ...process.execArgv];
|
|
65097
|
+
let mode = "throw";
|
|
65098
|
+
for (let index = 0;index < args.length; index += 1) {
|
|
65099
|
+
const arg = args[index] ?? "";
|
|
65100
|
+
if (arg.startsWith(`${FLAG}=`))
|
|
65101
|
+
mode = arg.slice(FLAG.length + 1);
|
|
65102
|
+
else if (arg === FLAG && args[index + 1] !== undefined)
|
|
65103
|
+
mode = args[index + 1] ?? mode;
|
|
65104
|
+
}
|
|
65105
|
+
return mode;
|
|
65106
|
+
}
|
|
65107
|
+
function surfaceNatively(boundary, reason) {
|
|
65108
|
+
const listener = boundary.listener;
|
|
65109
|
+
if (listener === undefined || process.listenerCount(EVENT) > 1)
|
|
65110
|
+
return;
|
|
65111
|
+
if (!NATIVE_REPORTING_MODES.has(unhandledRejectionsMode()))
|
|
65112
|
+
return;
|
|
65113
|
+
process.nextTick(() => {
|
|
65114
|
+
process.removeListener(EVENT, listener);
|
|
65115
|
+
Promise.reject(reason);
|
|
65116
|
+
setImmediate(() => {
|
|
65117
|
+
if (!process.listeners(EVENT).includes(listener))
|
|
65118
|
+
process.on(EVENT, listener);
|
|
65119
|
+
});
|
|
65120
|
+
});
|
|
65121
|
+
}
|
|
65122
|
+
function onUnhandledRejection(reason, promise) {
|
|
65123
|
+
const boundary = sharedBoundary();
|
|
65124
|
+
const owners = attribute(boundary, reason, promise);
|
|
65125
|
+
if (owners === undefined) {
|
|
65126
|
+
surfaceNatively(boundary, reason);
|
|
65127
|
+
return;
|
|
65128
|
+
}
|
|
65129
|
+
const error = isObject(reason) ? reason : unhandledRejectionError(reason);
|
|
65130
|
+
for (const [scope, effect] of owners) {
|
|
65131
|
+
if (effect !== "fail-run" || !scope.live)
|
|
65132
|
+
continue;
|
|
65133
|
+
try {
|
|
65134
|
+
scope.fail(error);
|
|
65135
|
+
} catch {}
|
|
65136
|
+
}
|
|
65137
|
+
}
|
|
65138
|
+
function ensureInstalled(boundary) {
|
|
65139
|
+
if (boundary.listener !== undefined)
|
|
65140
|
+
return;
|
|
65141
|
+
boundary.listener = onUnhandledRejection;
|
|
65142
|
+
process.on(EVENT, onUnhandledRejection);
|
|
65143
|
+
}
|
|
65144
|
+
function record(boundary, scope, reason, effect) {
|
|
65145
|
+
if (isPrimitive(reason)) {
|
|
65146
|
+
recordPrimitive(scope, reason, effect);
|
|
65147
|
+
return;
|
|
65148
|
+
}
|
|
65149
|
+
const owners = boundary.owners.get(reason);
|
|
65150
|
+
if (owners === undefined)
|
|
65151
|
+
boundary.owners.set(reason, new Map([[scope, effect]]));
|
|
65152
|
+
else
|
|
65153
|
+
addAttribution(owners, scope, effect);
|
|
65154
|
+
}
|
|
65155
|
+
function recordStop(boundary, reason) {
|
|
65156
|
+
boundary.stops.delete(reason);
|
|
65157
|
+
boundary.stops.add(reason);
|
|
65158
|
+
if (boundary.stops.size <= MAX_STOP_STRINGS)
|
|
65159
|
+
return;
|
|
65160
|
+
const oldest = boundary.stops.values().next();
|
|
65161
|
+
if (!oldest.done)
|
|
65162
|
+
boundary.stops.delete(oldest.value);
|
|
65163
|
+
}
|
|
65164
|
+
function recordPrimitive(scope, reason, effect) {
|
|
65165
|
+
if (!scope.live)
|
|
65166
|
+
return;
|
|
65167
|
+
if (scope.primitives.size >= MAX_PRIMITIVES_PER_RUN && !scope.primitives.has(reason)) {
|
|
65168
|
+
const oldest = scope.primitives.keys().next();
|
|
65169
|
+
if (!oldest.done)
|
|
65170
|
+
scope.primitives.delete(oldest.value);
|
|
65171
|
+
}
|
|
65172
|
+
scope.generation += 1;
|
|
65173
|
+
const generation = scope.generation;
|
|
65174
|
+
scope.primitives.set(reason, { effect: strongerEffect(scope.primitives.get(reason)?.effect, effect), generation });
|
|
65175
|
+
afterPendingRejectionReports().then(() => {
|
|
65176
|
+
if (scope.primitives.get(reason)?.generation === generation)
|
|
65177
|
+
scope.primitives.delete(reason);
|
|
65178
|
+
});
|
|
65179
|
+
}
|
|
65180
|
+
function discardFailure() {}
|
|
65181
|
+
function afterPendingRejectionReports() {
|
|
65182
|
+
return new Promise((resolve) => {
|
|
65183
|
+
const { port1, port2 } = new MessageChannel;
|
|
65184
|
+
port1.onmessage = () => {
|
|
65185
|
+
port1.close();
|
|
65186
|
+
port2.close();
|
|
65187
|
+
resolve();
|
|
65188
|
+
};
|
|
65189
|
+
port2.postMessage(undefined);
|
|
65190
|
+
});
|
|
65191
|
+
}
|
|
65192
|
+
function openRunRejectionScope(options) {
|
|
65193
|
+
const boundary = sharedBoundary();
|
|
65194
|
+
ensureInstalled(boundary);
|
|
65195
|
+
pruneEndedSources(boundary);
|
|
65196
|
+
const parent = options.parentRunId === undefined ? undefined : boundary.runs.get(options.parentRunId);
|
|
65197
|
+
const scope = {
|
|
65198
|
+
runId: options.runId,
|
|
65199
|
+
rootRunId: parent?.rootRunId ?? options.runId,
|
|
65200
|
+
source: options.source === undefined ? undefined : normalizeStackPath(options.source),
|
|
65201
|
+
parent,
|
|
65202
|
+
fail: options.fail,
|
|
65203
|
+
primitives: new Map,
|
|
65204
|
+
generation: 0,
|
|
65205
|
+
live: true,
|
|
65206
|
+
sharedSource: false
|
|
65207
|
+
};
|
|
65208
|
+
boundary.scopes.add(scope);
|
|
65209
|
+
boundary.runs.set(scope.runId, scope);
|
|
65210
|
+
if (scope.source !== undefined)
|
|
65211
|
+
markSharedSource(boundary, scope.source);
|
|
65212
|
+
return {
|
|
65213
|
+
run: (callback) => boundary.store.run(scope, callback),
|
|
65214
|
+
contain: (promise, effect = "fail-run") => {
|
|
65215
|
+
boundary.promises.set(promise, scope);
|
|
65216
|
+
promise.then(undefined, (reason) => record(boundary, scope, reason, effect));
|
|
65217
|
+
return promise;
|
|
65218
|
+
},
|
|
65219
|
+
watch: (promise) => {
|
|
65220
|
+
const watched = promise.then(undefined, (reason) => {
|
|
65221
|
+
record(boundary, scope, reason, "fail-run");
|
|
65222
|
+
throw reason;
|
|
65223
|
+
});
|
|
65224
|
+
boundary.promises.set(watched, scope);
|
|
65225
|
+
return watched;
|
|
65226
|
+
},
|
|
65227
|
+
ignore: (reason) => {
|
|
65228
|
+
if (typeof reason === "string")
|
|
65229
|
+
recordStop(boundary, reason);
|
|
65230
|
+
else
|
|
65231
|
+
record(boundary, scope, reason, "ignore");
|
|
65232
|
+
},
|
|
65233
|
+
settle: afterPendingRejectionReports,
|
|
65234
|
+
close: () => {
|
|
65235
|
+
scope.live = false;
|
|
65236
|
+
scope.fail = discardFailure;
|
|
65237
|
+
recordEndedRun(boundary, scope);
|
|
65238
|
+
afterPendingRejectionReports().then(() => {
|
|
65239
|
+
scope.primitives.clear();
|
|
65240
|
+
scope.parent = undefined;
|
|
65241
|
+
boundary.scopes.delete(scope);
|
|
65242
|
+
if (boundary.runs.get(scope.runId) === scope)
|
|
65243
|
+
boundary.runs.delete(scope.runId);
|
|
65244
|
+
});
|
|
65245
|
+
}
|
|
65246
|
+
};
|
|
65247
|
+
}
|
|
65248
|
+
var WATCHED_STAGE_METHODS = [
|
|
65249
|
+
"prompt",
|
|
65250
|
+
"complete",
|
|
65251
|
+
"sendUserMessage",
|
|
65252
|
+
"steer",
|
|
65253
|
+
"followUp",
|
|
65254
|
+
"setModel",
|
|
65255
|
+
"setThinkingLevel",
|
|
65256
|
+
"cycleModel",
|
|
65257
|
+
"cycleThinkingLevel",
|
|
65258
|
+
"navigateTree",
|
|
65259
|
+
"compact",
|
|
65260
|
+
"abort"
|
|
65261
|
+
];
|
|
65262
|
+
function containStageRejections(stage, scope) {
|
|
65263
|
+
const contained = Object.create(stage);
|
|
65264
|
+
const descriptors = {};
|
|
65265
|
+
for (const name of WATCHED_STAGE_METHODS) {
|
|
65266
|
+
descriptors[name] = {
|
|
65267
|
+
value: (...args) => {
|
|
65268
|
+
const result = Reflect.apply(stage[name], stage, args);
|
|
65269
|
+
return result instanceof Promise ? scope.watch(result) : result;
|
|
65270
|
+
}
|
|
65271
|
+
};
|
|
65272
|
+
}
|
|
65273
|
+
Object.defineProperties(contained, descriptors);
|
|
65274
|
+
return contained;
|
|
65275
|
+
}
|
|
65276
|
+
function containUiRejections(ui, scope) {
|
|
65277
|
+
return {
|
|
65278
|
+
input: (prompt) => scope.watch(ui.input(prompt)),
|
|
65279
|
+
confirm: (message) => scope.watch(ui.confirm(message)),
|
|
65280
|
+
select: (message, options) => scope.watch(ui.select(message, options)),
|
|
65281
|
+
editor: (initial) => scope.watch(ui.editor(initial)),
|
|
65282
|
+
custom: (factory, options) => scope.watch(ui.custom(factory, options))
|
|
65283
|
+
};
|
|
65284
|
+
}
|
|
65285
|
+
|
|
64651
65286
|
// dist/builtin/workflows/src/engine/run-returned-status.ts
|
|
64652
65287
|
function classifyReturnedRunStatus(result, runSnapshot) {
|
|
64653
65288
|
const structuredFailure = runSnapshot !== undefined ? structuredRecoverableWorkflowFailure(runSnapshot) : undefined;
|
|
@@ -66638,7 +67273,9 @@ import { createStructuredOutputCapture, runCallback as runCallback2 } from "@bas
|
|
|
66638
67273
|
import {
|
|
66639
67274
|
AutoRoutingInferenceError,
|
|
66640
67275
|
convertToLlm,
|
|
67276
|
+
isExtensionStartupFailure,
|
|
66641
67277
|
isModelRoutingDebugEnabled,
|
|
67278
|
+
isTransientExtensionStartupFailure,
|
|
66642
67279
|
parseModelConstraints,
|
|
66643
67280
|
setsProviders
|
|
66644
67281
|
} from "@bastani/atomic";
|
|
@@ -66909,6 +67546,23 @@ class StageDeliveryActivity {
|
|
|
66909
67546
|
}
|
|
66910
67547
|
}
|
|
66911
67548
|
|
|
67549
|
+
// dist/builtin/workflows/src/runs/foreground/stage-routing.ts
|
|
67550
|
+
var STAGE_ROUTING_CONCURRENCY = 8;
|
|
67551
|
+
var STAGE_ROUTING_DEADLINE_MS = 300000;
|
|
67552
|
+
var routingLimiter = new ConcurrencyLimiter(STAGE_ROUTING_CONCURRENCY);
|
|
67553
|
+
async function routeStageModel(route, input) {
|
|
67554
|
+
const deadline = new AbortController;
|
|
67555
|
+
const timer = setTimeout(() => deadline.abort(new Error("stage routing deadline")), STAGE_ROUTING_DEADLINE_MS);
|
|
67556
|
+
try {
|
|
67557
|
+
return await route({
|
|
67558
|
+
...input,
|
|
67559
|
+
inference: { deadline: deadline.signal, limit: (run, signal) => routingLimiter.run(run, signal) }
|
|
67560
|
+
});
|
|
67561
|
+
} finally {
|
|
67562
|
+
clearTimeout(timer);
|
|
67563
|
+
}
|
|
67564
|
+
}
|
|
67565
|
+
|
|
66912
67566
|
// dist/builtin/workflows/src/runs/foreground/stage-runner-artifact-capture.ts
|
|
66913
67567
|
class StageArtifactCapture {
|
|
66914
67568
|
session;
|
|
@@ -67399,6 +68053,7 @@ async function stripWorkflowOnlyOptions(options, defaultSessionDir, meta, pendin
|
|
|
67399
68053
|
}
|
|
67400
68054
|
const {
|
|
67401
68055
|
schema: _schema,
|
|
68056
|
+
schemaTimeoutMs: _schemaTimeoutMs,
|
|
67402
68057
|
mcp: _mcp,
|
|
67403
68058
|
fallbackModels,
|
|
67404
68059
|
modelConstraints: _modelConstraints,
|
|
@@ -67732,6 +68387,15 @@ class StageSessionReplacement {
|
|
|
67732
68387
|
this.previous = undefined;
|
|
67733
68388
|
await Promise.allSettled([...previous ? [disposeStageSession(previous)] : [], ...this.cleanups]);
|
|
67734
68389
|
}
|
|
68390
|
+
async disposeRetired() {
|
|
68391
|
+
const previous = this.previous;
|
|
68392
|
+
this.previous = undefined;
|
|
68393
|
+
if (!previous)
|
|
68394
|
+
return;
|
|
68395
|
+
await disposeStageSession(previous).catch((error) => {
|
|
68396
|
+
console.error("atomic-workflows: retired stage session disposal failed", error);
|
|
68397
|
+
});
|
|
68398
|
+
}
|
|
67735
68399
|
async disposeAfterIdle(session) {
|
|
67736
68400
|
const agent = session.agent;
|
|
67737
68401
|
if (typeof agent?.waitForIdle === "function")
|
|
@@ -67895,7 +68559,7 @@ function isWorkflowStructuredOutputContractError(error) {
|
|
|
67895
68559
|
return error instanceof Error && "code" in error && error.code === "ATOMIC_WORKFLOW_STRUCTURED_OUTPUT_CONTRACT";
|
|
67896
68560
|
}
|
|
67897
68561
|
function isStructuredOutputContractFailure(message) {
|
|
67898
|
-
return message.startsWith(STRUCTURED_OUTPUT_MISSING_ERROR) || message.startsWith('Validation failed for tool "structured_output":') || message.startsWith("Invalid structured output: response does not match the decision schema.") || message.startsWith("Invalid structured output: non-JSON decision.") || message.startsWith("Structured output requires one structured_output call.") || message.startsWith("Structured output requires exactly one structured_output call and no provider fallback.") || message === "Structured output requires complete judgment instructions." || message === "Structured output requires a nonempty named state object containing the task and relevant context text." || message === "Structured output inputs must be finite, acyclic JSON data." || message === "Structured output inputs must be plain JSON objects." || message === "structured_output tool call failed schema validation.";
|
|
68562
|
+
return message.startsWith(STRUCTURED_OUTPUT_MISSING_ERROR) || message.startsWith('Validation failed for tool "structured_output":') || message.startsWith("Invalid structured output: response does not match the decision schema.") || message.startsWith("Invalid structured output: non-JSON decision.") || message.startsWith("Invalid structured output: tool call arguments were not valid JSON.") || message.startsWith("Structured output requires one structured_output call.") || message.startsWith("Structured output requires exactly one structured_output call and no provider fallback.") || message === "Structured output requires complete judgment instructions." || message === "Structured output requires a nonempty named state object containing the task and relevant context text." || message === "Structured output inputs must be finite, acyclic JSON data." || message === "Structured output inputs must be plain JSON objects." || message === "structured_output tool call failed schema validation.";
|
|
67899
68563
|
}
|
|
67900
68564
|
var STRUCTURED_OUTPUT_TOOL_NAME = "structured_output";
|
|
67901
68565
|
function toolResultText(content) {
|
|
@@ -67947,7 +68611,8 @@ function stageOptionsWithStructuredOutput(options, capture, executionCapture) {
|
|
|
67947
68611
|
return options;
|
|
67948
68612
|
const structuredOutputTool = createStructuredOutputTool({
|
|
67949
68613
|
schema: options.schema,
|
|
67950
|
-
capture
|
|
68614
|
+
capture,
|
|
68615
|
+
...options.schemaTimeoutMs === undefined ? {} : { timeoutMs: options.schemaTimeoutMs }
|
|
67951
68616
|
});
|
|
67952
68617
|
const executeStructuredOutput = structuredOutputTool.execute;
|
|
67953
68618
|
const capturedStructuredOutputTool = {
|
|
@@ -68037,6 +68702,16 @@ function waitForStageStartup(operation, signal) {
|
|
|
68037
68702
|
// dist/builtin/workflows/src/runs/foreground/stage-runner-controller.ts
|
|
68038
68703
|
var WORKFLOW_STAGE_CLOSED_FOR_GOOD_STATE = "atomic:workflow-stage-closed-for-good";
|
|
68039
68704
|
var WORKFLOW_STAGE_END_CHILDREN_STATE = "atomic:workflow-stage-end-children";
|
|
68705
|
+
function isRetryableSameCandidateFailure(error) {
|
|
68706
|
+
if (isExtensionStartupFailure(error))
|
|
68707
|
+
return isTransientExtensionStartupFailure(error);
|
|
68708
|
+
return isRetryableSameModelFailure(error);
|
|
68709
|
+
}
|
|
68710
|
+
function mayAdvanceToNextCandidate(error) {
|
|
68711
|
+
if (isExtensionStartupFailure(error))
|
|
68712
|
+
return isTransientExtensionStartupFailure(error);
|
|
68713
|
+
return isRetryableModelFailure(error);
|
|
68714
|
+
}
|
|
68040
68715
|
function hasMeaningfulUsage(usage) {
|
|
68041
68716
|
if (usage === undefined)
|
|
68042
68717
|
return false;
|
|
@@ -68288,7 +68963,7 @@ class StageSessionController {
|
|
|
68288
68963
|
return;
|
|
68289
68964
|
if (!this.routingPromise) {
|
|
68290
68965
|
this.beginStartup();
|
|
68291
|
-
|
|
68966
|
+
const routing = (async () => {
|
|
68292
68967
|
const route = this.modelCatalog?.routeModel;
|
|
68293
68968
|
if (!route)
|
|
68294
68969
|
throw new Error("Workflow stage auto routing requires a routing-capable model catalog.");
|
|
@@ -68300,7 +68975,7 @@ class StageSessionController {
|
|
|
68300
68975
|
...thinking === undefined ? [] : [{ allowedEfforts: [thinking] }]
|
|
68301
68976
|
].filter((c) => c !== undefined);
|
|
68302
68977
|
try {
|
|
68303
|
-
this.modelRoute = await route
|
|
68978
|
+
this.modelRoute = await routeStageModel(route, {
|
|
68304
68979
|
task: text,
|
|
68305
68980
|
stageName: this.opts.stageName,
|
|
68306
68981
|
constraints,
|
|
@@ -68321,7 +68996,17 @@ class StageSessionController {
|
|
|
68321
68996
|
this.modelRoute.assertCurrent();
|
|
68322
68997
|
this.meta.stageOptions = { ...options, model: this.modelRoute.modelOverride };
|
|
68323
68998
|
this.opts.onModelFallbackMetaChange?.(this.currentModelFallbackMeta());
|
|
68324
|
-
})()
|
|
68999
|
+
})().catch((error) => {
|
|
69000
|
+
if (this.routingPromise === routing) {
|
|
69001
|
+
this.routingPromise = undefined;
|
|
69002
|
+
this.modelRoute = undefined;
|
|
69003
|
+
}
|
|
69004
|
+
if (this.startupWait.signal.aborted || this.opts.signal?.aborted)
|
|
69005
|
+
throw error;
|
|
69006
|
+
this.settleStartup(true);
|
|
69007
|
+
throw new Error(`atomic-workflows: stage "${this.opts.stageName}" failed during startup phase model-resolution: ${errorMessage3(error)}`);
|
|
69008
|
+
});
|
|
69009
|
+
this.routingPromise = routing;
|
|
68325
69010
|
}
|
|
68326
69011
|
await this.routingPromise;
|
|
68327
69012
|
}
|
|
@@ -69076,7 +69761,7 @@ class StageSessionController {
|
|
|
69076
69761
|
const errorSettingsManager = retrySettingsManagerFromError(error);
|
|
69077
69762
|
if (errorSettingsManager !== undefined)
|
|
69078
69763
|
this.sessionSettingsManager = errorSettingsManager;
|
|
69079
|
-
const decision = isWorkflowPendingStageDeliveryFailure(error) ? undefined : nextRetryDecision(this.retrySettings(), retryAttempt,
|
|
69764
|
+
const decision = isWorkflowPendingStageDeliveryFailure(error) ? undefined : nextRetryDecision(this.retrySettings(), retryAttempt, isRetryableSameCandidateFailure(error));
|
|
69080
69765
|
if (decision === undefined || this.disposed || this.opts.signal?.aborted === true || this.startupWait.signal.aborted || this.capturedStructuredOutputForAttempt()) {
|
|
69081
69766
|
throw error;
|
|
69082
69767
|
}
|
|
@@ -69488,10 +70173,11 @@ class StageSessionController {
|
|
|
69488
70173
|
...usage === undefined ? {} : { usage },
|
|
69489
70174
|
error: message
|
|
69490
70175
|
});
|
|
69491
|
-
if (this.opts.signal?.aborted || this.startupWait.signal.aborted || terminalStageDelivery || !
|
|
70176
|
+
if (this.opts.signal?.aborted || this.startupWait.signal.aborted || terminalStageDelivery || !mayAdvanceToNextCandidate(err) || index === candidates.length - 1) {
|
|
69492
70177
|
this.modelWarnings.push(...this.pendingFallbackWarnings);
|
|
69493
70178
|
this.pendingFallbackWarnings.length = 0;
|
|
69494
70179
|
this.notifyModelFallbackMetaChange();
|
|
70180
|
+
await this.replacement.disposeRetired();
|
|
69495
70181
|
return "throw";
|
|
69496
70182
|
}
|
|
69497
70183
|
const nextCandidate = candidates[index + 1];
|
|
@@ -70613,13 +71299,13 @@ class EngineRuntime {
|
|
|
70613
71299
|
|
|
70614
71300
|
// dist/builtin/workflows/src/engine/session-closed-error.ts
|
|
70615
71301
|
import { isStaleExtensionContextError as isStaleExtensionContextError5 } from "@bastani/atomic";
|
|
70616
|
-
var
|
|
71302
|
+
var MAX_CAUSE_DEPTH3 = 8;
|
|
70617
71303
|
function reportsClosedSession(error) {
|
|
70618
71304
|
return "code" in error && error.code === "SessionClosed" || isStaleExtensionContextError5(error);
|
|
70619
71305
|
}
|
|
70620
71306
|
function isSessionClosedError(error) {
|
|
70621
71307
|
let current = error;
|
|
70622
|
-
for (let depth = 0;depth <
|
|
71308
|
+
for (let depth = 0;depth < MAX_CAUSE_DEPTH3 && current !== undefined; depth++) {
|
|
70623
71309
|
try {
|
|
70624
71310
|
if (reportsClosedSession(current))
|
|
70625
71311
|
return true;
|
|
@@ -70691,7 +71377,12 @@ async function executeRun(def, resolvedInputs, opts) {
|
|
|
70691
71377
|
workflowObservationRuntime(activeStore).control(runId, "kill");
|
|
70692
71378
|
ownController.abort(callerSignal?.reason);
|
|
70693
71379
|
};
|
|
70694
|
-
const exit = createWorkflowExitManager({
|
|
71380
|
+
const exit = createWorkflowExitManager({
|
|
71381
|
+
runId,
|
|
71382
|
+
exitScope,
|
|
71383
|
+
controller: ownController,
|
|
71384
|
+
onExitSelected: (signal) => rejectionScope.ignore(signal)
|
|
71385
|
+
});
|
|
70695
71386
|
const sourceBackend = opts.durableBackend;
|
|
70696
71387
|
const backendView = sourceBackend;
|
|
70697
71388
|
const rootBackend = opts.durableRootBackend ?? backendView;
|
|
@@ -71205,6 +71896,22 @@ async function executeRun(def, resolvedInputs, opts) {
|
|
|
71205
71896
|
baseFromPromptNodes: getPromptNodeUi
|
|
71206
71897
|
});
|
|
71207
71898
|
let pausedExit;
|
|
71899
|
+
const authoredIn = workflowSource(def);
|
|
71900
|
+
const rejectionScope = openRunRejectionScope({
|
|
71901
|
+
runId,
|
|
71902
|
+
...opts.parentRun !== undefined ? { parentRunId: opts.parentRun.runId } : {},
|
|
71903
|
+
...authoredIn !== undefined ? { source: authoredIn } : {},
|
|
71904
|
+
fail: (error) => {
|
|
71905
|
+
if (findWorkflowGracefulQuit(error) !== undefined)
|
|
71906
|
+
return;
|
|
71907
|
+
const selected = terminalEvents.selectFailure(error);
|
|
71908
|
+
if (selected.kind === "failure" && !ownController.signal.aborted)
|
|
71909
|
+
ownController.abort(selected.error);
|
|
71910
|
+
}
|
|
71911
|
+
});
|
|
71912
|
+
ownController.signal.addEventListener("abort", () => rejectionScope.ignore(ownController.signal.reason), {
|
|
71913
|
+
once: true
|
|
71914
|
+
});
|
|
71208
71915
|
const ctx = {
|
|
71209
71916
|
inputs: resolvedInputs,
|
|
71210
71917
|
runId,
|
|
@@ -71215,28 +71922,30 @@ async function executeRun(def, resolvedInputs, opts) {
|
|
|
71215
71922
|
if (scheduler.isRunPaused()) {
|
|
71216
71923
|
pausedExit ??= whenRunning(async () => exit.exit(options));
|
|
71217
71924
|
pausedExit.catch(() => {});
|
|
71218
|
-
|
|
71925
|
+
const waiting = new Error("Workflow exit is waiting for explicit resume");
|
|
71926
|
+
rejectionScope.ignore(waiting);
|
|
71927
|
+
throw waiting;
|
|
71219
71928
|
}
|
|
71220
71929
|
return exit.exit(options);
|
|
71221
71930
|
},
|
|
71222
|
-
ui,
|
|
71931
|
+
ui: containUiRejections(ui, rejectionScope),
|
|
71223
71932
|
stage: (name, options) => {
|
|
71224
71933
|
ownController.signal.throwIfAborted();
|
|
71225
71934
|
if (!scheduler.isRunPaused())
|
|
71226
|
-
return durableStage(name, options);
|
|
71935
|
+
return containStageRejections(durableStage(name, options), rejectionScope);
|
|
71227
71936
|
const replayKey = stageReplayKeyGenerator(name);
|
|
71228
|
-
return deferStageUntilRunRelease({
|
|
71937
|
+
return containStageRejections(deferStageUntilRunRelease({
|
|
71229
71938
|
name,
|
|
71230
71939
|
create: () => durableStage(name, options, replayKey),
|
|
71231
71940
|
isPaused: scheduler.isRunPaused,
|
|
71232
71941
|
waitForRelease: waitForRunRelease,
|
|
71233
71942
|
signal: ownController.signal
|
|
71234
|
-
});
|
|
71943
|
+
}), rejectionScope);
|
|
71235
71944
|
},
|
|
71236
|
-
task: gatedTask,
|
|
71237
|
-
chain: (...args) => whenRunning(() => chain(...args)),
|
|
71238
|
-
parallel: (...args) => whenRunning(() => parallel(...args)),
|
|
71239
|
-
workflow: (...args) => whenRunning(() => {
|
|
71945
|
+
task: (...args) => rejectionScope.watch(gatedTask(...args)),
|
|
71946
|
+
chain: (...args) => rejectionScope.watch(whenRunning(() => chain(...args))),
|
|
71947
|
+
parallel: (...args) => rejectionScope.watch(whenRunning(() => parallel(...args))),
|
|
71948
|
+
workflow: (...args) => rejectionScope.watch(whenRunning(() => {
|
|
71240
71949
|
const pending = durableWorkflow(...args);
|
|
71241
71950
|
pendingChildWorkflows.add(pending);
|
|
71242
71951
|
const settled = () => {
|
|
@@ -71244,18 +71953,17 @@ async function executeRun(def, resolvedInputs, opts) {
|
|
|
71244
71953
|
};
|
|
71245
71954
|
pending.then(settled, settled);
|
|
71246
71955
|
return pending;
|
|
71247
|
-
}),
|
|
71956
|
+
})),
|
|
71248
71957
|
tool: (...args) => {
|
|
71249
71958
|
if (admittedTools.closed)
|
|
71250
|
-
return tool(...args);
|
|
71251
|
-
|
|
71252
|
-
pending.catch(() => {});
|
|
71253
|
-
return pending;
|
|
71959
|
+
return rejectionScope.contain(tool(...args), "ignore");
|
|
71960
|
+
return rejectionScope.contain(whenRunning(() => tool(...args)));
|
|
71254
71961
|
},
|
|
71255
71962
|
...opts.models !== undefined ? { models: opts.models } : {}
|
|
71256
71963
|
};
|
|
71257
71964
|
const runtimeSettled = Promise.withResolvers();
|
|
71258
71965
|
let durableRootAdmitted = false;
|
|
71966
|
+
let terminalStatusCommitted = false;
|
|
71259
71967
|
let pausePersistence;
|
|
71260
71968
|
let resumePersistence;
|
|
71261
71969
|
let controlSettlements = Promise.resolve();
|
|
@@ -71401,7 +72109,7 @@ async function executeRun(def, resolvedInputs, opts) {
|
|
|
71401
72109
|
while (scheduler.isRunPaused())
|
|
71402
72110
|
await waitForRunRelease();
|
|
71403
72111
|
ownController.signal.throwIfAborted();
|
|
71404
|
-
const rawResult = await raceAbort(runWorkflowDefinitionCallback(def.name, runId, () => def.run(ctx)), ownController.signal);
|
|
72112
|
+
const rawResult = await raceAbort(runWorkflowDefinitionCallback(def.name, runId, () => rejectionScope.run(() => def.run(ctx))), ownController.signal);
|
|
71405
72113
|
await drainCachedStagePersistence();
|
|
71406
72114
|
while (scheduler.isRunPaused())
|
|
71407
72115
|
await waitForRunRelease();
|
|
@@ -71411,6 +72119,7 @@ async function executeRun(def, resolvedInputs, opts) {
|
|
|
71411
72119
|
if (pausedExit !== undefined)
|
|
71412
72120
|
await pausedExit;
|
|
71413
72121
|
budget.rethrowIfSystemOwnedStop(runSnapshot.stages.at(-1)?.name ?? startupFrontierStage);
|
|
72122
|
+
await rejectionScope.settle();
|
|
71414
72123
|
const normalTerminalEvent = terminalEvents.winner();
|
|
71415
72124
|
if (normalTerminalEvent?.kind === "cancellation") {
|
|
71416
72125
|
const gracefulQuit = findWorkflowGracefulQuit(normalTerminalEvent.reason);
|
|
@@ -71445,6 +72154,7 @@ async function executeRun(def, resolvedInputs, opts) {
|
|
|
71445
72154
|
await recordRunResultCheckpointAsync(durableBackend, runSnapshot);
|
|
71446
72155
|
}
|
|
71447
72156
|
await durableBackend.commitWorkflowStatus(runId, returned.status, undefined, returned.metadata?.resumable);
|
|
72157
|
+
terminalStatusCommitted = true;
|
|
71448
72158
|
await appendRunEndWhenRecorded(opts.persistence, recorded, {
|
|
71449
72159
|
runId,
|
|
71450
72160
|
status: returned.status,
|
|
@@ -71479,6 +72189,9 @@ async function executeRun(def, resolvedInputs, opts) {
|
|
|
71479
72189
|
}
|
|
71480
72190
|
if (ownerClosing && err instanceof Error && isSessionClosedError(err))
|
|
71481
72191
|
return await suspendForClosedSession(err);
|
|
72192
|
+
if (selectedTerminalEvent.kind === "failure" && pendingChildWorkflows.size > 0 && !ownController.signal.aborted) {
|
|
72193
|
+
ownController.abort(err);
|
|
72194
|
+
}
|
|
71482
72195
|
await admittedTools.closeAndDrain();
|
|
71483
72196
|
if (ownController.signal.aborted)
|
|
71484
72197
|
await Promise.allSettled([...pendingChildWorkflows]);
|
|
@@ -71553,6 +72266,7 @@ async function executeRun(def, resolvedInputs, opts) {
|
|
|
71553
72266
|
});
|
|
71554
72267
|
return failed;
|
|
71555
72268
|
} finally {
|
|
72269
|
+
rejectionScope.close();
|
|
71556
72270
|
callerSignal?.removeEventListener("abort", onCallerAbort);
|
|
71557
72271
|
workflowObservationRuntime(activeStore).finishRun(runId);
|
|
71558
72272
|
runtimeSettled.resolve();
|
|
@@ -71566,7 +72280,9 @@ async function executeRun(def, resolvedInputs, opts) {
|
|
|
71566
72280
|
runId,
|
|
71567
72281
|
runSnapshot,
|
|
71568
72282
|
isRoot: opts.parentRun === undefined,
|
|
71569
|
-
durableBackend
|
|
72283
|
+
durableBackend,
|
|
72284
|
+
terminalStatusCommitted,
|
|
72285
|
+
store: activeStore
|
|
71570
72286
|
});
|
|
71571
72287
|
}
|
|
71572
72288
|
} finally {
|
|
@@ -71645,11 +72361,17 @@ function runDetached(def, inputs, opts = {}) {
|
|
|
71645
72361
|
opts.onWorkflowStartReady?.();
|
|
71646
72362
|
}
|
|
71647
72363
|
};
|
|
71648
|
-
|
|
71649
|
-
const
|
|
71650
|
-
|
|
71651
|
-
|
|
71652
|
-
|
|
72364
|
+
const jobSettled = Promise.withResolvers();
|
|
72365
|
+
const jobOutcome = Promise.withResolvers();
|
|
72366
|
+
jobOutcome.promise.catch(() => {});
|
|
72367
|
+
const settleJob = (failure) => {
|
|
72368
|
+
jobSettled.resolve();
|
|
72369
|
+
if (failure === undefined)
|
|
72370
|
+
jobOutcome.resolve();
|
|
72371
|
+
else
|
|
72372
|
+
jobOutcome.reject(failure.error);
|
|
72373
|
+
};
|
|
72374
|
+
const jobEntry = { runId, controller, promise: jobSettled.promise, outcome: jobOutcome.promise };
|
|
71653
72375
|
try {
|
|
71654
72376
|
opts.startupSignal?.addEventListener("abort", cancelStartup, { once: true });
|
|
71655
72377
|
registry.register(runId, controller);
|
|
@@ -71697,6 +72419,7 @@ function runDetached(def, inputs, opts = {}) {
|
|
|
71697
72419
|
throw error;
|
|
71698
72420
|
}
|
|
71699
72421
|
const settle = async (...args) => {
|
|
72422
|
+
const [ok, , error] = args;
|
|
71700
72423
|
try {
|
|
71701
72424
|
if (!observed)
|
|
71702
72425
|
await observe(...args);
|
|
@@ -71704,7 +72427,7 @@ function runDetached(def, inputs, opts = {}) {
|
|
|
71704
72427
|
detachStartup();
|
|
71705
72428
|
registry.unregister(runId, controller);
|
|
71706
72429
|
tracker.unregister(runId, jobEntry);
|
|
71707
|
-
settleJob();
|
|
72430
|
+
settleJob(ok ? undefined : { error });
|
|
71708
72431
|
}
|
|
71709
72432
|
};
|
|
71710
72433
|
backgroundPromise.then((result) => {
|
|
@@ -72658,11 +73381,17 @@ function runSnapshotsFromCheckpoints(checkpoints, rootRunId, rootRunName, fallba
|
|
|
72658
73381
|
retainReachableRunGroups(grouped, rootRunId);
|
|
72659
73382
|
if (policy.failOnUnreachable && grouped.size !== groupedCount)
|
|
72660
73383
|
return [];
|
|
72661
|
-
if (!validateRunGroups(grouped, rootRunId, toolCheckpoints, checkpoints))
|
|
73384
|
+
if (!validateRunGroups(grouped, rootRunId, toolCheckpoints, checkpoints, policy.retainActive))
|
|
72662
73385
|
return [];
|
|
72663
73386
|
const syntheticChildren = [];
|
|
73387
|
+
const pendingChildren = [];
|
|
72664
73388
|
for (const [parentRunId, runDrafts] of grouped) {
|
|
72665
73389
|
for (const draft of runDrafts) {
|
|
73390
|
+
const pendingChildRunId = childRunIdFromDraft(draft);
|
|
73391
|
+
if (policy.retainActive && pendingChildRunId !== undefined && !grouped.has(pendingChildRunId) && isPendingChildBoundary(draft, parentRunId, pendingChildRunId, rootRunId)) {
|
|
73392
|
+
pendingChildren.push({ parentRunId, owner: draft });
|
|
73393
|
+
continue;
|
|
73394
|
+
}
|
|
72666
73395
|
const child = workflowChildFromDraft(draft);
|
|
72667
73396
|
if (child?.exited !== true || grouped.has(child.runId))
|
|
72668
73397
|
continue;
|
|
@@ -72771,6 +73500,28 @@ function runSnapshotsFromCheckpoints(checkpoints, rootRunId, rootRunName, fallba
|
|
|
72771
73500
|
resumable: false
|
|
72772
73501
|
});
|
|
72773
73502
|
}
|
|
73503
|
+
for (const { parentRunId, owner } of pendingChildren) {
|
|
73504
|
+
if (!emittedRunIds.has(parentRunId))
|
|
73505
|
+
return [];
|
|
73506
|
+
const topology = owner.topology;
|
|
73507
|
+
const boundary = topology.boundary;
|
|
73508
|
+
const parentStageId = idMaps.get(parentRunId)?.get(topology.stageId);
|
|
73509
|
+
if (parentStageId === undefined)
|
|
73510
|
+
return [];
|
|
73511
|
+
runs.push({
|
|
73512
|
+
id: boundary.child.runId,
|
|
73513
|
+
name: boundary.child.runName,
|
|
73514
|
+
inputs: {},
|
|
73515
|
+
status: "running",
|
|
73516
|
+
stages: [],
|
|
73517
|
+
toolNodes: [],
|
|
73518
|
+
startedAt: owner.startedAt ?? owner.firstCompletedAt,
|
|
73519
|
+
parentRunId,
|
|
73520
|
+
parentStageId,
|
|
73521
|
+
rootRunId: boundary.child.rootRunId,
|
|
73522
|
+
resumable: false
|
|
73523
|
+
});
|
|
73524
|
+
}
|
|
72774
73525
|
return runs;
|
|
72775
73526
|
}
|
|
72776
73527
|
function stageSnapshotFromDraft(draft, id, parentIds) {
|
|
@@ -73285,6 +74036,43 @@ function isDormantMessageEvent(value2) {
|
|
|
73285
74036
|
// dist/builtin/workflows/src/extension/extension-lifecycle.ts
|
|
73286
74037
|
import { registerExtensionContextRetirementEffect, sessionScopedExtensionState as sessionScopedExtensionState2 } from "@bastani/atomic";
|
|
73287
74038
|
|
|
74039
|
+
// dist/builtin/workflows/src/runs/background/ended-run-settlement.ts
|
|
74040
|
+
var ENDED_RUN_SETTLEMENT_TIMEOUT_MS = 1e4;
|
|
74041
|
+
function awaitJobSettlement(job) {
|
|
74042
|
+
return job.outcome ?? job.promise;
|
|
74043
|
+
}
|
|
74044
|
+
async function settleEndedRuns(opts) {
|
|
74045
|
+
const timeoutMs = opts.timeoutMs ?? ENDED_RUN_SETTLEMENT_TIMEOUT_MS;
|
|
74046
|
+
const ending = topLevelWorkflowRuns(opts.store.runs()).flatMap((run) => {
|
|
74047
|
+
const job = run.endedAt === undefined ? undefined : opts.jobs.get(run.id);
|
|
74048
|
+
return job === undefined ? [] : [{ runId: run.id, job }];
|
|
74049
|
+
});
|
|
74050
|
+
if (ending.length === 0)
|
|
74051
|
+
return [];
|
|
74052
|
+
const deadline = Promise.withResolvers();
|
|
74053
|
+
const timer = setTimeout(deadline.resolve, timeoutMs);
|
|
74054
|
+
timer.unref?.();
|
|
74055
|
+
try {
|
|
74056
|
+
const settled = await Promise.all(ending.map(({ runId, job }) => Promise.race([
|
|
74057
|
+
awaitJobSettlement(job).then(() => {
|
|
74058
|
+
return;
|
|
74059
|
+
}, (error) => ({
|
|
74060
|
+
runId,
|
|
74061
|
+
reason: "failed",
|
|
74062
|
+
message: describeErrorWithCauses(error)
|
|
74063
|
+
})),
|
|
74064
|
+
deadline.promise.then(() => ({
|
|
74065
|
+
runId,
|
|
74066
|
+
reason: "timed_out",
|
|
74067
|
+
message: `still recording its ending after ${timeoutMs} ms`
|
|
74068
|
+
}))
|
|
74069
|
+
])));
|
|
74070
|
+
return settled.filter((failure) => failure !== undefined);
|
|
74071
|
+
} finally {
|
|
74072
|
+
clearTimeout(timer);
|
|
74073
|
+
}
|
|
74074
|
+
}
|
|
74075
|
+
|
|
73288
74076
|
// dist/builtin/workflows/src/runs/background/workflow-lifecycle-aggregate.ts
|
|
73289
74077
|
function expandedControlRunIds(store, runId) {
|
|
73290
74078
|
const graph = expandWorkflowGraph(readGraphStoreSnapshot(store), runId);
|
|
@@ -76545,6 +77333,13 @@ function registerWorkflowLifecycleHandlers(pi, deps) {
|
|
|
76545
77333
|
if (failures.length > 0)
|
|
76546
77334
|
throw new Error(failures.map((result) => `${result.runId}: ${result.reason}${"message" in result ? ` (${result.message})` : ""}`).join("; "));
|
|
76547
77335
|
},
|
|
77336
|
+
async () => {
|
|
77337
|
+
if (boundary !== "quit")
|
|
77338
|
+
return;
|
|
77339
|
+
const failures = await settleEndedRuns({ store, jobs });
|
|
77340
|
+
if (failures.length > 0)
|
|
77341
|
+
throw new Error(failures.map((failure) => `${failure.runId}: ended but its ending was not recorded (${failure.message})`).join("; "));
|
|
77342
|
+
},
|
|
76548
77343
|
() => stageControlRegistry.clear()
|
|
76549
77344
|
]);
|
|
76550
77345
|
lifetime.generations.add(quitAndCheckpointRuns);
|
|
@@ -83295,6 +84090,7 @@ import { join as join28 } from "node:path";
|
|
|
83295
84090
|
import {
|
|
83296
84091
|
isStaleExtensionContextError as isStaleExtensionContextError6,
|
|
83297
84092
|
ModelRuntime,
|
|
84093
|
+
noOpUIContext,
|
|
83298
84094
|
resolveRestoredModelReference
|
|
83299
84095
|
} from "@bastani/atomic";
|
|
83300
84096
|
|
|
@@ -83621,7 +84417,14 @@ function stripWorkflowOnlyOptions2(options) {
|
|
|
83621
84417
|
if (!options)
|
|
83622
84418
|
return options;
|
|
83623
84419
|
const maybeWorkflowOptions = options;
|
|
83624
|
-
const {
|
|
84420
|
+
const {
|
|
84421
|
+
schema: _schema,
|
|
84422
|
+
schemaTimeoutMs: _schemaTimeoutMs,
|
|
84423
|
+
mcp: _mcp,
|
|
84424
|
+
fallbackModels,
|
|
84425
|
+
group: _group,
|
|
84426
|
+
...sessionOptions
|
|
84427
|
+
} = maybeWorkflowOptions;
|
|
83625
84428
|
return fallbackModels?.length === 0 ? { ...sessionOptions, fallbackModels: [] } : sessionOptions;
|
|
83626
84429
|
}
|
|
83627
84430
|
function emitLateIntercomRoute(pi, meta, messages, options, batch) {
|
|
@@ -83738,6 +84541,7 @@ function makeStageExtensionUiContext(ui, meta, broker, inheritedBindingRevision,
|
|
|
83738
84541
|
notify: ui.notify ?? (() => {
|
|
83739
84542
|
return;
|
|
83740
84543
|
}),
|
|
84544
|
+
requestRender: noOpUIContext.requestRender,
|
|
83741
84545
|
onTerminalInput: ui.onTerminalInput ?? (() => () => {
|
|
83742
84546
|
return;
|
|
83743
84547
|
}),
|
|
@@ -83797,7 +84601,7 @@ function makeStageExtensionUiContext(ui, meta, broker, inheritedBindingRevision,
|
|
|
83797
84601
|
getEditorComponent: ui.getEditorComponent ?? (() => {
|
|
83798
84602
|
return;
|
|
83799
84603
|
}),
|
|
83800
|
-
theme: ui.theme,
|
|
84604
|
+
theme: ui.theme ?? noOpUIContext.theme,
|
|
83801
84605
|
getAllThemes: ui.getAllThemes ?? (() => []),
|
|
83802
84606
|
getTheme: ui.getTheme ?? (() => {
|
|
83803
84607
|
return;
|
|
@@ -83807,9 +84611,8 @@ function makeStageExtensionUiContext(ui, meta, broker, inheritedBindingRevision,
|
|
|
83807
84611
|
setToolsExpanded: ui.setToolsExpanded ?? (() => {
|
|
83808
84612
|
return;
|
|
83809
84613
|
}),
|
|
83810
|
-
|
|
83811
|
-
|
|
83812
|
-
})
|
|
84614
|
+
getFooterDataProvider: noOpUIContext.getFooterDataProvider,
|
|
84615
|
+
getChatRenderSettings: ui.getChatRenderSettings ?? noOpUIContext.getChatRenderSettings
|
|
83813
84616
|
};
|
|
83814
84617
|
}
|
|
83815
84618
|
function findStageModel(runtime, reference) {
|
|
@@ -85912,6 +86715,7 @@ function workflowModelCatalogFromContext(ctx, resolveLiveContext) {
|
|
|
85912
86715
|
model: current.model,
|
|
85913
86716
|
getRouterModel: () => current.getRouterModel(),
|
|
85914
86717
|
...current.getModelRouting ? { getModelRouting: () => current.getModelRouting() } : {},
|
|
86718
|
+
...current.getHttpIdleTimeoutMs ? { getHttpIdleTimeoutMs: () => current.getHttpIdleTimeoutMs() } : {},
|
|
85915
86719
|
modelRegistry: {
|
|
85916
86720
|
getAvailable: () => registry.getAvailable(),
|
|
85917
86721
|
getAll: () => registry.getAll(),
|
|
@@ -85929,7 +86733,8 @@ function workflowModelCatalogFromContext(ctx, resolveLiveContext) {
|
|
|
85929
86733
|
signal: input.signal,
|
|
85930
86734
|
selection: input.selection,
|
|
85931
86735
|
...input.taskNeeds ? { taskNeeds: input.taskNeeds } : {},
|
|
85932
|
-
...input.overrideProviderSettings ? { overrideProviderSettings: true } : {}
|
|
86736
|
+
...input.overrideProviderSettings ? { overrideProviderSettings: true } : {},
|
|
86737
|
+
...input.inference ? { inference: input.inference } : {}
|
|
85933
86738
|
});
|
|
85934
86739
|
},
|
|
85935
86740
|
listModels: async () => {
|
|
@@ -86708,7 +87513,7 @@ function registerPendingStageIntercomBridge(pi, activeStore) {
|
|
|
86708
87513
|
const entry = { signature };
|
|
86709
87514
|
announcedRoutes.set(run.id, entry);
|
|
86710
87515
|
try {
|
|
86711
|
-
pi.events?.emit?.(PENDING_STAGE_ROUTE_EVENT2, announcement);
|
|
87516
|
+
outsideWorkflowExecutions(() => pi.events?.emit?.(PENDING_STAGE_ROUTE_EVENT2, announcement));
|
|
86712
87517
|
} catch (error) {
|
|
86713
87518
|
if (announcedRoutes.get(run.id) === entry)
|
|
86714
87519
|
announcedRoutes.delete(run.id);
|
|
@@ -86747,7 +87552,7 @@ function registerPendingStageIntercomBridge(pi, activeStore) {
|
|
|
86747
87552
|
announcedRoutes.clear();
|
|
86748
87553
|
announceRoutes();
|
|
86749
87554
|
});
|
|
86750
|
-
const
|
|
87555
|
+
const routePendingStageMessage = (payload) => {
|
|
86751
87556
|
if (disposed || !isPendingStageMessageEvent(payload) || payload.handled)
|
|
86752
87557
|
return;
|
|
86753
87558
|
const runs = activeStore.runs();
|
|
@@ -86810,12 +87615,13 @@ function registerPendingStageIntercomBridge(pi, activeStore) {
|
|
|
86810
87615
|
}
|
|
86811
87616
|
payload.handled = true;
|
|
86812
87617
|
payload.completion = queueAndPersist(activeStore, resolvedEvent, workflowInvocationIntercomGroup(rootRunId), stage.pendingStageDeliveryAvailable === true);
|
|
86813
|
-
}
|
|
87618
|
+
};
|
|
87619
|
+
const subscription = pi.events?.on?.(PENDING_STAGE_MESSAGE_EVENT2, (payload) => outsideWorkflowExecutions(() => routePendingStageMessage(payload)));
|
|
86814
87620
|
const stickySubscription = pi.events?.on?.(STICKY_LIVE_DELIVERED_EVENT, (payload) => {
|
|
86815
87621
|
if (disposed || !isStickyLiveDeliveredEvent(payload) || payload.handled)
|
|
86816
87622
|
return;
|
|
86817
87623
|
payload.handled = true;
|
|
86818
|
-
payload.completion = recordConfirmedStickyDeliveries(activeStore, payload);
|
|
87624
|
+
payload.completion = outsideWorkflowExecutions(() => recordConfirmedStickyDeliveries(activeStore, payload));
|
|
86819
87625
|
});
|
|
86820
87626
|
const dispose = () => {
|
|
86821
87627
|
disposed = true;
|
|
@@ -87595,7 +88401,7 @@ function openInputsPicker(ui, opts) {
|
|
|
87595
88401
|
// dist/builtin/workflows/src/tui/session-picker.ts
|
|
87596
88402
|
import { keyText as keyText3 } from "@bastani/atomic";
|
|
87597
88403
|
var ESCAPE_CODE = 27;
|
|
87598
|
-
function
|
|
88404
|
+
function isQuitRun5(run) {
|
|
87599
88405
|
return run.endedAt === undefined && run.status === "paused" && run.exitReason === "quit";
|
|
87600
88406
|
}
|
|
87601
88407
|
var DOUBLE_ESCAPE_SEQUENCE = String.fromCharCode(ESCAPE_CODE, ESCAPE_CODE);
|
|
@@ -87632,8 +88438,7 @@ function selectRunsForPicker(runs, query, includeAll, now = Date.now(), intent =
|
|
|
87632
88438
|
return true;
|
|
87633
88439
|
return r.name.toLowerCase().includes(q) || r.id.startsWith(q);
|
|
87634
88440
|
};
|
|
87635
|
-
const
|
|
87636
|
-
const terminal = [];
|
|
88441
|
+
const rows = [];
|
|
87637
88442
|
for (const r of runs) {
|
|
87638
88443
|
if (!isTopLevelWorkflowRun(r))
|
|
87639
88444
|
continue;
|
|
@@ -87646,16 +88451,30 @@ function selectRunsForPicker(runs, query, includeAll, now = Date.now(), intent =
|
|
|
87646
88451
|
}
|
|
87647
88452
|
const endedAt = r.endedAt;
|
|
87648
88453
|
if (endedAt === undefined) {
|
|
87649
|
-
|
|
88454
|
+
rows.push({ run: r, bucket: "active" });
|
|
87650
88455
|
continue;
|
|
87651
88456
|
}
|
|
87652
88457
|
if (includeAll || now - endedAt <= RECENT_WINDOW_MS) {
|
|
87653
|
-
|
|
88458
|
+
rows.push({ run: r, bucket: "terminal" });
|
|
87654
88459
|
}
|
|
87655
88460
|
}
|
|
87656
|
-
|
|
87657
|
-
|
|
87658
|
-
|
|
88461
|
+
return sortRunsByStatus(rows, (row) => row.run, createRunIndicatorStatusResolver(runs));
|
|
88462
|
+
}
|
|
88463
|
+
function syncSessionPickerSelection(state, rows) {
|
|
88464
|
+
if (state.selectedRunId !== undefined) {
|
|
88465
|
+
const index = rows.findIndex((row) => row.run.id === state.selectedRunId);
|
|
88466
|
+
if (index >= 0)
|
|
88467
|
+
state.selectedIndex = index;
|
|
88468
|
+
}
|
|
88469
|
+
state.selectedRunId = rows[state.selectedIndex]?.run.id;
|
|
88470
|
+
}
|
|
88471
|
+
function selectIndex2(state, rows, index) {
|
|
88472
|
+
state.selectedIndex = index;
|
|
88473
|
+
state.selectedRunId = rows[index]?.run.id;
|
|
88474
|
+
}
|
|
88475
|
+
function resetSelection(state) {
|
|
88476
|
+
state.selectedIndex = 0;
|
|
88477
|
+
state.selectedRunId = undefined;
|
|
87659
88478
|
}
|
|
87660
88479
|
var TITLE = "Connect to workflow run";
|
|
87661
88480
|
function renderHeader3(width, theme) {
|
|
@@ -87736,7 +88555,7 @@ function renderRunRow(row, isSelected, inner, theme, now, allRuns) {
|
|
|
87736
88555
|
const border = hexToAnsi(theme.border);
|
|
87737
88556
|
const panelBg = hexBg(theme.bg);
|
|
87738
88557
|
const run = row.run;
|
|
87739
|
-
const indicatorStatus =
|
|
88558
|
+
const indicatorStatus = isQuitRun5(run) ? run.status : runIndicatorStatus(run, allRuns);
|
|
87740
88559
|
const icon = statusIcon(indicatorStatus);
|
|
87741
88560
|
const iconColor = hexToAnsi(statusColor(indicatorStatus, theme));
|
|
87742
88561
|
const dim = hexToAnsi(theme.dim);
|
|
@@ -87828,12 +88647,12 @@ function handleSessionPickerInput(data, state, rows) {
|
|
|
87828
88647
|
}
|
|
87829
88648
|
if (matchesKey(data, Key.backspace)) {
|
|
87830
88649
|
state.query = state.query.slice(0, -1);
|
|
87831
|
-
state
|
|
88650
|
+
resetSelection(state);
|
|
87832
88651
|
return { kind: "noop" };
|
|
87833
88652
|
}
|
|
87834
88653
|
if (data.length === 1 && data >= " " && data <= "~") {
|
|
87835
88654
|
state.query += data;
|
|
87836
|
-
state
|
|
88655
|
+
resetSelection(state);
|
|
87837
88656
|
return { kind: "noop" };
|
|
87838
88657
|
}
|
|
87839
88658
|
return { kind: "noop" };
|
|
@@ -87848,17 +88667,17 @@ function handleSessionPickerInput(data, state, rows) {
|
|
|
87848
88667
|
return { kind: "close" };
|
|
87849
88668
|
if (matchesKey(data, "a") || matchesKey(data, Key.shift("a"))) {
|
|
87850
88669
|
state.includeAll = !state.includeAll;
|
|
87851
|
-
state
|
|
88670
|
+
resetSelection(state);
|
|
87852
88671
|
return { kind: "noop" };
|
|
87853
88672
|
}
|
|
87854
88673
|
if (matchesKey(data, Key.down) || matchesKey(data, "j")) {
|
|
87855
|
-
state
|
|
88674
|
+
selectIndex2(state, rows, Math.min(state.selectedIndex + 1, Math.max(0, rows.length - 1)));
|
|
87856
88675
|
return { kind: "noop" };
|
|
87857
88676
|
}
|
|
87858
88677
|
if (matchesKey(data, Key.up) || matchesKey(data, "k")) {
|
|
87859
88678
|
if (rows.length > 0 && state.selectedIndex === 0)
|
|
87860
88679
|
return { kind: "noop" };
|
|
87861
|
-
state
|
|
88680
|
+
selectIndex2(state, rows, Math.max(state.selectedIndex - 1, 0));
|
|
87862
88681
|
return { kind: "noop" };
|
|
87863
88682
|
}
|
|
87864
88683
|
if (matchesKey(data, Key.enter)) {
|
|
@@ -88185,10 +89004,12 @@ function openSessionPicker(ui, store, theme, intent = "connect") {
|
|
|
88185
89004
|
return {
|
|
88186
89005
|
render: (width) => {
|
|
88187
89006
|
const rows = selectRows();
|
|
89007
|
+
syncSessionPickerSelection(state, rows);
|
|
88188
89008
|
return renderSessionPicker({ width, theme, rows, state, allRuns: store.runs() });
|
|
88189
89009
|
},
|
|
88190
89010
|
handleInput: (data) => {
|
|
88191
89011
|
const rows = selectRows();
|
|
89012
|
+
syncSessionPickerSelection(state, rows);
|
|
88192
89013
|
const consumed = isSessionPickerKey(data, state, rows);
|
|
88193
89014
|
const action = handleSessionPickerInput(data, state, rows);
|
|
88194
89015
|
if (action.kind === "noop") {
|
|
@@ -89221,6 +90042,18 @@ function createSessionRunControl(host) {
|
|
|
89221
90042
|
async quit(runId) {
|
|
89222
90043
|
return controlOutcome(await request({ action: "quit", ...target(runId) }));
|
|
89223
90044
|
},
|
|
90045
|
+
async waitForSettled(runId) {
|
|
90046
|
+
const job = (host.jobs ?? currentJobTracker()).get(runId);
|
|
90047
|
+
if (job === undefined)
|
|
90048
|
+
return;
|
|
90049
|
+
try {
|
|
90050
|
+
await awaitJobSettlement(job);
|
|
90051
|
+
} catch (error) {
|
|
90052
|
+
const cause = error instanceof Error ? error : new Error(String(error));
|
|
90053
|
+
const code = error instanceof JournalError ? "storage_unavailable" : classifyControlError(error);
|
|
90054
|
+
throw failure3(code, `Run ${runId} did not settle cleanly: ${describeErrorWithCauses(error)}`, runId, cause);
|
|
90055
|
+
}
|
|
90056
|
+
},
|
|
89224
90057
|
async resume(runId, options) {
|
|
89225
90058
|
return controlOutcome(await request({
|
|
89226
90059
|
action: "resume",
|
|
@@ -91664,6 +92497,7 @@ function factory(pi) {
|
|
|
91664
92497
|
execute: executeWorkflowTool,
|
|
91665
92498
|
context: () => sessionContext,
|
|
91666
92499
|
store: owner.store,
|
|
92500
|
+
jobs: runState.jobs,
|
|
91667
92501
|
catalog: async () => {
|
|
91668
92502
|
const runtime = runtimeState.runtimeForContext(sessionContext);
|
|
91669
92503
|
return await runtime.prepareDurableCatalog?.() ?? { resumable: [], completed: [] };
|