@bastani/atomic 0.9.18 → 0.9.19-alpha.10
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 +206 -0
- package/README.md +2 -2
- package/dist/builtin/intercom/CHANGELOG.md +51 -0
- package/dist/builtin/intercom/README.md +28 -18
- package/dist/builtin/intercom/broker/broker.ts +81 -9
- package/dist/builtin/intercom/broker/client.ts +45 -1
- package/dist/builtin/intercom/broker/framing.ts +5 -2
- package/dist/builtin/intercom/broker/group-membership.ts +4 -2
- package/dist/builtin/intercom/broker/presence-handler.ts +14 -0
- package/dist/builtin/intercom/broker/send-handler.ts +61 -6
- package/dist/builtin/intercom/broker/terminal-questions.ts +29 -0
- package/dist/builtin/intercom/index.bundle.mjs +1120 -783
- package/dist/builtin/intercom/package.json +2 -2
- package/dist/builtin/intercom/recipient-purpose.ts +9 -0
- package/dist/builtin/intercom/recoverable-disconnect.ts +2 -3
- package/dist/builtin/intercom/retry-policy.ts +4 -2
- package/dist/builtin/intercom/skills/intercom/SKILL.md +8 -7
- package/dist/builtin/intercom/types.ts +18 -3
- package/dist/builtin/mcp/CHANGELOG.md +6 -0
- package/dist/builtin/mcp/README.md +2 -0
- package/dist/builtin/mcp/index.bundle.mjs +2201 -12000
- package/dist/builtin/mcp/package.json +2 -2
- package/dist/builtin/subagents/CHANGELOG.md +57 -0
- package/dist/builtin/subagents/README.md +46 -23
- package/dist/builtin/subagents/agents/code-simplifier.md +1 -1
- package/dist/builtin/subagents/agents/codebase-analyzer.md +1 -1
- package/dist/builtin/subagents/agents/codebase-locator.md +2 -2
- package/dist/builtin/subagents/agents/codebase-online-researcher.md +8 -8
- package/dist/builtin/subagents/agents/codebase-pattern-finder.md +2 -2
- package/dist/builtin/subagents/agents/codebase-research-analyzer.md +1 -1
- package/dist/builtin/subagents/agents/codebase-research-locator.md +2 -2
- package/dist/builtin/subagents/agents/debugger.md +2 -2
- package/dist/builtin/subagents/agents/worker.md +1 -1
- package/dist/builtin/subagents/package.json +2 -2
- package/dist/builtin/subagents/skills/herdr/LICENSE +201 -0
- package/dist/builtin/subagents/skills/herdr/SKILL.md +202 -0
- package/dist/builtin/subagents/skills/subagent/SKILL.md +41 -35
- package/dist/builtin/subagents/skills/tmux/SKILL.md +1 -1
- package/dist/builtin/subagents/src/extension/index.bundle.mjs +1414 -656
- package/dist/builtin/web-access/CHANGELOG.md +19 -0
- package/dist/builtin/web-access/README.md +31 -24
- package/dist/builtin/web-access/index.bundle.mjs +42723 -26674
- package/dist/builtin/web-access/package.json +3 -2
- package/dist/builtin/workflows/CHANGELOG.md +131 -0
- package/dist/builtin/workflows/README.md +15 -16
- package/dist/builtin/workflows/builtin/adversarial-verification.js +5 -7
- package/dist/builtin/workflows/builtin/{chunk-hqpe2cyx.js → chunk-1jth021m.js} +85 -85
- package/dist/builtin/workflows/builtin/{chunk-7430zyas.js → chunk-2377r57g.js} +5 -3
- package/dist/builtin/workflows/builtin/{chunk-79fjkcvh.js → chunk-31j2gs7h.js} +18 -18
- package/dist/builtin/workflows/builtin/{chunk-wgccch41.js → chunk-6w6cvk6b.js} +16 -16
- package/dist/builtin/workflows/builtin/{chunk-zbekjqew.js → chunk-a2kdsqn8.js} +4 -4
- package/dist/builtin/workflows/builtin/{chunk-ze5x3d1r.js → chunk-fg9esgkj.js} +7 -7
- package/dist/builtin/workflows/builtin/{chunk-n8h4yyew.js → chunk-g0csgs7w.js} +11 -11
- package/dist/builtin/workflows/builtin/{chunk-b0v2xab1.js → chunk-ngkqkzej.js} +221 -23
- package/dist/builtin/workflows/builtin/{chunk-ed4jfn5t.js → chunk-nkrafh9s.js} +61 -61
- package/dist/builtin/workflows/builtin/{chunk-reqr3sr3.js → chunk-wf741bv3.js} +22 -22
- package/dist/builtin/workflows/builtin/{chunk-42s7sw0b.js → chunk-yeee2jrc.js} +19 -19
- package/dist/builtin/workflows/builtin/{chunk-6fqs7c01.js → chunk-z0d03ktm.js} +1 -1
- package/dist/builtin/workflows/builtin/{chunk-k3w87x8y.js → chunk-z29qbehr.js} +10 -10
- package/dist/builtin/workflows/builtin/classify-and-act.js +5 -6
- package/dist/builtin/workflows/builtin/fan-out-and-synthesize.js +3 -4
- package/dist/builtin/workflows/builtin/generate-and-filter.js +5 -6
- package/dist/builtin/workflows/builtin/goal.js +7 -8
- package/dist/builtin/workflows/builtin/index.js +20 -22
- package/dist/builtin/workflows/builtin/loop-until-done.js +5 -6
- package/dist/builtin/workflows/builtin/open-claude-design.js +3 -3
- package/dist/builtin/workflows/builtin/ralph.js +7 -8
- package/dist/builtin/workflows/builtin/steering-context.js +3 -3
- package/dist/builtin/workflows/builtin/tournament.js +5 -7
- package/dist/builtin/workflows/package.json +6 -6
- package/dist/builtin/workflows/src/extension/index.bundle.mjs +57318 -25709
- package/dist/builtin/workflows/src/index.js +1413 -589
- package/dist/builtin/workflows/src/shared/authoring-contract-stage.d.ts +4 -1
- package/dist/builtin/workflows/src/shared/authoring-contract-ui.d.ts +1 -1
- package/dist/cli/config-selector.js.map +1 -1
- package/dist/cli/startup-ui.d.ts +1 -1
- package/dist/cli/startup-ui.js.map +1 -1
- package/dist/core/agent-session-auto-compaction.d.ts.map +1 -1
- package/dist/core/agent-session-auto-compaction.js +6 -5
- package/dist/core/agent-session-auto-compaction.js.map +1 -1
- package/dist/core/agent-session-bash.d.ts +1 -1
- package/dist/core/agent-session-bash.d.ts.map +1 -1
- package/dist/core/agent-session-bash.js +5 -1
- package/dist/core/agent-session-bash.js.map +1 -1
- package/dist/core/agent-session-compaction.d.ts +1 -1
- package/dist/core/agent-session-compaction.js +1 -1
- package/dist/core/agent-session-compaction.js.map +1 -1
- package/dist/core/agent-session-custom-message-commit.d.ts +1 -1
- package/dist/core/agent-session-custom-message-commit.d.ts.map +1 -1
- package/dist/core/agent-session-custom-message-commit.js +33 -2
- package/dist/core/agent-session-custom-message-commit.js.map +1 -1
- package/dist/core/agent-session-delivery-forwarding.d.ts +1 -1
- package/dist/core/agent-session-delivery-forwarding.js.map +1 -1
- package/dist/core/agent-session-events.d.ts.map +1 -1
- package/dist/core/agent-session-events.js +5 -0
- package/dist/core/agent-session-events.js.map +1 -1
- package/dist/core/agent-session-export.d.ts +1 -1
- package/dist/core/agent-session-export.js.map +1 -1
- package/dist/core/agent-session-extension-bindings.d.ts +8 -1
- package/dist/core/agent-session-extension-bindings.d.ts.map +1 -1
- package/dist/core/agent-session-extension-bindings.js +45 -3
- package/dist/core/agent-session-extension-bindings.js.map +1 -1
- package/dist/core/agent-session-message-queue.d.ts +2 -2
- package/dist/core/agent-session-message-queue.d.ts.map +1 -1
- package/dist/core/agent-session-message-queue.js +22 -8
- package/dist/core/agent-session-message-queue.js.map +1 -1
- package/dist/core/agent-session-methods.d.ts +21 -8
- 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-persistent-custom-messages.d.ts +1 -1
- package/dist/core/agent-session-persistent-custom-messages.d.ts.map +1 -1
- package/dist/core/agent-session-persistent-custom-messages.js +13 -3
- package/dist/core/agent-session-persistent-custom-messages.js.map +1 -1
- package/dist/core/agent-session-post-tool-compaction.js +1 -1
- package/dist/core/agent-session-post-tool-compaction.js.map +1 -1
- package/dist/core/agent-session-prompt.d.ts +2 -2
- package/dist/core/agent-session-prompt.d.ts.map +1 -1
- package/dist/core/agent-session-prompt.js +105 -18
- package/dist/core/agent-session-prompt.js.map +1 -1
- package/dist/core/agent-session-queue-pause.d.ts.map +1 -1
- package/dist/core/agent-session-queue-pause.js +11 -0
- package/dist/core/agent-session-queue-pause.js.map +1 -1
- package/dist/core/agent-session-runtime-auth.d.ts +1 -1
- package/dist/core/agent-session-runtime-auth.js.map +1 -1
- package/dist/core/agent-session-runtime.d.ts +13 -4
- package/dist/core/agent-session-runtime.d.ts.map +1 -1
- package/dist/core/agent-session-runtime.js +27 -4
- package/dist/core/agent-session-runtime.js.map +1 -1
- package/dist/core/agent-session-services.d.ts +5 -1
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js +44 -34
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session-state.d.ts +1 -1
- package/dist/core/agent-session-state.js.map +1 -1
- package/dist/core/agent-session-tasks.d.ts +14 -0
- package/dist/core/agent-session-tasks.d.ts.map +1 -0
- package/dist/core/agent-session-tasks.js +120 -0
- package/dist/core/agent-session-tasks.js.map +1 -0
- package/dist/core/agent-session-tool-hooks.d.ts.map +1 -1
- package/dist/core/agent-session-tool-hooks.js +2 -0
- package/dist/core/agent-session-tool-hooks.js.map +1 -1
- package/dist/core/agent-session-tool-registry.d.ts +1 -0
- package/dist/core/agent-session-tool-registry.d.ts.map +1 -1
- package/dist/core/agent-session-tool-registry.js +52 -5
- package/dist/core/agent-session-tool-registry.js.map +1 -1
- package/dist/core/agent-session-transfer.d.ts.map +1 -1
- package/dist/core/agent-session-transfer.js +7 -0
- package/dist/core/agent-session-transfer.js.map +1 -1
- package/dist/core/agent-session-tree.d.ts.map +1 -1
- package/dist/core/agent-session-tree.js +3 -0
- package/dist/core/agent-session-tree.js.map +1 -1
- package/dist/core/agent-session-types.d.ts +4 -2
- package/dist/core/agent-session-types.d.ts.map +1 -1
- package/dist/core/agent-session-types.js +2 -0
- package/dist/core/agent-session-types.js.map +1 -1
- package/dist/core/agent-session.d.ts +8 -1
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +29 -1
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/bash-executor.d.ts +1 -1
- package/dist/core/bash-executor.js.map +1 -1
- package/dist/core/export-html/index.js.map +1 -1
- package/dist/core/export-html/tool-renderer.d.ts +1 -1
- package/dist/core/export-html/tool-renderer.js.map +1 -1
- package/dist/core/extension-session-state.js.map +1 -1
- package/dist/core/extensions/agent-events.d.ts +4 -4
- package/dist/core/extensions/agent-events.d.ts.map +1 -1
- package/dist/core/extensions/agent-events.js.map +1 -1
- package/dist/core/extensions/api-types.d.ts +10 -2
- package/dist/core/extensions/api-types.d.ts.map +1 -1
- package/dist/core/extensions/api-types.js.map +1 -1
- package/dist/core/extensions/context-types.d.ts +15 -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/event-results.d.ts +1 -1
- package/dist/core/extensions/event-results.js.map +1 -1
- package/dist/core/extensions/event-types.d.ts +2 -1
- package/dist/core/extensions/event-types.d.ts.map +1 -1
- package/dist/core/extensions/event-types.js.map +1 -1
- package/dist/core/extensions/index.d.ts +3 -2
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/loader-api.d.ts +1 -1
- package/dist/core/extensions/loader-api.d.ts.map +1 -1
- package/dist/core/extensions/loader-api.js +10 -0
- package/dist/core/extensions/loader-api.js.map +1 -1
- package/dist/core/extensions/loader-core.d.ts +1 -1
- package/dist/core/extensions/loader-core.js.map +1 -1
- package/dist/core/extensions/loader-discovery.d.ts +1 -1
- package/dist/core/extensions/loader-discovery.js.map +1 -1
- package/dist/core/extensions/loader-host-modules.d.ts +1 -1
- package/dist/core/extensions/loader-host-modules.d.ts.map +1 -1
- package/dist/core/extensions/loader-host-modules.js +5 -2
- package/dist/core/extensions/loader-host-modules.js.map +1 -1
- package/dist/core/extensions/loader-runtime.d.ts.map +1 -1
- package/dist/core/extensions/loader-runtime.js +3 -0
- package/dist/core/extensions/loader-runtime.js.map +1 -1
- package/dist/core/extensions/loader-virtual-modules.d.ts.map +1 -1
- package/dist/core/extensions/loader-virtual-modules.js +6 -1
- package/dist/core/extensions/loader-virtual-modules.js.map +1 -1
- package/dist/core/extensions/loader.d.ts +1 -1
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/message-types.d.ts +1 -1
- package/dist/core/extensions/message-types.js.map +1 -1
- package/dist/core/extensions/reactive-widget.d.ts +6 -0
- package/dist/core/extensions/reactive-widget.d.ts.map +1 -1
- package/dist/core/extensions/reactive-widget.js +7 -1
- package/dist/core/extensions/reactive-widget.js.map +1 -1
- package/dist/core/extensions/runner-context.d.ts +12 -2
- package/dist/core/extensions/runner-context.d.ts.map +1 -1
- package/dist/core/extensions/runner-context.js +49 -4
- package/dist/core/extensions/runner-context.js.map +1 -1
- package/dist/core/extensions/runner-events.d.ts +1 -1
- package/dist/core/extensions/runner-events.d.ts.map +1 -1
- package/dist/core/extensions/runner-events.js +17 -2
- package/dist/core/extensions/runner-events.js.map +1 -1
- package/dist/core/extensions/runner-shortcuts.d.ts.map +1 -1
- package/dist/core/extensions/runner-shortcuts.js +32 -3
- package/dist/core/extensions/runner-shortcuts.js.map +1 -1
- package/dist/core/extensions/runner-ui.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +17 -2
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +69 -19
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/runtime-types.d.ts +8 -1
- 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/tool-types.d.ts +1 -1
- package/dist/core/extensions/tool-types.js.map +1 -1
- package/dist/core/extensions/types.d.ts +1 -0
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/extensions/ui-types.d.ts +25 -1
- package/dist/core/extensions/ui-types.d.ts.map +1 -1
- package/dist/core/extensions/ui-types.js.map +1 -1
- package/dist/core/extensions/workflow-activity-hub.d.ts +25 -0
- package/dist/core/extensions/workflow-activity-hub.d.ts.map +1 -0
- package/dist/core/extensions/workflow-activity-hub.js +183 -0
- package/dist/core/extensions/workflow-activity-hub.js.map +1 -0
- package/dist/core/extensions/workflow-events.d.ts +118 -0
- package/dist/core/extensions/workflow-events.d.ts.map +1 -0
- package/dist/core/extensions/workflow-events.js +2 -0
- package/dist/core/extensions/workflow-events.js.map +1 -0
- package/dist/core/footer-data-provider.d.ts +8 -4
- package/dist/core/footer-data-provider.d.ts.map +1 -1
- package/dist/core/footer-data-provider.js +97 -11
- package/dist/core/footer-data-provider.js.map +1 -1
- package/dist/core/index.d.ts +3 -3
- package/dist/core/index.js.map +1 -1
- package/dist/core/keybinding-identity.d.ts +4 -0
- package/dist/core/keybinding-identity.d.ts.map +1 -0
- package/dist/core/keybinding-identity.js +10 -0
- package/dist/core/keybinding-identity.js.map +1 -0
- package/dist/core/keybindings.d.ts +37 -2
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +9 -2
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/mandatory-runtime-tools.d.ts +1 -1
- package/dist/core/mandatory-runtime-tools.js.map +1 -1
- package/dist/core/model-fallback-failures.js +2 -2
- package/dist/core/model-fallback-failures.js.map +1 -1
- package/dist/core/model-registry.d.ts +5 -1
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +8 -0
- package/dist/core/model-registry.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/resource-loader-assets.js.map +1 -1
- package/dist/core/resource-loader-core.d.ts +1 -1
- package/dist/core/resource-loader-core.js.map +1 -1
- package/dist/core/resource-loader-internals.d.ts +2 -2
- package/dist/core/resource-loader-internals.js.map +1 -1
- package/dist/core/resource-loader-reload.d.ts +2 -0
- package/dist/core/resource-loader-reload.d.ts.map +1 -1
- package/dist/core/resource-loader-reload.js +231 -191
- package/dist/core/resource-loader-reload.js.map +1 -1
- package/dist/core/resource-loader-types.d.ts +4 -2
- package/dist/core/resource-loader-types.d.ts.map +1 -1
- package/dist/core/resource-loader-types.js.map +1 -1
- package/dist/core/retry-policy.d.ts +1 -0
- package/dist/core/retry-policy.d.ts.map +1 -1
- package/dist/core/retry-policy.js +2 -1
- package/dist/core/retry-policy.js.map +1 -1
- package/dist/core/sdk-exports.d.ts +3 -3
- package/dist/core/sdk-exports.d.ts.map +1 -1
- package/dist/core/sdk-exports.js +1 -1
- package/dist/core/sdk-exports.js.map +1 -1
- package/dist/core/sdk-types.d.ts +2 -2
- package/dist/core/sdk-types.js.map +1 -1
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/settings-manager-basic-accessors.d.ts +6 -3
- package/dist/core/settings-manager-basic-accessors.d.ts.map +1 -1
- package/dist/core/settings-manager-basic-accessors.js +25 -8
- package/dist/core/settings-manager-basic-accessors.js.map +1 -1
- package/dist/core/settings-manager-core.d.ts.map +1 -1
- package/dist/core/settings-manager-core.js +10 -4
- package/dist/core/settings-manager-core.js.map +1 -1
- package/dist/core/settings-manager.d.ts +1 -1
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/settings-storage.d.ts +1 -0
- package/dist/core/settings-storage.d.ts.map +1 -1
- package/dist/core/settings-storage.js +18 -0
- package/dist/core/settings-storage.js.map +1 -1
- package/dist/core/settings-types.d.ts +17 -0
- package/dist/core/settings-types.d.ts.map +1 -1
- package/dist/core/settings-types.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +6 -5
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +5 -6
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tasks/agent-adapter.d.ts +44 -0
- package/dist/core/tasks/agent-adapter.d.ts.map +1 -0
- package/dist/core/tasks/agent-adapter.js +112 -0
- package/dist/core/tasks/agent-adapter.js.map +1 -0
- package/dist/core/tasks/command-output.d.ts +15 -0
- package/dist/core/tasks/command-output.d.ts.map +1 -0
- package/dist/core/tasks/command-output.js +29 -0
- package/dist/core/tasks/command-output.js.map +1 -0
- package/dist/core/tasks/completion-ordering.d.ts +11 -0
- package/dist/core/tasks/completion-ordering.d.ts.map +1 -0
- package/dist/core/tasks/completion-ordering.js +19 -0
- package/dist/core/tasks/completion-ordering.js.map +1 -0
- package/dist/core/tasks/completion.d.ts +36 -0
- package/dist/core/tasks/completion.d.ts.map +1 -0
- package/dist/core/tasks/completion.js +119 -0
- package/dist/core/tasks/completion.js.map +1 -0
- package/dist/core/tasks/contracts.d.ts +404 -0
- package/dist/core/tasks/contracts.d.ts.map +1 -0
- package/dist/core/tasks/contracts.js +2 -0
- package/dist/core/tasks/contracts.js.map +1 -0
- package/dist/core/tasks/execution-scope.d.ts +10 -0
- package/dist/core/tasks/execution-scope.d.ts.map +1 -0
- package/dist/core/tasks/execution-scope.js +27 -0
- package/dist/core/tasks/execution-scope.js.map +1 -0
- package/dist/core/tasks/owner-store.d.ts +53 -0
- package/dist/core/tasks/owner-store.d.ts.map +1 -0
- package/dist/core/tasks/owner-store.js +155 -0
- package/dist/core/tasks/owner-store.js.map +1 -0
- package/dist/core/tasks/pause.d.ts +4 -0
- package/dist/core/tasks/pause.d.ts.map +1 -0
- package/dist/core/tasks/pause.js +49 -0
- package/dist/core/tasks/pause.js.map +1 -0
- package/dist/core/tasks/supervisor.d.ts +123 -0
- package/dist/core/tasks/supervisor.d.ts.map +1 -0
- package/dist/core/tasks/supervisor.js +942 -0
- package/dist/core/tasks/supervisor.js.map +1 -0
- package/dist/core/tasks/transcript.d.ts +23 -0
- package/dist/core/tasks/transcript.d.ts.map +1 -0
- package/dist/core/tasks/transcript.js +74 -0
- package/dist/core/tasks/transcript.js.map +1 -0
- package/dist/core/tools/ask-user-question/ask-user-question.d.ts +2 -2
- package/dist/core/tools/ask-user-question/ask-user-question.d.ts.map +1 -1
- package/dist/core/tools/ask-user-question/ask-user-question.js +8 -4
- package/dist/core/tools/ask-user-question/ask-user-question.js.map +1 -1
- package/dist/core/tools/ask-user-question/state/build-questionnaire.d.ts +1 -1
- package/dist/core/tools/ask-user-question/state/build-questionnaire.js.map +1 -1
- package/dist/core/tools/ask-user-question/state/questionnaire-session.d.ts +1 -1
- package/dist/core/tools/ask-user-question/state/questionnaire-session.js.map +1 -1
- package/dist/core/tools/ask-user-question/view/components/multi-select-view.d.ts +1 -1
- package/dist/core/tools/ask-user-question/view/components/multi-select-view.js.map +1 -1
- package/dist/core/tools/ask-user-question/view/components/preview/markdown-content-cache.d.ts +1 -1
- package/dist/core/tools/ask-user-question/view/components/preview/markdown-content-cache.js.map +1 -1
- package/dist/core/tools/ask-user-question/view/components/preview/preview-block-renderer.d.ts +1 -1
- package/dist/core/tools/ask-user-question/view/components/preview/preview-block-renderer.js.map +1 -1
- package/dist/core/tools/ask-user-question/view/components/submit-picker.d.ts +1 -1
- package/dist/core/tools/ask-user-question/view/components/submit-picker.js.map +1 -1
- package/dist/core/tools/ask-user-question/view/components/tab-bar.d.ts +1 -1
- package/dist/core/tools/ask-user-question/view/components/tab-bar.js.map +1 -1
- package/dist/core/tools/ask-user-question/view/dialog-builder.d.ts +1 -1
- package/dist/core/tools/ask-user-question/view/dialog-builder.js.map +1 -1
- package/dist/core/tools/ask-user-question/view/tab-content-strategy.d.ts +1 -1
- package/dist/core/tools/ask-user-question/view/tab-content-strategy.js.map +1 -1
- package/dist/core/tools/bash-pty-native.d.ts +32 -3
- package/dist/core/tools/bash-pty-native.d.ts.map +1 -1
- package/dist/core/tools/bash-pty-native.js +198 -1
- package/dist/core/tools/bash-pty-native.js.map +1 -1
- package/dist/core/tools/bash.d.ts +25 -5
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +100 -10
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/edit.d.ts +3 -0
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +92 -14
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/file-mutation-coordinator.d.ts +255 -0
- package/dist/core/tools/file-mutation-coordinator.d.ts.map +1 -0
- package/dist/core/tools/file-mutation-coordinator.js +300 -0
- package/dist/core/tools/file-mutation-coordinator.js.map +1 -0
- package/dist/core/tools/file-mutation-queue.d.ts +14 -1
- package/dist/core/tools/file-mutation-queue.d.ts.map +1 -1
- package/dist/core/tools/file-mutation-queue.js +15 -3
- package/dist/core/tools/file-mutation-queue.js.map +1 -1
- package/dist/core/tools/find.js.map +1 -1
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/hashline.d.ts +9 -0
- package/dist/core/tools/hashline.d.ts.map +1 -1
- package/dist/core/tools/hashline.js +12 -1
- package/dist/core/tools/hashline.js.map +1 -1
- package/dist/core/tools/index.d.ts +15 -4
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +79 -12
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/kill.d.ts +17 -0
- package/dist/core/tools/kill.d.ts.map +1 -0
- package/dist/core/tools/kill.js +49 -0
- package/dist/core/tools/kill.js.map +1 -0
- package/dist/core/tools/ls.js.map +1 -1
- package/dist/core/tools/non-minting-snapshot-store.d.ts +49 -0
- package/dist/core/tools/non-minting-snapshot-store.d.ts.map +1 -0
- package/dist/core/tools/non-minting-snapshot-store.js +64 -0
- package/dist/core/tools/non-minting-snapshot-store.js.map +1 -0
- package/dist/core/tools/powershell.d.ts +100 -34
- package/dist/core/tools/powershell.d.ts.map +1 -1
- package/dist/core/tools/powershell.js +41 -11
- package/dist/core/tools/powershell.js.map +1 -1
- package/dist/core/tools/read-document-extract.js.map +1 -1
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +1 -2
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/render-utils.d.ts +1 -1
- package/dist/core/tools/render-utils.js.map +1 -1
- package/dist/core/tools/resource-selectors.d.ts +1 -1
- package/dist/core/tools/resource-selectors.d.ts.map +1 -1
- package/dist/core/tools/resource-selectors.js +21 -10
- package/dist/core/tools/resource-selectors.js.map +1 -1
- package/dist/core/tools/search.js.map +1 -1
- package/dist/core/tools/todos-render.d.ts +1 -1
- package/dist/core/tools/todos-render.js.map +1 -1
- package/dist/core/tools/write.d.ts +30 -1
- package/dist/core/tools/write.d.ts.map +1 -1
- package/dist/core/tools/write.js +98 -10
- package/dist/core/tools/write.js.map +1 -1
- package/dist/core/workflow-stage-admission.d.ts +24 -0
- package/dist/core/workflow-stage-admission.d.ts.map +1 -1
- package/dist/core/workflow-stage-admission.js +87 -3
- package/dist/core/workflow-stage-admission.js.map +1 -1
- package/dist/extensions/herdr/activity.d.ts +15 -0
- package/dist/extensions/herdr/activity.d.ts.map +1 -0
- package/dist/extensions/herdr/activity.js +24 -0
- package/dist/extensions/herdr/activity.js.map +1 -0
- package/dist/extensions/herdr/environment.d.ts +7 -0
- package/dist/extensions/herdr/environment.d.ts.map +1 -0
- package/dist/extensions/herdr/environment.js +6 -0
- package/dist/extensions/herdr/environment.js.map +1 -0
- package/dist/extensions/herdr/index.d.ts +9 -0
- package/dist/extensions/herdr/index.d.ts.map +1 -0
- package/dist/extensions/herdr/index.js +225 -0
- package/dist/extensions/herdr/index.js.map +1 -0
- package/dist/extensions/herdr/pane-owner.d.ts +30 -0
- package/dist/extensions/herdr/pane-owner.d.ts.map +1 -0
- package/dist/extensions/herdr/pane-owner.js +111 -0
- package/dist/extensions/herdr/pane-owner.js.map +1 -0
- package/dist/extensions/herdr/transport.d.ts +8 -0
- package/dist/extensions/herdr/transport.d.ts.map +1 -0
- package/dist/extensions/herdr/transport.js +28 -0
- package/dist/extensions/herdr/transport.js.map +1 -0
- package/dist/extensions/index.d.ts.map +1 -1
- package/dist/extensions/index.js +2 -0
- package/dist/extensions/index.js.map +1 -1
- package/dist/extensions/llama/huggingface-ui.d.ts +1 -1
- package/dist/extensions/llama/huggingface-ui.js.map +1 -1
- package/dist/extensions/llama/ui.js.map +1 -1
- package/dist/index-extensions.d.ts +3 -2
- package/dist/index-extensions.d.ts.map +1 -1
- package/dist/index-extensions.js.map +1 -1
- package/dist/index.d.ts +14 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -1
- package/dist/index.js.map +1 -1
- package/dist/main-session.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +149 -69
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/armin.js.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/atomic-banner.d.ts +1 -1
- package/dist/modes/interactive/components/atomic-banner.js.map +1 -1
- package/dist/modes/interactive/components/atomic-working-status.js.map +1 -1
- package/dist/modes/interactive/components/bash-execution.js.map +1 -1
- package/dist/modes/interactive/components/bordered-loader.d.ts +1 -1
- package/dist/modes/interactive/components/bordered-loader.js.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/chat-message-renderer.d.ts +12 -0
- package/dist/modes/interactive/components/chat-message-renderer.d.ts.map +1 -1
- package/dist/modes/interactive/components/chat-message-renderer.js +44 -0
- package/dist/modes/interactive/components/chat-message-renderer.js.map +1 -1
- package/dist/modes/interactive/components/chat-session-host-actions.d.ts +1 -1
- package/dist/modes/interactive/components/chat-session-host-actions.d.ts.map +1 -1
- package/dist/modes/interactive/components/chat-session-host-actions.js +43 -8
- package/dist/modes/interactive/components/chat-session-host-actions.js.map +1 -1
- package/dist/modes/interactive/components/chat-session-host-editor.d.ts +1 -1
- package/dist/modes/interactive/components/chat-session-host-editor.js.map +1 -1
- package/dist/modes/interactive/components/chat-session-host-events.d.ts +2 -2
- package/dist/modes/interactive/components/chat-session-host-events.js.map +1 -1
- package/dist/modes/interactive/components/chat-session-host-rendering.d.ts +2 -2
- package/dist/modes/interactive/components/chat-session-host-rendering.d.ts.map +1 -1
- package/dist/modes/interactive/components/chat-session-host-rendering.js +12 -3
- package/dist/modes/interactive/components/chat-session-host-rendering.js.map +1 -1
- package/dist/modes/interactive/components/chat-session-host-runtime.d.ts +4 -5
- package/dist/modes/interactive/components/chat-session-host-runtime.d.ts.map +1 -1
- package/dist/modes/interactive/components/chat-session-host-runtime.js +8 -6
- package/dist/modes/interactive/components/chat-session-host-runtime.js.map +1 -1
- package/dist/modes/interactive/components/chat-session-host-state.d.ts +7 -2
- package/dist/modes/interactive/components/chat-session-host-state.d.ts.map +1 -1
- package/dist/modes/interactive/components/chat-session-host-state.js +1 -0
- package/dist/modes/interactive/components/chat-session-host-state.js.map +1 -1
- package/dist/modes/interactive/components/chat-session-host-terminal-cleanup.d.ts +1 -1
- package/dist/modes/interactive/components/chat-session-host-terminal-cleanup.js.map +1 -1
- package/dist/modes/interactive/components/chat-session-host-types.d.ts +8 -3
- package/dist/modes/interactive/components/chat-session-host-types.d.ts.map +1 -1
- package/dist/modes/interactive/components/chat-session-host-types.js.map +1 -1
- package/dist/modes/interactive/components/chat-session-host-utils.d.ts +1 -1
- package/dist/modes/interactive/components/chat-session-host-utils.d.ts.map +1 -1
- package/dist/modes/interactive/components/chat-session-host-utils.js +2 -0
- package/dist/modes/interactive/components/chat-session-host-utils.js.map +1 -1
- package/dist/modes/interactive/components/chat-session-host.d.ts +17 -2
- package/dist/modes/interactive/components/chat-session-host.d.ts.map +1 -1
- package/dist/modes/interactive/components/chat-session-host.js +100 -3
- package/dist/modes/interactive/components/chat-session-host.js.map +1 -1
- package/dist/modes/interactive/components/chat-transcript.d.ts +1 -0
- package/dist/modes/interactive/components/chat-transcript.d.ts.map +1 -1
- package/dist/modes/interactive/components/chat-transcript.js +1 -1
- package/dist/modes/interactive/components/chat-transcript.js.map +1 -1
- package/dist/modes/interactive/components/compaction-boundary-message.js.map +1 -1
- package/dist/modes/interactive/components/config-selector-list.js.map +1 -1
- package/dist/modes/interactive/components/config-selector.js.map +1 -1
- package/dist/modes/interactive/components/custom-editor.js.map +1 -1
- package/dist/modes/interactive/components/custom-entry.js.map +1 -1
- package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-message.js +12 -0
- package/dist/modes/interactive/components/custom-message.js.map +1 -1
- package/dist/modes/interactive/components/daxnuts.js.map +1 -1
- package/dist/modes/interactive/components/diff.js.map +1 -1
- package/dist/modes/interactive/components/dynamic-border.js.map +1 -1
- package/dist/modes/interactive/components/earendil-announcement.js.map +1 -1
- package/dist/modes/interactive/components/extension-editor.js.map +1 -1
- package/dist/modes/interactive/components/extension-input.js.map +1 -1
- package/dist/modes/interactive/components/extension-selector.js.map +1 -1
- package/dist/modes/interactive/components/first-time-setup.d.ts +1 -1
- package/dist/modes/interactive/components/first-time-setup.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts +7 -6
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +27 -9
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/host-input-form-mount.js.map +1 -1
- package/dist/modes/interactive/components/host-input-form.d.ts +1 -1
- package/dist/modes/interactive/components/host-input-form.js.map +1 -1
- package/dist/modes/interactive/components/index.d.ts +2 -2
- package/dist/modes/interactive/components/index.js.map +1 -1
- package/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
- package/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/dist/modes/interactive/components/mermaid.d.ts +1 -1
- package/dist/modes/interactive/components/mermaid.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
- package/dist/modes/interactive/components/reserved-bottom-overlay.js.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
- package/dist/modes/interactive/components/scroll-widget.d.ts +23 -0
- package/dist/modes/interactive/components/scroll-widget.d.ts.map +1 -0
- package/dist/modes/interactive/components/scroll-widget.js +61 -0
- package/dist/modes/interactive/components/scroll-widget.js.map +1 -0
- package/dist/modes/interactive/components/session-selector-header.js.map +1 -1
- package/dist/modes/interactive/components/session-selector-list.js.map +1 -1
- package/dist/modes/interactive/components/session-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector-items.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector-submenus.d.ts +1 -1
- package/dist/modes/interactive/components/settings-selector-submenus.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector-types.d.ts +1 -1
- package/dist/modes/interactive/components/settings-selector-types.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/show-images-selector.js.map +1 -1
- package/dist/modes/interactive/components/skill-invocation-message.d.ts +1 -1
- package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
- package/dist/modes/interactive/components/task-completion-message.d.ts +13 -0
- package/dist/modes/interactive/components/task-completion-message.d.ts.map +1 -0
- package/dist/modes/interactive/components/task-completion-message.js +65 -0
- package/dist/modes/interactive/components/task-completion-message.js.map +1 -0
- package/dist/modes/interactive/components/task-detail.d.ts +27 -0
- package/dist/modes/interactive/components/task-detail.d.ts.map +1 -0
- package/dist/modes/interactive/components/task-detail.js +107 -0
- package/dist/modes/interactive/components/task-detail.js.map +1 -0
- package/dist/modes/interactive/components/task-inspector.d.ts +50 -0
- package/dist/modes/interactive/components/task-inspector.d.ts.map +1 -0
- package/dist/modes/interactive/components/task-inspector.js +599 -0
- package/dist/modes/interactive/components/task-inspector.js.map +1 -0
- package/dist/modes/interactive/components/task-list.d.ts +18 -0
- package/dist/modes/interactive/components/task-list.d.ts.map +1 -0
- package/dist/modes/interactive/components/task-list.js +59 -0
- package/dist/modes/interactive/components/task-list.js.map +1 -0
- package/dist/modes/interactive/components/task-live-transcript.d.ts +17 -0
- package/dist/modes/interactive/components/task-live-transcript.d.ts.map +1 -0
- package/dist/modes/interactive/components/task-live-transcript.js +41 -0
- package/dist/modes/interactive/components/task-live-transcript.js.map +1 -0
- package/dist/modes/interactive/components/task-navigation.d.ts +38 -0
- package/dist/modes/interactive/components/task-navigation.d.ts.map +1 -0
- package/dist/modes/interactive/components/task-navigation.js +93 -0
- package/dist/modes/interactive/components/task-navigation.js.map +1 -0
- package/dist/modes/interactive/components/task-row.d.ts +34 -0
- package/dist/modes/interactive/components/task-row.d.ts.map +1 -0
- package/dist/modes/interactive/components/task-row.js +165 -0
- package/dist/modes/interactive/components/task-row.js.map +1 -0
- package/dist/modes/interactive/components/theme-selector.js.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/components/transcript-follow-indicator.js.map +1 -1
- package/dist/modes/interactive/components/tree-selector-component.js.map +1 -1
- package/dist/modes/interactive/components/tree-selector-content.js.map +1 -1
- package/dist/modes/interactive/components/tree-selector-help.js.map +1 -1
- package/dist/modes/interactive/components/tree-selector-label-input.js.map +1 -1
- package/dist/modes/interactive/components/tree-selector-list.js.map +1 -1
- package/dist/modes/interactive/components/trust-selector.js.map +1 -1
- package/dist/modes/interactive/components/user-message-selector.js.map +1 -1
- package/dist/modes/interactive/components/user-message.js.map +1 -1
- package/dist/modes/interactive/components/working-status.js.map +1 -1
- package/dist/modes/interactive/interactive-agent-events.js +8 -2
- package/dist/modes/interactive/interactive-agent-events.js.map +1 -1
- package/dist/modes/interactive/interactive-auth-login.js +3 -1
- package/dist/modes/interactive/interactive-auth-login.js.map +1 -1
- package/dist/modes/interactive/interactive-autocomplete.js +9 -30
- package/dist/modes/interactive/interactive-autocomplete.js.map +1 -1
- package/dist/modes/interactive/interactive-deferred-startup.js +2 -1
- package/dist/modes/interactive/interactive-deferred-startup.js.map +1 -1
- package/dist/modes/interactive/interactive-extension-context.js +14 -4
- package/dist/modes/interactive/interactive-extension-context.js.map +1 -1
- package/dist/modes/interactive/interactive-extension-custom-ui.js +52 -4
- package/dist/modes/interactive/interactive-extension-custom-ui.js.map +1 -1
- package/dist/modes/interactive/interactive-extension-runtime.js +11 -3
- package/dist/modes/interactive/interactive-extension-runtime.js.map +1 -1
- package/dist/modes/interactive/interactive-extension-widgets.js +9 -1
- package/dist/modes/interactive/interactive-extension-widgets.js.map +1 -1
- package/dist/modes/interactive/interactive-input-handling.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-input-handling.js +19 -0
- package/dist/modes/interactive/interactive-input-handling.js.map +1 -1
- package/dist/modes/interactive/interactive-mode-base.d.ts +7 -1
- package/dist/modes/interactive/interactive-mode-base.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode-base.js +10 -4
- package/dist/modes/interactive/interactive-mode-base.js.map +1 -1
- package/dist/modes/interactive/interactive-mode-deps.d.ts +6 -6
- package/dist/modes/interactive/interactive-mode-deps.js.map +1 -1
- package/dist/modes/interactive/interactive-mode-surface.d.ts +3 -2
- 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.d.ts +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +3 -0
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/interactive-process-lifecycle.js +4 -1
- package/dist/modes/interactive/interactive-process-lifecycle.js.map +1 -1
- package/dist/modes/interactive/interactive-render-chat.js +30 -4
- package/dist/modes/interactive/interactive-render-chat.js.map +1 -1
- package/dist/modes/interactive/interactive-session-routing.js +33 -23
- package/dist/modes/interactive/interactive-session-routing.js.map +1 -1
- package/dist/modes/interactive/interactive-session-runtime.js +1 -0
- package/dist/modes/interactive/interactive-session-runtime.js.map +1 -1
- package/dist/modes/interactive/interactive-slash-commands.js.map +1 -1
- package/dist/modes/interactive/interactive-startup.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-startup.js +3 -0
- package/dist/modes/interactive/interactive-startup.js.map +1 -1
- package/dist/modes/interactive/interactive-summarization-retry-events.js +2 -2
- package/dist/modes/interactive/interactive-summarization-retry-events.js.map +1 -1
- package/dist/modes/interactive/interactive-task-projection.d.ts +13 -0
- package/dist/modes/interactive/interactive-task-projection.d.ts.map +1 -0
- package/dist/modes/interactive/interactive-task-projection.js +72 -0
- package/dist/modes/interactive/interactive-task-projection.js.map +1 -0
- package/dist/modes/interactive/interactive-tui.js.map +1 -1
- package/dist/modes/interactive/interactive-windows-subshell.d.ts +17 -0
- package/dist/modes/interactive/interactive-windows-subshell.d.ts.map +1 -0
- package/dist/modes/interactive/interactive-windows-subshell.js +92 -0
- package/dist/modes/interactive/interactive-windows-subshell.js.map +1 -0
- package/dist/modes/interactive/skill-command-autocomplete.d.ts +12 -0
- package/dist/modes/interactive/skill-command-autocomplete.d.ts.map +1 -0
- package/dist/modes/interactive/skill-command-autocomplete.js +69 -0
- package/dist/modes/interactive/skill-command-autocomplete.js.map +1 -0
- package/dist/modes/interactive/theme/theme-class.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme-class.js +4 -1
- package/dist/modes/interactive/theme/theme-class.js.map +1 -1
- package/dist/modes/interactive/theme/theme-controller.d.ts +1 -1
- package/dist/modes/interactive/theme/theme-controller.js.map +1 -1
- package/dist/modes/interactive-engine/activity-watchdog.d.ts +2 -2
- package/dist/modes/interactive-engine/activity-watchdog.d.ts.map +1 -1
- package/dist/modes/interactive-engine/activity-watchdog.js.map +1 -1
- package/dist/modes/interactive-engine/create-isolated-runtime.d.ts +1 -1
- package/dist/modes/interactive-engine/create-isolated-runtime.js.map +1 -1
- package/dist/modes/interactive-engine/engine-custom-ui.d.ts +9 -10
- package/dist/modes/interactive-engine/engine-custom-ui.d.ts.map +1 -1
- package/dist/modes/interactive-engine/engine-custom-ui.js +29 -12
- package/dist/modes/interactive-engine/engine-custom-ui.js.map +1 -1
- package/dist/modes/interactive-engine/engine-diagnostic-view.d.ts +3 -1
- package/dist/modes/interactive-engine/engine-diagnostic-view.d.ts.map +1 -1
- package/dist/modes/interactive-engine/engine-diagnostic-view.js +11 -0
- package/dist/modes/interactive-engine/engine-diagnostic-view.js.map +1 -1
- package/dist/modes/interactive-engine/engine-dialog-host.d.ts +2 -2
- package/dist/modes/interactive-engine/engine-dialog-host.d.ts.map +1 -1
- package/dist/modes/interactive-engine/engine-dialog-host.js +4 -1
- package/dist/modes/interactive-engine/engine-dialog-host.js.map +1 -1
- package/dist/modes/interactive-engine/engine-project-trust.d.ts +10 -0
- package/dist/modes/interactive-engine/engine-project-trust.d.ts.map +1 -0
- package/dist/modes/interactive-engine/engine-project-trust.js +28 -0
- package/dist/modes/interactive-engine/engine-project-trust.js.map +1 -0
- package/dist/modes/interactive-engine/engine-render-service.d.ts +1 -1
- package/dist/modes/interactive-engine/engine-render-service.js.map +1 -1
- package/dist/modes/interactive-engine/extension-ui-bridge.d.ts +3 -1
- package/dist/modes/interactive-engine/extension-ui-bridge.d.ts.map +1 -1
- package/dist/modes/interactive-engine/extension-ui-bridge.js +7 -1
- package/dist/modes/interactive-engine/extension-ui-bridge.js.map +1 -1
- package/dist/modes/interactive-engine/input-form-host.d.ts +2 -2
- package/dist/modes/interactive-engine/input-form-host.js.map +1 -1
- package/dist/modes/interactive-engine/isolated-auth.d.ts +1 -1
- package/dist/modes/interactive-engine/isolated-auth.js.map +1 -1
- package/dist/modes/interactive-engine/isolated-runtime.d.ts +5 -2
- package/dist/modes/interactive-engine/isolated-runtime.d.ts.map +1 -1
- package/dist/modes/interactive-engine/isolated-runtime.js +42 -4
- package/dist/modes/interactive-engine/isolated-runtime.js.map +1 -1
- package/dist/modes/interactive-engine/protocol.d.ts +21 -1
- package/dist/modes/interactive-engine/protocol.d.ts.map +1 -1
- package/dist/modes/interactive-engine/protocol.js +53 -2
- package/dist/modes/interactive-engine/protocol.js.map +1 -1
- package/dist/modes/interactive-engine/remote-component.d.ts +2 -2
- package/dist/modes/interactive-engine/remote-component.d.ts.map +1 -1
- package/dist/modes/interactive-engine/remote-component.js +19 -8
- package/dist/modes/interactive-engine/remote-component.js.map +1 -1
- package/dist/modes/interactive-engine/remote-model-catalog.d.ts +1 -1
- package/dist/modes/interactive-engine/remote-model-catalog.js.map +1 -1
- package/dist/modes/interactive-engine/remote-renderer.d.ts +1 -1
- package/dist/modes/interactive-engine/remote-renderer.js.map +1 -1
- package/dist/modes/interactive-engine/session-picker-host.d.ts +2 -2
- package/dist/modes/interactive-engine/session-picker-host.js.map +1 -1
- package/dist/modes/json-event.d.ts +1 -1
- package/dist/modes/json-event.js.map +1 -1
- package/dist/modes/print-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-bash-request-owners.d.ts +2 -2
- package/dist/modes/rpc/rpc-bash-request-owners.js.map +1 -1
- package/dist/modes/rpc/rpc-client-api.d.ts +2 -2
- package/dist/modes/rpc/rpc-client-api.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client-api.js +2 -2
- package/dist/modes/rpc/rpc-client-api.js.map +1 -1
- package/dist/modes/rpc/rpc-client-process.d.ts +2 -0
- package/dist/modes/rpc/rpc-client-process.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client-process.js +23 -1
- package/dist/modes/rpc/rpc-client-process.js.map +1 -1
- package/dist/modes/rpc/rpc-client-waits.d.ts +1 -1
- package/dist/modes/rpc/rpc-client-waits.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts +3 -1
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +40 -3
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-command-handler.d.ts +4 -2
- package/dist/modes/rpc/rpc-command-handler.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-command-handler.js +12 -4
- package/dist/modes/rpc/rpc-command-handler.js.map +1 -1
- package/dist/modes/rpc/rpc-extension-ui.d.ts +1 -1
- package/dist/modes/rpc/rpc-extension-ui.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-extension-ui.js +2 -1
- package/dist/modes/rpc/rpc-extension-ui.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +12 -2
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-provider-auth.d.ts +1 -1
- package/dist/modes/rpc/rpc-provider-auth.js.map +1 -1
- package/dist/modes/rpc/rpc-session-binding.d.ts +4 -1
- package/dist/modes/rpc/rpc-session-binding.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-session-binding.js +35 -1
- package/dist/modes/rpc/rpc-session-binding.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +17 -1
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/modes/rpc/task-ui-bridge.d.ts +9 -0
- package/dist/modes/rpc/task-ui-bridge.d.ts.map +1 -0
- package/dist/modes/rpc/task-ui-bridge.js +146 -0
- package/dist/modes/rpc/task-ui-bridge.js.map +1 -0
- package/dist/self-update-plan.js.map +1 -1
- package/dist/utils/markit.d.ts +2 -0
- package/dist/utils/markit.d.ts.map +1 -1
- package/dist/utils/markit.js +65 -5
- package/dist/utils/markit.js.map +1 -1
- package/docs/background-tasks.md +232 -0
- package/docs/build.md +51 -0
- package/docs/changelog.mdx +8 -8
- package/docs/compaction/reference.md +267 -0
- package/docs/compaction.md +39 -200
- package/docs/computer-use.md +425 -0
- package/docs/containerization.md +9 -5
- package/docs/custom-provider/api-reference.md +145 -0
- package/docs/custom-provider/oauth.md +131 -0
- package/docs/custom-provider/override.md +34 -0
- package/docs/custom-provider/registration.md +163 -0
- package/docs/custom-provider/streaming.md +214 -0
- package/docs/custom-provider.md +43 -607
- package/docs/development.md +68 -30
- package/docs/docs.json +199 -73
- package/docs/environment-variables.md +2 -2
- package/docs/extensions/api-reference.md +1003 -0
- package/docs/extensions/authoring.md +676 -0
- package/docs/extensions/events.md +793 -0
- package/docs/extensions/examples.md +94 -0
- package/docs/extensions/ui.md +470 -0
- package/docs/extensions.md +241 -2623
- package/docs/getting-started/authentication.md +55 -0
- package/docs/getting-started/first-session.md +172 -0
- package/docs/getting-started/installation.md +154 -0
- package/docs/getting-started/project-instructions.md +43 -0
- package/docs/guides/configuration.md +65 -0
- package/docs/guides/intercom.md +24 -0
- package/docs/guides/non-interactive.md +33 -0
- package/docs/guides/subagents.md +24 -0
- package/docs/guides/workflows.md +27 -0
- package/docs/guides.md +41 -0
- package/docs/herdr.md +55 -0
- package/docs/index.md +13 -44
- package/docs/intercom/operations.md +178 -0
- package/docs/intercom/reference.md +150 -0
- package/docs/intercom.md +61 -251
- package/docs/json.md +17 -0
- package/docs/keybindings.md +36 -2
- package/docs/llama-cpp.md +5 -0
- package/docs/models/artificial-analysis-index.md +89 -0
- package/docs/models/evals.md +225 -148
- package/docs/models/model-selection.md +30 -21
- package/docs/models/pareto-efficiency.md +4 -4
- package/docs/models/reference.md +601 -0
- package/docs/models.md +45 -550
- package/docs/packages/authoring.md +88 -0
- package/docs/packages/reference.md +43 -0
- package/docs/packages.md +28 -107
- package/docs/programmatic.md +29 -0
- package/docs/prompt-templates.md +11 -0
- package/docs/providers/reference.md +23 -0
- package/docs/providers.md +59 -62
- package/docs/quickstart.md +45 -239
- package/docs/reference/cli.md +252 -0
- package/docs/reference.md +52 -0
- package/docs/rpc/examples.md +64 -0
- package/docs/rpc/extension-ui.md +198 -0
- package/docs/rpc/protocol.md +1341 -0
- package/docs/rpc.md +109 -1346
- package/docs/sdk/reference.md +1090 -0
- package/docs/sdk.md +64 -756
- package/docs/session-format.md +2 -0
- package/docs/sessions.md +6 -10
- package/docs/settings.md +45 -48
- package/docs/skills/authoring.md +95 -0
- package/docs/skills/reference.md +60 -0
- package/docs/skills.md +37 -117
- package/docs/subagents/authoring.md +37 -0
- package/docs/subagents/reference.md +60 -0
- package/docs/subagents.md +90 -78
- package/docs/terminal-setup.md +1 -1
- package/docs/themes/reference.md +176 -0
- package/docs/themes.md +25 -135
- package/docs/tmux.md +7 -0
- package/docs/tools/edit.md +5 -0
- package/docs/tools.md +67 -1
- package/docs/tui/reference.md +343 -0
- package/docs/tui.md +83 -285
- package/docs/usage.md +31 -210
- package/docs/web-access.md +50 -0
- package/docs/windows.md +6 -5
- package/docs/workflows/api-reference.md +31 -12
- package/docs/workflows/authoring.md +7 -5
- package/docs/workflows/builtins.md +11 -8
- package/docs/workflows/operations.md +117 -39
- package/docs/workflows/reliable-design.md +59 -10
- package/docs/workflows/verification.md +116 -32
- package/docs/workflows.md +7 -3
- package/examples/extensions/gondolin/index.ts +116 -148
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/ssh.ts +56 -34
- package/npm-shrinkwrap.json +798 -678
- package/package.json +11 -11
- /package/dist/builtin/workflows/builtin/{chunk-cg9tmks0.js → chunk-n1910xc4.js} +0 -0
- /package/dist/builtin/workflows/builtin/{chunk-wpckd35c.js → chunk-rc5ec5xx.js} +0 -0
- /package/dist/builtin/workflows/builtin/{chunk-7at6dnkr.js → chunk-tgt0s5e5.js} +0 -0
- /package/dist/builtin/workflows/builtin/{chunk-bfkmzv9h.js → chunk-xtxcq5tj.js} +0 -0
|
@@ -302,7 +302,7 @@ function createSessionScopedSingleton(key, createLocal) {
|
|
|
302
302
|
const live = () => shared.instance ?? instance;
|
|
303
303
|
const current = () => live();
|
|
304
304
|
const adoptWithResult = (scope, options) => {
|
|
305
|
-
const
|
|
305
|
+
const current = live();
|
|
306
306
|
let targetCreated = false;
|
|
307
307
|
const target = sessionScopedExtensionState(scope, key, () => {
|
|
308
308
|
targetCreated = true;
|
|
@@ -311,8 +311,8 @@ function createSessionScopedSingleton(key, createLocal) {
|
|
|
311
311
|
shared.localClaimed = true;
|
|
312
312
|
return shared.local;
|
|
313
313
|
});
|
|
314
|
-
const preservedCurrent = !targetCreated && target !==
|
|
315
|
-
shared.instance = preservedCurrent ?
|
|
314
|
+
const preservedCurrent = !targetCreated && target !== current && options?.preserveCurrentWhenTargetExists?.(current, target) === true;
|
|
315
|
+
shared.instance = preservedCurrent ? current : target;
|
|
316
316
|
instance = shared.instance;
|
|
317
317
|
return { instance: shared.instance, preservedCurrent };
|
|
318
318
|
};
|
|
@@ -569,17 +569,17 @@ function cloneWorkflowExitSnapshotValue(value, seen, stack = new Set) {
|
|
|
569
569
|
return stack.has(objectValue) ? makeWorkflowExitSnapshotInvalidValue("circular object") : previousClone;
|
|
570
570
|
}
|
|
571
571
|
if (Array.isArray(value)) {
|
|
572
|
-
const
|
|
573
|
-
seen.set(objectValue,
|
|
572
|
+
const clone = [];
|
|
573
|
+
seen.set(objectValue, clone);
|
|
574
574
|
stack.add(objectValue);
|
|
575
575
|
try {
|
|
576
576
|
for (let index = 0;index < value.length; index += 1) {
|
|
577
|
-
|
|
577
|
+
clone[index] = cloneWorkflowExitSnapshotValue(value[index], seen, stack);
|
|
578
578
|
}
|
|
579
579
|
} finally {
|
|
580
580
|
stack.delete(objectValue);
|
|
581
581
|
}
|
|
582
|
-
return
|
|
582
|
+
return clone;
|
|
583
583
|
}
|
|
584
584
|
if (!isPlainWorkflowExitSnapshotObject(objectValue)) {
|
|
585
585
|
return makeWorkflowExitSnapshotInvalidValue(workflowSerializableTypeName(value));
|
|
@@ -952,7 +952,7 @@ function buildStagePromptAdapter(id, kind, args, createdAt) {
|
|
|
952
952
|
}
|
|
953
953
|
|
|
954
954
|
// dist/builtin/workflows/src/shared/stage-ui-broker.ts
|
|
955
|
-
import { randomUUID } from "node:crypto";
|
|
955
|
+
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
956
956
|
|
|
957
957
|
// dist/builtin/workflows/src/shared/pending-stage-delivery.ts
|
|
958
958
|
var PENDING_STAGE_MESSAGE_LIMIT = 50;
|
|
@@ -963,7 +963,7 @@ function queueStageMessage(messages, input, senderGroup, runGroup, stageIdentity
|
|
|
963
963
|
}
|
|
964
964
|
const messageId = input.message.id;
|
|
965
965
|
const queued = pendingStageMessagesFor(messages, input.runId, input.stageKey, stageIdentity);
|
|
966
|
-
const existing = messages.find((
|
|
966
|
+
const existing = messages.find((entry) => entry.runId === input.runId && entry.id === messageId);
|
|
967
967
|
if (existing !== undefined) {
|
|
968
968
|
if (pendingStageMessageSignature(existing, stageIdentity) !== pendingStageMessageSignature(input, stageIdentity)) {
|
|
969
969
|
return {
|
|
@@ -1013,7 +1013,7 @@ function queueStickyStageMessage(messages, input, senderGroup, runGroup) {
|
|
|
1013
1013
|
return { ok: false, reason: "group_mismatch", runId: input.runId, stageKey: input.targetPath };
|
|
1014
1014
|
}
|
|
1015
1015
|
const messageId = input.message.id;
|
|
1016
|
-
const existing = messages.find((
|
|
1016
|
+
const existing = messages.find((entry) => entry.runId === input.runId && entry.id === messageId);
|
|
1017
1017
|
if (existing !== undefined) {
|
|
1018
1018
|
if (pendingStageMessageSignature(existing) !== pendingStageMessageSignature(input)) {
|
|
1019
1019
|
return {
|
|
@@ -1064,7 +1064,7 @@ function queuedStickyCount(messages, runId, targetPath) {
|
|
|
1064
1064
|
return messages.filter((entry) => entry.runId === runId && entry.sticky === true && entry.targetPath === targetPath && entry.status === "queued").length;
|
|
1065
1065
|
}
|
|
1066
1066
|
function recordPendingStageMessageDeliveries(messages, runId, messageId, records, deliveredAt) {
|
|
1067
|
-
const index = messages.findIndex((
|
|
1067
|
+
const index = messages.findIndex((entry) => entry.runId === runId && entry.id === messageId && entry.sticky === true && entry.status === "queued");
|
|
1068
1068
|
if (index < 0)
|
|
1069
1069
|
return messages;
|
|
1070
1070
|
const entry = messages[index];
|
|
@@ -1507,6 +1507,7 @@ function compactStage(stage) {
|
|
|
1507
1507
|
attemptedModels: _attemptedModels,
|
|
1508
1508
|
modelAttempts: _modelAttempts,
|
|
1509
1509
|
result: _result,
|
|
1510
|
+
structured: _structured,
|
|
1510
1511
|
...metadata
|
|
1511
1512
|
} = stage;
|
|
1512
1513
|
return {
|
|
@@ -1565,6 +1566,173 @@ function deepFreezeGraphValue(value) {
|
|
|
1565
1566
|
}
|
|
1566
1567
|
}
|
|
1567
1568
|
|
|
1569
|
+
// dist/builtin/workflows/src/shared/workflow-observation-runtime.ts
|
|
1570
|
+
import { randomUUID } from "node:crypto";
|
|
1571
|
+
|
|
1572
|
+
// dist/builtin/workflows/src/shared/workflow-activity.ts
|
|
1573
|
+
function workflowActivityNodeKey(runId, nodeId) {
|
|
1574
|
+
return `${runId}:${nodeId}`;
|
|
1575
|
+
}
|
|
1576
|
+
|
|
1577
|
+
// dist/builtin/workflows/src/shared/workflow-observation-runtime.ts
|
|
1578
|
+
class WorkflowObservationRuntime {
|
|
1579
|
+
runs;
|
|
1580
|
+
invalidate;
|
|
1581
|
+
liveRunIds = new Set;
|
|
1582
|
+
executingStageIds = new Set;
|
|
1583
|
+
executingToolNodeIds = new Set;
|
|
1584
|
+
stoppingRunIds = new Set;
|
|
1585
|
+
retryingStageIds = new Set;
|
|
1586
|
+
acknowledgedFailureRunIds = new Set;
|
|
1587
|
+
listeners = new Set;
|
|
1588
|
+
replayStageIds = new Set;
|
|
1589
|
+
previous = new Map;
|
|
1590
|
+
recoveryDepth = 0;
|
|
1591
|
+
constructor(runs, invalidate) {
|
|
1592
|
+
this.runs = runs;
|
|
1593
|
+
this.invalidate = invalidate;
|
|
1594
|
+
}
|
|
1595
|
+
get recovering() {
|
|
1596
|
+
return this.recoveryDepth > 0;
|
|
1597
|
+
}
|
|
1598
|
+
startRun(runId) {
|
|
1599
|
+
this.liveRunIds.add(runId);
|
|
1600
|
+
this.stoppingRunIds.delete(runId);
|
|
1601
|
+
}
|
|
1602
|
+
finishRun(runId) {
|
|
1603
|
+
this.liveRunIds.delete(runId);
|
|
1604
|
+
this.stoppingRunIds.delete(runId);
|
|
1605
|
+
for (const ids of [
|
|
1606
|
+
this.executingStageIds,
|
|
1607
|
+
this.executingToolNodeIds,
|
|
1608
|
+
this.retryingStageIds,
|
|
1609
|
+
this.replayStageIds
|
|
1610
|
+
]) {
|
|
1611
|
+
for (const id of ids)
|
|
1612
|
+
if (id.startsWith(`${runId}:`))
|
|
1613
|
+
ids.delete(id);
|
|
1614
|
+
}
|
|
1615
|
+
this.invalidate();
|
|
1616
|
+
}
|
|
1617
|
+
emit(event) {
|
|
1618
|
+
for (const listener of this.listeners) {
|
|
1619
|
+
try {
|
|
1620
|
+
listener(event);
|
|
1621
|
+
} catch {}
|
|
1622
|
+
}
|
|
1623
|
+
}
|
|
1624
|
+
rootRunId(run) {
|
|
1625
|
+
if (run.rootRunId !== undefined)
|
|
1626
|
+
return run.rootRunId;
|
|
1627
|
+
if (run.parentRunId === undefined)
|
|
1628
|
+
return run.id;
|
|
1629
|
+
const parent = this.runs().find((candidate) => candidate.id === run.parentRunId);
|
|
1630
|
+
return parent ? this.rootRunId(parent) : run.parentRunId;
|
|
1631
|
+
}
|
|
1632
|
+
lifecycle(target, attribution = "unknown") {
|
|
1633
|
+
if (this.recovering && !this.liveRunIds.has(target.runId))
|
|
1634
|
+
return;
|
|
1635
|
+
const run = this.runs().find((candidate) => candidate.id === target.runId);
|
|
1636
|
+
if (!run)
|
|
1637
|
+
return;
|
|
1638
|
+
const rootRunId = this.rootRunId(run);
|
|
1639
|
+
const now = Date.now();
|
|
1640
|
+
this.emit({
|
|
1641
|
+
kind: "lifecycle",
|
|
1642
|
+
event: {
|
|
1643
|
+
type: "workflow_lifecycle",
|
|
1644
|
+
eventId: randomUUID(),
|
|
1645
|
+
runId: run.id,
|
|
1646
|
+
rootRunId,
|
|
1647
|
+
occurredAt: now,
|
|
1648
|
+
observedAt: now,
|
|
1649
|
+
target: canonicalTarget(target, rootRunId),
|
|
1650
|
+
attribution,
|
|
1651
|
+
delivery: target.kind === "stage" && this.replayStageIds.has(workflowActivityNodeKey(run.id, target.stageId)) ? "replay" : "live"
|
|
1652
|
+
}
|
|
1653
|
+
});
|
|
1654
|
+
}
|
|
1655
|
+
control(runId, action, attribution = "unknown") {
|
|
1656
|
+
const run = this.runs().find((candidate) => candidate.id === runId);
|
|
1657
|
+
if (!run)
|
|
1658
|
+
return;
|
|
1659
|
+
if ((action === "quit" || action === "kill" || action === "pause") && this.liveRunIds.has(runId))
|
|
1660
|
+
this.stoppingRunIds.add(runId);
|
|
1661
|
+
if (action === "resume")
|
|
1662
|
+
this.stoppingRunIds.delete(runId);
|
|
1663
|
+
this.lifecycle({ kind: "run", runId, status: run.status, action }, attribution);
|
|
1664
|
+
this.invalidate();
|
|
1665
|
+
}
|
|
1666
|
+
heartbeat(runId, scheduledAt, intervalMinutes) {
|
|
1667
|
+
const run = this.runs().find((candidate) => candidate.id === runId);
|
|
1668
|
+
if (run)
|
|
1669
|
+
this.emit({
|
|
1670
|
+
kind: "heartbeat",
|
|
1671
|
+
event: { type: "workflow_heartbeat", runId, rootRunId: this.rootRunId(run), scheduledAt, intervalMinutes }
|
|
1672
|
+
});
|
|
1673
|
+
}
|
|
1674
|
+
beginRecovery() {
|
|
1675
|
+
this.recoveryDepth++;
|
|
1676
|
+
if (this.recoveryDepth === 1)
|
|
1677
|
+
this.emit({ kind: "availability" });
|
|
1678
|
+
let ended = false;
|
|
1679
|
+
return () => {
|
|
1680
|
+
if (ended)
|
|
1681
|
+
return;
|
|
1682
|
+
ended = true;
|
|
1683
|
+
this.capture();
|
|
1684
|
+
this.recoveryDepth--;
|
|
1685
|
+
if (!this.recovering)
|
|
1686
|
+
this.emit({ kind: "availability" });
|
|
1687
|
+
};
|
|
1688
|
+
}
|
|
1689
|
+
capture() {
|
|
1690
|
+
const next = new Map;
|
|
1691
|
+
const visit = (key, target, historical = false) => {
|
|
1692
|
+
next.set(key, target);
|
|
1693
|
+
const previous = this.previous.get(key);
|
|
1694
|
+
if (!historical && this.liveRunIds.has(target.runId) && previous?.status !== target.status) {
|
|
1695
|
+
this.lifecycle(previous && previous.kind !== "prompt" && target.kind !== "prompt" ? { ...target, previousStatus: previous.status } : target, this.runs().find((run) => run.id === target.runId)?.origin);
|
|
1696
|
+
}
|
|
1697
|
+
};
|
|
1698
|
+
for (const run of this.runs()) {
|
|
1699
|
+
const existing = this.previous.has(`run:${run.id}`);
|
|
1700
|
+
visit(`run:${run.id}`, { kind: "run", runId: run.id, status: run.status });
|
|
1701
|
+
for (const stage of run.stages) {
|
|
1702
|
+
visit(`stage:${workflowActivityNodeKey(run.id, stage.id)}`, { kind: "stage", runId: run.id, stageId: stage.id, stageName: stage.name, status: stage.status }, !existing);
|
|
1703
|
+
if (stage.pendingPrompt)
|
|
1704
|
+
visit(`prompt:${stage.pendingPrompt.id}`, {
|
|
1705
|
+
kind: "prompt",
|
|
1706
|
+
runId: run.id,
|
|
1707
|
+
stageId: stage.id,
|
|
1708
|
+
promptId: stage.pendingPrompt.id,
|
|
1709
|
+
status: "opened"
|
|
1710
|
+
}, !existing);
|
|
1711
|
+
}
|
|
1712
|
+
for (const tool of run.toolNodes ?? [])
|
|
1713
|
+
visit(`tool:${workflowActivityNodeKey(run.id, tool.id)}`, { kind: "tool", runId: run.id, toolNodeId: tool.id, toolName: tool.name, status: tool.status }, !existing);
|
|
1714
|
+
if (run.pendingPrompt)
|
|
1715
|
+
visit(`prompt:${run.pendingPrompt.id}`, { kind: "prompt", runId: run.id, promptId: run.pendingPrompt.id, status: "opened" }, !existing);
|
|
1716
|
+
}
|
|
1717
|
+
this.previous = next;
|
|
1718
|
+
}
|
|
1719
|
+
}
|
|
1720
|
+
var workflowObservationRuntimeKey = Symbol.for("atomic-workflows/store-observation-runtime@1");
|
|
1721
|
+
function canonicalTarget(target, rootRunId) {
|
|
1722
|
+
if (target.runId === rootRunId)
|
|
1723
|
+
return target;
|
|
1724
|
+
switch (target.kind) {
|
|
1725
|
+
case "stage":
|
|
1726
|
+
return { ...target, stageId: workflowActivityNodeKey(target.runId, target.stageId) };
|
|
1727
|
+
case "tool":
|
|
1728
|
+
return { ...target, toolNodeId: workflowActivityNodeKey(target.runId, target.toolNodeId) };
|
|
1729
|
+
case "prompt":
|
|
1730
|
+
return target.stageId === undefined ? target : { ...target, stageId: workflowActivityNodeKey(target.runId, target.stageId) };
|
|
1731
|
+
case "run":
|
|
1732
|
+
return target;
|
|
1733
|
+
}
|
|
1734
|
+
}
|
|
1735
|
+
|
|
1568
1736
|
// dist/builtin/workflows/src/shared/store-internal.ts
|
|
1569
1737
|
var TERMINAL_STATUSES = new Set([
|
|
1570
1738
|
"completed",
|
|
@@ -1667,6 +1835,7 @@ function createStoreState() {
|
|
|
1667
1835
|
function createStoreContext(state = createStoreState()) {
|
|
1668
1836
|
let cachedGraphVersion = -1;
|
|
1669
1837
|
let cachedGraphSnapshot;
|
|
1838
|
+
const observation = new WorkflowObservationRuntime(() => state.runs, bumpAndNotify);
|
|
1670
1839
|
function snapshot() {
|
|
1671
1840
|
return JSON.parse(JSON.stringify({ runs: state.runs, notices: state.notices, version: state.version }));
|
|
1672
1841
|
}
|
|
@@ -1678,6 +1847,7 @@ function createStoreContext(state = createStoreState()) {
|
|
|
1678
1847
|
return cachedGraphSnapshot;
|
|
1679
1848
|
}
|
|
1680
1849
|
function notify() {
|
|
1850
|
+
observation.capture();
|
|
1681
1851
|
for (const fn of state.invalidationListeners) {
|
|
1682
1852
|
try {
|
|
1683
1853
|
fn();
|
|
@@ -1733,6 +1903,7 @@ function createStoreContext(state = createStoreState()) {
|
|
|
1733
1903
|
const prompt = stage.pendingPrompt;
|
|
1734
1904
|
if (!prompt)
|
|
1735
1905
|
return;
|
|
1906
|
+
observation.lifecycle({ kind: "prompt", runId, stageId: stage.id, promptId: prompt.id, status: "cancelled" });
|
|
1736
1907
|
stage.pendingPrompt = undefined;
|
|
1737
1908
|
state.stagePromptDrafts.delete(stagePromptDraftKey(runId, stage.id, prompt.id));
|
|
1738
1909
|
rejectPrompt(prompt.id, reason);
|
|
@@ -1744,6 +1915,7 @@ function createStoreContext(state = createStoreState()) {
|
|
|
1744
1915
|
}
|
|
1745
1916
|
return {
|
|
1746
1917
|
state,
|
|
1918
|
+
observation,
|
|
1747
1919
|
snapshot,
|
|
1748
1920
|
graphSnapshot,
|
|
1749
1921
|
notify,
|
|
@@ -1913,8 +2085,8 @@ function createPendingStageDeliveryStoreMethods(context) {
|
|
|
1913
2085
|
};
|
|
1914
2086
|
}
|
|
1915
2087
|
function resolvePendingStageIdentity(run, stageKey) {
|
|
1916
|
-
const exactIds = run.stages.filter((
|
|
1917
|
-
const candidates = exactIds.length > 0 ? exactIds : run.stages.filter((
|
|
2088
|
+
const exactIds = run.stages.filter((stage) => stage.id === stageKey);
|
|
2089
|
+
const candidates = exactIds.length > 0 ? exactIds : run.stages.filter((stage) => stage.name === stageKey);
|
|
1918
2090
|
if (candidates.length !== 1)
|
|
1919
2091
|
return;
|
|
1920
2092
|
const stage = candidates[0];
|
|
@@ -1953,6 +2125,7 @@ function createPromptStoreMethods(context) {
|
|
|
1953
2125
|
const pending = run.pendingPrompt;
|
|
1954
2126
|
if (!pending || pending.id !== promptId)
|
|
1955
2127
|
return false;
|
|
2128
|
+
context.observation.lifecycle({ kind: "prompt", runId, promptId, status: "answered" });
|
|
1956
2129
|
run.pendingPrompt = undefined;
|
|
1957
2130
|
context.bumpAndNotify();
|
|
1958
2131
|
const entry = state.resolvers.get(promptId);
|
|
@@ -2023,6 +2196,13 @@ function createPromptStoreMethods(context) {
|
|
|
2023
2196
|
state.stagePromptAnswers.delete(context.stagePromptAnswerKey(runId, stageId));
|
|
2024
2197
|
delete stage.promptAnswerState;
|
|
2025
2198
|
}
|
|
2199
|
+
context.observation.lifecycle({
|
|
2200
|
+
kind: "prompt",
|
|
2201
|
+
runId,
|
|
2202
|
+
stageId,
|
|
2203
|
+
promptId,
|
|
2204
|
+
status: options.recordAnswer === false ? "cancelled" : "answered"
|
|
2205
|
+
});
|
|
2026
2206
|
stage.pendingPrompt = undefined;
|
|
2027
2207
|
if (stage.status === "awaiting_input") {
|
|
2028
2208
|
stage.status = "running";
|
|
@@ -2239,6 +2419,7 @@ function createRunStoreMethods(context) {
|
|
|
2239
2419
|
}
|
|
2240
2420
|
const pending = run.pendingPrompt;
|
|
2241
2421
|
if (pending) {
|
|
2422
|
+
context.observation.lifecycle({ kind: "prompt", runId, promptId: pending.id, status: "cancelled" });
|
|
2242
2423
|
run.pendingPrompt = undefined;
|
|
2243
2424
|
context.rejectPrompt(pending.id, `atomic-workflows: run ${runId} ended before prompt resolved`);
|
|
2244
2425
|
}
|
|
@@ -2320,6 +2501,7 @@ function createRunStoreMethods(context) {
|
|
|
2320
2501
|
const run = state.runs[index];
|
|
2321
2502
|
const pending = run.pendingPrompt;
|
|
2322
2503
|
if (pending) {
|
|
2504
|
+
context.observation.lifecycle({ kind: "prompt", runId, promptId: pending.id, status: "cancelled" });
|
|
2323
2505
|
context.rejectPrompt(pending.id, `atomic-workflows: run ${runId} was removed before prompt resolved`);
|
|
2324
2506
|
}
|
|
2325
2507
|
context.rejectAllStagePrompts(runId, run, `atomic-workflows: run ${runId} was removed before prompt resolved`);
|
|
@@ -2480,6 +2662,8 @@ function createToolNodeStoreMethods(context) {
|
|
|
2480
2662
|
return false;
|
|
2481
2663
|
node.status = "running";
|
|
2482
2664
|
node.startedAt = startedAt;
|
|
2665
|
+
if (context.observation.liveRunIds.has(runId))
|
|
2666
|
+
context.observation.executingToolNodeIds.add(workflowActivityNodeKey(runId, nodeId));
|
|
2483
2667
|
context.bumpAndNotify();
|
|
2484
2668
|
return true;
|
|
2485
2669
|
},
|
|
@@ -2487,6 +2671,7 @@ function createToolNodeStoreMethods(context) {
|
|
|
2487
2671
|
const node = context.findRun(runId)?.toolNodes?.find((candidate) => candidate.id === nodeId);
|
|
2488
2672
|
if (node === undefined || node.status === "completed" || node.status === "failed" || node.status === "cached" || node.status === "cancelled")
|
|
2489
2673
|
return false;
|
|
2674
|
+
context.observation.executingToolNodeIds.delete(workflowActivityNodeKey(runId, nodeId));
|
|
2490
2675
|
node.status = update.status;
|
|
2491
2676
|
if (update.endedAt !== undefined)
|
|
2492
2677
|
node.endedAt = update.endedAt;
|
|
@@ -2516,6 +2701,9 @@ function createStageStoreMethods(context) {
|
|
|
2516
2701
|
if (!run.stages.some((s) => s.id === stage.id)) {
|
|
2517
2702
|
run.stages.push(stage);
|
|
2518
2703
|
}
|
|
2704
|
+
if (stage.status === "running" && context.observation.liveRunIds.has(runId)) {
|
|
2705
|
+
context.observation.executingStageIds.add(workflowActivityNodeKey(runId, stage.id));
|
|
2706
|
+
}
|
|
2519
2707
|
context.bumpAndNotify();
|
|
2520
2708
|
},
|
|
2521
2709
|
recordStageWorkflowChildRun(runId, stageId, ref) {
|
|
@@ -2525,8 +2713,12 @@ function createStageStoreMethods(context) {
|
|
|
2525
2713
|
const stage = context.findStage(run, stageId);
|
|
2526
2714
|
if (!stage)
|
|
2527
2715
|
return false;
|
|
2528
|
-
|
|
2716
|
+
const released = context.observation.executingStageIds.delete(workflowActivityNodeKey(runId, stageId));
|
|
2717
|
+
if (stage.workflowChildRun?.runId === ref.runId && stage.workflowChildRun.alias === ref.alias && stage.workflowChildRun.workflow === ref.workflow) {
|
|
2718
|
+
if (released)
|
|
2719
|
+
context.bumpAndNotify();
|
|
2529
2720
|
return false;
|
|
2721
|
+
}
|
|
2530
2722
|
stage.workflowChildRun = { ...ref };
|
|
2531
2723
|
context.bumpAndNotify();
|
|
2532
2724
|
return true;
|
|
@@ -2565,6 +2757,7 @@ function createStageStoreMethods(context) {
|
|
|
2565
2757
|
const existing = context.findStage(run, stage.id);
|
|
2566
2758
|
if (!existing)
|
|
2567
2759
|
return;
|
|
2760
|
+
context.observation.executingStageIds.delete(workflowActivityNodeKey(runId, stage.id));
|
|
2568
2761
|
existing.status = stage.status;
|
|
2569
2762
|
existing.endedAt = stage.endedAt;
|
|
2570
2763
|
if (existing.endedAt !== undefined && existing.pausedAt !== undefined) {
|
|
@@ -2788,6 +2981,7 @@ function createStageStoreMethods(context) {
|
|
|
2788
2981
|
context.bumpAndNotify();
|
|
2789
2982
|
return false;
|
|
2790
2983
|
}
|
|
2984
|
+
context.observation.executingStageIds.delete(workflowActivityNodeKey(runId, stageId));
|
|
2791
2985
|
stage.status = "paused";
|
|
2792
2986
|
stage.pausedAt = nextControlTimestamp(pausedAt, stage.resumedAt);
|
|
2793
2987
|
stage.resumedAt = undefined;
|
|
@@ -2820,6 +3014,8 @@ function createStageStoreMethods(context) {
|
|
|
2820
3014
|
return false;
|
|
2821
3015
|
}
|
|
2822
3016
|
const resumedTs = nextControlTimestamp(resumedAt, stage.pausedAt);
|
|
3017
|
+
if (context.observation.liveRunIds.has(runId))
|
|
3018
|
+
context.observation.executingStageIds.add(workflowActivityNodeKey(runId, stageId));
|
|
2823
3019
|
stage.status = "running";
|
|
2824
3020
|
if (stage.startedAt !== undefined) {
|
|
2825
3021
|
stage.pausedDurationMs = accumulatePausedDurationMs(stage.pausedDurationMs, stage.pausedAt, resumedTs);
|
|
@@ -2842,13 +3038,18 @@ function createStageStoreMethods(context) {
|
|
|
2842
3038
|
// dist/builtin/workflows/src/shared/store-factory.ts
|
|
2843
3039
|
function createStore() {
|
|
2844
3040
|
const context = createStoreContext();
|
|
2845
|
-
|
|
3041
|
+
const created = {
|
|
3042
|
+
[workflowObservationRuntimeKey]: context.observation,
|
|
2846
3043
|
...createRunStoreMethods(context),
|
|
2847
3044
|
...createPendingStageDeliveryStoreMethods(context),
|
|
2848
3045
|
...createStageStoreMethods(context),
|
|
2849
3046
|
...createToolNodeStoreMethods(context),
|
|
2850
3047
|
...createPromptStoreMethods(context)
|
|
2851
3048
|
};
|
|
3049
|
+
return created;
|
|
3050
|
+
}
|
|
3051
|
+
function workflowObservationRuntime(activeStore) {
|
|
3052
|
+
return activeStore[workflowObservationRuntimeKey];
|
|
2852
3053
|
}
|
|
2853
3054
|
var SESSION_KEY2 = "workflows:store:v1";
|
|
2854
3055
|
var singleton2 = createSessionScopedSingleton(SESSION_KEY2, createStore);
|
|
@@ -2858,7 +3059,7 @@ function key(runId, stageId) {
|
|
|
2858
3059
|
return `${runId}\x00${stageId}`;
|
|
2859
3060
|
}
|
|
2860
3061
|
function nextRequestId() {
|
|
2861
|
-
return `stage-ui-${
|
|
3062
|
+
return `stage-ui-${randomUUID2()}`;
|
|
2862
3063
|
}
|
|
2863
3064
|
|
|
2864
3065
|
class StageUiBroker {
|
|
@@ -2955,6 +3156,7 @@ class StageUiBroker {
|
|
|
2955
3156
|
};
|
|
2956
3157
|
}
|
|
2957
3158
|
requestCustomUi(runId, stageId, factory, options, signal) {
|
|
3159
|
+
signal = options?.signal ? signal ? AbortSignal.any([signal, options.signal]) : options.signal : signal;
|
|
2958
3160
|
if (signal?.aborted) {
|
|
2959
3161
|
return Promise.reject(signal.reason ?? new Error("atomic-workflows: stage UI request aborted"));
|
|
2960
3162
|
}
|
|
@@ -3265,8 +3467,8 @@ function normalizeUIContext(adapter) {
|
|
|
3265
3467
|
};
|
|
3266
3468
|
}
|
|
3267
3469
|
function stringField(value, keys) {
|
|
3268
|
-
for (const
|
|
3269
|
-
const candidate = value[
|
|
3470
|
+
for (const key of keys) {
|
|
3471
|
+
const candidate = value[key];
|
|
3270
3472
|
if (typeof candidate === "string" && candidate.length > 0)
|
|
3271
3473
|
return candidate;
|
|
3272
3474
|
}
|
|
@@ -3463,17 +3665,17 @@ function schemaIsRequired(schema) {
|
|
|
3463
3665
|
import { Value as Value2 } from "typebox/value";
|
|
3464
3666
|
function validateInputs(schema, inputs) {
|
|
3465
3667
|
const errors = [];
|
|
3466
|
-
for (const
|
|
3467
|
-
if (!(
|
|
3468
|
-
errors.push({ key
|
|
3668
|
+
for (const key of Object.keys(inputs)) {
|
|
3669
|
+
if (!(key in schema)) {
|
|
3670
|
+
errors.push({ key, reason: "unknown input key (not declared by this workflow)" });
|
|
3469
3671
|
}
|
|
3470
3672
|
}
|
|
3471
|
-
for (const [
|
|
3472
|
-
const value = inputs[
|
|
3673
|
+
for (const [key, def] of Object.entries(schema)) {
|
|
3674
|
+
const value = inputs[key];
|
|
3473
3675
|
let hasTypeError = false;
|
|
3474
3676
|
if (value === undefined) {
|
|
3475
3677
|
if (schemaIsRequired(def)) {
|
|
3476
|
-
errors.push({ key
|
|
3678
|
+
errors.push({ key, reason: "required input is missing" });
|
|
3477
3679
|
}
|
|
3478
3680
|
continue;
|
|
3479
3681
|
}
|
|
@@ -3481,25 +3683,25 @@ function validateInputs(schema, inputs) {
|
|
|
3481
3683
|
switch (kind) {
|
|
3482
3684
|
case "text":
|
|
3483
3685
|
if (typeof value !== "string") {
|
|
3484
|
-
errors.push({ key
|
|
3686
|
+
errors.push({ key, reason: `expected string, got ${workflowSerializableTypeName(value)}` });
|
|
3485
3687
|
hasTypeError = true;
|
|
3486
3688
|
}
|
|
3487
3689
|
break;
|
|
3488
3690
|
case "number":
|
|
3489
3691
|
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
3490
|
-
errors.push({ key
|
|
3692
|
+
errors.push({ key, reason: `expected finite number, got ${workflowSerializableTypeName(value)}` });
|
|
3491
3693
|
hasTypeError = true;
|
|
3492
3694
|
}
|
|
3493
3695
|
break;
|
|
3494
3696
|
case "integer":
|
|
3495
3697
|
if (typeof value !== "number" || !Number.isInteger(value)) {
|
|
3496
|
-
errors.push({ key
|
|
3698
|
+
errors.push({ key, reason: `expected integer, got ${workflowSerializableTypeName(value)}` });
|
|
3497
3699
|
hasTypeError = true;
|
|
3498
3700
|
}
|
|
3499
3701
|
break;
|
|
3500
3702
|
case "boolean":
|
|
3501
3703
|
if (typeof value !== "boolean") {
|
|
3502
|
-
errors.push({ key
|
|
3704
|
+
errors.push({ key, reason: `expected boolean, got ${workflowSerializableTypeName(value)}` });
|
|
3503
3705
|
hasTypeError = true;
|
|
3504
3706
|
}
|
|
3505
3707
|
break;
|
|
@@ -3507,24 +3709,24 @@ function validateInputs(schema, inputs) {
|
|
|
3507
3709
|
const choices = schemaChoices(def) ?? [];
|
|
3508
3710
|
const allowed = choices.join(", ");
|
|
3509
3711
|
if (typeof value !== "string") {
|
|
3510
|
-
errors.push({ key
|
|
3712
|
+
errors.push({ key, reason: `expected one of [${allowed}], got ${workflowSerializableTypeName(value)}` });
|
|
3511
3713
|
hasTypeError = true;
|
|
3512
3714
|
} else if (!choices.includes(value)) {
|
|
3513
|
-
errors.push({ key
|
|
3715
|
+
errors.push({ key, reason: `must be one of [${allowed}]` });
|
|
3514
3716
|
}
|
|
3515
3717
|
break;
|
|
3516
3718
|
}
|
|
3517
3719
|
default:
|
|
3518
3720
|
if (!Value2.Check(def, value)) {
|
|
3519
3721
|
const first = [...Value2.Errors(def, value)][0];
|
|
3520
|
-
errors.push({ key
|
|
3722
|
+
errors.push({ key, reason: first === undefined ? `does not match ${kind} schema` : first.message });
|
|
3521
3723
|
hasTypeError = true;
|
|
3522
3724
|
}
|
|
3523
3725
|
break;
|
|
3524
3726
|
}
|
|
3525
|
-
const serializableError = hasTypeError ? undefined : workflowSerializableValidationError(value, `input "${
|
|
3727
|
+
const serializableError = hasTypeError ? undefined : workflowSerializableValidationError(value, `input "${key}"`);
|
|
3526
3728
|
if (serializableError !== undefined) {
|
|
3527
|
-
errors.push({ key
|
|
3729
|
+
errors.push({ key, reason: serializableError.replace(/^input "[^"]+" /, "") });
|
|
3528
3730
|
}
|
|
3529
3731
|
}
|
|
3530
3732
|
return errors;
|
|
@@ -3533,18 +3735,19 @@ function validateInputs(schema, inputs) {
|
|
|
3533
3735
|
// dist/builtin/workflows/src/runs/foreground/executor-inputs.ts
|
|
3534
3736
|
function resolveInputs(schema, provided) {
|
|
3535
3737
|
const resolved = {};
|
|
3536
|
-
for (const [
|
|
3738
|
+
for (const [key, value] of Object.entries(provided)) {
|
|
3537
3739
|
if (value !== undefined)
|
|
3538
|
-
resolved[
|
|
3740
|
+
resolved[key] = value;
|
|
3539
3741
|
}
|
|
3540
|
-
const
|
|
3541
|
-
|
|
3742
|
+
const ownedInputs = Value3.Clone(resolved);
|
|
3743
|
+
const withDefaults = Value3.Default(Type2.Object(schema, { additionalProperties: true }), ownedInputs);
|
|
3744
|
+
for (const [key, value] of Object.entries(withDefaults)) {
|
|
3542
3745
|
if (value !== undefined)
|
|
3543
|
-
resolved[
|
|
3746
|
+
resolved[key] = value;
|
|
3544
3747
|
}
|
|
3545
|
-
for (const [
|
|
3546
|
-
if (schemaIsRequired(schemaDef) && resolved[
|
|
3547
|
-
throw new TypeError(`atomic-workflows: required input "${
|
|
3748
|
+
for (const [key, schemaDef] of Object.entries(schema)) {
|
|
3749
|
+
if (schemaIsRequired(schemaDef) && resolved[key] === undefined) {
|
|
3750
|
+
throw new TypeError(`atomic-workflows: required input "${key}" not provided`);
|
|
3548
3751
|
}
|
|
3549
3752
|
}
|
|
3550
3753
|
return resolved;
|
|
@@ -3590,12 +3793,12 @@ ${formatValidationErrors(errors)}`);
|
|
|
3590
3793
|
function asRecord(value) {
|
|
3591
3794
|
return value !== null && typeof value === "object" ? value : undefined;
|
|
3592
3795
|
}
|
|
3593
|
-
function field(value,
|
|
3594
|
-
return asRecord(value)?.[
|
|
3796
|
+
function field(value, key) {
|
|
3797
|
+
return asRecord(value)?.[key];
|
|
3595
3798
|
}
|
|
3596
|
-
function safeField(value,
|
|
3799
|
+
function safeField(value, key) {
|
|
3597
3800
|
try {
|
|
3598
|
-
return field(value,
|
|
3801
|
+
return field(value, key);
|
|
3599
3802
|
} catch {
|
|
3600
3803
|
return;
|
|
3601
3804
|
}
|
|
@@ -3625,8 +3828,8 @@ function findProcessFailureError(value, seen, depth) {
|
|
|
3625
3828
|
return value;
|
|
3626
3829
|
if (nonEmptyProcessOutput(safeField(value, "stderr")))
|
|
3627
3830
|
return value;
|
|
3628
|
-
for (const
|
|
3629
|
-
const selected = findProcessFailureError(safeField(value,
|
|
3831
|
+
for (const key of ["cause", "error", "response", "body"]) {
|
|
3832
|
+
const selected = findProcessFailureError(safeField(value, key), seen, depth + 1);
|
|
3630
3833
|
if (selected !== undefined)
|
|
3631
3834
|
return selected;
|
|
3632
3835
|
}
|
|
@@ -3654,8 +3857,8 @@ function selectProcessFailureError(error) {
|
|
|
3654
3857
|
function hasProcessFailureEvidence(error) {
|
|
3655
3858
|
return findProcessFailureError(error, new Set, 0) !== undefined;
|
|
3656
3859
|
}
|
|
3657
|
-
function stringField2(value,
|
|
3658
|
-
const raw = field(value,
|
|
3860
|
+
function stringField2(value, key) {
|
|
3861
|
+
const raw = field(value, key);
|
|
3659
3862
|
return typeof raw === "string" && raw.length > 0 ? raw : undefined;
|
|
3660
3863
|
}
|
|
3661
3864
|
function errorMessage(error) {
|
|
@@ -3837,15 +4040,15 @@ function redactSensitiveText(value) {
|
|
|
3837
4040
|
var TOOL_FAILURE_TEXT_LIMIT_BYTES = 16384;
|
|
3838
4041
|
var TRUNCATION_PREFIX = `[workflow tool output truncated; showing final bytes]
|
|
3839
4042
|
`;
|
|
3840
|
-
function safeField2(error,
|
|
4043
|
+
function safeField2(error, key) {
|
|
3841
4044
|
try {
|
|
3842
|
-
return field(error,
|
|
4045
|
+
return field(error, key);
|
|
3843
4046
|
} catch {
|
|
3844
4047
|
return;
|
|
3845
4048
|
}
|
|
3846
4049
|
}
|
|
3847
|
-
function exposedText(error,
|
|
3848
|
-
const value = safeField2(error,
|
|
4050
|
+
function exposedText(error, key) {
|
|
4051
|
+
const value = safeField2(error, key);
|
|
3849
4052
|
if (typeof value === "string")
|
|
3850
4053
|
return value;
|
|
3851
4054
|
try {
|
|
@@ -3954,7 +4157,7 @@ function canonicalJsonString(value) {
|
|
|
3954
4157
|
return `[${value.map(canonicalJsonString).join(",")}]`;
|
|
3955
4158
|
const object = value;
|
|
3956
4159
|
const keys = Object.keys(object).sort();
|
|
3957
|
-
return `{${keys.map((
|
|
4160
|
+
return `{${keys.map((key) => `${JSON.stringify(key)}:${canonicalJsonString(object[key])}`).join(",")}}`;
|
|
3958
4161
|
}
|
|
3959
4162
|
// dist/builtin/workflows/src/durable/backend.ts
|
|
3960
4163
|
function pendingStageMessagesForDurableRun(backend, logicalRunId, rootWorkflowId = logicalRunId) {
|
|
@@ -3993,13 +4196,13 @@ function cloneWorkflowChildReplaySnapshot(snapshot) {
|
|
|
3993
4196
|
}
|
|
3994
4197
|
function workflowChildReplaySnapshot(alias, childResult) {
|
|
3995
4198
|
const outputs = {};
|
|
3996
|
-
for (const [
|
|
4199
|
+
for (const [key, value] of Object.entries(childResult.outputs)) {
|
|
3997
4200
|
if (value === undefined)
|
|
3998
4201
|
continue;
|
|
3999
4202
|
try {
|
|
4000
|
-
outputs[
|
|
4203
|
+
outputs[key] = cloneWorkflowChildValue(value);
|
|
4001
4204
|
} catch (err) {
|
|
4002
|
-
throw new Error(`atomic-workflows: child workflow "${alias}" (${childResult.workflow}) exposed output "${
|
|
4205
|
+
throw new Error(`atomic-workflows: child workflow "${alias}" (${childResult.workflow}) exposed output "${key}" is not serializable for continuation replay: ${workflowChildSerializationMessage(err)}`, { cause: err });
|
|
4003
4206
|
}
|
|
4004
4207
|
}
|
|
4005
4208
|
const exitReason = childResult.exited === true ? childResult.exitReason : undefined;
|
|
@@ -4148,10 +4351,10 @@ function durableStageGroupKey(stage, stages = [stage]) {
|
|
|
4148
4351
|
function groupByDurableStageKey(stages) {
|
|
4149
4352
|
const groups = new Map;
|
|
4150
4353
|
for (const stage of stages) {
|
|
4151
|
-
const
|
|
4152
|
-
const group = groups.get(
|
|
4354
|
+
const key = durableStageGroupKey(stage, stages);
|
|
4355
|
+
const group = groups.get(key) ?? [];
|
|
4153
4356
|
group.push(stage);
|
|
4154
|
-
groups.set(
|
|
4357
|
+
groups.set(key, group);
|
|
4155
4358
|
}
|
|
4156
4359
|
return groups;
|
|
4157
4360
|
}
|
|
@@ -4193,13 +4396,13 @@ function hasCycle(topologies) {
|
|
|
4193
4396
|
function parseWorkflowChildResult(value) {
|
|
4194
4397
|
if (!isOrdinaryObject(value))
|
|
4195
4398
|
return;
|
|
4196
|
-
const
|
|
4399
|
+
const workflow = value.workflow;
|
|
4197
4400
|
const runId = value.runId;
|
|
4198
4401
|
const status = value.status;
|
|
4199
4402
|
const exited = value.exited;
|
|
4200
4403
|
const outputs = value.outputs;
|
|
4201
4404
|
const exitReason = value.exitReason;
|
|
4202
|
-
if (typeof
|
|
4405
|
+
if (typeof workflow !== "string" || typeof runId !== "string" || !isOrdinaryObject(outputs))
|
|
4203
4406
|
return;
|
|
4204
4407
|
if (exited === false) {
|
|
4205
4408
|
if (status !== "completed" || exitReason !== undefined)
|
|
@@ -4628,6 +4831,7 @@ function durableStageCheckpointMetadata(stage, run, sourceOrder) {
|
|
|
4628
4831
|
...stage.sessionFile !== undefined ? { sessionFile: stage.sessionFile } : {},
|
|
4629
4832
|
...stage.durationMs !== undefined ? { durationMs: stage.durationMs } : {},
|
|
4630
4833
|
...stage.model !== undefined ? { model: stage.model } : {},
|
|
4834
|
+
...stage.thinkingLevel !== undefined ? { thinkingLevel: stage.thinkingLevel } : {},
|
|
4631
4835
|
...stage.attemptedModels !== undefined ? { attemptedModels: [...stage.attemptedModels] } : {},
|
|
4632
4836
|
...stage.modelAttempts !== undefined ? { modelAttempts: [...stage.modelAttempts] } : {},
|
|
4633
4837
|
...stage.structured !== undefined ? { structured: stage.structured } : {},
|
|
@@ -4637,7 +4841,7 @@ function durableStageCheckpointMetadata(stage, run, sourceOrder) {
|
|
|
4637
4841
|
}
|
|
4638
4842
|
|
|
4639
4843
|
// dist/builtin/workflows/src/durable/tool-primitive.ts
|
|
4640
|
-
import { runCallback } from "@bastani/atomic";
|
|
4844
|
+
import { collectAgentTasks, runCallback } from "@bastani/atomic";
|
|
4641
4845
|
|
|
4642
4846
|
// dist/builtin/workflows/src/engine/workflow-tool-abort.ts
|
|
4643
4847
|
class WorkflowToolAbortError extends Error {
|
|
@@ -4767,6 +4971,58 @@ function captureCallbackSource(fn) {
|
|
|
4767
4971
|
return;
|
|
4768
4972
|
}
|
|
4769
4973
|
}
|
|
4974
|
+
async function awaitTerminalTask(task) {
|
|
4975
|
+
for (;; ) {
|
|
4976
|
+
const observed = await task.host.waitForTask(task.taskId);
|
|
4977
|
+
if (!observed.ok)
|
|
4978
|
+
throw new Error(`${observed.error.code}: ${observed.error.message}`);
|
|
4979
|
+
if (observed.value.kind === "settled")
|
|
4980
|
+
return observed.value.result;
|
|
4981
|
+
}
|
|
4982
|
+
}
|
|
4983
|
+
function replaceTaskObservations(value, terminal) {
|
|
4984
|
+
if (!value || typeof value !== "object")
|
|
4985
|
+
return value;
|
|
4986
|
+
if (Array.isArray(value)) {
|
|
4987
|
+
const next = value.map((item) => replaceTaskObservations(item, terminal));
|
|
4988
|
+
return next.some((item, index) => item !== value[index]) ? next : value;
|
|
4989
|
+
}
|
|
4990
|
+
const object = value;
|
|
4991
|
+
if (object.kind === "yielded" && typeof object.taskId === "string") {
|
|
4992
|
+
const result = terminal.get(object.taskId);
|
|
4993
|
+
if (result)
|
|
4994
|
+
return { kind: "settled", taskId: object.taskId, result };
|
|
4995
|
+
}
|
|
4996
|
+
let changed = false;
|
|
4997
|
+
const next = {};
|
|
4998
|
+
for (const [key, item] of Object.entries(object)) {
|
|
4999
|
+
next[key] = replaceTaskObservations(item, terminal);
|
|
5000
|
+
changed ||= next[key] !== item;
|
|
5001
|
+
}
|
|
5002
|
+
if (changed && next.details !== object.details && next.details && typeof next.details === "object" && !Array.isArray(next.details) && Array.isArray(object.content)) {
|
|
5003
|
+
const details = next.details;
|
|
5004
|
+
const original = object.details;
|
|
5005
|
+
if (details.taskResponse !== undefined && details.taskResponse !== original.taskResponse) {
|
|
5006
|
+
const before = JSON.stringify(original.taskResponse);
|
|
5007
|
+
next.content = object.content.map((part) => {
|
|
5008
|
+
if (!part || typeof part !== "object" || Array.isArray(part))
|
|
5009
|
+
return part;
|
|
5010
|
+
const content = part;
|
|
5011
|
+
return content.type === "text" && content.text === before ? { ...content, text: JSON.stringify(details.taskResponse) } : part;
|
|
5012
|
+
});
|
|
5013
|
+
}
|
|
5014
|
+
}
|
|
5015
|
+
return changed ? next : value;
|
|
5016
|
+
}
|
|
5017
|
+
function invokeTaskCallback(fn, signal) {
|
|
5018
|
+
return collectAgentTasks(signal, () => fn({ signal }), async (value, tasks) => {
|
|
5019
|
+
if (tasks.length === 0)
|
|
5020
|
+
return value;
|
|
5021
|
+
const terminal = new Map;
|
|
5022
|
+
await Promise.all(tasks.map(async (task) => terminal.set(task.taskId, await awaitTerminalTask(task))));
|
|
5023
|
+
return replaceTaskObservations(value, terminal);
|
|
5024
|
+
});
|
|
5025
|
+
}
|
|
4770
5026
|
function createToolPrimitive(input) {
|
|
4771
5027
|
const ordinals = new Map;
|
|
4772
5028
|
return (name, args, fn, options) => {
|
|
@@ -4883,11 +5139,11 @@ async function executeToolInvocation(input, ordinals, name, args, fn, options, c
|
|
|
4883
5139
|
control.noteCancelled();
|
|
4884
5140
|
else
|
|
4885
5141
|
input.onFailureObserved?.(error, node.id);
|
|
4886
|
-
const
|
|
5142
|
+
const endedAt = Date.now();
|
|
4887
5143
|
input.onNodeEnd?.(node.id, {
|
|
4888
5144
|
status: cancelled ? "cancelled" : "failed",
|
|
4889
|
-
endedAt
|
|
4890
|
-
...node.startedAt !== undefined ? { durationMs: Math.max(0,
|
|
5145
|
+
endedAt,
|
|
5146
|
+
...node.startedAt !== undefined ? { durationMs: Math.max(0, endedAt - node.startedAt) } : {},
|
|
4891
5147
|
error: error instanceof Error ? error.message : String(error)
|
|
4892
5148
|
});
|
|
4893
5149
|
input.onNodeSettle?.(node.id);
|
|
@@ -4942,7 +5198,7 @@ async function executeTimedToolAttempt(toolName, runId, fn, baseSignal, timeoutM
|
|
|
4942
5198
|
const timeoutController = new AbortController;
|
|
4943
5199
|
const attemptSignal = AbortSignal.any([baseSignal, timeoutController.signal]);
|
|
4944
5200
|
return runCallback({ kind: "workflow.ctx_tool", name: toolName, runId }, async () => {
|
|
4945
|
-
const callbackResult = Promise.resolve().then(() => fn
|
|
5201
|
+
const callbackResult = Promise.resolve().then(() => invokeTaskCallback(fn, attemptSignal)).then((value) => ({ kind: "value", value }), (error) => ({ kind: "error", error }));
|
|
4946
5202
|
let cancelDeadline;
|
|
4947
5203
|
let onAbort;
|
|
4948
5204
|
let timeoutError;
|
|
@@ -4997,7 +5253,7 @@ async function executeLiveToolInvocation(live) {
|
|
|
4997
5253
|
try {
|
|
4998
5254
|
const result = await executeWithRetries(() => {
|
|
4999
5255
|
attempts += 1;
|
|
5000
|
-
const callback = options?.timeoutMs === undefined ? runCallback({ kind: "workflow.ctx_tool", name, runId: input.workflowId }, () => fn
|
|
5256
|
+
const callback = options?.timeoutMs === undefined ? runCallback({ kind: "workflow.ctx_tool", name, runId: input.workflowId }, () => invokeTaskCallback(fn, toolSignal)) : executeTimedToolAttempt(name, input.workflowId, fn, toolSignal, options.timeoutMs);
|
|
5001
5257
|
return callback.catch((error) => {
|
|
5002
5258
|
callbackError = error;
|
|
5003
5259
|
throw error;
|
|
@@ -5060,12 +5316,12 @@ async function executeLiveToolInvocation(live) {
|
|
|
5060
5316
|
const callbackFailure = callbackError ?? error;
|
|
5061
5317
|
if (returnFailure && !callbackCompleted && isExplicitCallbackCancellation(callbackFailure)) {
|
|
5062
5318
|
input.onFailureObserved?.(callbackFailure, node.id);
|
|
5063
|
-
const
|
|
5319
|
+
const failure = await recordThrowingToolFailure(input, node, { name, args, ...source !== undefined ? { source } : {}, argsHash, ordinal, startedAt }, callbackFailure, attempts);
|
|
5064
5320
|
input.onNodeEnd?.(node.id, {
|
|
5065
5321
|
status: "failed",
|
|
5066
|
-
endedAt:
|
|
5067
|
-
durationMs: Math.max(0,
|
|
5068
|
-
error:
|
|
5322
|
+
endedAt: failure.failedAt,
|
|
5323
|
+
durationMs: Math.max(0, failure.failedAt - startedAt),
|
|
5324
|
+
error: failure.message
|
|
5069
5325
|
});
|
|
5070
5326
|
input.onNodeSettle?.(node.id);
|
|
5071
5327
|
throw callbackFailure;
|
|
@@ -5123,12 +5379,12 @@ async function executeLiveToolInvocation(live) {
|
|
|
5123
5379
|
}
|
|
5124
5380
|
const reportedFailure = timeoutFailure ? callbackError : error;
|
|
5125
5381
|
input.onFailureObserved?.(reportedFailure, node.id);
|
|
5126
|
-
const
|
|
5382
|
+
const failure = await recordThrowingToolFailure(input, node, { name, args, ...source !== undefined ? { source } : {}, argsHash, ordinal, startedAt }, reportedFailure, attempts);
|
|
5127
5383
|
input.onNodeEnd?.(node.id, {
|
|
5128
5384
|
status: "failed",
|
|
5129
|
-
endedAt:
|
|
5130
|
-
durationMs: Math.max(0,
|
|
5131
|
-
error:
|
|
5385
|
+
endedAt: failure.failedAt,
|
|
5386
|
+
durationMs: Math.max(0, failure.failedAt - startedAt),
|
|
5387
|
+
error: failure.message
|
|
5132
5388
|
});
|
|
5133
5389
|
input.onNodeSettle?.(node.id);
|
|
5134
5390
|
throw reportedFailure;
|
|
@@ -5184,9 +5440,9 @@ var CALLBACK_CANCELLATION_CODES = new Set([
|
|
|
5184
5440
|
"err_cancelled"
|
|
5185
5441
|
]);
|
|
5186
5442
|
var CALLBACK_CANCELLATION_STOP_REASONS = new Set(["aborted", "canceled", "cancelled"]);
|
|
5187
|
-
function safeCancellationField(error,
|
|
5443
|
+
function safeCancellationField(error, key) {
|
|
5188
5444
|
try {
|
|
5189
|
-
return field(error,
|
|
5445
|
+
return field(error, key);
|
|
5190
5446
|
} catch {
|
|
5191
5447
|
return;
|
|
5192
5448
|
}
|
|
@@ -5213,16 +5469,16 @@ function isExplicitCallbackCancellation(error) {
|
|
|
5213
5469
|
return true;
|
|
5214
5470
|
if (!hasProcessFailure && hasCancellationMarker(CALLBACK_CANCELLATION_CODES, safeCancellationField(current.value, "code")))
|
|
5215
5471
|
return true;
|
|
5216
|
-
for (const
|
|
5217
|
-
pending.push({ value: safeCancellationField(current.value,
|
|
5472
|
+
for (const key of ["cause", "error", "response", "body"]) {
|
|
5473
|
+
pending.push({ value: safeCancellationField(current.value, key), depth: current.depth + 1 });
|
|
5218
5474
|
}
|
|
5219
|
-
for (const
|
|
5220
|
-
const entries = safeCancellationField(current.value,
|
|
5475
|
+
for (const key of ["diagnostics", "errors"]) {
|
|
5476
|
+
const entries = safeCancellationField(current.value, key);
|
|
5221
5477
|
if (!Array.isArray(entries))
|
|
5222
5478
|
continue;
|
|
5223
5479
|
for (const entry of entries) {
|
|
5224
5480
|
pending.push({
|
|
5225
|
-
value:
|
|
5481
|
+
value: key === "diagnostics" ? safeCancellationField(entry, "error") ?? entry : entry,
|
|
5226
5482
|
depth: current.depth + 1
|
|
5227
5483
|
});
|
|
5228
5484
|
}
|
|
@@ -5387,8 +5643,8 @@ function pendingStageIdForReplay(backend, workflowId, replayKey, stageName) {
|
|
|
5387
5643
|
return candidates.size === 1 ? candidates.values().next().value : undefined;
|
|
5388
5644
|
}
|
|
5389
5645
|
function createDurableStagePrimitive(input) {
|
|
5390
|
-
return (name, options) => {
|
|
5391
|
-
const replayKey = input.nextReplayKey(name);
|
|
5646
|
+
return (name, options, reservedReplayKey) => {
|
|
5647
|
+
const replayKey = reservedReplayKey ?? input.nextReplayKey(name);
|
|
5392
5648
|
const cached = stageCheckpointWithOutput(input.backend, input.workflowId, replayKey);
|
|
5393
5649
|
if (cached !== undefined) {
|
|
5394
5650
|
input.recordCachedStage?.(name, replayKey, cached);
|
|
@@ -5553,6 +5809,7 @@ function completeTaskResult(name, base, checkpoint) {
|
|
|
5553
5809
|
...base.sessionFile !== undefined || checkpoint.sessionFile !== undefined ? { sessionFile: base.sessionFile ?? checkpoint.sessionFile } : {},
|
|
5554
5810
|
...base.artifacts !== undefined || checkpoint.artifacts !== undefined ? { artifacts: [...base.artifacts ?? checkpoint.artifacts ?? []] } : {},
|
|
5555
5811
|
...base.model !== undefined || checkpoint.model !== undefined ? { model: base.model ?? checkpoint.model } : {},
|
|
5812
|
+
...base.thinkingLevel !== undefined || checkpoint.thinkingLevel !== undefined ? { thinkingLevel: base.thinkingLevel ?? checkpoint.thinkingLevel } : {},
|
|
5556
5813
|
...base.attemptedModels !== undefined || checkpoint.attemptedModels !== undefined ? { attemptedModels: [...base.attemptedModels ?? checkpoint.attemptedModels ?? []] } : {},
|
|
5557
5814
|
...base.modelAttempts !== undefined || checkpoint.modelAttempts !== undefined ? { modelAttempts: [...base.modelAttempts ?? checkpoint.modelAttempts ?? []] } : {},
|
|
5558
5815
|
...base.warnings !== undefined || checkpoint.warnings !== undefined ? { warnings: [...base.warnings ?? checkpoint.warnings ?? []] } : {}
|
|
@@ -5653,6 +5910,7 @@ function taskCheckpointMetadata(result) {
|
|
|
5653
5910
|
...result.sessionId !== undefined ? { sessionId: result.sessionId } : {},
|
|
5654
5911
|
...result.sessionFile !== undefined ? { sessionFile: result.sessionFile } : {},
|
|
5655
5912
|
...result.model !== undefined ? { model: result.model } : {},
|
|
5913
|
+
...result.thinkingLevel !== undefined ? { thinkingLevel: result.thinkingLevel } : {},
|
|
5656
5914
|
...result.attemptedModels !== undefined ? { attemptedModels: [...result.attemptedModels] } : {},
|
|
5657
5915
|
...result.modelAttempts !== undefined ? { modelAttempts: [...result.modelAttempts] } : {},
|
|
5658
5916
|
...result.structured !== undefined ? { structured: result.structured } : {},
|
|
@@ -5682,6 +5940,7 @@ function mergeCheckpointHydrationMetadata(replayValueCheckpoint, checkpoints) {
|
|
|
5682
5940
|
...replayValueCheckpoint.sessionId === undefined ? metadataValue(checkpoints, "sessionId") : {},
|
|
5683
5941
|
...replayValueCheckpoint.sessionFile === undefined ? metadataValue(checkpoints, "sessionFile") : {},
|
|
5684
5942
|
...replayValueCheckpoint.model === undefined ? metadataValue(checkpoints, "model") : {},
|
|
5943
|
+
...replayValueCheckpoint.thinkingLevel === undefined ? metadataValue(checkpoints, "thinkingLevel") : {},
|
|
5685
5944
|
...replayValueCheckpoint.attemptedModels === undefined ? metadataValue(checkpoints, "attemptedModels") : {},
|
|
5686
5945
|
...replayValueCheckpoint.modelAttempts === undefined ? metadataValue(checkpoints, "modelAttempts") : {},
|
|
5687
5946
|
...replayValueCheckpoint.structured === undefined ? metadataValue(checkpoints, "structured") : {},
|
|
@@ -5702,11 +5961,11 @@ function preferredHydrationTopology(replayValueCheckpoint, checkpoints) {
|
|
|
5702
5961
|
}
|
|
5703
5962
|
return replayValueCheckpoint.topology === undefined ? metadataValue(checkpoints, "topology") : {};
|
|
5704
5963
|
}
|
|
5705
|
-
function metadataValue(checkpoints,
|
|
5964
|
+
function metadataValue(checkpoints, key) {
|
|
5706
5965
|
for (let index = checkpoints.length - 1;index >= 0; index -= 1) {
|
|
5707
|
-
const value = checkpoints[index]?.[
|
|
5966
|
+
const value = checkpoints[index]?.[key];
|
|
5708
5967
|
if (value !== undefined)
|
|
5709
|
-
return { [
|
|
5968
|
+
return { [key]: value };
|
|
5710
5969
|
}
|
|
5711
5970
|
return {};
|
|
5712
5971
|
}
|
|
@@ -5741,7 +6000,7 @@ function stageMetadataCheckpointId(replayKey, stage) {
|
|
|
5741
6000
|
result: stage.result ?? ""
|
|
5742
6001
|
})}`;
|
|
5743
6002
|
}
|
|
5744
|
-
function recordCachedStageIntoStore(
|
|
6003
|
+
function recordCachedStageIntoStore(store, runId, name, replayKey, output, completedStageReplayKeys, parentIds, checkpoint) {
|
|
5745
6004
|
const now = Date.now();
|
|
5746
6005
|
const sourceStageId = checkpoint?.topology?.run?.runId === runId ? checkpoint.topology.stageId : undefined;
|
|
5747
6006
|
const stageId = sourceStageId ?? cachedStageId(runId, replayKey);
|
|
@@ -5771,22 +6030,23 @@ function recordCachedStageIntoStore(store2, runId, name, replayKey, output, comp
|
|
|
5771
6030
|
...checkpoint?.sessionId !== undefined ? { sessionId: checkpoint.sessionId } : {},
|
|
5772
6031
|
...checkpoint?.sessionFile !== undefined ? { sessionFile: checkpoint.sessionFile } : {},
|
|
5773
6032
|
...checkpoint?.model !== undefined ? { model: checkpoint.model } : {},
|
|
6033
|
+
...checkpoint?.thinkingLevel !== undefined ? { thinkingLevel: checkpoint.thinkingLevel } : {},
|
|
5774
6034
|
...checkpoint?.attemptedModels !== undefined ? { attemptedModels: checkpoint.attemptedModels } : {},
|
|
5775
6035
|
...checkpoint?.modelAttempts !== undefined ? { modelAttempts: checkpoint.modelAttempts } : {},
|
|
5776
6036
|
...checkpoint?.structured !== undefined ? { structured: checkpoint.structured } : {},
|
|
5777
6037
|
...checkpoint?.artifacts !== undefined ? { artifacts: checkpoint.artifacts } : {},
|
|
5778
6038
|
...checkpoint?.warnings !== undefined ? { warnings: checkpoint.warnings } : {}
|
|
5779
6039
|
};
|
|
5780
|
-
|
|
5781
|
-
|
|
6040
|
+
store.recordStageStart(runId, snapshot);
|
|
6041
|
+
store.recordStageEnd(runId, snapshot);
|
|
5782
6042
|
completedStageReplayKeys.set(stageId, replayKey);
|
|
5783
6043
|
}
|
|
5784
|
-
function recordCachedStageWithTracker(
|
|
6044
|
+
function recordCachedStageWithTracker(store, tracker, runId, name, replayKey, checkpoint, completedStageReplayKeys, stageFailFastScope, sourceToReplayedNodeIds) {
|
|
5785
6045
|
const sourceStageId = checkpoint.topology?.run?.runId === runId ? checkpoint.topology.stageId : undefined;
|
|
5786
6046
|
const stageId = sourceStageId ?? cachedStageId(runId, replayKey);
|
|
5787
6047
|
let parentIds = tracker.onSpawn(stageId, name);
|
|
5788
6048
|
const sourceParents = sourceStageId === undefined ? undefined : checkpoint.topology?.parentIds;
|
|
5789
|
-
const run =
|
|
6049
|
+
const run = store.runs().find((candidate) => candidate.id === runId);
|
|
5790
6050
|
const restored = sourceParents?.map((sourceId) => sourceToReplayedNodeIds?.get(sourceId) ?? run?.stages.find((stage) => stage.id === sourceId || stage.replayedFromStageId === sourceId)?.id);
|
|
5791
6051
|
if (restored?.every((id) => id !== undefined)) {
|
|
5792
6052
|
parentIds = restored;
|
|
@@ -5797,7 +6057,7 @@ function recordCachedStageWithTracker(store2, tracker, runId, name, replayKey, c
|
|
|
5797
6057
|
}
|
|
5798
6058
|
if (checkpoint.topology?.run?.runId === runId)
|
|
5799
6059
|
sourceToReplayedNodeIds?.set(checkpoint.topology.stageId, stageId);
|
|
5800
|
-
recordCachedStageIntoStore(
|
|
6060
|
+
recordCachedStageIntoStore(store, runId, name, replayKey, checkpoint.output, completedStageReplayKeys, parentIds, checkpoint);
|
|
5801
6061
|
tracker.onSettle(stageId);
|
|
5802
6062
|
}
|
|
5803
6063
|
function isWorkflowTaskResult(value) {
|
|
@@ -6467,6 +6727,11 @@ function classifyWorkflowFailure(error) {
|
|
|
6467
6727
|
}
|
|
6468
6728
|
return failureForDecision(unknownDecision(), message, error);
|
|
6469
6729
|
}
|
|
6730
|
+
// dist/builtin/workflows/src/durable/workflow-status-transition.ts
|
|
6731
|
+
async function transitionDurableWorkflowStatus(backend, workflowId, expectedStatuses, status, pendingPrompts, resumable) {
|
|
6732
|
+
return await backend.transitionWorkflowStatus(workflowId, expectedStatuses, status, pendingPrompts, resumable);
|
|
6733
|
+
}
|
|
6734
|
+
|
|
6470
6735
|
// dist/builtin/workflows/src/durable/dbos-process-owner.ts
|
|
6471
6736
|
var DBOS_PROCESS_OWNER_KEY = Symbol.for("atomic-workflows/dbos-process-owner@1");
|
|
6472
6737
|
function emptyOwner2() {
|
|
@@ -6540,9 +6805,9 @@ function isMemoizedBackendUsable(backend) {
|
|
|
6540
6805
|
return !backend.persistent || dbosLifecycleState() === "ready";
|
|
6541
6806
|
}
|
|
6542
6807
|
function getDurableBackend() {
|
|
6543
|
-
const
|
|
6544
|
-
const memoized =
|
|
6545
|
-
const backend =
|
|
6808
|
+
const owner = getDurableBackendProcessOwner();
|
|
6809
|
+
const memoized = owner.initializedBackend !== undefined && isMemoizedBackendUsable(owner.initializedBackend) ? owner.initializedBackend : undefined;
|
|
6810
|
+
const backend = owner.injectedBackend ?? memoized ?? getReadyDbosBackendSync();
|
|
6546
6811
|
if (backend === undefined)
|
|
6547
6812
|
throw new DbosNotReadyError;
|
|
6548
6813
|
return backend;
|
|
@@ -6575,7 +6840,7 @@ function restoreBudgetState(value) {
|
|
|
6575
6840
|
if (restored !== undefined)
|
|
6576
6841
|
warnings[dimension] = restored;
|
|
6577
6842
|
}
|
|
6578
|
-
const requiredNumbers = (candidate, fields) => isRecord(candidate) && fields.every((
|
|
6843
|
+
const requiredNumbers = (candidate, fields) => isRecord(candidate) && fields.every((field) => numericDuration(candidate[field]) !== undefined);
|
|
6579
6844
|
const accountingValue = value.accounting;
|
|
6580
6845
|
const accounting = isRecord(accountingValue) && requiredNumbers(accountingValue, ["tokens", "cost"]) && requiredNumbers(accountingValue.baseline, ["input", "output", "cacheRead", "cacheWrite", "cost"]) && requiredNumbers(accountingValue.perCounter, ["input", "output", "cacheRead", "cacheWrite"]) ? accountingValue : undefined;
|
|
6581
6846
|
const state = {
|
|
@@ -6807,8 +7072,8 @@ class ScopedDurableBackend {
|
|
|
6807
7072
|
scope
|
|
6808
7073
|
};
|
|
6809
7074
|
}
|
|
6810
|
-
scopeKey(
|
|
6811
|
-
return `${this.scope.scopePrefix}:${
|
|
7075
|
+
scopeKey(key) {
|
|
7076
|
+
return `${this.scope.scopePrefix}:${key}`;
|
|
6812
7077
|
}
|
|
6813
7078
|
remap(checkpoint) {
|
|
6814
7079
|
const workflowId = this.scope.rootWorkflowId;
|
|
@@ -7313,31 +7578,31 @@ function createGitWorktreeSetupCache() {
|
|
|
7313
7578
|
get(options) {
|
|
7314
7579
|
if (disposed)
|
|
7315
7580
|
throw new Error("Git worktree setup cache is already disposed");
|
|
7316
|
-
const
|
|
7317
|
-
const cached = results.get(
|
|
7581
|
+
const key = gitWorktreeSetupCacheKey(options);
|
|
7582
|
+
const cached = results.get(key);
|
|
7318
7583
|
if (cached !== undefined) {
|
|
7319
7584
|
assertCachedGitWorktreeIdentity(cached, options);
|
|
7320
7585
|
return cached.result;
|
|
7321
7586
|
}
|
|
7322
7587
|
const result = setupGitWorktree(options);
|
|
7323
|
-
results.set(
|
|
7588
|
+
results.set(key, { result, identity: captureGitWorktreeIdentity(result) });
|
|
7324
7589
|
return result;
|
|
7325
7590
|
},
|
|
7326
7591
|
dispose() {
|
|
7327
7592
|
if (disposed)
|
|
7328
7593
|
return;
|
|
7329
7594
|
disposed = true;
|
|
7330
|
-
let
|
|
7595
|
+
let firstError;
|
|
7331
7596
|
for (const cached of results.values()) {
|
|
7332
7597
|
try {
|
|
7333
7598
|
cached.identity.generation.dispose();
|
|
7334
7599
|
} catch (error) {
|
|
7335
|
-
|
|
7600
|
+
firstError ??= error instanceof Error ? error : new Error(String(error));
|
|
7336
7601
|
}
|
|
7337
7602
|
}
|
|
7338
7603
|
results.clear();
|
|
7339
|
-
if (
|
|
7340
|
-
throw
|
|
7604
|
+
if (firstError !== undefined)
|
|
7605
|
+
throw firstError;
|
|
7341
7606
|
}
|
|
7342
7607
|
};
|
|
7343
7608
|
}
|
|
@@ -7637,24 +7902,24 @@ function safePatchAgentName(agent) {
|
|
|
7637
7902
|
}
|
|
7638
7903
|
function removeSyntheticPath(worktree, syntheticPath) {
|
|
7639
7904
|
const resolved = path4.resolve(worktree.path, syntheticPath);
|
|
7640
|
-
const
|
|
7641
|
-
if (!
|
|
7905
|
+
const relative = path4.relative(worktree.path, resolved);
|
|
7906
|
+
if (!relative || relative === "." || relative === ".." || relative.startsWith(`..${path4.sep}`) || path4.isAbsolute(relative)) {
|
|
7642
7907
|
return;
|
|
7643
7908
|
}
|
|
7644
|
-
let
|
|
7909
|
+
let stat;
|
|
7645
7910
|
try {
|
|
7646
|
-
|
|
7911
|
+
stat = fs4.lstatSync(resolved);
|
|
7647
7912
|
} catch (error) {
|
|
7648
7913
|
const code = error && typeof error === "object" && "code" in error ? error.code : undefined;
|
|
7649
7914
|
if (code === "ENOENT")
|
|
7650
7915
|
return;
|
|
7651
7916
|
throw error;
|
|
7652
7917
|
}
|
|
7653
|
-
if (
|
|
7918
|
+
if (stat.isSymbolicLink()) {
|
|
7654
7919
|
fs4.unlinkSync(resolved);
|
|
7655
7920
|
return;
|
|
7656
7921
|
}
|
|
7657
|
-
if (
|
|
7922
|
+
if (stat.isDirectory()) {
|
|
7658
7923
|
fs4.rmSync(resolved, { recursive: true, force: true });
|
|
7659
7924
|
return;
|
|
7660
7925
|
}
|
|
@@ -8018,14 +8283,14 @@ function normalizeSyntheticPath(worktreePath, rawPath) {
|
|
|
8018
8283
|
if (path6.isAbsolute(trimmed))
|
|
8019
8284
|
throw new Error(`synthetic path must be relative: ${rawPath}`);
|
|
8020
8285
|
const resolved = path6.resolve(worktreePath, trimmed);
|
|
8021
|
-
const
|
|
8022
|
-
if (!
|
|
8286
|
+
const relative = path6.relative(worktreePath, resolved);
|
|
8287
|
+
if (!relative || relative === ".") {
|
|
8023
8288
|
throw new Error(`synthetic path cannot target the worktree root: ${rawPath}`);
|
|
8024
8289
|
}
|
|
8025
|
-
if (
|
|
8290
|
+
if (relative === ".." || relative.startsWith(`..${path6.sep}`) || path6.isAbsolute(relative)) {
|
|
8026
8291
|
throw new Error(`synthetic path escapes the worktree root: ${rawPath}`);
|
|
8027
8292
|
}
|
|
8028
|
-
return path6.normalize(
|
|
8293
|
+
return path6.normalize(relative);
|
|
8029
8294
|
}
|
|
8030
8295
|
function hasTrackedEntries(worktreePath, relativePath) {
|
|
8031
8296
|
const result = runGit(worktreePath, ["ls-files", "--", relativePath]);
|
|
@@ -8168,15 +8433,15 @@ function cleanupWorktrees(setup) {
|
|
|
8168
8433
|
import { lstatSync as lstatSync4, realpathSync as realpathSync4 } from "node:fs";
|
|
8169
8434
|
import { dirname as dirname6, isAbsolute as isAbsolute5, relative as relative4, resolve as resolve6, sep as sep5 } from "node:path";
|
|
8170
8435
|
function relativePathWithin(root, candidate) {
|
|
8171
|
-
const
|
|
8172
|
-
return
|
|
8436
|
+
const path = relative4(root, candidate);
|
|
8437
|
+
return path === ".." || path.startsWith(`..${sep5}`) || isAbsolute5(path) ? undefined : path;
|
|
8173
8438
|
}
|
|
8174
|
-
function existingRealPath(
|
|
8439
|
+
function existingRealPath(path, description) {
|
|
8175
8440
|
try {
|
|
8176
|
-
return realpathSync4.native(
|
|
8441
|
+
return realpathSync4.native(path);
|
|
8177
8442
|
} catch (error) {
|
|
8178
8443
|
const message = error instanceof Error ? error.message : String(error);
|
|
8179
|
-
throw new Error(`atomic-workflows: cannot resolve ${description} ${
|
|
8444
|
+
throw new Error(`atomic-workflows: cannot resolve ${description} ${path}: ${message}`);
|
|
8180
8445
|
}
|
|
8181
8446
|
}
|
|
8182
8447
|
function resolveWorktreeStageCwd(cwd, setup) {
|
|
@@ -8394,7 +8659,7 @@ function truncateTaskOutput(text, maxOutput) {
|
|
|
8394
8659
|
[workflow output truncated; limits: ${limits.bytes} bytes, ${limits.lines} lines]`;
|
|
8395
8660
|
}
|
|
8396
8661
|
function withoutUndefinedProperties(value) {
|
|
8397
|
-
return Object.fromEntries(Object.entries(value).filter(([,
|
|
8662
|
+
return Object.fromEntries(Object.entries(value).filter(([, field]) => field !== undefined));
|
|
8398
8663
|
}
|
|
8399
8664
|
function sharedTaskDefaultsFromOptions(options) {
|
|
8400
8665
|
const {
|
|
@@ -8500,7 +8765,7 @@ async function mapParallelSteps(steps, concurrency, failFast, mapper, onFirstFai
|
|
|
8500
8765
|
if (selectedFailure !== undefined)
|
|
8501
8766
|
throw selectedFailure;
|
|
8502
8767
|
}
|
|
8503
|
-
throw new AggregateError(failures.map((
|
|
8768
|
+
throw new AggregateError(failures.map((failure) => failure.error), `atomic-workflows: ${failures.length} parallel ${failures.length === 1 ? "step" : "steps"} failed`);
|
|
8504
8769
|
}
|
|
8505
8770
|
return results;
|
|
8506
8771
|
}
|
|
@@ -8773,32 +9038,32 @@ function reconcileTerminalRunResult(runId, runSnapshot, activeStore, fallback, o
|
|
|
8773
9038
|
onRunEnd?.(runId, result.status, result.result, result.error, result.exitReason);
|
|
8774
9039
|
return result;
|
|
8775
9040
|
}
|
|
8776
|
-
function applyFailureToStage(stage,
|
|
9041
|
+
function applyFailureToStage(stage, failure) {
|
|
8777
9042
|
stage.status = "failed";
|
|
8778
|
-
stage.error =
|
|
8779
|
-
stage.failureKind =
|
|
8780
|
-
stage.failureCode =
|
|
8781
|
-
stage.failureRecoverability =
|
|
8782
|
-
stage.failureDisposition =
|
|
8783
|
-
stage.retryAfterMs =
|
|
8784
|
-
stage.failureMessage =
|
|
8785
|
-
}
|
|
8786
|
-
function runFailureMetadata(
|
|
9043
|
+
stage.error = failure.userMessage;
|
|
9044
|
+
stage.failureKind = failure.kind;
|
|
9045
|
+
stage.failureCode = failure.code;
|
|
9046
|
+
stage.failureRecoverability = failure.recoverability;
|
|
9047
|
+
stage.failureDisposition = failure.disposition;
|
|
9048
|
+
stage.retryAfterMs = failure.retryAfterMs;
|
|
9049
|
+
stage.failureMessage = failure.message;
|
|
9050
|
+
}
|
|
9051
|
+
function runFailureMetadata(failure, stages) {
|
|
8787
9052
|
const failedStage = stages.find((stage) => stage.status === "failed");
|
|
8788
|
-
const failureKind = failedStage?.failureKind ??
|
|
8789
|
-
const failureCode = failedStage?.failureCode ??
|
|
8790
|
-
const failureRecoverability = failedStage?.failureRecoverability ??
|
|
8791
|
-
const failureDisposition = failedStage?.failureDisposition ??
|
|
8792
|
-
const retryAfterMs = failedStage?.retryAfterMs ??
|
|
9053
|
+
const failureKind = failedStage?.failureKind ?? failure.kind;
|
|
9054
|
+
const failureCode = failedStage?.failureCode ?? failure.code;
|
|
9055
|
+
const failureRecoverability = failedStage?.failureRecoverability ?? failure.recoverability;
|
|
9056
|
+
const failureDisposition = failedStage?.failureDisposition ?? failure.disposition;
|
|
9057
|
+
const retryAfterMs = failedStage?.retryAfterMs ?? failure.retryAfterMs;
|
|
8793
9058
|
return {
|
|
8794
|
-
errorMessage: failedStage?.error ??
|
|
9059
|
+
errorMessage: failedStage?.error ?? failure.userMessage,
|
|
8795
9060
|
failureKind,
|
|
8796
9061
|
...failureCode !== undefined ? { failureCode } : {},
|
|
8797
9062
|
failureRecoverability,
|
|
8798
9063
|
failureDisposition,
|
|
8799
|
-
failureMessage: failedStage?.failureMessage ??
|
|
9064
|
+
failureMessage: failedStage?.failureMessage ?? failure.message,
|
|
8800
9065
|
...failedStage !== undefined ? { failedStageId: failedStage.id } : {},
|
|
8801
|
-
resumable:
|
|
9066
|
+
resumable: failure.resumable,
|
|
8802
9067
|
...retryAfterMs !== undefined ? { retryAfterMs } : {}
|
|
8803
9068
|
};
|
|
8804
9069
|
}
|
|
@@ -8827,17 +9092,17 @@ function runFailureMetadataFromStage(fallbackFailure, stage) {
|
|
|
8827
9092
|
...retryAfterMs !== undefined ? { retryAfterMs } : {}
|
|
8828
9093
|
};
|
|
8829
9094
|
}
|
|
8830
|
-
function runFailureMetadataFromFailure(
|
|
9095
|
+
function runFailureMetadataFromFailure(failure, failedStage) {
|
|
8831
9096
|
return {
|
|
8832
|
-
errorMessage: failedStage?.error ??
|
|
8833
|
-
failureKind:
|
|
8834
|
-
...
|
|
8835
|
-
failureRecoverability:
|
|
8836
|
-
failureDisposition:
|
|
8837
|
-
failureMessage: failedStage?.failureMessage ??
|
|
9097
|
+
errorMessage: failedStage?.error ?? failure.userMessage,
|
|
9098
|
+
failureKind: failure.kind,
|
|
9099
|
+
...failure.code !== undefined ? { failureCode: failure.code } : {},
|
|
9100
|
+
failureRecoverability: failure.recoverability,
|
|
9101
|
+
failureDisposition: failure.disposition,
|
|
9102
|
+
failureMessage: failedStage?.failureMessage ?? failure.message,
|
|
8838
9103
|
...failedStage !== undefined ? { failedStageId: failedStage.id } : {},
|
|
8839
|
-
resumable:
|
|
8840
|
-
...
|
|
9104
|
+
resumable: failure.resumable,
|
|
9105
|
+
...failure.retryAfterMs !== undefined ? { retryAfterMs: failure.retryAfterMs } : {}
|
|
8841
9106
|
};
|
|
8842
9107
|
}
|
|
8843
9108
|
function aggregateInnerFailures(error, classifyFailure) {
|
|
@@ -8851,20 +9116,20 @@ function stageFailureCandidate(stage) {
|
|
|
8851
9116
|
recoverability: stage.failureRecoverability ?? "unknown"
|
|
8852
9117
|
};
|
|
8853
9118
|
}
|
|
8854
|
-
function aggregateFailureCandidate(
|
|
9119
|
+
function aggregateFailureCandidate(failure) {
|
|
8855
9120
|
return {
|
|
8856
9121
|
source: "aggregate",
|
|
8857
|
-
failure
|
|
8858
|
-
disposition:
|
|
8859
|
-
recoverability:
|
|
9122
|
+
failure,
|
|
9123
|
+
disposition: failure.disposition,
|
|
9124
|
+
recoverability: failure.recoverability
|
|
8860
9125
|
};
|
|
8861
9126
|
}
|
|
8862
|
-
function outerFailureCandidate(
|
|
9127
|
+
function outerFailureCandidate(failure) {
|
|
8863
9128
|
return {
|
|
8864
9129
|
source: "outer",
|
|
8865
|
-
failure
|
|
8866
|
-
disposition:
|
|
8867
|
-
recoverability:
|
|
9130
|
+
failure,
|
|
9131
|
+
disposition: failure.disposition,
|
|
9132
|
+
recoverability: failure.recoverability
|
|
8868
9133
|
};
|
|
8869
9134
|
}
|
|
8870
9135
|
function isRecoverableActiveBlockedCandidate(candidate) {
|
|
@@ -8951,24 +9216,24 @@ function stageReplayFields(stage) {
|
|
|
8951
9216
|
};
|
|
8952
9217
|
}
|
|
8953
9218
|
function finalizeKilled(runId, runSnapshot, activeStore, persistence, onRunEnd) {
|
|
8954
|
-
const
|
|
9219
|
+
const errorMessage = "workflow killed";
|
|
8955
9220
|
const metadata = {
|
|
8956
9221
|
failureKind: "cancelled",
|
|
8957
9222
|
failureCode: "cancelled",
|
|
8958
9223
|
failureRecoverability: "non_recoverable",
|
|
8959
9224
|
failureDisposition: "terminal_killed",
|
|
8960
|
-
failureMessage:
|
|
9225
|
+
failureMessage: errorMessage,
|
|
8961
9226
|
resumable: false
|
|
8962
9227
|
};
|
|
8963
|
-
const recorded = activeStore.recordRunEnd(runId, "killed", undefined,
|
|
9228
|
+
const recorded = activeStore.recordRunEnd(runId, "killed", undefined, errorMessage, metadata);
|
|
8964
9229
|
appendRunEndWhenRecorded(persistence, recorded, {
|
|
8965
9230
|
runId,
|
|
8966
9231
|
status: "killed",
|
|
8967
|
-
error:
|
|
9232
|
+
error: errorMessage,
|
|
8968
9233
|
...metadata,
|
|
8969
9234
|
ts: Date.now()
|
|
8970
9235
|
});
|
|
8971
|
-
return reconcileTerminalRunResult(runId, runSnapshot, activeStore, { status: "killed", error:
|
|
9236
|
+
return reconcileTerminalRunResult(runId, runSnapshot, activeStore, { status: "killed", error: errorMessage }, onRunEnd);
|
|
8972
9237
|
}
|
|
8973
9238
|
function finalizeKilledByFailure(runId, runSnapshot, activeStore, persistence, onRunEnd, metadata) {
|
|
8974
9239
|
const recorded = activeStore.recordRunEnd(runId, "killed", undefined, metadata.errorMessage, metadata);
|
|
@@ -9035,32 +9300,32 @@ function recordActiveBlockedFailure(runId, runSnapshot, activeStore, persistence
|
|
|
9035
9300
|
|
|
9036
9301
|
// dist/builtin/workflows/src/runs/foreground/executor-outputs.ts
|
|
9037
9302
|
import { Value as Value5 } from "typebox/value";
|
|
9038
|
-
function hasOwnWorkflowOutput(record,
|
|
9039
|
-
return Object.hasOwn(record,
|
|
9303
|
+
function hasOwnWorkflowOutput(record, key) {
|
|
9304
|
+
return Object.hasOwn(record, key);
|
|
9040
9305
|
}
|
|
9041
9306
|
function assertWorkflowOutputsExplicit(scope, sourceOutput, declarations, missingOutputSuffix = "") {
|
|
9042
|
-
for (const
|
|
9043
|
-
if (!hasOwnWorkflowOutput(declarations,
|
|
9044
|
-
throw new Error(`atomic-workflows: ${scope} returned undeclared output "${
|
|
9307
|
+
for (const key of Object.keys(sourceOutput)) {
|
|
9308
|
+
if (!hasOwnWorkflowOutput(declarations, key)) {
|
|
9309
|
+
throw new Error(`atomic-workflows: ${scope} returned undeclared output "${key}"; declare it in outputs: { "${key}": Type.... } or remove it from the .run() return`);
|
|
9045
9310
|
}
|
|
9046
9311
|
}
|
|
9047
|
-
for (const [
|
|
9048
|
-
if (!(
|
|
9312
|
+
for (const [key, schema] of Object.entries(declarations)) {
|
|
9313
|
+
if (!(key in sourceOutput)) {
|
|
9049
9314
|
if (schemaIsRequired(schema)) {
|
|
9050
|
-
throw new Error(`atomic-workflows: ${scope} missing output "${
|
|
9315
|
+
throw new Error(`atomic-workflows: ${scope} missing output "${key}"${missingOutputSuffix}`);
|
|
9051
9316
|
}
|
|
9052
9317
|
continue;
|
|
9053
9318
|
}
|
|
9054
|
-
const value = sourceOutput[
|
|
9319
|
+
const value = sourceOutput[key];
|
|
9055
9320
|
const kind = schemaFieldKind(schema);
|
|
9056
9321
|
if (!Value5.Check(schema, value)) {
|
|
9057
9322
|
const choices = schemaChoices(schema);
|
|
9058
9323
|
if (kind === "select" && choices !== undefined && typeof value === "string") {
|
|
9059
|
-
throw new Error(`atomic-workflows: ${scope} output "${
|
|
9324
|
+
throw new Error(`atomic-workflows: ${scope} output "${key}" must be one of [${choices.join(", ")}], got ${JSON.stringify(value)}`);
|
|
9060
9325
|
}
|
|
9061
|
-
throw new Error(`atomic-workflows: ${scope} output "${
|
|
9326
|
+
throw new Error(`atomic-workflows: ${scope} output "${key}" expected ${kind}, got ${workflowSerializableTypeName(value)}`);
|
|
9062
9327
|
}
|
|
9063
|
-
const serializableError = workflowSerializableValidationError(value, `${scope} output "${
|
|
9328
|
+
const serializableError = workflowSerializableValidationError(value, `${scope} output "${key}"`);
|
|
9064
9329
|
if (serializableError !== undefined)
|
|
9065
9330
|
throw new Error(`atomic-workflows: ${serializableError}`);
|
|
9066
9331
|
}
|
|
@@ -9093,27 +9358,27 @@ function assertWorkflowExitOutputs(workflowName, result, declaredOutputs) {
|
|
|
9093
9358
|
const declarations = declaredOutputs ?? {};
|
|
9094
9359
|
const sourceOutput = result ?? {};
|
|
9095
9360
|
const scope = `workflow "${workflowName}" ctx.exit()`;
|
|
9096
|
-
for (const
|
|
9097
|
-
if (!hasOwnWorkflowOutput(declarations,
|
|
9098
|
-
throw new Error(`atomic-workflows: ${scope} provided undeclared output "${
|
|
9361
|
+
for (const key of Object.keys(sourceOutput)) {
|
|
9362
|
+
if (!hasOwnWorkflowOutput(declarations, key)) {
|
|
9363
|
+
throw new Error(`atomic-workflows: ${scope} provided undeclared output "${key}"; declare it in outputs: { "${key}": Type.... } or remove it from ctx.exit({ outputs })`);
|
|
9099
9364
|
}
|
|
9100
9365
|
}
|
|
9101
|
-
for (const [
|
|
9102
|
-
if (!(
|
|
9366
|
+
for (const [key, schema] of Object.entries(declarations)) {
|
|
9367
|
+
if (!(key in sourceOutput))
|
|
9103
9368
|
continue;
|
|
9104
|
-
const value = sourceOutput[
|
|
9105
|
-
const invalidSnapshotValue = workflowExitSnapshotInvalidValueMessage(`${scope} output "${
|
|
9369
|
+
const value = sourceOutput[key];
|
|
9370
|
+
const invalidSnapshotValue = workflowExitSnapshotInvalidValueMessage(`${scope} output "${key}"`, value);
|
|
9106
9371
|
if (invalidSnapshotValue !== undefined)
|
|
9107
9372
|
throw new Error(`atomic-workflows: ${invalidSnapshotValue}`);
|
|
9108
9373
|
const kind = schemaFieldKind(schema);
|
|
9109
9374
|
if (!Value5.Check(schema, value)) {
|
|
9110
9375
|
const choices = schemaChoices(schema);
|
|
9111
9376
|
if (kind === "select" && choices !== undefined && typeof value === "string") {
|
|
9112
|
-
throw new Error(`atomic-workflows: ${scope} output "${
|
|
9377
|
+
throw new Error(`atomic-workflows: ${scope} output "${key}" must be one of [${choices.join(", ")}], got ${JSON.stringify(value)}`);
|
|
9113
9378
|
}
|
|
9114
|
-
throw new Error(`atomic-workflows: ${scope} output "${
|
|
9379
|
+
throw new Error(`atomic-workflows: ${scope} output "${key}" expected ${kind}, got ${workflowSerializableTypeName(value)}`);
|
|
9115
9380
|
}
|
|
9116
|
-
const serializableError = workflowSerializableValidationError(value, `${scope} output "${
|
|
9381
|
+
const serializableError = workflowSerializableValidationError(value, `${scope} output "${key}"`);
|
|
9117
9382
|
if (serializableError !== undefined)
|
|
9118
9383
|
throw new Error(`atomic-workflows: ${serializableError}`);
|
|
9119
9384
|
}
|
|
@@ -9122,10 +9387,10 @@ function selectWorkflowOutputs(child, rawOutput) {
|
|
|
9122
9387
|
const declarations = child.outputs ?? {};
|
|
9123
9388
|
const sourceOutput = rawOutput ?? {};
|
|
9124
9389
|
const selected = {};
|
|
9125
|
-
for (const
|
|
9126
|
-
const value = sourceOutput[
|
|
9390
|
+
for (const key of Object.keys(declarations)) {
|
|
9391
|
+
const value = sourceOutput[key];
|
|
9127
9392
|
if (value !== undefined)
|
|
9128
|
-
selected[
|
|
9393
|
+
selected[key] = value;
|
|
9129
9394
|
}
|
|
9130
9395
|
return selected;
|
|
9131
9396
|
}
|
|
@@ -9540,8 +9805,8 @@ function buildPromptNodeUiAdapter(input) {
|
|
|
9540
9805
|
try {
|
|
9541
9806
|
if (mergedSignal.signal.aborted)
|
|
9542
9807
|
throw hilAbortError(mergedSignal.signal);
|
|
9543
|
-
const
|
|
9544
|
-
if (!
|
|
9808
|
+
const accepted = input.activeStore.recordStageAwaitingInput(input.runId, stageId, true, prompt.createdAt);
|
|
9809
|
+
if (!accepted) {
|
|
9545
9810
|
const error = new Error("atomic-workflows: ctx.ui.custom prompt node is unavailable");
|
|
9546
9811
|
stageSnapshot.skippedReason = "prompt-unavailable";
|
|
9547
9812
|
await finalizePromptStage("skipped");
|
|
@@ -9571,15 +9836,15 @@ function buildPromptNodeUiAdapter(input) {
|
|
|
9571
9836
|
mergedSignal.dispose();
|
|
9572
9837
|
}
|
|
9573
9838
|
}
|
|
9574
|
-
const
|
|
9575
|
-
if (!
|
|
9839
|
+
const accepted = input.activeStore.recordStagePendingPrompt(input.runId, stageId, prompt);
|
|
9840
|
+
if (!accepted) {
|
|
9576
9841
|
stageSnapshot.skippedReason = "prompt-unavailable";
|
|
9577
9842
|
await finalizePromptStage("skipped");
|
|
9578
9843
|
return fallbackForPromptDescriptor(descriptor);
|
|
9579
9844
|
}
|
|
9580
9845
|
const waiter = input.activeStore.awaitStagePendingPrompt(input.runId, stageId, prompt.id);
|
|
9581
9846
|
try {
|
|
9582
|
-
const response = await new Promise((
|
|
9847
|
+
const response = await new Promise((resolve, reject) => {
|
|
9583
9848
|
const onAbort = () => {
|
|
9584
9849
|
input.activeStore.resolveStagePendingPrompt(input.runId, stageId, prompt.id, fallbackForPromptDescriptor(descriptor), { recordAnswer: false });
|
|
9585
9850
|
reject(hilAbortError(input.signal));
|
|
@@ -9591,7 +9856,7 @@ function buildPromptNodeUiAdapter(input) {
|
|
|
9591
9856
|
input.signal.addEventListener("abort", onAbort, { once: true });
|
|
9592
9857
|
waiter.then((value) => {
|
|
9593
9858
|
input.signal.removeEventListener("abort", onAbort);
|
|
9594
|
-
|
|
9859
|
+
resolve(value);
|
|
9595
9860
|
}, (err) => {
|
|
9596
9861
|
input.signal.removeEventListener("abort", onAbort);
|
|
9597
9862
|
reject(err);
|
|
@@ -9652,8 +9917,8 @@ function buildPromptNodeUiAdapter(input) {
|
|
|
9652
9917
|
// dist/builtin/workflows/src/runs/foreground/executor-run-finalizers.ts
|
|
9653
9918
|
function createRunFinalizers(input) {
|
|
9654
9919
|
const finalizeWorkflowExitValidationFailure = (err, exitReason) => {
|
|
9655
|
-
const
|
|
9656
|
-
const classifiedMetadata = runFailureMetadata(
|
|
9920
|
+
const failure = input.classifyExecutorFailure(err);
|
|
9921
|
+
const classifiedMetadata = runFailureMetadata(failure, input.runSnapshot.stages);
|
|
9657
9922
|
const metadata = {
|
|
9658
9923
|
...classifiedMetadata,
|
|
9659
9924
|
resumable: false,
|
|
@@ -9718,8 +9983,8 @@ function createRunFinalizers(input) {
|
|
|
9718
9983
|
...signal.reason !== undefined ? { exitReason: signal.reason } : {}
|
|
9719
9984
|
}, input.opts.onRunEnd);
|
|
9720
9985
|
};
|
|
9721
|
-
const finalizeParentWorkflowExitCancellation = async (
|
|
9722
|
-
const parentReason =
|
|
9986
|
+
const finalizeParentWorkflowExitCancellation = async (abortReason) => {
|
|
9987
|
+
const parentReason = abortReason.workflowExitReason;
|
|
9723
9988
|
await input.drainWorkflowExitCleanups(parentReason);
|
|
9724
9989
|
const exitReason = parentWorkflowExitRunReason(parentReason);
|
|
9725
9990
|
const metadata = { resumable: false, exited: true, exitReason };
|
|
@@ -9748,6 +10013,7 @@ function isTerminalStage(stage) {
|
|
|
9748
10013
|
function createStageScheduler(input) {
|
|
9749
10014
|
const releaseBarriers = new Map;
|
|
9750
10015
|
const cascadePauseOwners = new Map;
|
|
10016
|
+
let runBarrier;
|
|
9751
10017
|
const makeReleaseBarrier = () => {
|
|
9752
10018
|
const resolver = Promise.withResolvers();
|
|
9753
10019
|
resolver.promise.catch(() => {});
|
|
@@ -9869,6 +10135,8 @@ function createStageScheduler(input) {
|
|
|
9869
10135
|
}
|
|
9870
10136
|
};
|
|
9871
10137
|
const rejectReleaseBarriers = (reason) => {
|
|
10138
|
+
runBarrier?.reject(reason);
|
|
10139
|
+
runBarrier = undefined;
|
|
9872
10140
|
cascadePauseOwners.clear();
|
|
9873
10141
|
for (const [stageId, barrier] of releaseBarriers) {
|
|
9874
10142
|
releaseBarriers.delete(stageId);
|
|
@@ -9891,6 +10159,19 @@ function createStageScheduler(input) {
|
|
|
9891
10159
|
};
|
|
9892
10160
|
return {
|
|
9893
10161
|
tracker: input.tracker,
|
|
10162
|
+
isRunPaused: () => runBarrier !== undefined,
|
|
10163
|
+
pauseRun: () => {
|
|
10164
|
+
runBarrier ??= makeReleaseBarrier();
|
|
10165
|
+
},
|
|
10166
|
+
releaseRun: () => {
|
|
10167
|
+
const barrier = runBarrier;
|
|
10168
|
+
runBarrier = undefined;
|
|
10169
|
+
barrier?.resolve();
|
|
10170
|
+
},
|
|
10171
|
+
waitForRunRelease: async () => {
|
|
10172
|
+
while (runBarrier !== undefined)
|
|
10173
|
+
await runBarrier.promise;
|
|
10174
|
+
},
|
|
9894
10175
|
stageById,
|
|
9895
10176
|
setStageParentIds,
|
|
9896
10177
|
descendantsOf,
|
|
@@ -10165,8 +10446,8 @@ class ConcurrencyLimiter {
|
|
|
10165
10446
|
this._running++;
|
|
10166
10447
|
return Promise.resolve();
|
|
10167
10448
|
}
|
|
10168
|
-
return new Promise((
|
|
10169
|
-
this._queue.push(
|
|
10449
|
+
return new Promise((resolve) => {
|
|
10450
|
+
this._queue.push(resolve);
|
|
10170
10451
|
});
|
|
10171
10452
|
}
|
|
10172
10453
|
release() {
|
|
@@ -10187,7 +10468,25 @@ class ConcurrencyLimiter {
|
|
|
10187
10468
|
}
|
|
10188
10469
|
}
|
|
10189
10470
|
function createRunLimiter(defaultConcurrency) {
|
|
10190
|
-
return new ConcurrencyLimiter(defaultConcurrency ??
|
|
10471
|
+
return new ConcurrencyLimiter(defaultConcurrency ?? 3);
|
|
10472
|
+
}
|
|
10473
|
+
|
|
10474
|
+
// dist/builtin/workflows/src/shared/abort.ts
|
|
10475
|
+
function raceAbort2(operation, signal) {
|
|
10476
|
+
if (signal === undefined)
|
|
10477
|
+
return operation;
|
|
10478
|
+
if (signal.aborted) {
|
|
10479
|
+
operation.catch(() => {});
|
|
10480
|
+
return Promise.reject(signal.reason ?? new DOMException("Workflow request aborted", "AbortError"));
|
|
10481
|
+
}
|
|
10482
|
+
const abort = Promise.withResolvers();
|
|
10483
|
+
const onAbort = () => {
|
|
10484
|
+
abort.reject(signal.reason ?? new DOMException("Workflow request aborted", "AbortError"));
|
|
10485
|
+
};
|
|
10486
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
10487
|
+
return Promise.race([operation, abort.promise]).finally(() => {
|
|
10488
|
+
signal.removeEventListener("abort", onAbort);
|
|
10489
|
+
});
|
|
10191
10490
|
}
|
|
10192
10491
|
|
|
10193
10492
|
// dist/builtin/workflows/src/engine/primitives/chain.ts
|
|
@@ -10234,11 +10533,11 @@ function createWorkflowExitManager(input) {
|
|
|
10234
10533
|
const trackWorkflowExitCleanup = (operation) => {
|
|
10235
10534
|
if (operation === undefined)
|
|
10236
10535
|
return;
|
|
10237
|
-
let
|
|
10238
|
-
|
|
10239
|
-
workflowExitCleanupPromises.delete(
|
|
10536
|
+
let tracked;
|
|
10537
|
+
tracked = Promise.resolve(operation).catch(() => {}).finally(() => {
|
|
10538
|
+
workflowExitCleanupPromises.delete(tracked);
|
|
10240
10539
|
});
|
|
10241
|
-
workflowExitCleanupPromises.add(
|
|
10540
|
+
workflowExitCleanupPromises.add(tracked);
|
|
10242
10541
|
};
|
|
10243
10542
|
const invokeWorkflowExitCleanup = (cleanup, reason) => {
|
|
10244
10543
|
try {
|
|
@@ -10364,10 +10663,10 @@ function createWorkflowExitManager(input) {
|
|
|
10364
10663
|
};
|
|
10365
10664
|
}
|
|
10366
10665
|
// dist/builtin/workflows/src/engine/primitives/parallel.ts
|
|
10367
|
-
import { randomUUID as
|
|
10666
|
+
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
10368
10667
|
|
|
10369
10668
|
// dist/builtin/workflows/src/shared/intercom-group.ts
|
|
10370
|
-
import { randomUUID as
|
|
10669
|
+
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
10371
10670
|
var DEFAULT_INTERCOM_GROUP = "default";
|
|
10372
10671
|
function workflowInvocationIntercomGroup(rootRunId) {
|
|
10373
10672
|
return `workflow:${rootRunId}`;
|
|
@@ -10390,22 +10689,22 @@ function resolveStageGroup(stageOptions, workflowGroup) {
|
|
|
10390
10689
|
const group = stageOptions.group;
|
|
10391
10690
|
if (group === undefined)
|
|
10392
10691
|
return workflowGroup;
|
|
10393
|
-
const authored = group === true ?
|
|
10692
|
+
const authored = group === true ? randomUUID3() : group.trim();
|
|
10394
10693
|
if (authored.length === 0)
|
|
10395
10694
|
return;
|
|
10396
10695
|
if (workflowGroup === undefined || authored === DEFAULT_INTERCOM_GROUP)
|
|
10397
10696
|
return authored;
|
|
10398
|
-
const
|
|
10399
|
-
if (authored ===
|
|
10697
|
+
const owner = normalizeGroup(workflowGroup);
|
|
10698
|
+
if (authored === owner || authored.startsWith(`${owner}/`))
|
|
10400
10699
|
return authored;
|
|
10401
|
-
return `${
|
|
10700
|
+
return `${owner}/${authored}`;
|
|
10402
10701
|
}
|
|
10403
10702
|
function workflowInvocationOwnsGroup(workflowGroup, candidate) {
|
|
10404
10703
|
if (workflowGroup === undefined || candidate === undefined)
|
|
10405
10704
|
return false;
|
|
10406
|
-
const
|
|
10705
|
+
const owner = normalizeGroup(workflowGroup);
|
|
10407
10706
|
const group = normalizeGroup(candidate);
|
|
10408
|
-
return group ===
|
|
10707
|
+
return group === owner || group.startsWith(`${owner}/`);
|
|
10409
10708
|
}
|
|
10410
10709
|
function stageHasIntercomAccess(_stageOptions) {
|
|
10411
10710
|
return true;
|
|
@@ -10448,7 +10747,7 @@ function fold_usage(results) {
|
|
|
10448
10747
|
|
|
10449
10748
|
// dist/builtin/workflows/src/shared/budget-meter.ts
|
|
10450
10749
|
var usageFields = ["input", "output", "cacheRead", "cacheWrite", "cost"];
|
|
10451
|
-
var addUsage = (left, right) => Object.fromEntries(usageFields.map((
|
|
10750
|
+
var addUsage = (left, right) => Object.fromEntries(usageFields.map((field) => [field, left[field] + right[field]]));
|
|
10452
10751
|
function foldTreeUsage(tree) {
|
|
10453
10752
|
const run = "run" in tree ? tree.run : tree;
|
|
10454
10753
|
const folded = fold_usage(run.stages.filter((stage) => stage.replayed !== true).map((stage) => ({ stageName: stage.name, text: stage.result ?? "", modelAttempts: stage.modelAttempts })));
|
|
@@ -10460,7 +10759,7 @@ function meter_run(tree, now) {
|
|
|
10460
10759
|
durationMs: elapsedRunMs("run" in tree ? tree.run : tree, now),
|
|
10461
10760
|
tokens: usage.input + usage.output,
|
|
10462
10761
|
cost: usage.cost,
|
|
10463
|
-
perCounter: Object.fromEntries(usageFields.filter((
|
|
10762
|
+
perCounter: Object.fromEntries(usageFields.filter((field) => field !== "cost").map((field) => [field, usage[field]]))
|
|
10464
10763
|
};
|
|
10465
10764
|
}
|
|
10466
10765
|
|
|
@@ -10479,7 +10778,7 @@ class WorkflowBudgetExceededError extends Error {
|
|
|
10479
10778
|
var withFrontier = (report, frontierStage, summary, usage) => Object.assign({ ...report, frontierStage: frontierStage ?? "workflow frontier" }, summary === undefined ? {} : { wrapUpSummary: summary }, usage === undefined ? {} : { wrapUpUsage: usage });
|
|
10480
10779
|
var usageFields2 = ["input", "output", "cacheRead", "cacheWrite", "cost"];
|
|
10481
10780
|
var counterFields = ["input", "output", "cacheRead", "cacheWrite"];
|
|
10482
|
-
var mapFields = (fields, fn = () => 0) => Object.fromEntries(fields.map((
|
|
10781
|
+
var mapFields = (fields, fn = () => 0) => Object.fromEntries(fields.map((field) => [field, fn(field)]));
|
|
10483
10782
|
function createRunBudgetController(input) {
|
|
10484
10783
|
const { run, budget } = input;
|
|
10485
10784
|
const ownEnabled = budget.maxDurationMs > 0 || budget.maxTokens > 0 || budget.maxCost > 0;
|
|
@@ -10490,7 +10789,7 @@ function createRunBudgetController(input) {
|
|
|
10490
10789
|
const previousAccounting = state?.accounting;
|
|
10491
10790
|
const initial = previousAccounting && usageEnabled ? meter_run(input.usageTree?.() ?? { run }, Date.now()) : undefined;
|
|
10492
10791
|
const initialAccounting = initial === undefined ? undefined : { ...initial.perCounter, cost: initial.cost };
|
|
10493
|
-
let baseline = mapFields(usageFields2, (
|
|
10792
|
+
let baseline = mapFields(usageFields2, (field) => initialAccounting?.[field] ?? 0);
|
|
10494
10793
|
let charged = {
|
|
10495
10794
|
baseline,
|
|
10496
10795
|
tokens: previousAccounting?.tokens ?? 0,
|
|
@@ -10508,13 +10807,13 @@ function createRunBudgetController(input) {
|
|
|
10508
10807
|
};
|
|
10509
10808
|
const accountUsage = (meters) => {
|
|
10510
10809
|
const current = { ...meters.perCounter, cost: meters.cost };
|
|
10511
|
-
const delta = mapFields(usageFields2, (
|
|
10512
|
-
baseline = mapFields(usageFields2, (
|
|
10810
|
+
const delta = mapFields(usageFields2, (field) => Math.max(0, current[field] - baseline[field]));
|
|
10811
|
+
baseline = mapFields(usageFields2, (field) => Math.max(baseline[field], current[field]));
|
|
10513
10812
|
charged = {
|
|
10514
10813
|
baseline,
|
|
10515
10814
|
tokens: charged.tokens + delta.input + delta.output,
|
|
10516
10815
|
cost: charged.cost + delta.cost,
|
|
10517
|
-
perCounter: mapFields(counterFields, (
|
|
10816
|
+
perCounter: mapFields(counterFields, (field) => charged.perCounter[field] + delta[field])
|
|
10518
10817
|
};
|
|
10519
10818
|
updateState({ accounting: charged });
|
|
10520
10819
|
return Object.assign(meters, { tokens: charged.tokens, cost: charged.cost, perCounter: charged.perCounter });
|
|
@@ -10591,21 +10890,21 @@ function createRunBudgetController(input) {
|
|
|
10591
10890
|
return { check: ownCheckpoint(frontierStage) };
|
|
10592
10891
|
};
|
|
10593
10892
|
const checkpoint = (frontierStage) => boundaryCheckpoint(frontierStage).check;
|
|
10594
|
-
const finishBoundary = (
|
|
10595
|
-
throw
|
|
10893
|
+
const finishBoundary = (owner, frontierStage) => {
|
|
10894
|
+
throw owner?.finishWrapUp(frontierStage, undefined, undefined, false) ?? finishWrapUp(frontierStage, undefined, undefined, false);
|
|
10596
10895
|
};
|
|
10597
|
-
const deliverBoundary = (
|
|
10598
|
-
|
|
10896
|
+
const deliverBoundary = (owner, frontierStage) => {
|
|
10897
|
+
owner?.deliverWrapUp(frontierStage) ?? deliverWrapUp(frontierStage);
|
|
10599
10898
|
};
|
|
10600
10899
|
const stopAtBoundary = (frontierStage) => {
|
|
10601
10900
|
const resolvedFrontierStage = frontierStage ?? handlers.at(-1)?.frontierStage;
|
|
10602
|
-
const { check, owner
|
|
10901
|
+
const { check, owner } = boundaryCheckpoint(resolvedFrontierStage);
|
|
10603
10902
|
if (check.kind === "wrap_up") {
|
|
10604
|
-
deliverBoundary(
|
|
10605
|
-
finishBoundary(
|
|
10903
|
+
deliverBoundary(owner, resolvedFrontierStage ?? "workflow frontier");
|
|
10904
|
+
finishBoundary(owner, resolvedFrontierStage);
|
|
10606
10905
|
}
|
|
10607
10906
|
if (check.kind === "exhausted")
|
|
10608
|
-
finishBoundary(
|
|
10907
|
+
finishBoundary(owner, resolvedFrontierStage);
|
|
10609
10908
|
};
|
|
10610
10909
|
const rethrowIfSystemOwnedStop = (frontierStage) => {
|
|
10611
10910
|
root?.rethrowIfSystemOwnedStop(frontierStage);
|
|
@@ -10699,11 +10998,11 @@ function createRunBudgetController(input) {
|
|
|
10699
10998
|
function createParallelPrimitive(input) {
|
|
10700
10999
|
return async (steps, options = {}) => {
|
|
10701
11000
|
input.runtime.exit.throwIfWorkflowExitSelected();
|
|
10702
|
-
const
|
|
10703
|
-
const normalizedOptions =
|
|
10704
|
-
const normalizedSteps = steps.map(
|
|
11001
|
+
const normalizeGroup = (value) => value.group === undefined ? value : { ...value, group: normalizeAutoGroupSentinel(value.group) };
|
|
11002
|
+
const normalizedOptions = normalizeGroup(options);
|
|
11003
|
+
const normalizedSteps = steps.map(normalizeGroup);
|
|
10705
11004
|
const needsAutoGroup = normalizedOptions.group === true || normalizedSteps.some((step) => step.group === true);
|
|
10706
|
-
const autoGroup = needsAutoGroup ?
|
|
11005
|
+
const autoGroup = needsAutoGroup ? randomUUID4() : undefined;
|
|
10707
11006
|
const resolveAutoGroup = (value) => value.group === true && autoGroup ? { ...value, group: autoGroup } : value;
|
|
10708
11007
|
const resolvedOptions = resolveAutoGroup(normalizedOptions);
|
|
10709
11008
|
const resolvedSteps = normalizedSteps.map(resolveAutoGroup);
|
|
@@ -10744,9 +11043,9 @@ function createParallelPrimitive(input) {
|
|
|
10744
11043
|
beforeMap: input.runtime.exit.throwIfWorkflowExitSelected,
|
|
10745
11044
|
isControlSignal: (error) => findWorkflowExitSignal(error, input.runtime.exit.exitScope) !== undefined,
|
|
10746
11045
|
selectSettledFailure: (failures) => {
|
|
10747
|
-
if (!everyStepCompleted() || !failures.every((
|
|
11046
|
+
if (!everyStepCompleted() || !failures.every((failure) => failure.error instanceof WorkflowBudgetExceededError))
|
|
10748
11047
|
return;
|
|
10749
|
-
return failures.reduce((selected,
|
|
11048
|
+
return failures.reduce((selected, failure) => failure.index < selected.index ? failure : selected).error;
|
|
10750
11049
|
}
|
|
10751
11050
|
});
|
|
10752
11051
|
};
|
|
@@ -10791,6 +11090,7 @@ function createTaskPrimitive(runtime) {
|
|
|
10791
11090
|
...sessionId !== undefined ? { sessionId } : {},
|
|
10792
11091
|
...stage.sessionFile !== undefined ? { sessionFile: stage.sessionFile } : {},
|
|
10793
11092
|
...stageMeta.model !== undefined ? { model: stageMeta.model } : {},
|
|
11093
|
+
...stageMeta.thinkingLevel !== undefined ? { thinkingLevel: stageMeta.thinkingLevel } : {},
|
|
10794
11094
|
...stageMeta.attemptedModels !== undefined ? { attemptedModels: stageMeta.attemptedModels } : {},
|
|
10795
11095
|
...stageMeta.modelAttempts !== undefined ? { modelAttempts: stageMeta.modelAttempts } : {},
|
|
10796
11096
|
...stageMeta.warnings !== undefined ? { warnings: stageMeta.warnings } : {}
|
|
@@ -10896,6 +11196,8 @@ function wrapUiWithDurable(base, deps) {
|
|
|
10896
11196
|
return {
|
|
10897
11197
|
async input(promptText) {
|
|
10898
11198
|
const callerStack = new Error().stack;
|
|
11199
|
+
for (let wait = deps.beforeCall?.();wait !== undefined; wait = deps.beforeCall?.())
|
|
11200
|
+
await wait;
|
|
10899
11201
|
const identity = nextIdentity("input", promptText, callerStack);
|
|
10900
11202
|
const hit = cached(identity);
|
|
10901
11203
|
if (typeof hit === "string") {
|
|
@@ -10915,6 +11217,8 @@ function wrapUiWithDurable(base, deps) {
|
|
|
10915
11217
|
},
|
|
10916
11218
|
async confirm(message) {
|
|
10917
11219
|
const callerStack = new Error().stack;
|
|
11220
|
+
for (let wait = deps.beforeCall?.();wait !== undefined; wait = deps.beforeCall?.())
|
|
11221
|
+
await wait;
|
|
10918
11222
|
const identity = nextIdentity("confirm", message, callerStack);
|
|
10919
11223
|
const hit = cached(identity);
|
|
10920
11224
|
if (typeof hit === "boolean") {
|
|
@@ -10934,6 +11238,8 @@ function wrapUiWithDurable(base, deps) {
|
|
|
10934
11238
|
},
|
|
10935
11239
|
async select(message, options) {
|
|
10936
11240
|
const callerStack = new Error().stack;
|
|
11241
|
+
for (let wait = deps.beforeCall?.();wait !== undefined; wait = deps.beforeCall?.())
|
|
11242
|
+
await wait;
|
|
10937
11243
|
const identity = nextIdentity("select", message, callerStack, [...options]);
|
|
10938
11244
|
const hit = cached(identity);
|
|
10939
11245
|
if (typeof hit === "string") {
|
|
@@ -10953,6 +11259,8 @@ function wrapUiWithDurable(base, deps) {
|
|
|
10953
11259
|
},
|
|
10954
11260
|
async editor(initial) {
|
|
10955
11261
|
const callerStack = new Error().stack;
|
|
11262
|
+
for (let wait = deps.beforeCall?.();wait !== undefined; wait = deps.beforeCall?.())
|
|
11263
|
+
await wait;
|
|
10956
11264
|
const identity = nextIdentity("editor", initial ?? "", callerStack, initial ?? null);
|
|
10957
11265
|
const hit = cached(identity);
|
|
10958
11266
|
if (typeof hit === "string") {
|
|
@@ -10972,6 +11280,8 @@ function wrapUiWithDurable(base, deps) {
|
|
|
10972
11280
|
},
|
|
10973
11281
|
async custom(factory, options) {
|
|
10974
11282
|
const callerStack = new Error().stack;
|
|
11283
|
+
for (let wait = deps.beforeCall?.();wait !== undefined; wait = deps.beforeCall?.())
|
|
11284
|
+
await wait;
|
|
10975
11285
|
const replayIdentity = options?.replayIdentity ?? factory?.name ?? "custom";
|
|
10976
11286
|
const identity = nextIdentity("custom", replayIdentity, callerStack, { replayIdentity });
|
|
10977
11287
|
const hit = cachedCustom(identity);
|
|
@@ -11004,26 +11314,32 @@ function buildExitGatedUiContext(input) {
|
|
|
11004
11314
|
const base = input.opts.usePromptNodesForUi === true ? input.baseFromPromptNodes() : input.opts.executionMode === "non_interactive" && input.opts.ui === undefined ? makeHeadlessUnavailableUIContext() : normalizeUIContext(input.opts.ui);
|
|
11005
11315
|
const promptNodeReplay = input.opts.usePromptNodesForUi === true && input.opts.continuation !== undefined;
|
|
11006
11316
|
const durableBase = input.durableUi !== undefined && !promptNodeReplay ? wrapUiWithDurable(base, input.durableUi) : base;
|
|
11317
|
+
const invoke = (call) => {
|
|
11318
|
+
input.throwIfWorkflowExitSelected();
|
|
11319
|
+
if (!promptNodeReplay || input.durableUi?.beforeCall === undefined)
|
|
11320
|
+
return call();
|
|
11321
|
+
return withPromptCallerStack(new Error().stack, async () => {
|
|
11322
|
+
for (let wait = input.durableUi?.beforeCall?.();wait !== undefined; wait = input.durableUi?.beforeCall?.())
|
|
11323
|
+
await wait;
|
|
11324
|
+
input.throwIfWorkflowExitSelected();
|
|
11325
|
+
return call();
|
|
11326
|
+
});
|
|
11327
|
+
};
|
|
11007
11328
|
return {
|
|
11008
11329
|
async input(promptText) {
|
|
11009
|
-
input
|
|
11010
|
-
return await durableBase.input(promptText);
|
|
11330
|
+
return await invoke(() => durableBase.input(promptText));
|
|
11011
11331
|
},
|
|
11012
11332
|
async confirm(message) {
|
|
11013
|
-
|
|
11014
|
-
return await durableBase.confirm(message);
|
|
11333
|
+
return await invoke(() => durableBase.confirm(message));
|
|
11015
11334
|
},
|
|
11016
11335
|
async select(message, options) {
|
|
11017
|
-
|
|
11018
|
-
return await durableBase.select(message, options);
|
|
11336
|
+
return await invoke(() => durableBase.select(message, options));
|
|
11019
11337
|
},
|
|
11020
11338
|
async editor(initial) {
|
|
11021
|
-
|
|
11022
|
-
return await durableBase.editor(initial);
|
|
11339
|
+
return await invoke(() => durableBase.editor(initial));
|
|
11023
11340
|
},
|
|
11024
11341
|
async custom(factory, options) {
|
|
11025
|
-
|
|
11026
|
-
return await durableBase.custom(factory, options);
|
|
11342
|
+
return await invoke(() => durableBase.custom(factory, options));
|
|
11027
11343
|
}
|
|
11028
11344
|
};
|
|
11029
11345
|
}
|
|
@@ -11273,8 +11589,8 @@ function structuredRecoverableFailureFromSnapshot(snapshot, failedStageId) {
|
|
|
11273
11589
|
function isRecoverableProviderFailureKind(kind) {
|
|
11274
11590
|
return kind === "auth" || kind === "rate_limit" || kind === "provider";
|
|
11275
11591
|
}
|
|
11276
|
-
function stringResultField(result,
|
|
11277
|
-
const value = result?.[
|
|
11592
|
+
function stringResultField(result, key) {
|
|
11593
|
+
const value = result?.[key];
|
|
11278
11594
|
return typeof value === "string" && value.trim().length > 0 ? value.trim() : undefined;
|
|
11279
11595
|
}
|
|
11280
11596
|
|
|
@@ -11292,7 +11608,7 @@ async function finalizeDurableTerminalStatus(input) {
|
|
|
11292
11608
|
if (durableStatus === "failed" || durableStatus === "blocked") {
|
|
11293
11609
|
recordRunTimingCheckpoint(input.durableBackend, input.runSnapshot);
|
|
11294
11610
|
}
|
|
11295
|
-
const
|
|
11611
|
+
const failure = durableStatus === "failed" ? {
|
|
11296
11612
|
...input.runSnapshot.error !== undefined ? { error: input.runSnapshot.error } : {},
|
|
11297
11613
|
...input.runSnapshot.exited === true ? {
|
|
11298
11614
|
exited: true,
|
|
@@ -11304,7 +11620,7 @@ async function finalizeDurableTerminalStatus(input) {
|
|
|
11304
11620
|
...input.runSnapshot.failureDisposition !== undefined ? { failureDisposition: input.runSnapshot.failureDisposition } : {},
|
|
11305
11621
|
...input.runSnapshot.failedToolNodeId !== undefined ? { failedToolNodeId: input.runSnapshot.failedToolNodeId } : {}
|
|
11306
11622
|
} : undefined;
|
|
11307
|
-
input.durableBackend.setWorkflowStatus(input.runId, durableStatus, undefined, input.runSnapshot.resumable,
|
|
11623
|
+
input.durableBackend.setWorkflowStatus(input.runId, durableStatus, undefined, input.runSnapshot.resumable, failure);
|
|
11308
11624
|
}
|
|
11309
11625
|
await input.durableBackend.flush(input.runId);
|
|
11310
11626
|
}
|
|
@@ -11561,17 +11877,17 @@ function childRunIdFromDraft(draft) {
|
|
|
11561
11877
|
}
|
|
11562
11878
|
function boundaryOwner(grouped, childRunId) {
|
|
11563
11879
|
for (const drafts of grouped.values()) {
|
|
11564
|
-
const
|
|
11565
|
-
if (
|
|
11566
|
-
return
|
|
11880
|
+
const owner = drafts.find((draft) => childRunIdFromDraft(draft) === childRunId);
|
|
11881
|
+
if (owner !== undefined)
|
|
11882
|
+
return owner;
|
|
11567
11883
|
}
|
|
11568
11884
|
return;
|
|
11569
11885
|
}
|
|
11570
|
-
function childRunStatus(
|
|
11571
|
-
const child = workflowChildFromDraft(
|
|
11886
|
+
function childRunStatus(owner) {
|
|
11887
|
+
const child = workflowChildFromDraft(owner);
|
|
11572
11888
|
if (child !== undefined)
|
|
11573
11889
|
return child.status;
|
|
11574
|
-
const status =
|
|
11890
|
+
const status = owner.topology?.boundary?.status;
|
|
11575
11891
|
return status === "failed" || status === "skipped" || status === "completed" ? status : "running";
|
|
11576
11892
|
}
|
|
11577
11893
|
function mergeStageGroup(records, allStages, allCheckpoints) {
|
|
@@ -11616,17 +11932,18 @@ function mergeStageDraft(existing, checkpoint, sequence) {
|
|
|
11616
11932
|
...valueOrExisting("endedAt", checkpoint, existing),
|
|
11617
11933
|
...valueOrExisting("durationMs", checkpoint, existing),
|
|
11618
11934
|
...valueOrExisting("model", checkpoint, existing),
|
|
11935
|
+
...valueOrExisting("thinkingLevel", checkpoint, existing),
|
|
11619
11936
|
...valueOrExisting("attemptedModels", checkpoint, existing),
|
|
11620
11937
|
...valueOrExisting("modelAttempts", checkpoint, existing),
|
|
11621
11938
|
...checkpoint.topology !== undefined ? { topology: checkpoint.topology } : existing?.topology !== undefined ? { topology: existing.topology } : {}
|
|
11622
11939
|
};
|
|
11623
11940
|
}
|
|
11624
|
-
function valueOrExisting(
|
|
11625
|
-
const checkpointValue = checkpoint[
|
|
11941
|
+
function valueOrExisting(key, checkpoint, existing) {
|
|
11942
|
+
const checkpointValue = checkpoint[key];
|
|
11626
11943
|
if (checkpointValue !== undefined)
|
|
11627
|
-
return { [
|
|
11628
|
-
const existingValue = existing?.[
|
|
11629
|
-
return existingValue === undefined ? {} : { [
|
|
11944
|
+
return { [key]: checkpointValue };
|
|
11945
|
+
const existingValue = existing?.[key];
|
|
11946
|
+
return existingValue === undefined ? {} : { [key]: existingValue };
|
|
11630
11947
|
}
|
|
11631
11948
|
function workflowChildFromDraft(draft) {
|
|
11632
11949
|
const strict = parseWorkflowChildResult(draft.output);
|
|
@@ -11702,7 +12019,7 @@ function durableNestedRunSnapshots(backend, rootWorkflowId) {
|
|
|
11702
12019
|
const handle = backend.getWorkflow(rootWorkflowId);
|
|
11703
12020
|
if (handle === undefined)
|
|
11704
12021
|
return [];
|
|
11705
|
-
return runSnapshotsFromCheckpoints(backend.listCheckpoints(rootWorkflowId), rootWorkflowId, handle.name, handle.updatedAt, LEGACY_ACTIVE_RECONSTRUCTION).filter((
|
|
12022
|
+
return runSnapshotsFromCheckpoints(backend.listCheckpoints(rootWorkflowId), rootWorkflowId, handle.name, handle.updatedAt, LEGACY_ACTIVE_RECONSTRUCTION).filter((run) => run.id !== rootWorkflowId);
|
|
11706
12023
|
}
|
|
11707
12024
|
function checkpointDrafts(checkpoints) {
|
|
11708
12025
|
const stageByReplayKey = new Map;
|
|
@@ -11711,8 +12028,8 @@ function checkpointDrafts(checkpoints) {
|
|
|
11711
12028
|
checkpoints.forEach((checkpoint, index) => {
|
|
11712
12029
|
const sequence = index + 1;
|
|
11713
12030
|
if (checkpoint.kind === "stage") {
|
|
11714
|
-
const
|
|
11715
|
-
stageByReplayKey.set(checkpoint.replayKey, mergeStageDraft(
|
|
12031
|
+
const existing = stageByReplayKey.get(checkpoint.replayKey);
|
|
12032
|
+
stageByReplayKey.set(checkpoint.replayKey, mergeStageDraft(existing, checkpoint, sequence));
|
|
11716
12033
|
return;
|
|
11717
12034
|
}
|
|
11718
12035
|
if (checkpoint.kind !== "tool" || isReservedRunCheckpointHash(checkpoint.argsHash))
|
|
@@ -11913,29 +12230,29 @@ function runSnapshotsFromCheckpoints(checkpoints, rootRunId, rootRunName, fallba
|
|
|
11913
12230
|
}
|
|
11914
12231
|
const stages = runDrafts.map((draft) => stageSnapshotFromDraft(draft, ids.get(draft.topology.stageId), draft.topology.parentIds.map((parentId) => ids.get(parentId))));
|
|
11915
12232
|
const toolNodes = completedToolNodes(toolCheckpoints, runId, rootRunId, ids, drafts.firstToolSequenceByHash);
|
|
11916
|
-
const
|
|
12233
|
+
const run = runTopologyFor(runDrafts, ownedTools);
|
|
11917
12234
|
const startedAt = Math.min(...stages.map((stage) => stage.startedAt ?? fallbackCompletedAt), ...toolNodes.map((tool) => tool.startedAt ?? tool.endedAt ?? fallbackCompletedAt));
|
|
11918
12235
|
const endedAt = Math.max(...stages.map((stage) => stage.endedAt ?? fallbackCompletedAt), ...toolNodes.map((tool) => tool.endedAt ?? fallbackCompletedAt));
|
|
11919
|
-
const
|
|
11920
|
-
const status =
|
|
12236
|
+
const owner = runId === rootRunId ? undefined : boundaryOwner(grouped, runId);
|
|
12237
|
+
const status = owner === undefined ? "completed" : childRunStatus(owner);
|
|
11921
12238
|
const terminal = status !== "running" && status !== "pending" && status !== "paused" && status !== "blocked";
|
|
11922
|
-
const parentRunId =
|
|
12239
|
+
const parentRunId = run?.parentRunId ?? rootRunId;
|
|
11923
12240
|
const boundarySourceId = grouped.get(parentRunId)?.find((draft) => childRunIdFromDraft(draft) === runId)?.topology?.stageId;
|
|
11924
|
-
const declaredParentStageId =
|
|
12241
|
+
const declaredParentStageId = run?.parentStageId === undefined ? undefined : idMaps.get(parentRunId)?.get(run.parentStageId);
|
|
11925
12242
|
const parentStageId = declaredParentStageId ?? (boundarySourceId === undefined ? undefined : idMaps.get(parentRunId)?.get(boundarySourceId));
|
|
11926
|
-
const ownerChild =
|
|
12243
|
+
const ownerChild = owner === undefined ? undefined : workflowChildFromDraft(owner);
|
|
11927
12244
|
runs.push({
|
|
11928
12245
|
id: runId,
|
|
11929
|
-
name:
|
|
12246
|
+
name: run?.runName ?? rootRunName,
|
|
11930
12247
|
inputs: {},
|
|
11931
12248
|
status,
|
|
11932
12249
|
stages,
|
|
11933
12250
|
toolNodes,
|
|
11934
12251
|
startedAt,
|
|
11935
12252
|
...terminal ? { endedAt, durationMs: Math.max(0, endedAt - startedAt) } : {},
|
|
11936
|
-
...
|
|
12253
|
+
...run?.parentRunId !== undefined ? { parentRunId: run.parentRunId } : {},
|
|
11937
12254
|
...parentStageId !== undefined ? { parentStageId } : {},
|
|
11938
|
-
...
|
|
12255
|
+
...run?.rootRunId !== undefined ? { rootRunId: run.rootRunId } : {},
|
|
11939
12256
|
...ownerChild?.exited === true ? {
|
|
11940
12257
|
result: ownerChild.outputs,
|
|
11941
12258
|
exited: true,
|
|
@@ -11945,13 +12262,13 @@ function runSnapshotsFromCheckpoints(checkpoints, rootRunId, rootRunName, fallba
|
|
|
11945
12262
|
});
|
|
11946
12263
|
emittedRunIds.add(runId);
|
|
11947
12264
|
}
|
|
11948
|
-
for (const { parentRunId, owner
|
|
12265
|
+
for (const { parentRunId, owner, child } of syntheticChildren) {
|
|
11949
12266
|
if (!emittedRunIds.has(parentRunId)) {
|
|
11950
12267
|
if (policy.failClosed)
|
|
11951
12268
|
return [];
|
|
11952
12269
|
continue;
|
|
11953
12270
|
}
|
|
11954
|
-
const topology =
|
|
12271
|
+
const topology = owner.topology;
|
|
11955
12272
|
const boundary = topology.boundary;
|
|
11956
12273
|
const parentStageId = idMaps.get(parentRunId)?.get(topology.stageId);
|
|
11957
12274
|
if (parentStageId === undefined) {
|
|
@@ -11959,8 +12276,8 @@ function runSnapshotsFromCheckpoints(checkpoints, rootRunId, rootRunName, fallba
|
|
|
11959
12276
|
return [];
|
|
11960
12277
|
continue;
|
|
11961
12278
|
}
|
|
11962
|
-
const startedAt =
|
|
11963
|
-
const endedAt =
|
|
12279
|
+
const startedAt = owner.startedAt ?? owner.firstCompletedAt;
|
|
12280
|
+
const endedAt = owner.endedAt ?? owner.firstCompletedAt;
|
|
11964
12281
|
runs.push({
|
|
11965
12282
|
id: child.runId,
|
|
11966
12283
|
name: boundary.child.runName,
|
|
@@ -12012,6 +12329,7 @@ function stageSnapshotFromDraft(draft, id, parentIds) {
|
|
|
12012
12329
|
...draft.sessionId !== undefined ? { sessionId: draft.sessionId } : {},
|
|
12013
12330
|
...draft.sessionFile !== undefined ? { sessionFile: draft.sessionFile } : {},
|
|
12014
12331
|
...draft.model !== undefined ? { model: draft.model } : {},
|
|
12332
|
+
...draft.thinkingLevel !== undefined ? { thinkingLevel: draft.thinkingLevel } : {},
|
|
12015
12333
|
...draft.attemptedModels !== undefined ? { attemptedModels: draft.attemptedModels } : {},
|
|
12016
12334
|
...draft.modelAttempts !== undefined ? { modelAttempts: draft.modelAttempts } : {}
|
|
12017
12335
|
};
|
|
@@ -12068,7 +12386,7 @@ function syntheticCheckpointStage(checkpointCount, completedAt) {
|
|
|
12068
12386
|
// dist/builtin/workflows/src/durable/completed-subtree.ts
|
|
12069
12387
|
function durableCompletedNestedRunSubtree(backend, rootWorkflowId, childRunId) {
|
|
12070
12388
|
const nested = durableNestedRunSnapshots(backend, rootWorkflowId);
|
|
12071
|
-
if (!nested.some((
|
|
12389
|
+
if (!nested.some((run) => run.id === childRunId))
|
|
12072
12390
|
return;
|
|
12073
12391
|
const intentionalExitStatuses = new Map;
|
|
12074
12392
|
for (const checkpoint of backend.listCheckpoints(rootWorkflowId)) {
|
|
@@ -12082,22 +12400,22 @@ function durableCompletedNestedRunSubtree(backend, rootWorkflowId, childRunId) {
|
|
|
12082
12400
|
let priorSize = -1;
|
|
12083
12401
|
while (priorSize !== included.size) {
|
|
12084
12402
|
priorSize = included.size;
|
|
12085
|
-
for (const
|
|
12086
|
-
if (
|
|
12087
|
-
included.add(
|
|
12403
|
+
for (const run of nested) {
|
|
12404
|
+
if (run.parentRunId !== undefined && included.has(run.parentRunId))
|
|
12405
|
+
included.add(run.id);
|
|
12088
12406
|
}
|
|
12089
12407
|
}
|
|
12090
|
-
const subtree = nested.filter((
|
|
12091
|
-
const complete = subtree.length === included.size && subtree.every((
|
|
12408
|
+
const subtree = nested.filter((run) => included.has(run.id));
|
|
12409
|
+
const complete = subtree.length === included.size && subtree.every((run) => isCompleteCachedRun(run, intentionalExitStatuses));
|
|
12092
12410
|
return complete ? subtree : undefined;
|
|
12093
12411
|
}
|
|
12094
|
-
function isCompleteCachedRun(
|
|
12095
|
-
if (
|
|
12412
|
+
function isCompleteCachedRun(run, intentionalExitStatuses) {
|
|
12413
|
+
if (run.endedAt === undefined || !run.stages.every((stage) => isTerminalStage2(stage.status) && stage.endedAt !== undefined)) {
|
|
12096
12414
|
return false;
|
|
12097
12415
|
}
|
|
12098
|
-
if (
|
|
12416
|
+
if (run.status === "completed" || run.exited === true)
|
|
12099
12417
|
return true;
|
|
12100
|
-
return intentionalExitStatuses.get(
|
|
12418
|
+
return intentionalExitStatuses.get(run.id) === run.status;
|
|
12101
12419
|
}
|
|
12102
12420
|
function isTerminalStage2(status) {
|
|
12103
12421
|
return status === "completed" || status === "failed" || status === "skipped";
|
|
@@ -12142,13 +12460,13 @@ function reciprocalWorkflowRootRunId(runById, runId) {
|
|
|
12142
12460
|
}
|
|
12143
12461
|
|
|
12144
12462
|
// dist/builtin/workflows/src/engine/run-durable-topology.ts
|
|
12145
|
-
function durableRunTopology(
|
|
12463
|
+
function durableRunTopology(run) {
|
|
12146
12464
|
return {
|
|
12147
|
-
runId:
|
|
12148
|
-
runName:
|
|
12149
|
-
...
|
|
12150
|
-
...
|
|
12151
|
-
...
|
|
12465
|
+
runId: run.id,
|
|
12466
|
+
runName: run.name,
|
|
12467
|
+
...run.parentRunId !== undefined ? { parentRunId: run.parentRunId } : {},
|
|
12468
|
+
...run.parentStageId !== undefined ? { parentStageId: run.parentStageId } : {},
|
|
12469
|
+
...run.rootRunId !== undefined ? { rootRunId: run.rootRunId } : {}
|
|
12152
12470
|
};
|
|
12153
12471
|
}
|
|
12154
12472
|
function createDurableStageDeps(input) {
|
|
@@ -12223,7 +12541,7 @@ function createDurableCachedStageRecorder(input) {
|
|
|
12223
12541
|
return {
|
|
12224
12542
|
record(name, replayKey, checkpoint, scope) {
|
|
12225
12543
|
const cachedChildRunId = workflowChildRunId(checkpoint);
|
|
12226
|
-
const runById = new Map(input.store.runs().map((
|
|
12544
|
+
const runById = new Map(input.store.runs().map((run) => [run.id, run]));
|
|
12227
12545
|
if (!runById.has(input.run.id))
|
|
12228
12546
|
runById.set(input.run.id, input.run);
|
|
12229
12547
|
const durableRootId = reciprocalWorkflowRootRunId(runById, input.run.id);
|
|
@@ -12239,7 +12557,7 @@ function createDurableCachedStageRecorder(input) {
|
|
|
12239
12557
|
replaySourceOrders.set(replayedStage.id, sourceOrder);
|
|
12240
12558
|
input.run.stages.sort((left, right) => (replaySourceOrders.get(left.id) ?? Number.MAX_SAFE_INTEGER) - (replaySourceOrders.get(right.id) ?? Number.MAX_SAFE_INTEGER));
|
|
12241
12559
|
}
|
|
12242
|
-
const stage = input.store.runs().find((
|
|
12560
|
+
const stage = input.store.runs().find((run) => run.id === input.run.id)?.stages.find((candidate) => candidate.replayKey === replayKey);
|
|
12243
12561
|
if (stage !== undefined) {
|
|
12244
12562
|
input.backend.recordCheckpoint({
|
|
12245
12563
|
kind: "stage",
|
|
@@ -12277,10 +12595,10 @@ function createDurableCachedStageRecorder(input) {
|
|
|
12277
12595
|
};
|
|
12278
12596
|
}
|
|
12279
12597
|
function reconcileCachedDirectChildParentStage(input) {
|
|
12280
|
-
const existingRun = input.store.runs().find((
|
|
12598
|
+
const existingRun = input.store.runs().find((run) => run.id === input.checkpointChildRunId);
|
|
12281
12599
|
if (existingRun === undefined)
|
|
12282
12600
|
return false;
|
|
12283
|
-
const runById = new Map(input.store.runs().map((
|
|
12601
|
+
const runById = new Map(input.store.runs().map((run) => [run.id, run]));
|
|
12284
12602
|
const storedParentRun = runById.get(input.parentRun.id);
|
|
12285
12603
|
if (storedParentRun !== undefined && (storedParentRun.parentRunId !== input.parentRun.parentRunId || storedParentRun.parentStageId !== input.parentRun.parentStageId))
|
|
12286
12604
|
return false;
|
|
@@ -12304,6 +12622,61 @@ function workflowChildRunId(checkpoint) {
|
|
|
12304
12622
|
return (parseWorkflowChildResult(checkpoint.output) ?? (hasCurrentIdentity ? undefined : parseLegacyWorkflowChildResult(checkpoint.output)))?.runId;
|
|
12305
12623
|
}
|
|
12306
12624
|
|
|
12625
|
+
// dist/builtin/workflows/src/engine/run-paused-stage.ts
|
|
12626
|
+
function deferStageUntilRunRelease(input) {
|
|
12627
|
+
let stage;
|
|
12628
|
+
const current = () => {
|
|
12629
|
+
input.signal.throwIfAborted();
|
|
12630
|
+
if (input.isPaused())
|
|
12631
|
+
throw new Error(`Workflow is paused; resume before synchronous access to stage ${input.name}`);
|
|
12632
|
+
stage ??= input.create();
|
|
12633
|
+
return stage;
|
|
12634
|
+
};
|
|
12635
|
+
const invoke = async (call) => {
|
|
12636
|
+
while (input.isPaused())
|
|
12637
|
+
await input.waitForRelease();
|
|
12638
|
+
return call(current());
|
|
12639
|
+
};
|
|
12640
|
+
return {
|
|
12641
|
+
name: input.name,
|
|
12642
|
+
prompt: (...args) => invoke((stage) => stage.prompt(...args)),
|
|
12643
|
+
complete: (...args) => invoke((stage) => stage.complete(...args)),
|
|
12644
|
+
sendUserMessage: (...args) => invoke((stage) => stage.sendUserMessage(...args)),
|
|
12645
|
+
steer: (...args) => invoke((stage) => stage.steer(...args)),
|
|
12646
|
+
followUp: (...args) => invoke((stage) => stage.followUp(...args)),
|
|
12647
|
+
subscribe: (...args) => current().subscribe(...args),
|
|
12648
|
+
get sessionFile() {
|
|
12649
|
+
return current().sessionFile;
|
|
12650
|
+
},
|
|
12651
|
+
get sessionId() {
|
|
12652
|
+
return current().sessionId;
|
|
12653
|
+
},
|
|
12654
|
+
setModel: (...args) => invoke((stage) => stage.setModel(...args)),
|
|
12655
|
+
setThinkingLevel: (...args) => current().setThinkingLevel(...args),
|
|
12656
|
+
cycleModel: () => invoke((stage) => stage.cycleModel()),
|
|
12657
|
+
cycleThinkingLevel: () => current().cycleThinkingLevel(),
|
|
12658
|
+
get agent() {
|
|
12659
|
+
return current().agent;
|
|
12660
|
+
},
|
|
12661
|
+
get model() {
|
|
12662
|
+
return current().model;
|
|
12663
|
+
},
|
|
12664
|
+
get thinkingLevel() {
|
|
12665
|
+
return current().thinkingLevel;
|
|
12666
|
+
},
|
|
12667
|
+
get messages() {
|
|
12668
|
+
return current().messages;
|
|
12669
|
+
},
|
|
12670
|
+
get isStreaming() {
|
|
12671
|
+
return current().isStreaming;
|
|
12672
|
+
},
|
|
12673
|
+
navigateTree: (...args) => invoke((stage) => stage.navigateTree(...args)),
|
|
12674
|
+
compact: () => invoke((stage) => stage.compact()),
|
|
12675
|
+
abortCompaction: () => current().abortCompaction(),
|
|
12676
|
+
abort: () => invoke((stage) => stage.abort())
|
|
12677
|
+
};
|
|
12678
|
+
}
|
|
12679
|
+
|
|
12307
12680
|
// dist/builtin/workflows/src/engine/run-returned-status.ts
|
|
12308
12681
|
function classifyReturnedRunStatus(result, runSnapshot) {
|
|
12309
12682
|
const structuredFailure = runSnapshot !== undefined ? structuredRecoverableWorkflowFailure(runSnapshot) : undefined;
|
|
@@ -12384,9 +12757,9 @@ function createRunTerminalEventArbiter(runId) {
|
|
|
12384
12757
|
|
|
12385
12758
|
// dist/builtin/workflows/src/engine/run-terminal-failure.ts
|
|
12386
12759
|
function finalizeTerminalFailure(input) {
|
|
12387
|
-
const { runId, runSnapshot, store
|
|
12760
|
+
const { runId, runSnapshot, store, persistence, metadata, onRunEnd } = input;
|
|
12388
12761
|
const failedToolNode = metadata.failedToolNodeId === undefined ? undefined : runSnapshot.toolNodes?.find((node) => node.id === metadata.failedToolNodeId);
|
|
12389
|
-
const recorded =
|
|
12762
|
+
const recorded = store.recordRunEnd(runId, "failed", undefined, metadata.errorMessage, metadata);
|
|
12390
12763
|
appendRunEndWhenRecorded(persistence, recorded, {
|
|
12391
12764
|
runId,
|
|
12392
12765
|
status: "failed",
|
|
@@ -12405,7 +12778,7 @@ function finalizeTerminalFailure(input) {
|
|
|
12405
12778
|
...runSnapshot.durationMs !== undefined ? { durationMs: runSnapshot.durationMs } : {},
|
|
12406
12779
|
ts: Date.now()
|
|
12407
12780
|
});
|
|
12408
|
-
return reconcileTerminalRunResult(runId, runSnapshot,
|
|
12781
|
+
return reconcileTerminalRunResult(runId, runSnapshot, store, { status: "failed", error: metadata.errorMessage }, onRunEnd);
|
|
12409
12782
|
}
|
|
12410
12783
|
|
|
12411
12784
|
// dist/builtin/workflows/src/engine/run-tool-admission-boundary.ts
|
|
@@ -12459,6 +12832,7 @@ function createToolAdmissionBoundary() {
|
|
|
12459
12832
|
function createToolControlRegistry() {
|
|
12460
12833
|
const byRun = new Map;
|
|
12461
12834
|
const admissionByRun = new Map;
|
|
12835
|
+
const runControls = new Map;
|
|
12462
12836
|
const makeHandle = (registration) => ({
|
|
12463
12837
|
runId: registration.runId,
|
|
12464
12838
|
nodeId: registration.nodeId,
|
|
@@ -12517,9 +12891,18 @@ function createToolControlRegistry() {
|
|
|
12517
12891
|
admissionBoundary(runId) {
|
|
12518
12892
|
return admissionByRun.get(runId);
|
|
12519
12893
|
},
|
|
12894
|
+
registerRun(runId, handle) {
|
|
12895
|
+
runControls.set(runId, handle);
|
|
12896
|
+
return () => {
|
|
12897
|
+
if (runControls.get(runId) === handle)
|
|
12898
|
+
runControls.delete(runId);
|
|
12899
|
+
};
|
|
12900
|
+
},
|
|
12901
|
+
runControl: (runId) => runControls.get(runId),
|
|
12520
12902
|
clear() {
|
|
12521
12903
|
byRun.clear();
|
|
12522
12904
|
admissionByRun.clear();
|
|
12905
|
+
runControls.clear();
|
|
12523
12906
|
}
|
|
12524
12907
|
};
|
|
12525
12908
|
}
|
|
@@ -12533,7 +12916,7 @@ function createAdmittedToolExecutionTracker(options = {}) {
|
|
|
12533
12916
|
const admissions = [];
|
|
12534
12917
|
const failures = [];
|
|
12535
12918
|
const cancellations = [];
|
|
12536
|
-
let
|
|
12919
|
+
let nextAdmissionOrder = 0;
|
|
12537
12920
|
let state = "OPEN";
|
|
12538
12921
|
let closing;
|
|
12539
12922
|
const abandonment = Promise.withResolvers();
|
|
@@ -12542,17 +12925,17 @@ function createAdmittedToolExecutionTracker(options = {}) {
|
|
|
12542
12925
|
const recordFailure = (admission, error, nodeId) => {
|
|
12543
12926
|
if (admission.failure !== undefined)
|
|
12544
12927
|
return;
|
|
12545
|
-
const
|
|
12546
|
-
admission.failure =
|
|
12547
|
-
failures.push(
|
|
12548
|
-
options.onFailureObserved?.(
|
|
12928
|
+
const failure = { admissionOrder: admission.admissionOrder, error, ...nodeId === undefined ? {} : { nodeId } };
|
|
12929
|
+
admission.failure = failure;
|
|
12930
|
+
failures.push(failure);
|
|
12931
|
+
options.onFailureObserved?.(failure);
|
|
12549
12932
|
};
|
|
12550
12933
|
const reportDrainFailure = () => {
|
|
12551
|
-
const
|
|
12552
|
-
if (state !== "DRAINING" ||
|
|
12934
|
+
const failure = failures[0];
|
|
12935
|
+
if (state !== "DRAINING" || failure === undefined || drainFailureReported)
|
|
12553
12936
|
return;
|
|
12554
12937
|
drainFailureReported = true;
|
|
12555
|
-
options.onFailureDuringDrain?.(
|
|
12938
|
+
options.onFailureDuringDrain?.(failure);
|
|
12556
12939
|
};
|
|
12557
12940
|
const drainRecordedFailures = () => Promise.all(admissions.flatMap((admission) => admission.failure !== undefined && admission.observed !== undefined ? [admission.observed] : []));
|
|
12558
12941
|
const closeAtFixedPoint = async () => {
|
|
@@ -12576,7 +12959,7 @@ function createAdmittedToolExecutionTracker(options = {}) {
|
|
|
12576
12959
|
};
|
|
12577
12960
|
return {
|
|
12578
12961
|
track(execution) {
|
|
12579
|
-
if (state === "CLOSED") {
|
|
12962
|
+
if (state === "CLOSED" || options.signal?.aborted) {
|
|
12580
12963
|
const error = new Error("atomic-workflows: ctx.tool admission is closed for this run");
|
|
12581
12964
|
execution.catch(() => {
|
|
12582
12965
|
return;
|
|
@@ -12584,7 +12967,7 @@ function createAdmittedToolExecutionTracker(options = {}) {
|
|
|
12584
12967
|
return { accepted: false, error, bindNode() {}, noteCancelled() {} };
|
|
12585
12968
|
}
|
|
12586
12969
|
const admission = {
|
|
12587
|
-
admissionOrder: ++
|
|
12970
|
+
admissionOrder: ++nextAdmissionOrder,
|
|
12588
12971
|
nodeId: undefined,
|
|
12589
12972
|
failure: undefined,
|
|
12590
12973
|
cancelled: false,
|
|
@@ -12644,7 +13027,7 @@ function createAdmittedToolExecutionTracker(options = {}) {
|
|
|
12644
13027
|
return failures[0];
|
|
12645
13028
|
},
|
|
12646
13029
|
uniqueFailureFor(error) {
|
|
12647
|
-
const matching = [...failures, ...cancellations].filter((
|
|
13030
|
+
const matching = [...failures, ...cancellations].filter((failure) => Object.is(failure.error, error));
|
|
12648
13031
|
return matching.length === 1 ? matching[0] : undefined;
|
|
12649
13032
|
}
|
|
12650
13033
|
};
|
|
@@ -12652,8 +13035,8 @@ function createAdmittedToolExecutionTracker(options = {}) {
|
|
|
12652
13035
|
|
|
12653
13036
|
// dist/builtin/workflows/src/engine/run-tool-node-lifecycle.ts
|
|
12654
13037
|
function createToolNodeLifecycle(input) {
|
|
12655
|
-
const { store
|
|
12656
|
-
const ownsCurrentRun = () =>
|
|
13038
|
+
const { store, tracker, run, sourceToContinuationNodeIds } = input;
|
|
13039
|
+
const ownsCurrentRun = () => store.runs().some((candidate) => candidate === run);
|
|
12657
13040
|
const replayedToolNodeIds = new Set;
|
|
12658
13041
|
let pendingFrontier = input.resumeToolNode;
|
|
12659
13042
|
return {
|
|
@@ -12671,11 +13054,11 @@ function createToolNodeLifecycle(input) {
|
|
|
12671
13054
|
const sourceParents = frontier?.parentIds ?? (node.replayed === true && node.topologyState !== "unavailable" ? node.parentIds : undefined);
|
|
12672
13055
|
const restored = sourceParents?.map((sourceId) => sourceToContinuationNodeIds.get(sourceId));
|
|
12673
13056
|
const translated = restored?.every((id) => id !== undefined) ? restored : undefined;
|
|
12674
|
-
if (
|
|
12675
|
-
throw new Error(`${REPLAY_TOPOLOGY_MISMATCH_MESSAGE} for tool "${node.name}" (node "${node.id}") in source run ${
|
|
13057
|
+
if (run.resumedFromRunId !== undefined && sourceParents !== undefined && translated === undefined) {
|
|
13058
|
+
throw new Error(`${REPLAY_TOPOLOGY_MISMATCH_MESSAGE} for tool "${node.name}" (node "${node.id}") in source run ${run.resumedFromRunId}`);
|
|
12676
13059
|
}
|
|
12677
|
-
if (translated !== undefined &&
|
|
12678
|
-
throw new Error(`${REPLAY_TOPOLOGY_MISMATCH_MESSAGE} for tool "${node.name}" (node "${node.id}") in source run ${
|
|
13060
|
+
if (translated !== undefined && run.resumedFromRunId !== undefined && !compatibleReplayedToolParents(tracker, translated, inferredParents, (parentId) => isReplayedContinuationNode(store, run, replayedToolNodeIds, parentId))) {
|
|
13061
|
+
throw new Error(`${REPLAY_TOPOLOGY_MISMATCH_MESSAGE} for tool "${node.name}" (node "${node.id}") in source run ${run.resumedFromRunId}`);
|
|
12679
13062
|
}
|
|
12680
13063
|
const parentIds = translated ?? inferredParents;
|
|
12681
13064
|
tracker.replaceParents(node.id, parentIds);
|
|
@@ -12684,28 +13067,28 @@ function createToolNodeLifecycle(input) {
|
|
|
12684
13067
|
if (node.replayed === true)
|
|
12685
13068
|
replayedToolNodeIds.add(node.id);
|
|
12686
13069
|
if (ownsCurrentRun())
|
|
12687
|
-
|
|
13070
|
+
store.recordToolNodeStart(run.id, node);
|
|
12688
13071
|
if (frontier !== undefined)
|
|
12689
13072
|
pendingFrontier = undefined;
|
|
12690
13073
|
},
|
|
12691
13074
|
onNodeRunning: (nodeId, startedAt) => {
|
|
12692
13075
|
if (ownsCurrentRun())
|
|
12693
|
-
|
|
13076
|
+
store.recordToolNodeRunning(run.id, nodeId, startedAt);
|
|
12694
13077
|
},
|
|
12695
13078
|
onNodeEnd: (nodeId, update) => {
|
|
12696
13079
|
if (ownsCurrentRun())
|
|
12697
|
-
|
|
13080
|
+
store.recordToolNodeEnd(run.id, nodeId, update);
|
|
12698
13081
|
},
|
|
12699
13082
|
onNodeSettle: (nodeId) => {
|
|
12700
13083
|
tracker.onSettle(nodeId);
|
|
12701
13084
|
},
|
|
12702
|
-
runTopology: durableRunTopology(
|
|
13085
|
+
runTopology: durableRunTopology(run)
|
|
12703
13086
|
};
|
|
12704
13087
|
}
|
|
12705
|
-
function isReplayedContinuationNode(
|
|
13088
|
+
function isReplayedContinuationNode(store, run, replayedToolNodeIds, nodeId) {
|
|
12706
13089
|
if (replayedToolNodeIds.has(nodeId))
|
|
12707
13090
|
return true;
|
|
12708
|
-
const live =
|
|
13091
|
+
const live = store.runs().find((candidate) => candidate === run);
|
|
12709
13092
|
return live?.stages.some((stage) => stage.id === nodeId && stage.replayed === true) === true;
|
|
12710
13093
|
}
|
|
12711
13094
|
function compatibleReplayedToolParents(tracker, translated, inferredParents, isReplayedNode) {
|
|
@@ -12718,12 +13101,13 @@ function compatibleReplayedToolParents(tracker, translated, inferredParents, isR
|
|
|
12718
13101
|
function createTrackedToolPrimitive(input) {
|
|
12719
13102
|
let observedQuit;
|
|
12720
13103
|
const admittedTools = createAdmittedToolExecutionTracker({
|
|
13104
|
+
signal: input.controller.signal,
|
|
12721
13105
|
onFailureObserved: ({ error, nodeId }) => {
|
|
12722
13106
|
input.terminalEvents.selectFailure(error, nodeId);
|
|
12723
13107
|
},
|
|
12724
|
-
onFailureDuringDrain: (
|
|
13108
|
+
onFailureDuringDrain: (failure) => {
|
|
12725
13109
|
if (input.terminalEvents.winner()?.kind === "failure")
|
|
12726
|
-
input.controller.abort(
|
|
13110
|
+
input.controller.abort(failure.error);
|
|
12727
13111
|
}
|
|
12728
13112
|
});
|
|
12729
13113
|
const lifecycle = createToolNodeLifecycle(input);
|
|
@@ -13046,21 +13430,17 @@ function throwFinalizationError(error) {
|
|
|
13046
13430
|
function createTrackedStageCaller(input) {
|
|
13047
13431
|
const { runtime } = input;
|
|
13048
13432
|
const readinessGateEnabled = runtime.opts.confirmStageReadiness !== undefined || runtime.opts.usePromptNodesForUi === true;
|
|
13049
|
-
const confirmReadiness = async () => {
|
|
13050
|
-
|
|
13051
|
-
|
|
13052
|
-
|
|
13053
|
-
|
|
13054
|
-
|
|
13055
|
-
|
|
13056
|
-
|
|
13057
|
-
|
|
13058
|
-
|
|
13059
|
-
|
|
13060
|
-
return await askReadinessViaStageBroker(runtime.runId, runtime.stageId, runtime.signal);
|
|
13061
|
-
} catch {
|
|
13062
|
-
return { action: "advance" };
|
|
13063
|
-
}
|
|
13433
|
+
const confirmReadiness = async (signal) => {
|
|
13434
|
+
if (runtime.opts.confirmStageReadiness !== undefined) {
|
|
13435
|
+
const ready = await raceAbort(runtime.opts.confirmStageReadiness({
|
|
13436
|
+
runId: runtime.runId,
|
|
13437
|
+
stageId: runtime.stageId,
|
|
13438
|
+
stageName: runtime.name,
|
|
13439
|
+
signal
|
|
13440
|
+
}), signal);
|
|
13441
|
+
return ready ? { action: "advance" } : { action: "stay" };
|
|
13442
|
+
}
|
|
13443
|
+
return await askReadinessViaStageBroker(runtime.runId, runtime.stageId, signal);
|
|
13064
13444
|
};
|
|
13065
13445
|
const suppressReadinessForCurrentTurn = () => {
|
|
13066
13446
|
runtime.state.askUserQuestionObservedThisTurn = false;
|
|
@@ -13102,7 +13482,7 @@ function createTrackedStageCaller(input) {
|
|
|
13102
13482
|
if (suppressQueuedContinuation)
|
|
13103
13483
|
runtime.state.suppressQueuedUserMessageContinuation = true;
|
|
13104
13484
|
try {
|
|
13105
|
-
result = await runtime.raceStageSessionHeartbeat(raceAbort(runtime.innerCtx.
|
|
13485
|
+
result = await runtime.raceStageSessionHeartbeat(raceAbort(runtime.innerCtx.__continuePrompt(RESUME_CONTINUATION_PROMPT), runtime.signal));
|
|
13106
13486
|
} finally {
|
|
13107
13487
|
if (suppressQueuedContinuation)
|
|
13108
13488
|
runtime.state.suppressQueuedUserMessageContinuation = false;
|
|
@@ -13207,30 +13587,56 @@ function createTrackedStageCaller(input) {
|
|
|
13207
13587
|
let resolveNextTurnEnd = null;
|
|
13208
13588
|
const unsubscribeTurnWatcher = runtime.innerCtx.subscribe((event) => {
|
|
13209
13589
|
if (event.type === "agent_end" && resolveNextTurnEnd) {
|
|
13210
|
-
const
|
|
13590
|
+
const resolve = resolveNextTurnEnd;
|
|
13211
13591
|
resolveNextTurnEnd = null;
|
|
13212
|
-
|
|
13592
|
+
resolve();
|
|
13213
13593
|
}
|
|
13214
13594
|
});
|
|
13215
13595
|
try {
|
|
13216
13596
|
while (runtime.state.askUserQuestionObservedThisTurn || repeatReadinessAfterChatTurn) {
|
|
13217
|
-
|
|
13597
|
+
runtime.signal.throwIfAborted();
|
|
13598
|
+
if (runtime.stageSnapshot.status === "paused" || runtime.stageSnapshot.status === "blocked") {
|
|
13599
|
+
await runtime.scheduler.waitForStageRelease(runtime.stageId, runtime.releaseLiveHandle);
|
|
13600
|
+
continue;
|
|
13601
|
+
}
|
|
13602
|
+
const controller = new AbortController;
|
|
13603
|
+
runtime.state.readinessController = controller;
|
|
13604
|
+
let decision;
|
|
13605
|
+
try {
|
|
13606
|
+
decision = await confirmReadiness(AbortSignal.any([runtime.signal, controller.signal]));
|
|
13607
|
+
if (decision.action === "advance" || decision.message !== undefined) {
|
|
13608
|
+
await runtime.scheduler.waitForStageRelease(runtime.stageId, runtime.releaseLiveHandle);
|
|
13609
|
+
}
|
|
13610
|
+
runtime.signal.throwIfAborted();
|
|
13611
|
+
if (controller.signal.aborted) {
|
|
13612
|
+
await runtime.scheduler.waitForStageRelease(runtime.stageId, runtime.releaseLiveHandle);
|
|
13613
|
+
continue;
|
|
13614
|
+
}
|
|
13615
|
+
} catch (error) {
|
|
13616
|
+
runtime.signal.throwIfAborted();
|
|
13617
|
+
if (controller.signal.aborted) {
|
|
13618
|
+
await runtime.scheduler.waitForStageRelease(runtime.stageId, runtime.releaseLiveHandle);
|
|
13619
|
+
continue;
|
|
13620
|
+
}
|
|
13621
|
+
throw error;
|
|
13622
|
+
}
|
|
13218
13623
|
if (decision.action === "advance")
|
|
13219
13624
|
break;
|
|
13625
|
+
delete runtime.state.readinessController;
|
|
13220
13626
|
if (runtime.signal.aborted)
|
|
13221
13627
|
break;
|
|
13222
13628
|
runtime.state.askUserQuestionObservedThisTurn = false;
|
|
13223
13629
|
runtime.state.chatAnswerObservedThisTurn = false;
|
|
13224
13630
|
if (decision.message !== undefined) {
|
|
13225
|
-
result = await runtime.raceStageSessionHeartbeat(raceAbort(runtime.innerCtx.
|
|
13631
|
+
result = await runtime.raceStageSessionHeartbeat(raceAbort(runtime.innerCtx.__continuePrompt(decision.message), runtime.signal));
|
|
13226
13632
|
if (runtime.budget.enabled && typeof result === "string")
|
|
13227
13633
|
stageResultBeforeBudget = result;
|
|
13228
13634
|
} else {
|
|
13229
13635
|
runtime.state.waitingForStageChatTurn = true;
|
|
13230
13636
|
try {
|
|
13231
|
-
await runtime.raceStageSessionHeartbeat(raceAbort(new Promise((
|
|
13232
|
-
resolveNextTurnEnd =
|
|
13233
|
-
runtime.state.wakeWaitingForStageChatTurn =
|
|
13637
|
+
await runtime.raceStageSessionHeartbeat(raceAbort(new Promise((resolve) => {
|
|
13638
|
+
resolveNextTurnEnd = resolve;
|
|
13639
|
+
runtime.state.wakeWaitingForStageChatTurn = resolve;
|
|
13234
13640
|
}), runtime.signal));
|
|
13235
13641
|
} finally {
|
|
13236
13642
|
runtime.state.wakeWaitingForStageChatTurn = undefined;
|
|
@@ -13270,7 +13676,9 @@ function createTrackedStageCaller(input) {
|
|
|
13270
13676
|
await runtime.budget.deliverWrapUp(runtime.name);
|
|
13271
13677
|
if (afterBudget.kind === "exhausted" && runtime.budget.enabled)
|
|
13272
13678
|
await runtime.budget.stopAtBoundaryAsync(runtime.name);
|
|
13273
|
-
await runtime.innerCtx.__closeGeneration();
|
|
13679
|
+
const finalizedArtifact = await runtime.innerCtx.__closeGeneration();
|
|
13680
|
+
if (typeof result === "string" && finalizedArtifact !== undefined)
|
|
13681
|
+
result = finalizedArtifact;
|
|
13274
13682
|
await runtime.captureStageSessionMeta({ awaitDurable: true });
|
|
13275
13683
|
if (trackStageLifecycle && runtime.stageFailFastScope?.failed === true && runtime.stageFailFastScope.activeStages.has(runtime.stageId)) {
|
|
13276
13684
|
runtime.markSkippedForParallelFailFast();
|
|
@@ -13299,7 +13707,7 @@ function createTrackedStageCaller(input) {
|
|
|
13299
13707
|
const budgetError = err instanceof WorkflowBudgetExceededError ? err : undefined;
|
|
13300
13708
|
if (budgetError !== undefined && trackStageLifecycle && !runtime.state.skippedForParallelFailFast) {
|
|
13301
13709
|
let selectedBudgetError = budgetError;
|
|
13302
|
-
if (runtime.activeStore.runs().find((
|
|
13710
|
+
if (runtime.activeStore.runs().find((run) => run.id === runtime.runId)?.budgetState?.wrapUpCompleted !== true) {
|
|
13303
13711
|
try {
|
|
13304
13712
|
await runtime.budget.deliverWrapUp(runtime.name);
|
|
13305
13713
|
} catch (wrapUpError) {
|
|
@@ -13327,8 +13735,8 @@ function createTrackedStageCaller(input) {
|
|
|
13327
13735
|
};
|
|
13328
13736
|
}
|
|
13329
13737
|
} else if (trackStageLifecycle && !runtime.signal.aborted && !runtime.state.skippedForParallelFailFast) {
|
|
13330
|
-
const
|
|
13331
|
-
applyTerminalStageState = () => applyFailureToStage(runtime.stageSnapshot,
|
|
13738
|
+
const failure = runtime.classifyExecutorFailure(err);
|
|
13739
|
+
applyTerminalStageState = () => applyFailureToStage(runtime.stageSnapshot, failure);
|
|
13332
13740
|
}
|
|
13333
13741
|
throw err;
|
|
13334
13742
|
} finally {
|
|
@@ -13354,12 +13762,20 @@ function createTrackedStageCaller(input) {
|
|
|
13354
13762
|
finalizationError ??= durableCheckpointError;
|
|
13355
13763
|
if (trackStageLifecycle) {
|
|
13356
13764
|
if (durableCheckpointError !== undefined && terminalStateIsSuccess) {
|
|
13357
|
-
const
|
|
13358
|
-
applyTerminalStageState = () => applyFailureToStage(runtime.stageSnapshot,
|
|
13765
|
+
const failure = runtime.classifyExecutorFailure(durableCheckpointError.error);
|
|
13766
|
+
applyTerminalStageState = () => applyFailureToStage(runtime.stageSnapshot, failure);
|
|
13359
13767
|
}
|
|
13360
|
-
if (!runtime.state.stageFinalized)
|
|
13361
|
-
applyTerminalStageState?.();
|
|
13362
13768
|
try {
|
|
13769
|
+
if (terminalStateIsSuccess && runtime.state.readinessController !== undefined) {
|
|
13770
|
+
let pauseVersion;
|
|
13771
|
+
do {
|
|
13772
|
+
pauseVersion = runtime.state.readinessPauseVersion;
|
|
13773
|
+
await runtime.scheduler.waitForStageRelease(runtime.stageId, runtime.releaseLiveHandle);
|
|
13774
|
+
} while (pauseVersion !== runtime.state.readinessPauseVersion);
|
|
13775
|
+
runtime.signal.throwIfAborted();
|
|
13776
|
+
}
|
|
13777
|
+
if (!runtime.state.stageFinalized)
|
|
13778
|
+
applyTerminalStageState?.();
|
|
13363
13779
|
await runtime.finalizeStageSnapshot();
|
|
13364
13780
|
} catch (err) {
|
|
13365
13781
|
finalizationError ??= { thrown: true, error: err };
|
|
@@ -13377,6 +13793,9 @@ function createTrackedStageCaller(input) {
|
|
|
13377
13793
|
input.limiter.release();
|
|
13378
13794
|
if (finalizationError !== undefined)
|
|
13379
13795
|
throwFinalizationError(finalizationError.error);
|
|
13796
|
+
delete runtime.state.readinessController;
|
|
13797
|
+
if (terminalStateIsSuccess && readinessGateEnabled)
|
|
13798
|
+
runtime.signal.throwIfAborted();
|
|
13380
13799
|
}
|
|
13381
13800
|
};
|
|
13382
13801
|
}
|
|
@@ -13613,8 +14032,8 @@ class StageToolExecutionBuffer {
|
|
|
13613
14032
|
// dist/builtin/workflows/src/runs/foreground/executor-stage-control.ts
|
|
13614
14033
|
function createStageControlHandle(runtime) {
|
|
13615
14034
|
const messagePreparation = () => {
|
|
13616
|
-
const
|
|
13617
|
-
if (
|
|
14035
|
+
const meta = runtime.innerCtx.__sessionMeta();
|
|
14036
|
+
if (meta.sessionId !== undefined || meta.sessionFile !== undefined) {
|
|
13618
14037
|
return { beforePreparation: runtime.throwIfStageMutationBlocked };
|
|
13619
14038
|
}
|
|
13620
14039
|
if (runtime.stageSnapshot.sessionFile !== undefined) {
|
|
@@ -13737,15 +14156,29 @@ function createStageControlHandle(runtime) {
|
|
|
13737
14156
|
async pause() {
|
|
13738
14157
|
runtime.throwIfStageMutationBlocked();
|
|
13739
14158
|
const statusBeforePause = runtime.stageSnapshot.status;
|
|
14159
|
+
let readinessPauseVersion;
|
|
14160
|
+
if (runtime.state.readinessController !== undefined) {
|
|
14161
|
+
runtime.scheduler.ensureReleaseBarrier(runtime.stageId);
|
|
14162
|
+
readinessPauseVersion = (runtime.state.readinessPauseVersion ?? 0) + 1;
|
|
14163
|
+
runtime.state.readinessPauseVersion = readinessPauseVersion;
|
|
14164
|
+
}
|
|
13740
14165
|
if (statusBeforePause === "pending" || statusBeforePause === "running" || runtime.innerCtx.isStreaming) {
|
|
13741
|
-
|
|
14166
|
+
try {
|
|
14167
|
+
await runtime.innerCtx.__requestPause();
|
|
14168
|
+
} catch (error) {
|
|
14169
|
+
if (readinessPauseVersion !== undefined && runtime.state.readinessPauseVersion === readinessPauseVersion && runtime.stageSnapshot.status !== "paused" && runtime.stageSnapshot.status !== "blocked" && !runtime.scheduler.hasCascadePauseOwners(runtime.stageId)) {
|
|
14170
|
+
runtime.scheduler.releaseStageBarrier(runtime.stageId);
|
|
14171
|
+
}
|
|
14172
|
+
throw error;
|
|
14173
|
+
}
|
|
13742
14174
|
}
|
|
13743
14175
|
const changed = runtime.activeStore.recordStagePaused(runtime.runId, runtime.stageId);
|
|
13744
14176
|
if (changed) {
|
|
13745
14177
|
runtime.scheduler.ensureReleaseBarrier(runtime.stageId);
|
|
14178
|
+
runtime.state.readinessController?.abort(new Error("atomic-workflows: readiness paused"));
|
|
13746
14179
|
await runtime.scheduler.cascadePauseFrom(runtime.stageId);
|
|
13747
|
-
const
|
|
13748
|
-
const stillActive =
|
|
14180
|
+
const run = runtime.activeStore.runs().find((candidate) => candidate.id === runtime.runId);
|
|
14181
|
+
const stillActive = run?.stages.some((stage) => stage.status === "running" && stage.id !== runtime.stageId) ?? false;
|
|
13749
14182
|
if (!stillActive)
|
|
13750
14183
|
runtime.activeStore.recordRunPaused(runtime.runId);
|
|
13751
14184
|
}
|
|
@@ -13812,6 +14245,7 @@ function createStageControlHandle(runtime) {
|
|
|
13812
14245
|
// dist/builtin/workflows/src/runs/foreground/executor-stage-replay.ts
|
|
13813
14246
|
function createReplayStageContext(input) {
|
|
13814
14247
|
const { runId, name, stageId, stageSnapshot, replaySource } = input;
|
|
14248
|
+
workflowObservationRuntime(input.activeStore).replayStageIds.add(workflowActivityNodeKey(runId, stageId));
|
|
13815
14249
|
let replayFinalized = false;
|
|
13816
14250
|
let unregisterWorkflowExitCleanup = () => {};
|
|
13817
14251
|
let stageStartEntryAppended = false;
|
|
@@ -13881,6 +14315,7 @@ function createReplayStageContext(input) {
|
|
|
13881
14315
|
return {
|
|
13882
14316
|
name,
|
|
13883
14317
|
prompt: replayText,
|
|
14318
|
+
__continuePrompt: replayText,
|
|
13884
14319
|
complete: replayText,
|
|
13885
14320
|
sendUserMessage: async () => rejectReplayMutation("send a user message"),
|
|
13886
14321
|
__sendUserMessage: async () => rejectReplayMutation("send a user message"),
|
|
@@ -13905,7 +14340,7 @@ function createReplayStageContext(input) {
|
|
|
13905
14340
|
return replaySource.model;
|
|
13906
14341
|
},
|
|
13907
14342
|
get thinkingLevel() {
|
|
13908
|
-
return;
|
|
14343
|
+
return replaySource.thinkingLevel;
|
|
13909
14344
|
},
|
|
13910
14345
|
get messages() {
|
|
13911
14346
|
return [];
|
|
@@ -13931,6 +14366,7 @@ function createReplayStageContext(input) {
|
|
|
13931
14366
|
__pendingMessageCount: () => 0,
|
|
13932
14367
|
__modelFallbackMeta: () => ({
|
|
13933
14368
|
...replaySource.model !== undefined ? { model: replaySource.model } : {},
|
|
14369
|
+
...replaySource.thinkingLevel !== undefined ? { thinkingLevel: replaySource.thinkingLevel } : {},
|
|
13934
14370
|
...replaySource.attemptedModels !== undefined ? { attemptedModels: replaySource.attemptedModels } : {},
|
|
13935
14371
|
...replaySource.modelAttempts !== undefined ? { modelAttempts: replaySource.modelAttempts } : {}
|
|
13936
14372
|
}),
|
|
@@ -13943,13 +14379,13 @@ function createReplayStageContext(input) {
|
|
|
13943
14379
|
|
|
13944
14380
|
// dist/builtin/workflows/src/durable/run-owner-backend.ts
|
|
13945
14381
|
function durableRootRunIdForRun(runs, runId) {
|
|
13946
|
-
return reciprocalWorkflowRootRunId(new Map(runs.map((
|
|
14382
|
+
return reciprocalWorkflowRootRunId(new Map(runs.map((run) => [run.id, run])), runId);
|
|
13947
14383
|
}
|
|
13948
14384
|
function durableBackendForRun(backend, runs, runId) {
|
|
13949
14385
|
const rootRunId = durableRootRunIdForRun(runs, runId);
|
|
13950
14386
|
if (rootRunId === undefined)
|
|
13951
14387
|
return;
|
|
13952
|
-
const runById = new Map(runs.map((
|
|
14388
|
+
const runById = new Map(runs.map((run) => [run.id, run]));
|
|
13953
14389
|
if (rootRunId === runId)
|
|
13954
14390
|
return backend;
|
|
13955
14391
|
const scopes = [];
|
|
@@ -13972,17 +14408,17 @@ function durableBackendForRun(backend, runs, runId) {
|
|
|
13972
14408
|
}
|
|
13973
14409
|
|
|
13974
14410
|
// dist/builtin/workflows/src/shared/pending-stage-route-capability.ts
|
|
13975
|
-
import { randomUUID as
|
|
14411
|
+
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
13976
14412
|
var routeCapabilities = new WeakMap;
|
|
13977
|
-
function workflowPendingStageRouteCapability(
|
|
13978
|
-
let capabilities = routeCapabilities.get(
|
|
14413
|
+
function workflowPendingStageRouteCapability(store, runId) {
|
|
14414
|
+
let capabilities = routeCapabilities.get(store);
|
|
13979
14415
|
if (capabilities === undefined) {
|
|
13980
14416
|
capabilities = new Map;
|
|
13981
|
-
routeCapabilities.set(
|
|
14417
|
+
routeCapabilities.set(store, capabilities);
|
|
13982
14418
|
}
|
|
13983
14419
|
let capability = capabilities.get(runId);
|
|
13984
14420
|
if (capability === undefined) {
|
|
13985
|
-
capability =
|
|
14421
|
+
capability = randomUUID5();
|
|
13986
14422
|
capabilities.set(runId, capability);
|
|
13987
14423
|
}
|
|
13988
14424
|
return capability;
|
|
@@ -14066,7 +14502,7 @@ function parseWorkflowStageTarget(target) {
|
|
|
14066
14502
|
|
|
14067
14503
|
// dist/builtin/workflows/src/shared/pending-stage-status.ts
|
|
14068
14504
|
function workflowBoundaryHops(runs, runId) {
|
|
14069
|
-
const runById = new Map(runs.map((
|
|
14505
|
+
const runById = new Map(runs.map((run) => [run.id, run]));
|
|
14070
14506
|
const hops = [];
|
|
14071
14507
|
let current = runById.get(runId);
|
|
14072
14508
|
while (current !== undefined && current.parentRunId !== undefined) {
|
|
@@ -14125,8 +14561,8 @@ function createWorkflowPendingStageDelivery(activeStore, runId, stageId, stageNa
|
|
|
14125
14561
|
let drainPromise;
|
|
14126
14562
|
const pendingReady = () => {
|
|
14127
14563
|
if (readyPromise === undefined) {
|
|
14128
|
-
readyPromise = new Promise((
|
|
14129
|
-
resolveReady =
|
|
14564
|
+
readyPromise = new Promise((resolve, reject) => {
|
|
14565
|
+
resolveReady = resolve;
|
|
14130
14566
|
rejectReady = reject;
|
|
14131
14567
|
});
|
|
14132
14568
|
}
|
|
@@ -14182,7 +14618,7 @@ async function deliverPendingStageMessages(activeStore, runId, stageId, stageNam
|
|
|
14182
14618
|
].map((entry) => entry.id));
|
|
14183
14619
|
const runs = activeStore.runs();
|
|
14184
14620
|
const entries = [
|
|
14185
|
-
...(runs.find((
|
|
14621
|
+
...(runs.find((run) => run.id === runId)?.pendingStageMessages ?? []).map((entry, index) => ({ entry, index })).filter(({ entry }) => candidateIds.has(entry.id) && entry.sticky !== true),
|
|
14186
14622
|
...stickyEntries.map((entry) => ({ entry, index: Number.MAX_SAFE_INTEGER }))
|
|
14187
14623
|
].sort((left, right) => (left.entry.admissionOrder ?? left.index + 1) - (right.entry.admissionOrder ?? right.index + 1) || left.index - right.index).map(({ entry }) => entry);
|
|
14188
14624
|
const rootBackend = getDurableBackend();
|
|
@@ -14226,7 +14662,7 @@ function stickyPendingStageEntriesForStage(activeStore, runId, stageId, stageNam
|
|
|
14226
14662
|
const rootRunId = durableRootRunIdForRun(runs, runId);
|
|
14227
14663
|
if (rootRunId === undefined)
|
|
14228
14664
|
return [];
|
|
14229
|
-
const rootRun = runs.find((
|
|
14665
|
+
const rootRun = runs.find((run) => run.id === rootRunId);
|
|
14230
14666
|
if (rootRun === undefined)
|
|
14231
14667
|
return [];
|
|
14232
14668
|
const hops = workflowBoundaryHops(runs, runId);
|
|
@@ -14244,20 +14680,20 @@ function stickyPendingStageEntriesForStage(activeStore, runId, stageId, stageNam
|
|
|
14244
14680
|
return stageMatchesPathPattern(parsed.segments, hops, [stageId, stageName]);
|
|
14245
14681
|
});
|
|
14246
14682
|
}
|
|
14247
|
-
function claimPendingDelivery(
|
|
14248
|
-
let claims = pendingDeliveryClaims.get(
|
|
14683
|
+
function claimPendingDelivery(store, runId, stageKey, messageId) {
|
|
14684
|
+
let claims = pendingDeliveryClaims.get(store);
|
|
14249
14685
|
if (claims === undefined) {
|
|
14250
14686
|
claims = new Set;
|
|
14251
|
-
pendingDeliveryClaims.set(
|
|
14687
|
+
pendingDeliveryClaims.set(store, claims);
|
|
14252
14688
|
}
|
|
14253
|
-
const
|
|
14254
|
-
if (claims.has(
|
|
14689
|
+
const key = JSON.stringify([runId, stageKey, messageId]);
|
|
14690
|
+
if (claims.has(key))
|
|
14255
14691
|
return;
|
|
14256
|
-
claims.add(
|
|
14692
|
+
claims.add(key);
|
|
14257
14693
|
return () => {
|
|
14258
|
-
claims?.delete(
|
|
14694
|
+
claims?.delete(key);
|
|
14259
14695
|
if (claims?.size === 0)
|
|
14260
|
-
pendingDeliveryClaims.delete(
|
|
14696
|
+
pendingDeliveryClaims.delete(store);
|
|
14261
14697
|
};
|
|
14262
14698
|
}
|
|
14263
14699
|
function toPendingStageSender(entry) {
|
|
@@ -14321,8 +14757,8 @@ class WorkflowModelValidationError extends Error {
|
|
|
14321
14757
|
}
|
|
14322
14758
|
function formatModelValidationError(failures) {
|
|
14323
14759
|
const lines = ["workflows: model validation failed before starting workflow.", "Unavailable or ambiguous models:"];
|
|
14324
|
-
for (const
|
|
14325
|
-
lines.push(`- ${
|
|
14760
|
+
for (const failure of failures) {
|
|
14761
|
+
lines.push(`- ${failure.input} (${failure.reason})`);
|
|
14326
14762
|
}
|
|
14327
14763
|
return lines.join(`
|
|
14328
14764
|
`);
|
|
@@ -14430,10 +14866,10 @@ function buildModelCandidates(input) {
|
|
|
14430
14866
|
failures.push(resolved);
|
|
14431
14867
|
continue;
|
|
14432
14868
|
}
|
|
14433
|
-
const
|
|
14434
|
-
if (seen.has(
|
|
14869
|
+
const key = candidateKey(resolved);
|
|
14870
|
+
if (seen.has(key))
|
|
14435
14871
|
continue;
|
|
14436
|
-
seen.add(
|
|
14872
|
+
seen.add(key);
|
|
14437
14873
|
candidates.push(resolved);
|
|
14438
14874
|
}
|
|
14439
14875
|
if (failures.length > 0)
|
|
@@ -14526,6 +14962,89 @@ class StageDeliveryActivity {
|
|
|
14526
14962
|
}
|
|
14527
14963
|
}
|
|
14528
14964
|
|
|
14965
|
+
// dist/builtin/workflows/src/runs/foreground/stage-runner-artifact-capture.ts
|
|
14966
|
+
class StageArtifactCapture {
|
|
14967
|
+
session;
|
|
14968
|
+
seen = new WeakSet;
|
|
14969
|
+
accepted = [];
|
|
14970
|
+
provisional;
|
|
14971
|
+
receivesMessageEvents = false;
|
|
14972
|
+
closed = false;
|
|
14973
|
+
reset() {
|
|
14974
|
+
this.session = undefined;
|
|
14975
|
+
this.seen = new WeakSet;
|
|
14976
|
+
this.accepted = [];
|
|
14977
|
+
this.provisional = undefined;
|
|
14978
|
+
this.receivesMessageEvents = false;
|
|
14979
|
+
this.closed = false;
|
|
14980
|
+
}
|
|
14981
|
+
beginAttempt(session) {
|
|
14982
|
+
if (this.closed)
|
|
14983
|
+
return;
|
|
14984
|
+
if (this.session === session)
|
|
14985
|
+
this.scan();
|
|
14986
|
+
else {
|
|
14987
|
+
this.session = session;
|
|
14988
|
+
this.receivesMessageEvents = false;
|
|
14989
|
+
this.rememberContext();
|
|
14990
|
+
}
|
|
14991
|
+
this.provisional = [];
|
|
14992
|
+
}
|
|
14993
|
+
settleAttempt(success) {
|
|
14994
|
+
if (this.closed)
|
|
14995
|
+
return;
|
|
14996
|
+
this.scan();
|
|
14997
|
+
if (success)
|
|
14998
|
+
this.accepted.push(...this.provisional ?? []);
|
|
14999
|
+
this.provisional = undefined;
|
|
15000
|
+
}
|
|
15001
|
+
close() {
|
|
15002
|
+
this.scan();
|
|
15003
|
+
this.closed = true;
|
|
15004
|
+
this.session = undefined;
|
|
15005
|
+
this.seen = new WeakSet;
|
|
15006
|
+
this.provisional = undefined;
|
|
15007
|
+
}
|
|
15008
|
+
onEvent(session, event) {
|
|
15009
|
+
if (session !== this.session)
|
|
15010
|
+
return;
|
|
15011
|
+
if (event.type === "message_end") {
|
|
15012
|
+
this.receivesMessageEvents = true;
|
|
15013
|
+
this.capture(event.message);
|
|
15014
|
+
}
|
|
15015
|
+
if (event.type === "compaction_end")
|
|
15016
|
+
this.rememberContext();
|
|
15017
|
+
}
|
|
15018
|
+
messages() {
|
|
15019
|
+
this.scan();
|
|
15020
|
+
return this.accepted;
|
|
15021
|
+
}
|
|
15022
|
+
rememberContext(session = this.session) {
|
|
15023
|
+
if (session !== this.session)
|
|
15024
|
+
return;
|
|
15025
|
+
for (const message of this.session?.messages ?? [])
|
|
15026
|
+
this.seen.add(message);
|
|
15027
|
+
}
|
|
15028
|
+
scan() {
|
|
15029
|
+
if (this.receivesMessageEvents)
|
|
15030
|
+
return;
|
|
15031
|
+
for (const message of this.session?.messages ?? [])
|
|
15032
|
+
this.capture(message);
|
|
15033
|
+
}
|
|
15034
|
+
capture(message) {
|
|
15035
|
+
if (this.seen.has(message))
|
|
15036
|
+
return;
|
|
15037
|
+
this.seen.add(message);
|
|
15038
|
+
if (message.role !== "assistant")
|
|
15039
|
+
return;
|
|
15040
|
+
if (message.stopReason !== "stop" && message.stopReason !== "length")
|
|
15041
|
+
return;
|
|
15042
|
+
if (message.content.some((block) => block.type === "toolCall"))
|
|
15043
|
+
return;
|
|
15044
|
+
(this.provisional ?? this.accepted).push(structuredClone(message));
|
|
15045
|
+
}
|
|
15046
|
+
}
|
|
15047
|
+
|
|
14529
15048
|
// dist/builtin/workflows/src/runs/foreground/stage-runner-candidate.ts
|
|
14530
15049
|
function effectiveCandidateReasoning(candidate, fallback) {
|
|
14531
15050
|
return candidate.reasoningLevel ?? fallback;
|
|
@@ -14731,6 +15250,23 @@ function extractMessageText(message) {
|
|
|
14731
15250
|
}
|
|
14732
15251
|
return "";
|
|
14733
15252
|
}
|
|
15253
|
+
function assistantArtifactTextForGeneration(messages) {
|
|
15254
|
+
const answers = messages.flatMap((message) => {
|
|
15255
|
+
if (message.role !== "assistant")
|
|
15256
|
+
return [];
|
|
15257
|
+
if (message.stopReason !== "stop" && message.stopReason !== "length")
|
|
15258
|
+
return [];
|
|
15259
|
+
if (message.content.some((block) => block.type === "toolCall"))
|
|
15260
|
+
return [];
|
|
15261
|
+
const text = extractMessageText(message);
|
|
15262
|
+
return text.length > 0 ? [text] : [];
|
|
15263
|
+
});
|
|
15264
|
+
return answers.map((text, index) => index === 0 ? text : `
|
|
15265
|
+
|
|
15266
|
+
## Supplement ${index}
|
|
15267
|
+
|
|
15268
|
+
${text}`).join("");
|
|
15269
|
+
}
|
|
14734
15270
|
function lastAssistantTextFromMessages(messages) {
|
|
14735
15271
|
for (let index = messages.length - 1;index >= 0; index -= 1) {
|
|
14736
15272
|
const message = messages[index];
|
|
@@ -14751,7 +15287,7 @@ function structuredOutputTurnDetail(messages, startIndex) {
|
|
|
14751
15287
|
}
|
|
14752
15288
|
return "The model produced no assistant message after the prompt";
|
|
14753
15289
|
}
|
|
14754
|
-
function assistantArtifactTextForToolCall(messages,
|
|
15290
|
+
function assistantArtifactTextForToolCall(messages, toolCallId) {
|
|
14755
15291
|
for (let index = messages.length - 1;index >= 0; index -= 1) {
|
|
14756
15292
|
const message = messages[index];
|
|
14757
15293
|
if (message?.role !== "assistant")
|
|
@@ -14759,7 +15295,7 @@ function assistantArtifactTextForToolCall(messages, toolCallId2) {
|
|
|
14759
15295
|
const { content } = message;
|
|
14760
15296
|
if (!Array.isArray(content))
|
|
14761
15297
|
continue;
|
|
14762
|
-
if (!content.some((block) => block.type === "toolCall" && block.id ===
|
|
15298
|
+
if (!content.some((block) => block.type === "toolCall" && block.id === toolCallId))
|
|
14763
15299
|
continue;
|
|
14764
15300
|
const text = extractMessageText(message);
|
|
14765
15301
|
if (text.trim().length > 0)
|
|
@@ -14834,8 +15370,8 @@ function terminatingToolResultText(messages, terminatingToolCallIds) {
|
|
|
14834
15370
|
if (!message)
|
|
14835
15371
|
continue;
|
|
14836
15372
|
if (message.role === "toolResult") {
|
|
14837
|
-
const
|
|
14838
|
-
if (typeof
|
|
15373
|
+
const toolCallId = message.toolCallId;
|
|
15374
|
+
if (typeof toolCallId !== "string" || !terminatingToolCallIds.has(toolCallId)) {
|
|
14839
15375
|
return;
|
|
14840
15376
|
}
|
|
14841
15377
|
const text = extractMessageText(message).trim();
|
|
@@ -14868,27 +15404,27 @@ function assistantMessage(text) {
|
|
|
14868
15404
|
|
|
14869
15405
|
// dist/builtin/workflows/src/runs/foreground/stage-runner-options.ts
|
|
14870
15406
|
import { SessionManager } from "@bastani/atomic";
|
|
14871
|
-
function workflowSessionOptions(
|
|
15407
|
+
function workflowSessionOptions(meta) {
|
|
14872
15408
|
return {
|
|
14873
15409
|
internal: true,
|
|
14874
|
-
workflow: { runId:
|
|
15410
|
+
workflow: { runId: meta.runId, stageId: meta.stageId, stageName: meta.stageName }
|
|
14875
15411
|
};
|
|
14876
15412
|
}
|
|
14877
|
-
function workflowOrchestrationContext(
|
|
15413
|
+
function workflowOrchestrationContext(meta, stageOptions, pendingStageDelivery) {
|
|
14878
15414
|
const base = {
|
|
14879
15415
|
kind: "workflow-stage",
|
|
14880
|
-
workflowRunId:
|
|
14881
|
-
workflowStageId:
|
|
14882
|
-
workflowStageName:
|
|
15416
|
+
workflowRunId: meta.runId,
|
|
15417
|
+
workflowStageId: meta.stageId,
|
|
15418
|
+
workflowStageName: meta.stageName,
|
|
14883
15419
|
constraints: { disableWorkflowTool: true }
|
|
14884
15420
|
};
|
|
14885
|
-
const intercomGroup = stageHasIntercomAccess(stageOptions) ? resolveStageGroup(stageOptions,
|
|
15421
|
+
const intercomGroup = stageHasIntercomAccess(stageOptions) ? resolveStageGroup(stageOptions, meta.workflowIntercomGroup) : undefined;
|
|
14886
15422
|
const context = intercomGroup ? { ...base, intercomGroup } : base;
|
|
14887
15423
|
return pendingStageDelivery === undefined ? context : { ...context, pendingStageDelivery };
|
|
14888
15424
|
}
|
|
14889
|
-
function stripWorkflowOnlyOptions(options, defaultSessionDir,
|
|
14890
|
-
const classification = workflowSessionOptions(
|
|
14891
|
-
const orchestrationContext = workflowOrchestrationContext(
|
|
15425
|
+
function stripWorkflowOnlyOptions(options, defaultSessionDir, meta, pendingStageDelivery) {
|
|
15426
|
+
const classification = workflowSessionOptions(meta);
|
|
15427
|
+
const orchestrationContext = workflowOrchestrationContext(meta, options, pendingStageDelivery);
|
|
14892
15428
|
if (!options) {
|
|
14893
15429
|
return defaultSessionDir === undefined ? { orchestrationContext } : {
|
|
14894
15430
|
orchestrationContext,
|
|
@@ -14969,7 +15505,8 @@ class StageSessionPause {
|
|
|
14969
15505
|
abortBoundary: Promise.withResolvers(),
|
|
14970
15506
|
runnerOwnedDeliveries: new Set,
|
|
14971
15507
|
confirmed: false,
|
|
14972
|
-
...nativeQueuePause === undefined ? {} : { nativeQueuePause }
|
|
15508
|
+
...nativeQueuePause === undefined ? {} : { nativeQueuePause },
|
|
15509
|
+
...session?.pauseTasks && session.resumeTasks ? { taskControl: session } : {}
|
|
14973
15510
|
};
|
|
14974
15511
|
request.deferred.promise.catch(() => {});
|
|
14975
15512
|
request.abortBoundary.promise.catch(() => {});
|
|
@@ -14977,7 +15514,11 @@ class StageSessionPause {
|
|
|
14977
15514
|
let failed = false;
|
|
14978
15515
|
try {
|
|
14979
15516
|
request.nativeQueuePause?.pauseQueuedMessages();
|
|
14980
|
-
|
|
15517
|
+
const tasks = request.taskControl?.pauseTasks?.();
|
|
15518
|
+
const settled = await Promise.allSettled([tasks, (async () => session?.abort())()]);
|
|
15519
|
+
for (const result of settled)
|
|
15520
|
+
if (result.status === "rejected")
|
|
15521
|
+
throw result.reason;
|
|
14981
15522
|
request.abortBoundary.resolve();
|
|
14982
15523
|
await request.abortBoundary.promise;
|
|
14983
15524
|
request.confirmed = true;
|
|
@@ -14985,6 +15526,7 @@ class StageSessionPause {
|
|
|
14985
15526
|
failed = true;
|
|
14986
15527
|
request.abortBoundary.reject(error);
|
|
14987
15528
|
request.deferred.reject(error);
|
|
15529
|
+
request.taskControl?.resumeTasks?.();
|
|
14988
15530
|
await this.rollbackNativePause(request.nativeQueuePause);
|
|
14989
15531
|
throw error;
|
|
14990
15532
|
} finally {
|
|
@@ -15052,6 +15594,7 @@ class StageSessionPause {
|
|
|
15052
15594
|
if (releaseAdmitted)
|
|
15053
15595
|
return;
|
|
15054
15596
|
beforeRelease?.();
|
|
15597
|
+
request.taskControl?.resumeTasks?.();
|
|
15055
15598
|
releaseAdmitted = true;
|
|
15056
15599
|
};
|
|
15057
15600
|
let releasedQueuedMessages;
|
|
@@ -15106,16 +15649,37 @@ function stageSessionExtensionRunner(current) {
|
|
|
15106
15649
|
}
|
|
15107
15650
|
return;
|
|
15108
15651
|
}
|
|
15652
|
+
var shutdowns = new WeakMap;
|
|
15653
|
+
function shutdownStageSession(current) {
|
|
15654
|
+
if (!current)
|
|
15655
|
+
return Promise.resolve();
|
|
15656
|
+
const existing = shutdowns.get(current);
|
|
15657
|
+
if (existing)
|
|
15658
|
+
return existing;
|
|
15659
|
+
const shutdown = Promise.resolve().then(async () => {
|
|
15660
|
+
const runner = stageSessionExtensionRunner(current);
|
|
15661
|
+
if (runner?.hasHandlers("session_shutdown"))
|
|
15662
|
+
await runner.emit({ type: "session_shutdown", reason: "quit" });
|
|
15663
|
+
});
|
|
15664
|
+
shutdowns.set(current, shutdown);
|
|
15665
|
+
return shutdown;
|
|
15666
|
+
}
|
|
15667
|
+
|
|
15668
|
+
class StageSessionBindingCleanupFailure extends AggregateError {
|
|
15669
|
+
constructor(bindingError, cleanupErrors) {
|
|
15670
|
+
super([bindingError, ...cleanupErrors], "atomic-workflows: failed binding cleanup did not release session ownership", {
|
|
15671
|
+
cause: bindingError
|
|
15672
|
+
});
|
|
15673
|
+
this.name = "StageSessionBindingCleanupFailure";
|
|
15674
|
+
}
|
|
15675
|
+
}
|
|
15109
15676
|
async function disposeStageSession(current) {
|
|
15110
15677
|
if (!current)
|
|
15111
15678
|
return;
|
|
15112
|
-
|
|
15113
|
-
|
|
15114
|
-
|
|
15115
|
-
|
|
15116
|
-
} catch (error) {
|
|
15117
|
-
console.error("atomic-workflows: stage session_shutdown handler failed", error);
|
|
15118
|
-
}
|
|
15679
|
+
try {
|
|
15680
|
+
await shutdownStageSession(current);
|
|
15681
|
+
} catch (error) {
|
|
15682
|
+
console.error("atomic-workflows: stage session_shutdown handler failed", error);
|
|
15119
15683
|
}
|
|
15120
15684
|
await current.dispose();
|
|
15121
15685
|
}
|
|
@@ -15148,6 +15712,9 @@ async function rejectDisposedCreatedSession(result, stageName) {
|
|
|
15148
15712
|
class StageSessionReplacement {
|
|
15149
15713
|
previous;
|
|
15150
15714
|
cleanups = new Set;
|
|
15715
|
+
get retiringSession() {
|
|
15716
|
+
return this.previous;
|
|
15717
|
+
}
|
|
15151
15718
|
retire(session) {
|
|
15152
15719
|
this.previous = session;
|
|
15153
15720
|
}
|
|
@@ -15227,30 +15794,31 @@ async function sendStageUserMessage(activeSession, content, options, beforeDeliv
|
|
|
15227
15794
|
if (activeSession.sendUserMessage !== undefined) {
|
|
15228
15795
|
beforeDelivery?.();
|
|
15229
15796
|
let reportedAction;
|
|
15230
|
-
const
|
|
15231
|
-
|
|
15232
|
-
const
|
|
15797
|
+
const ownership = streaming ? undefined : admission === undefined ? createLocalPromptOwnershipObserver(activeSession, promptStarted) : coordinatedPromptOwnershipObserver(admission.startTurn(activeSession, promptStarted ?? (() => {})));
|
|
15798
|
+
ownership?.arm();
|
|
15799
|
+
const deliveryId = streaming ? undefined : activity?.start();
|
|
15233
15800
|
try {
|
|
15234
15801
|
const delivery = activeSession.sendUserMessage(content, {
|
|
15235
15802
|
...deliverAs === undefined ? {} : { deliverAs },
|
|
15803
|
+
...options?.expandPromptTemplates === undefined ? {} : { expandPromptTemplates: options.expandPromptTemplates },
|
|
15236
15804
|
__workflowDelivery: {
|
|
15237
|
-
promptStarted:
|
|
15238
|
-
delivered(
|
|
15239
|
-
reportedAction =
|
|
15805
|
+
promptStarted: ownership?.observe ?? promptStarted,
|
|
15806
|
+
delivered(action) {
|
|
15807
|
+
reportedAction = action;
|
|
15240
15808
|
}
|
|
15241
15809
|
}
|
|
15242
15810
|
});
|
|
15243
|
-
|
|
15811
|
+
ownership?.observeStreaming();
|
|
15244
15812
|
await delivery;
|
|
15245
15813
|
const action = reportedAction ?? (streaming ? deliverAs ?? "followUp" : "prompt");
|
|
15246
|
-
|
|
15814
|
+
ownership?.settle(action);
|
|
15247
15815
|
return action;
|
|
15248
15816
|
} catch (error) {
|
|
15249
|
-
|
|
15817
|
+
ownership?.settle();
|
|
15250
15818
|
throw error;
|
|
15251
15819
|
} finally {
|
|
15252
|
-
|
|
15253
|
-
activity?.settle(
|
|
15820
|
+
ownership?.dispose();
|
|
15821
|
+
activity?.settle(deliveryId);
|
|
15254
15822
|
}
|
|
15255
15823
|
}
|
|
15256
15824
|
if (typeof content !== "string")
|
|
@@ -15508,6 +16076,8 @@ class StageSessionController {
|
|
|
15508
16076
|
abortReason;
|
|
15509
16077
|
abortReasonGeneration = 0;
|
|
15510
16078
|
sessionPromise;
|
|
16079
|
+
sessionShutdownPromise;
|
|
16080
|
+
bindingCleanupFailure;
|
|
15511
16081
|
reattachSessionFile;
|
|
15512
16082
|
lastPromptStartIndex;
|
|
15513
16083
|
attemptUsageStartIndex;
|
|
@@ -15531,7 +16101,7 @@ class StageSessionController {
|
|
|
15531
16101
|
pendingThinkingLevel;
|
|
15532
16102
|
pendingListeners = new Set;
|
|
15533
16103
|
listenerUnsubscribes = new Map;
|
|
15534
|
-
pauseControl = new StageSessionPause(() => this.session);
|
|
16104
|
+
pauseControl = new StageSessionPause(() => this.session ?? this.replacement.retiringSession);
|
|
15535
16105
|
hasExplicitModelFallbackConfig;
|
|
15536
16106
|
candidatesPromise;
|
|
15537
16107
|
activeCandidateIndex;
|
|
@@ -15550,9 +16120,25 @@ class StageSessionController {
|
|
|
15550
16120
|
pendingCreationResumeMessage;
|
|
15551
16121
|
messageAdmission = new StageMessageAdmission;
|
|
15552
16122
|
deliveryActivity = new StageDeliveryActivity;
|
|
15553
|
-
|
|
16123
|
+
artifactCapture = new StageArtifactCapture;
|
|
16124
|
+
beginOutputGeneration() {
|
|
16125
|
+
this.artifactCapture.reset();
|
|
16126
|
+
}
|
|
16127
|
+
outputGenerationMessages() {
|
|
16128
|
+
return this.artifactCapture.messages();
|
|
16129
|
+
}
|
|
16130
|
+
async navigateTree(...args) {
|
|
16131
|
+
const session = await this.ensureSession();
|
|
16132
|
+
this.artifactCapture.messages();
|
|
16133
|
+
try {
|
|
16134
|
+
return await session.navigateTree(...args);
|
|
16135
|
+
} finally {
|
|
16136
|
+
this.artifactCapture.rememberContext(session);
|
|
16137
|
+
}
|
|
16138
|
+
}
|
|
16139
|
+
constructor(opts, meta, effectiveStageOptions, structuredOutputCapture) {
|
|
15554
16140
|
this.opts = opts;
|
|
15555
|
-
this.meta =
|
|
16141
|
+
this.meta = meta;
|
|
15556
16142
|
this.effectiveStageOptions = effectiveStageOptions;
|
|
15557
16143
|
this.structuredOutputCapture = structuredOutputCapture;
|
|
15558
16144
|
this.hasExplicitModelFallbackConfig = effectiveStageOptions?.model !== undefined || (effectiveStageOptions?.fallbackModels?.length ?? 0) > 0;
|
|
@@ -15608,8 +16194,7 @@ class StageSessionController {
|
|
|
15608
16194
|
this.pendingFallbackWarnings.push(`[fallback] ${candidateLabel(candidate)} failed: ${error}. Retrying with ${candidateLabel(nextCandidate)}.`);
|
|
15609
16195
|
this.modelWarnings.push(...this.pendingFallbackWarnings);
|
|
15610
16196
|
this.pendingFallbackWarnings.length = 0;
|
|
15611
|
-
await this.disposeCurrentSession();
|
|
15612
|
-
this.activeCandidateIndex = index + 1;
|
|
16197
|
+
await this.disposeCurrentSession(index + 1);
|
|
15613
16198
|
this.notifyModelFallbackMetaChange();
|
|
15614
16199
|
return true;
|
|
15615
16200
|
}
|
|
@@ -15637,6 +16222,14 @@ class StageSessionController {
|
|
|
15637
16222
|
this.session?.setThinkingLevel(level);
|
|
15638
16223
|
}
|
|
15639
16224
|
async ensureSession(consumer = "prompt") {
|
|
16225
|
+
if (this.bindingCleanupFailure !== undefined)
|
|
16226
|
+
throw this.bindingCleanupFailure;
|
|
16227
|
+
if (this.sessionShutdownPromise !== undefined) {
|
|
16228
|
+
const generation = this.abortGeneration;
|
|
16229
|
+
await this.sessionShutdownPromise;
|
|
16230
|
+
if (this.disposed || this.opts.signal?.aborted || this.abortGeneration !== generation)
|
|
16231
|
+
throw this.staleCreationReason(generation);
|
|
16232
|
+
}
|
|
15640
16233
|
if (this.disposed)
|
|
15641
16234
|
throw new Error(`atomic-workflows: stage "${this.opts.stageName}" session has been disposed`);
|
|
15642
16235
|
if (this.session !== undefined)
|
|
@@ -15651,14 +16244,16 @@ class StageSessionController {
|
|
|
15651
16244
|
};
|
|
15652
16245
|
pending.then(release, () => {
|
|
15653
16246
|
release();
|
|
15654
|
-
if (this.sessionPromise === pending)
|
|
16247
|
+
if (this.sessionPromise === pending) {
|
|
15655
16248
|
this.sessionPromise = undefined;
|
|
16249
|
+
this.activeCandidateIndex = undefined;
|
|
16250
|
+
}
|
|
15656
16251
|
});
|
|
15657
16252
|
}
|
|
15658
16253
|
return this.sessionPromise;
|
|
15659
16254
|
}
|
|
15660
16255
|
async ensureSessionFromFile(sessionFile, consumer = "prompt") {
|
|
15661
|
-
if (!this.sessionPromise && !this.session)
|
|
16256
|
+
if (!this.sessionShutdownPromise && !this.sessionPromise && !this.session)
|
|
15662
16257
|
this.reattachSessionFile = sessionFile;
|
|
15663
16258
|
const session = await this.ensureSession(consumer);
|
|
15664
16259
|
await session.closeWorkflowStageGeneration?.();
|
|
@@ -15675,10 +16270,10 @@ class StageSessionController {
|
|
|
15675
16270
|
const sessionFile = preparation?.sessionFile;
|
|
15676
16271
|
const deliver = async (activity) => {
|
|
15677
16272
|
const activeSession = sessionFile === undefined ? await this.ensureSession("prompt") : await this.ensureSessionFromFile(sessionFile, "prompt");
|
|
15678
|
-
const
|
|
15679
|
-
if (
|
|
16273
|
+
const pausedDelivery = this.pauseControl.deferRunnerOwnedDelivery(() => sendStageUserMessage(activeSession, content, options, beforeDelivery, release, this.messageAdmission, activity));
|
|
16274
|
+
if (pausedDelivery !== undefined) {
|
|
15680
16275
|
release();
|
|
15681
|
-
return
|
|
16276
|
+
return pausedDelivery;
|
|
15682
16277
|
}
|
|
15683
16278
|
return sendStageUserMessage(activeSession, content, options, beforeDelivery, release, this.messageAdmission, activity);
|
|
15684
16279
|
};
|
|
@@ -15700,18 +16295,19 @@ class StageSessionController {
|
|
|
15700
16295
|
const pending = this.activeCreation ?? this.sessionPromise;
|
|
15701
16296
|
const session = pending ? await pending : this.session;
|
|
15702
16297
|
await session?.closeWorkflowStageGeneration?.();
|
|
16298
|
+
this.artifactCapture.close();
|
|
15703
16299
|
}
|
|
15704
16300
|
async promptWithFallback(text, sdkOptions, consumer = "prompt") {
|
|
15705
16301
|
if (!this.hasExplicitModelFallbackConfig) {
|
|
15706
16302
|
try {
|
|
15707
16303
|
const activeSession = await this.ensureSession(consumer);
|
|
15708
|
-
const
|
|
16304
|
+
const resumedText = this.pendingCreationResumeMessage;
|
|
15709
16305
|
this.pendingCreationResumeMessage = undefined;
|
|
15710
16306
|
const value = activeSession.model ?? "default";
|
|
15711
16307
|
const candidate = { id: workflowModelId(value) ?? "default", value };
|
|
15712
16308
|
this.beginAttemptUsage(activeSession);
|
|
15713
16309
|
try {
|
|
15714
|
-
await this.promptWithThrownErrorRetry(activeSession,
|
|
16310
|
+
await this.promptWithThrownErrorRetry(activeSession, resumedText ?? text, sdkOptions);
|
|
15715
16311
|
} catch (error) {
|
|
15716
16312
|
await this.handleCandidateFailure(error, candidate, [candidate], 0);
|
|
15717
16313
|
throw error;
|
|
@@ -15728,10 +16324,12 @@ class StageSessionController {
|
|
|
15728
16324
|
if (candidates.length === 0) {
|
|
15729
16325
|
try {
|
|
15730
16326
|
const activeSession = await this.ensureSession(consumer);
|
|
15731
|
-
const
|
|
16327
|
+
const resumedText = this.pendingCreationResumeMessage;
|
|
15732
16328
|
this.pendingCreationResumeMessage = undefined;
|
|
15733
|
-
await this.promptWithThrownErrorRetry(activeSession,
|
|
16329
|
+
await this.promptWithThrownErrorRetry(activeSession, resumedText ?? text, sdkOptions);
|
|
16330
|
+
this.artifactCapture.settleAttempt(true);
|
|
15734
16331
|
} catch (error) {
|
|
16332
|
+
this.artifactCapture.settleAttempt(false);
|
|
15735
16333
|
if (error instanceof StageSessionCreationCancelled)
|
|
15736
16334
|
return;
|
|
15737
16335
|
throw error;
|
|
@@ -15753,6 +16351,18 @@ class StageSessionController {
|
|
|
15753
16351
|
return;
|
|
15754
16352
|
let index = this.activeCandidateIndex ?? 0;
|
|
15755
16353
|
while (index < candidates.length) {
|
|
16354
|
+
if (this.session === undefined && this.ownedCreationPromise !== undefined) {
|
|
16355
|
+
try {
|
|
16356
|
+
await this.ownedCreationPromise;
|
|
16357
|
+
} catch (error) {
|
|
16358
|
+
if (error instanceof StageSessionCreationCancelled)
|
|
16359
|
+
return;
|
|
16360
|
+
throw error;
|
|
16361
|
+
}
|
|
16362
|
+
index = this.activeCandidateIndex ?? index;
|
|
16363
|
+
promptText = this.pendingCreationResumeMessage ?? promptText;
|
|
16364
|
+
this.pendingCreationResumeMessage = undefined;
|
|
16365
|
+
}
|
|
15756
16366
|
const candidate = candidates[index];
|
|
15757
16367
|
try {
|
|
15758
16368
|
const created = this.session && this.activeCandidateIndex === index ? this.session : await this.createSessionWithThrownErrorRetry(candidate, consumer);
|
|
@@ -15779,10 +16389,10 @@ class StageSessionController {
|
|
|
15779
16389
|
this.recordSuccessfulAttempt(candidate);
|
|
15780
16390
|
return;
|
|
15781
16391
|
} catch (err) {
|
|
15782
|
-
const
|
|
15783
|
-
if (
|
|
16392
|
+
const failure = await this.handleCandidateFailure(err, candidate, candidates, index);
|
|
16393
|
+
if (failure === "handled")
|
|
15784
16394
|
return;
|
|
15785
|
-
if (
|
|
16395
|
+
if (failure === "throw")
|
|
15786
16396
|
throw err;
|
|
15787
16397
|
index += 1;
|
|
15788
16398
|
}
|
|
@@ -15791,8 +16401,10 @@ class StageSessionController {
|
|
|
15791
16401
|
currentModelFallbackMeta() {
|
|
15792
16402
|
const attemptedModels = this.modelAttempts.map((attempt) => attempt.model);
|
|
15793
16403
|
const model = this.selectedModel ?? workflowModelId(this.session?.model);
|
|
16404
|
+
const thinkingLevel = this.session?.thinkingLevel ?? this.pendingThinkingLevel;
|
|
15794
16405
|
return {
|
|
15795
16406
|
...model !== undefined ? { model } : {},
|
|
16407
|
+
...thinkingLevel !== undefined ? { thinkingLevel } : {},
|
|
15796
16408
|
...attemptedModels.length > 0 ? { attemptedModels } : {},
|
|
15797
16409
|
...this.modelAttempts.length > 0 ? { modelAttempts: [...this.modelAttempts] } : {},
|
|
15798
16410
|
...this.modelWarnings.length > 0 ? { warnings: [...this.modelWarnings] } : {}
|
|
@@ -15876,14 +16488,14 @@ class StageSessionController {
|
|
|
15876
16488
|
const { signal } = this.opts;
|
|
15877
16489
|
if (!signal)
|
|
15878
16490
|
return;
|
|
15879
|
-
const
|
|
16491
|
+
const abortReason = () => {
|
|
15880
16492
|
const reason = signal.reason;
|
|
15881
16493
|
if (reason instanceof Error || reason instanceof DOMException || typeof reason === "string")
|
|
15882
16494
|
return reason;
|
|
15883
16495
|
return new DOMException("workflow killed", "AbortError");
|
|
15884
16496
|
};
|
|
15885
16497
|
const onAbort = () => {
|
|
15886
|
-
const reason =
|
|
16498
|
+
const reason = abortReason();
|
|
15887
16499
|
this.markAbort(reason);
|
|
15888
16500
|
this.session?.abort().catch(() => {});
|
|
15889
16501
|
this.pauseControl.reject(reason);
|
|
@@ -16023,6 +16635,7 @@ class StageSessionController {
|
|
|
16023
16635
|
let retainedPrompt;
|
|
16024
16636
|
let terminalScanStartIndex;
|
|
16025
16637
|
while (true) {
|
|
16638
|
+
this.artifactCapture.beginAttempt(activeSession);
|
|
16026
16639
|
const messagesBeforeAttempt = [...activeSession.messages];
|
|
16027
16640
|
try {
|
|
16028
16641
|
if (retryAdmittedPrompt) {
|
|
@@ -16065,6 +16678,7 @@ class StageSessionController {
|
|
|
16065
16678
|
const willRetry = decision !== undefined && !this.disposed && this.opts.signal?.aborted !== true && !this.capturedStructuredOutputForAttempt();
|
|
16066
16679
|
const willContinue = continuationSession !== undefined && admittedMessages;
|
|
16067
16680
|
if (retryableFailure && willRetry) {
|
|
16681
|
+
this.artifactCapture.settleAttempt(false);
|
|
16068
16682
|
retainedPrompt = this.restoreSessionMessages(activeSession, messagesBeforeAttempt, nextText, willContinue) ?? retainedPrompt;
|
|
16069
16683
|
}
|
|
16070
16684
|
if (!willRetry)
|
|
@@ -16140,7 +16754,8 @@ class StageSessionController {
|
|
|
16140
16754
|
return this.createSessionObservingPause(undefined, consumer).catch((error) => this.createInitialSessionWithRetry(undefined, consumer, { error }));
|
|
16141
16755
|
}
|
|
16142
16756
|
const candidates = await this.modelCandidates();
|
|
16143
|
-
const
|
|
16757
|
+
const initialIndex = this.activeCandidateIndex ?? 0;
|
|
16758
|
+
const first = candidates[initialIndex];
|
|
16144
16759
|
if (first === undefined) {
|
|
16145
16760
|
return this.createSessionObservingPause(undefined, consumer).catch((error) => this.createInitialSessionWithRetry(undefined, consumer, { error }));
|
|
16146
16761
|
}
|
|
@@ -16153,9 +16768,9 @@ class StageSessionController {
|
|
|
16153
16768
|
this.resumeCurrentSession = true;
|
|
16154
16769
|
return resumed;
|
|
16155
16770
|
}
|
|
16156
|
-
this.activeCandidateIndex =
|
|
16771
|
+
this.activeCandidateIndex = initialIndex;
|
|
16157
16772
|
this.selectedModel = first.id;
|
|
16158
|
-
return this.createSessionObservingPause(first, consumer).catch((error) => this.createInitialSessionCandidateWalk(candidates, consumer,
|
|
16773
|
+
return this.createSessionObservingPause(first, consumer).catch((error) => this.createInitialSessionCandidateWalk(candidates, consumer, initialIndex, { error }));
|
|
16159
16774
|
}
|
|
16160
16775
|
async createInitialSessionCandidateWalk(candidates, consumer, startIndex, initialFailure) {
|
|
16161
16776
|
let index = startIndex;
|
|
@@ -16231,12 +16846,14 @@ class StageSessionController {
|
|
|
16231
16846
|
while (true) {
|
|
16232
16847
|
try {
|
|
16233
16848
|
if (pendingFailure !== undefined) {
|
|
16234
|
-
const
|
|
16849
|
+
const failure = pendingFailure;
|
|
16235
16850
|
pendingFailure = undefined;
|
|
16236
|
-
throw
|
|
16851
|
+
throw failure.error;
|
|
16237
16852
|
}
|
|
16238
16853
|
return await this.createSessionObservingPause(candidate, consumer);
|
|
16239
16854
|
} catch (error) {
|
|
16855
|
+
if (error instanceof StageSessionBindingCleanupFailure)
|
|
16856
|
+
throw error;
|
|
16240
16857
|
const errorSettingsManager = retrySettingsManagerFromError(error);
|
|
16241
16858
|
if (errorSettingsManager !== undefined)
|
|
16242
16859
|
this.sessionSettingsManager = errorSettingsManager;
|
|
@@ -16270,6 +16887,20 @@ class StageSessionController {
|
|
|
16270
16887
|
}
|
|
16271
16888
|
}
|
|
16272
16889
|
createSession(candidate, consumer, resumeOptions) {
|
|
16890
|
+
if (this.bindingCleanupFailure !== undefined)
|
|
16891
|
+
return Promise.reject(this.bindingCleanupFailure);
|
|
16892
|
+
if (this.sessionShutdownPromise !== undefined) {
|
|
16893
|
+
const generation = this.abortGeneration;
|
|
16894
|
+
return this.sessionShutdownPromise.then(() => {
|
|
16895
|
+
if (this.disposed || this.opts.signal?.aborted || this.abortGeneration !== generation)
|
|
16896
|
+
throw this.staleCreationReason(generation);
|
|
16897
|
+
return this.createSession(candidate, consumer, resumeOptions);
|
|
16898
|
+
});
|
|
16899
|
+
}
|
|
16900
|
+
if (this.activeCreation !== undefined)
|
|
16901
|
+
return this.activeCreation;
|
|
16902
|
+
if (this.session !== undefined)
|
|
16903
|
+
return Promise.resolve(this.session);
|
|
16273
16904
|
const creation = this.createSessionAttempt(candidate, consumer, resumeOptions);
|
|
16274
16905
|
this.activeCreation = creation;
|
|
16275
16906
|
creation.finally(() => {
|
|
@@ -16296,6 +16927,10 @@ class StageSessionController {
|
|
|
16296
16927
|
...this.sharedOrchestrationContext !== undefined ? { orchestrationContext: this.sharedOrchestrationContext } : {}
|
|
16297
16928
|
}) : missingAdapter(consumer);
|
|
16298
16929
|
} catch (error) {
|
|
16930
|
+
if (error instanceof StageSessionBindingCleanupFailure) {
|
|
16931
|
+
this.bindingCleanupFailure = error;
|
|
16932
|
+
throw error;
|
|
16933
|
+
}
|
|
16299
16934
|
if (this.disposed || this.opts.signal?.aborted === true || this.abortGeneration !== startGeneration)
|
|
16300
16935
|
throw this.disposed ? new Error(`atomic-workflows: stage "${this.opts.stageName}" session has been disposed`) : this.staleCreationReason(startGeneration);
|
|
16301
16936
|
throw error;
|
|
@@ -16350,6 +16985,7 @@ class StageSessionController {
|
|
|
16350
16985
|
}
|
|
16351
16986
|
this.unsubscribeTerminateWatcher?.();
|
|
16352
16987
|
this.unsubscribeTerminateWatcher = result.session.subscribe((event) => {
|
|
16988
|
+
this.artifactCapture.onEvent(result.session, event);
|
|
16353
16989
|
const terminatingId = terminatingToolCallId(event);
|
|
16354
16990
|
if (terminatingId !== undefined)
|
|
16355
16991
|
this.terminatingToolCallIds.add(terminatingId);
|
|
@@ -16358,12 +16994,16 @@ class StageSessionController {
|
|
|
16358
16994
|
});
|
|
16359
16995
|
return result.session;
|
|
16360
16996
|
}
|
|
16361
|
-
async disposeCurrentSession() {
|
|
16997
|
+
async disposeCurrentSession(nextCandidateIndex) {
|
|
16998
|
+
if (this.sessionShutdownPromise !== undefined)
|
|
16999
|
+
await this.sessionShutdownPromise;
|
|
17000
|
+
const startGeneration = this.abortGeneration;
|
|
16362
17001
|
this.abortThrownErrorRetries(new Error(`atomic-workflows: stage "${this.opts.stageName}" session was replaced`));
|
|
16363
17002
|
const current = this.session;
|
|
16364
17003
|
this.messageAdmission.reset();
|
|
16365
17004
|
this.replacement.retire(current);
|
|
16366
17005
|
this.session = undefined;
|
|
17006
|
+
this.activeCandidateIndex = nextCandidateIndex;
|
|
16367
17007
|
if (this.sessionPromise !== this.ownedCreationPromise)
|
|
16368
17008
|
this.sessionPromise = undefined;
|
|
16369
17009
|
this.sessionSettingsManager = undefined;
|
|
@@ -16374,6 +17014,15 @@ class StageSessionController {
|
|
|
16374
17014
|
this.unsubscribeTerminateWatcher?.();
|
|
16375
17015
|
this.unsubscribeTerminateWatcher = undefined;
|
|
16376
17016
|
this.terminatingToolCallIds.clear();
|
|
17017
|
+
const shutdown = Promise.resolve().then(() => shutdownStageSession(current));
|
|
17018
|
+
this.sessionShutdownPromise = shutdown;
|
|
17019
|
+
shutdown.then(() => {
|
|
17020
|
+
if (this.sessionShutdownPromise === shutdown)
|
|
17021
|
+
this.sessionShutdownPromise = undefined;
|
|
17022
|
+
}, () => {});
|
|
17023
|
+
await shutdown;
|
|
17024
|
+
if (this.disposed || this.opts.signal?.aborted === true || this.abortGeneration !== startGeneration)
|
|
17025
|
+
throw this.staleCreationReason(startGeneration);
|
|
16377
17026
|
}
|
|
16378
17027
|
async promptWithPauseResume(activeSession, initialText, sdkOptions) {
|
|
16379
17028
|
let nextText = initialText;
|
|
@@ -16433,6 +17082,7 @@ class StageSessionController {
|
|
|
16433
17082
|
const { terminalScanStartIndex } = await this.promptWithThrownErrorRetry(resumedSession, text, sdkOptions);
|
|
16434
17083
|
const terminalFailure = latestTerminalAssistantFailureSince(resumedSession.messages, terminalScanStartIndex);
|
|
16435
17084
|
if (terminalFailure === undefined || this.capturedStructuredOutputForAttempt()) {
|
|
17085
|
+
this.artifactCapture.settleAttempt(true);
|
|
16436
17086
|
const usage = this.takeAttemptUsage(resumedSession);
|
|
16437
17087
|
this.modelAttempts.push({
|
|
16438
17088
|
model: resumedLabel,
|
|
@@ -16447,17 +17097,19 @@ class StageSessionController {
|
|
|
16447
17097
|
throw new WorkflowPromptModelFailure(terminalFailure);
|
|
16448
17098
|
} catch (err) {
|
|
16449
17099
|
if (this.capturedStructuredOutputForAttempt() && isRetryableModelFailure(err)) {
|
|
16450
|
-
|
|
17100
|
+
this.artifactCapture.settleAttempt(true);
|
|
17101
|
+
const usage = this.takeAttemptUsage(resumedSession);
|
|
16451
17102
|
this.modelAttempts.push({
|
|
16452
17103
|
model: resumedLabel,
|
|
16453
17104
|
success: true,
|
|
16454
|
-
...
|
|
17105
|
+
...usage === undefined ? {} : { usage }
|
|
16455
17106
|
});
|
|
16456
17107
|
this.pendingFallbackWarnings.length = 0;
|
|
16457
17108
|
this.resumeCurrentSession = true;
|
|
16458
17109
|
this.notifySuccessfulModelFallbackMeta();
|
|
16459
17110
|
return true;
|
|
16460
17111
|
}
|
|
17112
|
+
this.artifactCapture.settleAttempt(false);
|
|
16461
17113
|
const message = errorMessage2(err);
|
|
16462
17114
|
const usage = this.takeAttemptUsage(resumedSession);
|
|
16463
17115
|
this.modelAttempts.push({
|
|
@@ -16480,18 +17132,20 @@ class StageSessionController {
|
|
|
16480
17132
|
throw err;
|
|
16481
17133
|
}
|
|
16482
17134
|
this.pendingFallbackWarnings.push(resumedOverflowNextIndex === undefined ? `[fallback] resume on ${resumedLabel} failed: ${message}. Restarting fallback from ${candidateLabel(candidates[0])}.` : `[fallback] resume on ${resumedLabel} failed: ${message}. Retrying with ${candidateLabel(candidates[resumedOverflowNextIndex])}.`);
|
|
16483
|
-
await this.disposeCurrentSession();
|
|
16484
|
-
this.activeCandidateIndex = resumedOverflowNextIndex;
|
|
17135
|
+
await this.disposeCurrentSession(resumedOverflowNextIndex);
|
|
16485
17136
|
return false;
|
|
16486
17137
|
}
|
|
16487
17138
|
}
|
|
16488
17139
|
async handleCandidateFailure(err, candidate, candidates, index) {
|
|
17140
|
+
if (err instanceof StageSessionBindingCleanupFailure)
|
|
17141
|
+
throw err;
|
|
16489
17142
|
const message = errorMessage2(err);
|
|
16490
17143
|
const terminalStageDelivery = isWorkflowPendingStageDeliveryFailure(err);
|
|
16491
17144
|
if (!terminalStageDelivery && this.capturedStructuredOutputForAttempt() && isRetryableModelFailure(err)) {
|
|
16492
17145
|
this.recordSuccessfulAttempt(candidate);
|
|
16493
17146
|
return "handled";
|
|
16494
17147
|
}
|
|
17148
|
+
this.artifactCapture.settleAttempt(false);
|
|
16495
17149
|
const usage = this.takeAttemptUsage(this.session);
|
|
16496
17150
|
this.modelAttempts.push({
|
|
16497
17151
|
model: candidate.id,
|
|
@@ -16508,13 +17162,14 @@ class StageSessionController {
|
|
|
16508
17162
|
}
|
|
16509
17163
|
const nextCandidate = candidates[index + 1];
|
|
16510
17164
|
this.pendingFallbackWarnings.push(`[fallback] ${candidateLabel(candidate)} failed: ${message}. Retrying with ${candidateLabel(nextCandidate)}.`);
|
|
16511
|
-
await this.disposeCurrentSession();
|
|
17165
|
+
await this.disposeCurrentSession(index + 1);
|
|
16512
17166
|
return "retry";
|
|
16513
17167
|
}
|
|
16514
17168
|
capturedStructuredOutputForAttempt() {
|
|
16515
17169
|
return this.structuredOutputCapture?.called === true && this.opts.signal?.aborted !== true;
|
|
16516
17170
|
}
|
|
16517
17171
|
recordSuccessfulAttempt(candidate) {
|
|
17172
|
+
this.artifactCapture.settleAttempt(true);
|
|
16518
17173
|
const usage = this.takeAttemptUsage(this.session);
|
|
16519
17174
|
this.modelAttempts.push({
|
|
16520
17175
|
model: candidate.id,
|
|
@@ -16722,7 +17377,7 @@ function stageOutputInstruction(outputOptions, hasStructuredOutput = false) {
|
|
|
16722
17377
|
}
|
|
16723
17378
|
return `
|
|
16724
17379
|
|
|
16725
|
-
[This stage's
|
|
17380
|
+
[This stage's completed answers are saved as its artifact and are what later stages read. Return the complete result as ordinary assistant text rather than a pointer to it. Follow-up answers within this stage are appended as numbered supplements, not replacements; state corrections explicitly. Tool-call progress is transcript-only. Files you write yourself are not the artifact.]`;
|
|
16726
17381
|
}
|
|
16727
17382
|
async function finalizePromptOutput(fullOutput, outputOptions, runtimeCwd, runId, messages) {
|
|
16728
17383
|
const outputPath = resolveOutputPath(outputOptions.output, runtimeCwd, outputOptions.cwd);
|
|
@@ -16768,7 +17423,7 @@ function createStageContext2(opts) {
|
|
|
16768
17423
|
const structuredOutputCapture = stageOptions?.schema ? createStructuredOutputCapture() : undefined;
|
|
16769
17424
|
const structuredOutputExecutionCapture = stageOptions?.schema ? {} : undefined;
|
|
16770
17425
|
const effectiveStageOptions = stageOptionsWithStructuredOutput(stageOptions, structuredOutputCapture, structuredOutputExecutionCapture);
|
|
16771
|
-
const
|
|
17426
|
+
const meta = {
|
|
16772
17427
|
runId,
|
|
16773
17428
|
stageId,
|
|
16774
17429
|
stageName,
|
|
@@ -16777,21 +17432,40 @@ function createStageContext2(opts) {
|
|
|
16777
17432
|
stageOptions: effectiveStageOptions,
|
|
16778
17433
|
executionMode
|
|
16779
17434
|
};
|
|
16780
|
-
const controller = new StageSessionController(opts,
|
|
17435
|
+
const controller = new StageSessionController(opts, meta, effectiveStageOptions, structuredOutputCapture);
|
|
16781
17436
|
let lastAssistantText;
|
|
16782
17437
|
let lastFinalizedOutput;
|
|
16783
17438
|
let lastFinalizedMessageCount;
|
|
16784
17439
|
let structuredArtifactFinalized = false;
|
|
16785
17440
|
let adapterMessages = [];
|
|
17441
|
+
let artifactOptions;
|
|
17442
|
+
let artifactClosed = false;
|
|
17443
|
+
let artifactText;
|
|
17444
|
+
let continuing = false;
|
|
17445
|
+
async function exportArtifact() {
|
|
17446
|
+
const text = assistantArtifactTextForGeneration(controller.outputGenerationMessages());
|
|
17447
|
+
if (text !== artifactText || lastFinalizedOutput === undefined) {
|
|
17448
|
+
lastFinalizedOutput = await finalizePromptOutput(text, artifactOptions, runtimeCwd(), runId, controller.currentSession?.messages);
|
|
17449
|
+
artifactText = text;
|
|
17450
|
+
lastAssistantText = lastFinalizedOutput;
|
|
17451
|
+
}
|
|
17452
|
+
return lastFinalizedOutput;
|
|
17453
|
+
}
|
|
16786
17454
|
function runtimeCwd() {
|
|
16787
17455
|
return typeof effectiveStageOptions?.cwd === "string" ? effectiveStageOptions.cwd : process.cwd();
|
|
16788
17456
|
}
|
|
16789
17457
|
function finalizedOutputIsCurrent() {
|
|
16790
|
-
|
|
17458
|
+
if (lastFinalizedOutput === undefined)
|
|
17459
|
+
return false;
|
|
17460
|
+
if (artifactOptions !== undefined || structuredArtifactFinalized)
|
|
17461
|
+
return true;
|
|
17462
|
+
return lastFinalizedMessageCount === undefined || controller.currentSession?.messages.length === lastFinalizedMessageCount;
|
|
16791
17463
|
}
|
|
16792
17464
|
return {
|
|
16793
17465
|
name: stageName,
|
|
16794
17466
|
async prompt(text, options) {
|
|
17467
|
+
if (continuing && artifactOptions)
|
|
17468
|
+
options = { ...options, ...artifactOptions };
|
|
16795
17469
|
const { sdkOptions, outputOptions } = splitPromptOptions(options);
|
|
16796
17470
|
validatePromptOutputOptions(outputOptions);
|
|
16797
17471
|
const hasOutputArtifact = typeof outputOptions.output === "string" && outputOptions.output.length > 0;
|
|
@@ -16799,15 +17473,23 @@ function createStageContext2(opts) {
|
|
|
16799
17473
|
if (structuredOutputCapture?.called) {
|
|
16800
17474
|
throw new Error("atomic-workflows: stage schema supports one prompt() call per stage context because structured_output may be called exactly once. Create a new ctx.stage(...) for each additional schema-backed prompt.");
|
|
16801
17475
|
}
|
|
17476
|
+
if (!continuing) {
|
|
17477
|
+
controller.beginOutputGeneration();
|
|
17478
|
+
artifactOptions = undefined;
|
|
17479
|
+
artifactClosed = false;
|
|
17480
|
+
artifactText = undefined;
|
|
17481
|
+
}
|
|
17482
|
+
if (hasOutputArtifact && !structuredOutputCapture && !adapters.prompt)
|
|
17483
|
+
artifactOptions = outputOptions;
|
|
16802
17484
|
if (adapters.prompt) {
|
|
16803
17485
|
if (structuredOutputCapture) {
|
|
16804
17486
|
throw new Error("atomic-workflows: stage schema requires an AgentSessionAdapter so the structured_output tool can be registered.");
|
|
16805
17487
|
}
|
|
16806
|
-
const
|
|
16807
|
-
if (typeof
|
|
16808
|
-
return
|
|
16809
|
-
adapterMessages = assistantMessage(
|
|
16810
|
-
lastAssistantText = await finalizePromptOutput(
|
|
17488
|
+
const rawText = await runCallback2({ kind: "workflow.stage_adapter", name: `prompt:${stageName}`, runId, stageId }, () => adapters.prompt.prompt(promptText, meta));
|
|
17489
|
+
if (typeof rawText !== "string")
|
|
17490
|
+
return rawText;
|
|
17491
|
+
adapterMessages = assistantMessage(rawText);
|
|
17492
|
+
lastAssistantText = await finalizePromptOutput(rawText, outputOptions, runtimeCwd(), runId, adapterMessages);
|
|
16811
17493
|
lastFinalizedOutput = lastAssistantText;
|
|
16812
17494
|
lastFinalizedMessageCount = controller.currentSession?.messages.length;
|
|
16813
17495
|
return lastAssistantText;
|
|
@@ -16849,17 +17531,28 @@ function createStageContext2(opts) {
|
|
|
16849
17531
|
return executionSnapshot.value;
|
|
16850
17532
|
}
|
|
16851
17533
|
await controller.promptWithFallback(promptText, sdkOptions);
|
|
17534
|
+
if (artifactOptions)
|
|
17535
|
+
return await exportArtifact();
|
|
16852
17536
|
const rawText = controller.lastAssistantText(lastAssistantText) ?? "";
|
|
16853
17537
|
lastAssistantText = await finalizePromptOutput(rawText, outputOptions, runtimeCwd(), runId, controller.currentSession?.messages);
|
|
16854
17538
|
lastFinalizedOutput = lastAssistantText;
|
|
16855
17539
|
lastFinalizedMessageCount = controller.currentSession?.messages.length;
|
|
16856
17540
|
return lastAssistantText;
|
|
16857
17541
|
},
|
|
17542
|
+
async __continuePrompt(text) {
|
|
17543
|
+
continuing = true;
|
|
17544
|
+
try {
|
|
17545
|
+
return await this.prompt(text);
|
|
17546
|
+
} finally {
|
|
17547
|
+
continuing = false;
|
|
17548
|
+
}
|
|
17549
|
+
},
|
|
16858
17550
|
async complete(text, completeOpts) {
|
|
17551
|
+
artifactOptions = undefined;
|
|
16859
17552
|
if (adapters.complete) {
|
|
16860
17553
|
lastFinalizedOutput = undefined;
|
|
16861
17554
|
lastFinalizedMessageCount = undefined;
|
|
16862
|
-
lastAssistantText = await runCallback2({ kind: "workflow.stage_adapter", name: `complete:${stageName}`, runId, stageId }, () => adapters.complete.complete(text, completeOpts,
|
|
17555
|
+
lastAssistantText = await runCallback2({ kind: "workflow.stage_adapter", name: `complete:${stageName}`, runId, stageId }, () => adapters.complete.complete(text, completeOpts, meta));
|
|
16863
17556
|
adapterMessages = assistantMessage(lastAssistantText);
|
|
16864
17557
|
return lastAssistantText;
|
|
16865
17558
|
}
|
|
@@ -16924,7 +17617,7 @@ function createStageContext2(opts) {
|
|
|
16924
17617
|
return controller.currentSession?.isStreaming ?? false;
|
|
16925
17618
|
},
|
|
16926
17619
|
async navigateTree(targetId, options) {
|
|
16927
|
-
return
|
|
17620
|
+
return controller.navigateTree(targetId, options);
|
|
16928
17621
|
},
|
|
16929
17622
|
async compact() {
|
|
16930
17623
|
return (await controller.ensureSession()).compact();
|
|
@@ -16955,6 +17648,11 @@ function createStageContext2(opts) {
|
|
|
16955
17648
|
},
|
|
16956
17649
|
async __closeGeneration() {
|
|
16957
17650
|
await controller.closeGeneration();
|
|
17651
|
+
if (artifactOptions && !artifactClosed) {
|
|
17652
|
+
await exportArtifact();
|
|
17653
|
+
artifactClosed = true;
|
|
17654
|
+
}
|
|
17655
|
+
return artifactOptions ? lastFinalizedOutput : undefined;
|
|
16958
17656
|
},
|
|
16959
17657
|
__sessionMeta() {
|
|
16960
17658
|
return controller.sessionMeta();
|
|
@@ -16989,7 +17687,7 @@ function createStageSessionHeartbeat(checkpoint, intervalMs = STAGE_SESSION_HEAR
|
|
|
16989
17687
|
let timer;
|
|
16990
17688
|
let generation = 0;
|
|
16991
17689
|
let nextDeadline = 0;
|
|
16992
|
-
let
|
|
17690
|
+
let failure;
|
|
16993
17691
|
let inFlight;
|
|
16994
17692
|
let rejectFailure;
|
|
16995
17693
|
const failureSignal = new Promise((_resolve, reject) => {
|
|
@@ -17006,14 +17704,14 @@ function createStageSessionHeartbeat(checkpoint, intervalMs = STAGE_SESSION_HEAR
|
|
|
17006
17704
|
timer = undefined;
|
|
17007
17705
|
};
|
|
17008
17706
|
const fail = (error) => {
|
|
17009
|
-
if (
|
|
17707
|
+
if (failure !== undefined)
|
|
17010
17708
|
return;
|
|
17011
|
-
|
|
17709
|
+
failure = error;
|
|
17012
17710
|
stopScheduling();
|
|
17013
17711
|
rejectFailure(error);
|
|
17014
17712
|
};
|
|
17015
17713
|
const schedule = (scheduledGeneration) => {
|
|
17016
|
-
if (!active ||
|
|
17714
|
+
if (!active || failure !== undefined || scheduledGeneration !== generation)
|
|
17017
17715
|
return;
|
|
17018
17716
|
const delayMs = Math.max(0, nextDeadline - Date.now());
|
|
17019
17717
|
timer = setTimeout(() => {
|
|
@@ -17034,12 +17732,12 @@ function createStageSessionHeartbeat(checkpoint, intervalMs = STAGE_SESSION_HEAR
|
|
|
17034
17732
|
const drain = async () => {
|
|
17035
17733
|
stopScheduling();
|
|
17036
17734
|
await inFlight;
|
|
17037
|
-
if (
|
|
17038
|
-
throw
|
|
17735
|
+
if (failure !== undefined)
|
|
17736
|
+
throw failure;
|
|
17039
17737
|
};
|
|
17040
17738
|
return {
|
|
17041
17739
|
start() {
|
|
17042
|
-
if (active ||
|
|
17740
|
+
if (active || failure !== undefined)
|
|
17043
17741
|
return;
|
|
17044
17742
|
active = true;
|
|
17045
17743
|
generation += 1;
|
|
@@ -17050,8 +17748,8 @@ function createStageSessionHeartbeat(checkpoint, intervalMs = STAGE_SESSION_HEAR
|
|
|
17050
17748
|
drain,
|
|
17051
17749
|
fail,
|
|
17052
17750
|
race(work) {
|
|
17053
|
-
if (
|
|
17054
|
-
return Promise.reject(
|
|
17751
|
+
if (failure !== undefined)
|
|
17752
|
+
return Promise.reject(failure);
|
|
17055
17753
|
return Promise.race([work, failureSignal]);
|
|
17056
17754
|
}
|
|
17057
17755
|
};
|
|
@@ -17111,6 +17809,8 @@ function createWorkflowStageFactory(input) {
|
|
|
17111
17809
|
...replaySource.result !== undefined ? { result: replaySource.result } : {},
|
|
17112
17810
|
...replaySource.sessionId !== undefined ? { sessionId: replaySource.sessionId } : {},
|
|
17113
17811
|
...replaySource.sessionFile !== undefined ? { sessionFile: replaySource.sessionFile } : {},
|
|
17812
|
+
...replaySource.model !== undefined ? { model: replaySource.model } : {},
|
|
17813
|
+
...replaySource.thinkingLevel !== undefined ? { thinkingLevel: replaySource.thinkingLevel } : {},
|
|
17114
17814
|
replayedFromStageId: replaySource.id,
|
|
17115
17815
|
replayed: true
|
|
17116
17816
|
} : {},
|
|
@@ -17132,16 +17832,20 @@ function createWorkflowStageFactory(input) {
|
|
|
17132
17832
|
throwIfWorkflowExitSelected: input.exit.throwIfWorkflowExitSelected
|
|
17133
17833
|
});
|
|
17134
17834
|
}
|
|
17135
|
-
const applyModelFallbackMeta = (
|
|
17136
|
-
if (
|
|
17137
|
-
stageSnapshot.model =
|
|
17138
|
-
if (
|
|
17139
|
-
stageSnapshot.
|
|
17140
|
-
|
|
17141
|
-
stageSnapshot.
|
|
17142
|
-
if (
|
|
17143
|
-
|
|
17144
|
-
|
|
17835
|
+
const applyModelFallbackMeta = (meta) => {
|
|
17836
|
+
if (meta.model !== undefined)
|
|
17837
|
+
stageSnapshot.model = meta.model;
|
|
17838
|
+
if (meta.thinkingLevel !== undefined)
|
|
17839
|
+
stageSnapshot.thinkingLevel = meta.thinkingLevel;
|
|
17840
|
+
else
|
|
17841
|
+
delete stageSnapshot.thinkingLevel;
|
|
17842
|
+
if (meta.attemptedModels !== undefined)
|
|
17843
|
+
stageSnapshot.attemptedModels = meta.attemptedModels;
|
|
17844
|
+
if (meta.modelAttempts !== undefined)
|
|
17845
|
+
stageSnapshot.modelAttempts = meta.modelAttempts;
|
|
17846
|
+
if (meta.warnings !== undefined) {
|
|
17847
|
+
if (meta.warnings.length > 0)
|
|
17848
|
+
stageSnapshot.warnings = meta.warnings;
|
|
17145
17849
|
else
|
|
17146
17850
|
delete stageSnapshot.warnings;
|
|
17147
17851
|
}
|
|
@@ -17169,8 +17873,8 @@ function createWorkflowStageFactory(input) {
|
|
|
17169
17873
|
models: input.opts.models,
|
|
17170
17874
|
executionMode: input.opts.executionMode,
|
|
17171
17875
|
defaultSessionDir: input.opts.defaultSessionDir,
|
|
17172
|
-
onModelFallbackMetaChange(
|
|
17173
|
-
applyModelFallbackMeta(
|
|
17876
|
+
onModelFallbackMetaChange(meta) {
|
|
17877
|
+
applyModelFallbackMeta(meta);
|
|
17174
17878
|
if (stageSnapshot.status === "running")
|
|
17175
17879
|
input.activeStore.recordStageStart(input.runId, stageSnapshot);
|
|
17176
17880
|
},
|
|
@@ -17242,13 +17946,13 @@ function createWorkflowStageFactory(input) {
|
|
|
17242
17946
|
await innerCtx.__dispose();
|
|
17243
17947
|
};
|
|
17244
17948
|
const captureStageSessionMeta = async (checkpointOptions) => {
|
|
17245
|
-
const
|
|
17246
|
-
if (
|
|
17247
|
-
stageSnapshot.sessionId =
|
|
17248
|
-
if (
|
|
17249
|
-
stageSnapshot.sessionFile =
|
|
17250
|
-
if (
|
|
17251
|
-
input.activeStore.recordStageSession(input.runId, stageId,
|
|
17949
|
+
const meta = innerCtx.__sessionMeta();
|
|
17950
|
+
if (meta.sessionId !== undefined)
|
|
17951
|
+
stageSnapshot.sessionId = meta.sessionId;
|
|
17952
|
+
if (meta.sessionFile !== undefined)
|
|
17953
|
+
stageSnapshot.sessionFile = meta.sessionFile;
|
|
17954
|
+
if (meta.sessionId !== undefined || meta.sessionFile !== undefined)
|
|
17955
|
+
input.activeStore.recordStageSession(input.runId, stageId, meta);
|
|
17252
17956
|
const pending = input.opts.onStageSession?.(input.runId, stageSnapshot, checkpointOptions);
|
|
17253
17957
|
if (checkpointOptions?.forceDurable === true || checkpointOptions?.awaitDurable === true) {
|
|
17254
17958
|
await pending;
|
|
@@ -17588,7 +18292,7 @@ class EngineRuntime {
|
|
|
17588
18292
|
// dist/builtin/workflows/src/engine/workflow-activity.ts
|
|
17589
18293
|
import { runCallback as runCallback4 } from "@bastani/atomic";
|
|
17590
18294
|
function nextEventLoopTurn() {
|
|
17591
|
-
return new Promise((
|
|
18295
|
+
return new Promise((resolve) => setTimeout(resolve, 0));
|
|
17592
18296
|
}
|
|
17593
18297
|
function runWorkflowDefinitionCallback(name, runId, callback) {
|
|
17594
18298
|
return runCallback4({ kind: "workflow.run", name, runId }, callback);
|
|
@@ -17616,7 +18320,7 @@ async function run(def, inputs, opts = {}) {
|
|
|
17616
18320
|
}
|
|
17617
18321
|
const resolvedInputs = resolveAndValidateInputs(def.inputs, inputs, `workflow "${def.name}"`);
|
|
17618
18322
|
const runId = opts.runId ?? crypto.randomUUID();
|
|
17619
|
-
const declaresBudget = (
|
|
18323
|
+
const declaresBudget = (budget) => (budget?.maxDurationMs ?? 0) > 0 || (budget?.maxTokens ?? 0) > 0 || (budget?.maxCost ?? 0) > 0;
|
|
17620
18324
|
const hasBudgetDeclaration = declaresBudget(opts.budget) || declaresBudget(def.budget) || declaresBudget(opts.config?.budget);
|
|
17621
18325
|
const priorRun = hasBudgetDeclaration && opts.rootBudget === undefined && opts.continuation === undefined && opts.runId !== undefined ? activeStore.runs().find((candidate) => candidate.id === runId) : undefined;
|
|
17622
18326
|
const continuedBudget = opts.continuation?.source.budget ?? priorRun?.budget;
|
|
@@ -17629,21 +18333,17 @@ async function run(def, inputs, opts = {}) {
|
|
|
17629
18333
|
terminalEvents.selectCancellation(ownController.signal.reason);
|
|
17630
18334
|
}, { once: true });
|
|
17631
18335
|
const callerSignal = opts.signal;
|
|
17632
|
-
|
|
17633
|
-
|
|
17634
|
-
|
|
17635
|
-
|
|
17636
|
-
callerSignal.addEventListener("abort", () => {
|
|
17637
|
-
ownController.abort(callerSignal.reason);
|
|
17638
|
-
}, { once: true });
|
|
17639
|
-
}
|
|
18336
|
+
const onCallerAbort = () => {
|
|
18337
|
+
workflowObservationRuntime(activeStore).control(runId, "kill");
|
|
18338
|
+
ownController.abort(callerSignal?.reason);
|
|
18339
|
+
};
|
|
17640
18340
|
const exit = createWorkflowExitManager({ runId, exitScope, controller: ownController });
|
|
17641
18341
|
const backendView = opts.durableBackend ?? getDurableBackend();
|
|
17642
18342
|
const rootBackend = opts.durableRootBackend ?? backendView;
|
|
17643
18343
|
const durableBackend = opts.durableScope !== undefined ? new ScopedDurableBackend(backendView, opts.durableScope) : backendView;
|
|
17644
18344
|
const inheritedElapsedMs = opts.parentRun === undefined ? inheritedRunElapsedMs({ backend: durableBackend, runId, continuationSource: opts.continuation?.source }) : undefined;
|
|
17645
18345
|
const continuationOrigin = opts.continuation !== undefined ? opts.continuation.source.origin : opts.origin;
|
|
17646
|
-
const snapshotField = (
|
|
18346
|
+
const snapshotField = (field) => resolvedBudget[field] > 0 || opts.budget?.[field] !== undefined || def.budget?.[field] !== undefined ? resolvedBudget[field] : undefined;
|
|
17647
18347
|
const budgetSnapshot = resolvedBudget.maxDurationMs > 0 || resolvedBudget.maxTokens > 0 || resolvedBudget.maxCost > 0 ? {
|
|
17648
18348
|
maxDurationMs: resolvedBudget.maxDurationMs,
|
|
17649
18349
|
...snapshotField("maxTokens") !== undefined ? { maxTokens: snapshotField("maxTokens") } : {},
|
|
@@ -17652,7 +18352,7 @@ async function run(def, inputs, opts = {}) {
|
|
|
17652
18352
|
} : undefined;
|
|
17653
18353
|
const durableAccounting = hasBudgetDeclaration && opts.parentRun === undefined && opts.continuation === undefined && priorRun === undefined ? priorRunAccounting(durableBackend, runId) : undefined;
|
|
17654
18354
|
const continuedBudgetState = opts.continuation?.source.budgetState ?? priorRun?.budgetState ?? (durableAccounting === undefined ? undefined : { accounting: durableAccounting });
|
|
17655
|
-
const sameBudget = budgetSnapshot !== undefined && continuedBudget?.warnAtPercent === budgetSnapshot.warnAtPercent && ["maxDurationMs", "maxTokens", "maxCost"].every((
|
|
18355
|
+
const sameBudget = budgetSnapshot !== undefined && continuedBudget?.warnAtPercent === budgetSnapshot.warnAtPercent && ["maxDurationMs", "maxTokens", "maxCost"].every((field) => (continuedBudget?.[field] ?? 0) === (budgetSnapshot[field] ?? 0));
|
|
17656
18356
|
const continuationBudgetState = continuedBudgetState === undefined || !sameBudget && continuedBudgetState.accounting === undefined ? undefined : sameBudget ? continuedBudgetState : { accounting: continuedBudgetState.accounting };
|
|
17657
18357
|
const continuationSourceRunId = opts.continuation?.source.id;
|
|
17658
18358
|
const persistedPossibleStages = coercePossibleStages(opts.possibleStages) ?? (continuationSourceRunId !== undefined ? coercePossibleStages(rootBackend.getWorkflow(continuationSourceRunId)?.possibleStages) : undefined);
|
|
@@ -17694,9 +18394,9 @@ async function run(def, inputs, opts = {}) {
|
|
|
17694
18394
|
children.push(snapshot);
|
|
17695
18395
|
childrenByParent.set(snapshot.parentRunId, children);
|
|
17696
18396
|
}
|
|
17697
|
-
const build = (
|
|
17698
|
-
const children = (childrenByParent.get(
|
|
17699
|
-
return children.length === 0 ? { run
|
|
18397
|
+
const build = (run) => {
|
|
18398
|
+
const children = (childrenByParent.get(run.id) ?? []).map(build);
|
|
18399
|
+
return children.length === 0 ? { run } : { run, children };
|
|
17700
18400
|
};
|
|
17701
18401
|
return build(snapshots.find((snapshot) => snapshot.id === runSnapshot.id) ?? runSnapshot);
|
|
17702
18402
|
};
|
|
@@ -17730,28 +18430,7 @@ async function run(def, inputs, opts = {}) {
|
|
|
17730
18430
|
classifiedFailures.set(error, classified);
|
|
17731
18431
|
return classified;
|
|
17732
18432
|
};
|
|
17733
|
-
activeStore.recordRunStart(runSnapshot);
|
|
17734
18433
|
const ownsCancellationRegistration = opts.signal === undefined && opts.cancellation !== undefined;
|
|
17735
|
-
if (ownsCancellationRegistration)
|
|
17736
|
-
opts.cancellation?.register(runId, ownController);
|
|
17737
|
-
opts.onRunStart?.(runSnapshot);
|
|
17738
|
-
if (opts.persistence) {
|
|
17739
|
-
appendRunStart(opts.persistence, {
|
|
17740
|
-
runId,
|
|
17741
|
-
name: def.name,
|
|
17742
|
-
inputs: resolvedInputs,
|
|
17743
|
-
...runSnapshot.parentRunId !== undefined ? { parentRunId: runSnapshot.parentRunId } : {},
|
|
17744
|
-
...runSnapshot.parentStageId !== undefined ? { parentStageId: runSnapshot.parentStageId } : {},
|
|
17745
|
-
...runSnapshot.rootRunId !== undefined ? { rootRunId: runSnapshot.rootRunId } : {},
|
|
17746
|
-
...runSnapshot.resumedFromRunId !== undefined ? { resumedFromRunId: runSnapshot.resumedFromRunId } : {},
|
|
17747
|
-
...runSnapshot.origin !== undefined ? { origin: runSnapshot.origin } : {},
|
|
17748
|
-
...runSnapshot.resumeFromStageId !== undefined ? { resumeFromStageId: runSnapshot.resumeFromStageId } : {},
|
|
17749
|
-
...runSnapshot.accumulatedDurationMs !== undefined ? { accumulatedDurationMs: runSnapshot.accumulatedDurationMs } : {},
|
|
17750
|
-
...runSnapshot.budget !== undefined ? { budget: runSnapshot.budget } : {},
|
|
17751
|
-
...runSnapshot.budgetState !== undefined ? { budgetState: runSnapshot.budgetState } : {},
|
|
17752
|
-
ts: runSnapshot.startedAt
|
|
17753
|
-
});
|
|
17754
|
-
}
|
|
17755
18434
|
const tracker = new GraphFrontierTracker;
|
|
17756
18435
|
const inputConcurrency = resolveInputConcurrency(def.inputs, resolvedInputs);
|
|
17757
18436
|
const inputRuntimeDefaults = resolveInputRuntimeDefaults(def, resolvedInputs), gitWorktreeSetupCacheOwner = createGitWorktreeSetupCacheOwner(opts.gitWorktreeSetupCache);
|
|
@@ -17773,6 +18452,17 @@ async function run(def, inputs, opts = {}) {
|
|
|
17773
18452
|
tracker,
|
|
17774
18453
|
stageRegistry: () => stageRegistry
|
|
17775
18454
|
});
|
|
18455
|
+
const waitForRunRelease = async () => {
|
|
18456
|
+
await scheduler.waitForRunRelease();
|
|
18457
|
+
ownController.signal.throwIfAborted();
|
|
18458
|
+
};
|
|
18459
|
+
const whenRunning = (call) => {
|
|
18460
|
+
if (scheduler.isRunPaused())
|
|
18461
|
+
return waitForRunRelease().then(() => whenRunning(call));
|
|
18462
|
+
if (ownController.signal.aborted)
|
|
18463
|
+
return Promise.reject(ownController.signal.reason);
|
|
18464
|
+
return call();
|
|
18465
|
+
};
|
|
17776
18466
|
ownController.signal.addEventListener("abort", () => scheduler.rejectReleaseBarriers(ownController.signal.reason ?? new Error("atomic-workflows: run aborted")), { once: true });
|
|
17777
18467
|
const finalizers = createRunFinalizers({
|
|
17778
18468
|
def,
|
|
@@ -17901,7 +18591,7 @@ async function run(def, inputs, opts = {}) {
|
|
|
17901
18591
|
};
|
|
17902
18592
|
const taskRunners = createWorkflowTaskRunners({ runtime });
|
|
17903
18593
|
let pendingChildDurableInvocation;
|
|
17904
|
-
const
|
|
18594
|
+
const workflow = createChildWorkflowRunner({
|
|
17905
18595
|
runtime,
|
|
17906
18596
|
resolveWorkflowCwd,
|
|
17907
18597
|
nextWorkflowBoundaryReplayKey,
|
|
@@ -17974,6 +18664,10 @@ async function run(def, inputs, opts = {}) {
|
|
|
17974
18664
|
workflowId: runId,
|
|
17975
18665
|
backend: durableBackend,
|
|
17976
18666
|
nextCheckpointId: checkpointIdGenerator,
|
|
18667
|
+
beforeCall: () => {
|
|
18668
|
+
ownController.signal.throwIfAborted();
|
|
18669
|
+
return scheduler.isRunPaused() ? waitForRunRelease() : undefined;
|
|
18670
|
+
},
|
|
17977
18671
|
...opts.usePromptNodesForUi === true ? {
|
|
17978
18672
|
onReplay: async (request) => getPromptNodeUi().replayDurable(request)
|
|
17979
18673
|
} : {}
|
|
@@ -17987,6 +18681,10 @@ async function run(def, inputs, opts = {}) {
|
|
|
17987
18681
|
completedStageReplayKeys,
|
|
17988
18682
|
sourceToReplayedNodeIds: sourceToContinuationNodeIds
|
|
17989
18683
|
});
|
|
18684
|
+
const recordCachedStage = (...args) => {
|
|
18685
|
+
ownController.signal.throwIfAborted();
|
|
18686
|
+
cachedStage.record(...args);
|
|
18687
|
+
};
|
|
17990
18688
|
const durableIntercomGroup = (replayKey, stageId) => {
|
|
17991
18689
|
const stages = activeStore.runs().find((candidate) => candidate.id === runId)?.stages ?? [];
|
|
17992
18690
|
return stages.find((stage) => stageId !== undefined && stage.id === stageId || stage.replayKey === replayKey)?.intercomGroup;
|
|
@@ -17998,7 +18696,7 @@ async function run(def, inputs, opts = {}) {
|
|
|
17998
18696
|
nextReplayKey: (stageName) => stageReplayKeyGenerator(stageName),
|
|
17999
18697
|
durableIntercomGroup,
|
|
18000
18698
|
task: taskRunners.task,
|
|
18001
|
-
recordCachedTask:
|
|
18699
|
+
recordCachedTask: recordCachedStage,
|
|
18002
18700
|
signal: ownController.signal,
|
|
18003
18701
|
registerTailControl: (registration) => {
|
|
18004
18702
|
registration.controller.signal.addEventListener("abort", () => {
|
|
@@ -18024,60 +18722,153 @@ async function run(def, inputs, opts = {}) {
|
|
|
18024
18722
|
setChildDurableInvocation: (invocation) => {
|
|
18025
18723
|
pendingChildDurableInvocation = invocation;
|
|
18026
18724
|
},
|
|
18027
|
-
recordCachedStage
|
|
18725
|
+
recordCachedStage,
|
|
18028
18726
|
runTopology: durableRunTopology(runSnapshot),
|
|
18029
|
-
workflow
|
|
18727
|
+
workflow
|
|
18728
|
+
});
|
|
18729
|
+
const pendingChildWorkflows = new Set;
|
|
18730
|
+
const durableStage = createDurableStagePrimitive({
|
|
18731
|
+
workflowId: runId,
|
|
18732
|
+
backend: durableBackend,
|
|
18733
|
+
nextReplayKey: (stageName) => stageReplayKeyGenerator(stageName),
|
|
18734
|
+
durableIntercomGroup,
|
|
18735
|
+
recordCachedStage,
|
|
18736
|
+
stage: (name, options, replayKey) => {
|
|
18737
|
+
const stage = runtime.stage(name, options);
|
|
18738
|
+
const stageId = activeStore.runs().find((r) => r.id === runId)?.stages.at(-1)?.id;
|
|
18739
|
+
if (stageId !== undefined)
|
|
18740
|
+
completedStageReplayKeys.set(stageId, replayKey);
|
|
18741
|
+
return stage;
|
|
18742
|
+
}
|
|
18030
18743
|
});
|
|
18744
|
+
const gatedTask = (...args) => whenRunning(() => durableTask(...args));
|
|
18745
|
+
const chain = createChainPrimitive({ runtime, task: gatedTask });
|
|
18746
|
+
const parallel = createParallelPrimitive({ runtime, task: gatedTask });
|
|
18747
|
+
const ui = buildExitGatedUiContext({
|
|
18748
|
+
opts,
|
|
18749
|
+
throwIfWorkflowExitSelected: exit.throwIfWorkflowExitSelected,
|
|
18750
|
+
durableUi: durableUiDeps,
|
|
18751
|
+
baseFromPromptNodes: getPromptNodeUi
|
|
18752
|
+
});
|
|
18753
|
+
let pausedExit;
|
|
18031
18754
|
const ctx = {
|
|
18032
18755
|
inputs: resolvedInputs,
|
|
18033
18756
|
runId,
|
|
18034
18757
|
get cwd() {
|
|
18035
18758
|
return resolveWorkflowCwd();
|
|
18036
18759
|
},
|
|
18037
|
-
exit:
|
|
18038
|
-
|
|
18039
|
-
|
|
18040
|
-
|
|
18041
|
-
|
|
18042
|
-
baseFromPromptNodes: getPromptNodeUi
|
|
18043
|
-
}),
|
|
18044
|
-
stage: createDurableStagePrimitive({
|
|
18045
|
-
workflowId: runId,
|
|
18046
|
-
backend: durableBackend,
|
|
18047
|
-
nextReplayKey: (stageName) => stageReplayKeyGenerator(stageName),
|
|
18048
|
-
durableIntercomGroup,
|
|
18049
|
-
recordCachedStage: cachedStage.record,
|
|
18050
|
-
stage: (name, options, replayKey) => {
|
|
18051
|
-
const stage = runtime.stage(name, options);
|
|
18052
|
-
const stageId = activeStore.runs().find((r) => r.id === runId)?.stages.at(-1)?.id;
|
|
18053
|
-
if (stageId !== undefined)
|
|
18054
|
-
completedStageReplayKeys.set(stageId, replayKey);
|
|
18055
|
-
return stage;
|
|
18760
|
+
exit: (options) => {
|
|
18761
|
+
if (scheduler.isRunPaused()) {
|
|
18762
|
+
pausedExit ??= whenRunning(async () => exit.exit(options));
|
|
18763
|
+
pausedExit.catch(() => {});
|
|
18764
|
+
throw new Error("Workflow exit is waiting for explicit resume");
|
|
18056
18765
|
}
|
|
18766
|
+
return exit.exit(options);
|
|
18767
|
+
},
|
|
18768
|
+
ui,
|
|
18769
|
+
stage: (name, options) => {
|
|
18770
|
+
ownController.signal.throwIfAborted();
|
|
18771
|
+
if (!scheduler.isRunPaused())
|
|
18772
|
+
return durableStage(name, options);
|
|
18773
|
+
const replayKey = stageReplayKeyGenerator(name);
|
|
18774
|
+
return deferStageUntilRunRelease({
|
|
18775
|
+
name,
|
|
18776
|
+
create: () => durableStage(name, options, replayKey),
|
|
18777
|
+
isPaused: scheduler.isRunPaused,
|
|
18778
|
+
waitForRelease: waitForRunRelease,
|
|
18779
|
+
signal: ownController.signal
|
|
18780
|
+
});
|
|
18781
|
+
},
|
|
18782
|
+
task: gatedTask,
|
|
18783
|
+
chain: (...args) => whenRunning(() => chain(...args)),
|
|
18784
|
+
parallel: (...args) => whenRunning(() => parallel(...args)),
|
|
18785
|
+
workflow: (...args) => whenRunning(() => {
|
|
18786
|
+
const pending = durableWorkflow(...args);
|
|
18787
|
+
pendingChildWorkflows.add(pending);
|
|
18788
|
+
const settled = () => {
|
|
18789
|
+
pendingChildWorkflows.delete(pending);
|
|
18790
|
+
};
|
|
18791
|
+
pending.then(settled, settled);
|
|
18792
|
+
return pending;
|
|
18057
18793
|
}),
|
|
18058
|
-
|
|
18059
|
-
|
|
18060
|
-
|
|
18061
|
-
|
|
18062
|
-
|
|
18794
|
+
tool: (...args) => {
|
|
18795
|
+
if (!scheduler.isRunPaused())
|
|
18796
|
+
return tool(...args);
|
|
18797
|
+
const pending = whenRunning(() => tool(...args));
|
|
18798
|
+
pending.catch(() => {});
|
|
18799
|
+
return pending;
|
|
18800
|
+
},
|
|
18063
18801
|
...opts.models !== undefined ? { models: opts.models } : {}
|
|
18064
18802
|
};
|
|
18803
|
+
const runtimeSettled = Promise.withResolvers();
|
|
18804
|
+
let pausePersistence;
|
|
18805
|
+
const persistRunControl = async (status) => {
|
|
18806
|
+
ownController.signal.throwIfAborted();
|
|
18807
|
+
if (opts.parentRun !== undefined || durableBackend.getWorkflow(runId) === undefined)
|
|
18808
|
+
return;
|
|
18809
|
+
if (!await transitionDurableWorkflowStatus(durableBackend, runId, ["running", "paused"], status, undefined, true)) {
|
|
18810
|
+
throw new Error(`Workflow ${runId} refused the durable ${status} transition`);
|
|
18811
|
+
}
|
|
18812
|
+
recordRunTimingCheckpoint(durableBackend, runSnapshot);
|
|
18813
|
+
await durableBackend.flush(runId);
|
|
18814
|
+
};
|
|
18815
|
+
const unregisterRunControl = toolControls.registerRun(runId, {
|
|
18816
|
+
get paused() {
|
|
18817
|
+
return scheduler.isRunPaused();
|
|
18818
|
+
},
|
|
18819
|
+
pause: () => {
|
|
18820
|
+
ownController.signal.throwIfAborted();
|
|
18821
|
+
scheduler.pauseRun();
|
|
18822
|
+
activeStore.recordRunPaused(runId, undefined, { resumable: true });
|
|
18823
|
+
pausePersistence = persistRunControl("paused");
|
|
18824
|
+
return pausePersistence;
|
|
18825
|
+
},
|
|
18826
|
+
resume: async () => {
|
|
18827
|
+
await pausePersistence;
|
|
18828
|
+
await persistRunControl("running");
|
|
18829
|
+
ownController.signal.throwIfAborted();
|
|
18830
|
+
activeStore.recordRunResumed(runId, undefined, { source: "run_control" });
|
|
18831
|
+
scheduler.releaseRun();
|
|
18832
|
+
},
|
|
18833
|
+
quit: () => {
|
|
18834
|
+
ownController.abort(new WorkflowGracefulQuitError(runId, "workflow runtime"));
|
|
18835
|
+
return runtimeSettled.promise;
|
|
18836
|
+
}
|
|
18837
|
+
});
|
|
18065
18838
|
terminalEvents.register();
|
|
18066
18839
|
try {
|
|
18067
|
-
|
|
18068
|
-
|
|
18069
|
-
|
|
18070
|
-
|
|
18071
|
-
|
|
18072
|
-
|
|
18073
|
-
|
|
18074
|
-
|
|
18075
|
-
|
|
18076
|
-
|
|
18077
|
-
|
|
18078
|
-
|
|
18840
|
+
workflowObservationRuntime(activeStore).startRun(runId);
|
|
18841
|
+
activeStore.recordRunStart(runSnapshot);
|
|
18842
|
+
if (callerSignal?.aborted)
|
|
18843
|
+
onCallerAbort();
|
|
18844
|
+
else
|
|
18845
|
+
callerSignal?.addEventListener("abort", onCallerAbort, { once: true });
|
|
18846
|
+
if (ownsCancellationRegistration)
|
|
18847
|
+
opts.cancellation?.register(runId, ownController);
|
|
18848
|
+
opts.onRunStart?.(runSnapshot);
|
|
18849
|
+
if (opts.persistence) {
|
|
18850
|
+
appendRunStart(opts.persistence, {
|
|
18851
|
+
runId,
|
|
18852
|
+
name: def.name,
|
|
18853
|
+
inputs: resolvedInputs,
|
|
18854
|
+
...runSnapshot.parentRunId !== undefined ? { parentRunId: runSnapshot.parentRunId } : {},
|
|
18855
|
+
...runSnapshot.parentStageId !== undefined ? { parentStageId: runSnapshot.parentStageId } : {},
|
|
18856
|
+
...runSnapshot.rootRunId !== undefined ? { rootRunId: runSnapshot.rootRunId } : {},
|
|
18857
|
+
...runSnapshot.resumedFromRunId !== undefined ? { resumedFromRunId: runSnapshot.resumedFromRunId } : {},
|
|
18858
|
+
...runSnapshot.origin !== undefined ? { origin: runSnapshot.origin } : {},
|
|
18859
|
+
...runSnapshot.resumeFromStageId !== undefined ? { resumeFromStageId: runSnapshot.resumeFromStageId } : {},
|
|
18860
|
+
...runSnapshot.accumulatedDurationMs !== undefined ? { accumulatedDurationMs: runSnapshot.accumulatedDurationMs } : {},
|
|
18861
|
+
...runSnapshot.budget !== undefined ? { budget: runSnapshot.budget } : {},
|
|
18862
|
+
...runSnapshot.budgetState !== undefined ? { budgetState: runSnapshot.budgetState } : {},
|
|
18863
|
+
ts: runSnapshot.startedAt
|
|
18864
|
+
});
|
|
18079
18865
|
}
|
|
18080
|
-
|
|
18866
|
+
if (opts.deferWorkflowStart === true)
|
|
18867
|
+
await raceAbort2(nextEventLoopTurn(), ownController.signal);
|
|
18868
|
+
while (scheduler.isRunPaused())
|
|
18869
|
+
await waitForRunRelease();
|
|
18870
|
+
ownController.signal.throwIfAborted();
|
|
18871
|
+
await raceAbort2(admitDurableRootRun({
|
|
18081
18872
|
backend: durableBackend,
|
|
18082
18873
|
runId,
|
|
18083
18874
|
isChildRun: opts.parentRun !== undefined,
|
|
@@ -18085,7 +18876,10 @@ async function run(def, inputs, opts = {}) {
|
|
|
18085
18876
|
...durableRootRegistration,
|
|
18086
18877
|
...workflowInvocationMetadata(inputRuntimeDefaults, workflowInvocationCwd, gitWorktreeSetupCache, runSnapshot.origin)
|
|
18087
18878
|
}
|
|
18088
|
-
});
|
|
18879
|
+
}), ownController.signal);
|
|
18880
|
+
while (scheduler.isRunPaused())
|
|
18881
|
+
await waitForRunRelease();
|
|
18882
|
+
ownController.signal.throwIfAborted();
|
|
18089
18883
|
if (opts.deferWorkflowStart === true)
|
|
18090
18884
|
opts.onWorkflowStartReady?.();
|
|
18091
18885
|
const sourceFrontierStage = opts.continuation?.source;
|
|
@@ -18093,8 +18887,17 @@ async function run(def, inputs, opts = {}) {
|
|
|
18093
18887
|
const startupFrontierStage = sourceFrontierStage?.stages.find((stage) => stage.id === sourceFrontierId)?.name ?? "workflow frontier";
|
|
18094
18888
|
if (budget.enabled)
|
|
18095
18889
|
await budget.stopAtBoundaryAsync(startupFrontierStage);
|
|
18096
|
-
|
|
18890
|
+
while (scheduler.isRunPaused())
|
|
18891
|
+
await waitForRunRelease();
|
|
18892
|
+
ownController.signal.throwIfAborted();
|
|
18893
|
+
const rawResult = await raceAbort2(runWorkflowDefinitionCallback(def.name, runId, () => def.run(ctx)), ownController.signal);
|
|
18894
|
+
while (scheduler.isRunPaused())
|
|
18895
|
+
await waitForRunRelease();
|
|
18097
18896
|
await admittedTools.closeAndDrain();
|
|
18897
|
+
while (scheduler.isRunPaused())
|
|
18898
|
+
await waitForRunRelease();
|
|
18899
|
+
if (pausedExit !== undefined)
|
|
18900
|
+
await pausedExit;
|
|
18098
18901
|
budget.rethrowIfSystemOwnedStop(runSnapshot.stages.at(-1)?.name ?? startupFrontierStage);
|
|
18099
18902
|
const normalTerminalEvent = terminalEvents.winner();
|
|
18100
18903
|
if (normalTerminalEvent?.kind === "cancellation") {
|
|
@@ -18115,7 +18918,10 @@ async function run(def, inputs, opts = {}) {
|
|
|
18115
18918
|
const result = normalizeWorkflowRunOutput(def.name, rawResult);
|
|
18116
18919
|
assertWorkflowRunOutputs(def.name, result, def.outputs);
|
|
18117
18920
|
assertWorkflowCreatedExecution(runSnapshot);
|
|
18118
|
-
await durableBackend.flush(runId);
|
|
18921
|
+
await raceAbort2(durableBackend.flush(runId), ownController.signal);
|
|
18922
|
+
while (scheduler.isRunPaused())
|
|
18923
|
+
await waitForRunRelease();
|
|
18924
|
+
ownController.signal.throwIfAborted();
|
|
18119
18925
|
const returned = classifyReturnedRunStatus(result, runSnapshot);
|
|
18120
18926
|
if (returned.status === "completed")
|
|
18121
18927
|
assertFrontierConsumed();
|
|
@@ -18135,12 +18941,26 @@ async function run(def, inputs, opts = {}) {
|
|
|
18135
18941
|
durableBackend.setWorkflowStatus(runId, returned.status, undefined, returned.metadata?.resumable);
|
|
18136
18942
|
await durableBackend.flush(runId);
|
|
18137
18943
|
return reconcileTerminalRunResult(runId, runSnapshot, activeStore, { status: returned.status, result, error: returned.error }, opts.onRunEnd);
|
|
18138
|
-
} catch (
|
|
18139
|
-
|
|
18944
|
+
} catch (error) {
|
|
18945
|
+
let err = error;
|
|
18946
|
+
try {
|
|
18947
|
+
while (scheduler.isRunPaused())
|
|
18948
|
+
await waitForRunRelease();
|
|
18949
|
+
if (pausedExit !== undefined)
|
|
18950
|
+
await pausedExit;
|
|
18951
|
+
} catch (stop) {
|
|
18952
|
+
err = stop;
|
|
18953
|
+
}
|
|
18954
|
+
const selectedTerminalEvent = terminalEvents.selectFailure(err);
|
|
18955
|
+
if (selectedTerminalEvent.kind === "failure" && ownController.signal.aborted && Object.is(err, ownController.signal.reason)) {
|
|
18956
|
+
err = selectedTerminalEvent.error;
|
|
18957
|
+
}
|
|
18140
18958
|
const gracefulQuit = observedQuitCancellation() ?? observedTaskTailQuit ?? findWorkflowGracefulQuit(err) ?? findWorkflowGracefulQuit(ownController.signal.reason);
|
|
18141
18959
|
if (gracefulQuit !== undefined)
|
|
18142
18960
|
return suspendForGracefulQuit(gracefulQuit);
|
|
18143
18961
|
await admittedTools.closeAndDrain();
|
|
18962
|
+
if (ownController.signal.aborted)
|
|
18963
|
+
await Promise.allSettled([...pendingChildWorkflows]);
|
|
18144
18964
|
if (err instanceof WorkflowBudgetExceededError) {
|
|
18145
18965
|
const pendingBudgetError = await budget.awaitPendingWrapUp();
|
|
18146
18966
|
const selectedBudgetError = pendingBudgetError ?? err;
|
|
@@ -18173,15 +18993,15 @@ async function run(def, inputs, opts = {}) {
|
|
|
18173
18993
|
return await finalizers.finalizeParentWorkflowExitCancellation(parentExit);
|
|
18174
18994
|
return finalizeKilled(runId, runSnapshot, activeStore, opts.persistence, opts.onRunEnd);
|
|
18175
18995
|
}
|
|
18176
|
-
const
|
|
18177
|
-
const
|
|
18178
|
-
outerFailure:
|
|
18996
|
+
const failure = classifyExecutorFailure(err);
|
|
18997
|
+
const selectedMetadata = normalizeFailureWinnerMetadata(normalizeStageLessFailureMetadata(selectRunFailureDisposition({
|
|
18998
|
+
outerFailure: failure,
|
|
18179
18999
|
thrownError: err,
|
|
18180
19000
|
stages: runSnapshot.stages,
|
|
18181
19001
|
classifyFailure: classifyExecutorFailure
|
|
18182
19002
|
}), runSnapshot.stages.length));
|
|
18183
|
-
const failedToolNodeId =
|
|
18184
|
-
const metadata = failedToolNodeId === undefined ?
|
|
19003
|
+
const failedToolNodeId = selectedMetadata.failedStageId === undefined && selectedMetadata.failureDisposition !== "terminal_killed" ? catchTerminalEvent?.kind === "failure" && Object.is(catchTerminalEvent.error, err) ? catchTerminalEvent.nodeId ?? observedAdmittedToolFailure?.nodeId : observedAdmittedToolFailure?.nodeId : undefined;
|
|
19004
|
+
const metadata = failedToolNodeId === undefined ? selectedMetadata : { ...selectedMetadata, failedToolNodeId };
|
|
18185
19005
|
if (metadata.failureDisposition === "terminal_killed") {
|
|
18186
19006
|
for (const failedStageId of metadata.failedStageIds)
|
|
18187
19007
|
scheduler.blockKnownNonTerminalDescendants(failedStageId);
|
|
@@ -18209,6 +19029,10 @@ async function run(def, inputs, opts = {}) {
|
|
|
18209
19029
|
onRunEnd: opts.onRunEnd
|
|
18210
19030
|
});
|
|
18211
19031
|
} finally {
|
|
19032
|
+
callerSignal?.removeEventListener("abort", onCallerAbort);
|
|
19033
|
+
workflowObservationRuntime(activeStore).finishRun(runId);
|
|
19034
|
+
runtimeSettled.resolve();
|
|
19035
|
+
unregisterRunControl();
|
|
18212
19036
|
try {
|
|
18213
19037
|
await finalizeDurableTerminalStatus({
|
|
18214
19038
|
runId,
|
|
@@ -18246,45 +19070,45 @@ var NON_INTERACTIVE_WORKFLOW_POLICY = Object.freeze({
|
|
|
18246
19070
|
allowInputPicker: false
|
|
18247
19071
|
});
|
|
18248
19072
|
// dist/builtin/workflows/src/workflows/registry.ts
|
|
18249
|
-
function makeRegistry(
|
|
19073
|
+
function makeRegistry(store) {
|
|
18250
19074
|
return {
|
|
18251
19075
|
register(definition) {
|
|
18252
|
-
const next = new Map(
|
|
19076
|
+
const next = new Map(store);
|
|
18253
19077
|
next.set(definition.normalizedName, definition);
|
|
18254
19078
|
return makeRegistry(next);
|
|
18255
19079
|
},
|
|
18256
19080
|
merge(other) {
|
|
18257
|
-
const next = new Map(
|
|
19081
|
+
const next = new Map(store);
|
|
18258
19082
|
for (const def of other.all()) {
|
|
18259
19083
|
next.set(def.normalizedName, def);
|
|
18260
19084
|
}
|
|
18261
19085
|
return makeRegistry(next);
|
|
18262
19086
|
},
|
|
18263
19087
|
get(name) {
|
|
18264
|
-
return
|
|
19088
|
+
return store.get(normalizeWorkflowName(name));
|
|
18265
19089
|
},
|
|
18266
19090
|
has(name) {
|
|
18267
|
-
return
|
|
19091
|
+
return store.has(normalizeWorkflowName(name));
|
|
18268
19092
|
},
|
|
18269
19093
|
remove(name) {
|
|
18270
|
-
const
|
|
18271
|
-
if (!
|
|
19094
|
+
const key = normalizeWorkflowName(name);
|
|
19095
|
+
if (!store.has(key))
|
|
18272
19096
|
return this;
|
|
18273
|
-
const next = new Map(
|
|
18274
|
-
next.delete(
|
|
19097
|
+
const next = new Map(store);
|
|
19098
|
+
next.delete(key);
|
|
18275
19099
|
return makeRegistry(next);
|
|
18276
19100
|
},
|
|
18277
19101
|
names() {
|
|
18278
|
-
return [...
|
|
19102
|
+
return [...store.keys()];
|
|
18279
19103
|
},
|
|
18280
19104
|
all() {
|
|
18281
|
-
return [...
|
|
19105
|
+
return [...store.values()];
|
|
18282
19106
|
}
|
|
18283
19107
|
};
|
|
18284
19108
|
}
|
|
18285
19109
|
function createRegistry(initial = []) {
|
|
18286
|
-
const
|
|
18287
|
-
return makeRegistry(
|
|
19110
|
+
const store = new Map(initial.map((d) => [d.normalizedName, d]));
|
|
19111
|
+
return makeRegistry(store);
|
|
18288
19112
|
}
|
|
18289
19113
|
|
|
18290
19114
|
// dist/builtin/workflows/src/sdk-surface.ts
|