@bastani/atomic 0.9.18 → 0.9.19-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +100 -0
- package/dist/builtin/intercom/CHANGELOG.md +16 -0
- package/dist/builtin/intercom/README.md +21 -11
- package/dist/builtin/intercom/broker/broker.ts +73 -9
- package/dist/builtin/intercom/broker/client.ts +4 -0
- 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 +34 -5
- package/dist/builtin/intercom/broker/terminal-questions.ts +29 -0
- package/dist/builtin/intercom/index.bundle.mjs +936 -740
- 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 +5 -4
- package/dist/builtin/intercom/types.ts +16 -2
- 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 +27 -0
- package/dist/builtin/subagents/README.md +33 -12
- 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 +1 -1
- 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 +1 -1
- 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 +14 -10
- package/dist/builtin/subagents/skills/tmux/SKILL.md +1 -1
- package/dist/builtin/subagents/src/extension/index.bundle.mjs +1284 -609
- package/dist/builtin/web-access/index.bundle.mjs +26280 -26274
- package/dist/builtin/web-access/package.json +2 -2
- package/dist/builtin/workflows/CHANGELOG.md +48 -0
- package/dist/builtin/workflows/README.md +1 -1
- package/dist/builtin/workflows/builtin/adversarial-verification.js +5 -7
- package/dist/builtin/workflows/builtin/{chunk-reqr3sr3.js → chunk-1kx4aggw.js} +22 -22
- package/dist/builtin/workflows/builtin/{chunk-42s7sw0b.js → chunk-62v3gg9f.js} +9 -9
- 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-79fjkcvh.js → chunk-hbnwv56f.js} +17 -17
- package/dist/builtin/workflows/builtin/{chunk-ed4jfn5t.js → chunk-mygmtz6e.js} +43 -43
- package/dist/builtin/workflows/builtin/{chunk-7430zyas.js → chunk-p8jjwfg6.js} +1 -1
- package/dist/builtin/workflows/builtin/{chunk-hqpe2cyx.js → chunk-r9qq7xfj.js} +49 -49
- package/dist/builtin/workflows/builtin/{chunk-k3w87x8y.js → chunk-t6x2d78s.js} +10 -10
- package/dist/builtin/workflows/builtin/{chunk-6fqs7c01.js → chunk-z0d03ktm.js} +1 -1
- package/dist/builtin/workflows/builtin/{chunk-b0v2xab1.js → chunk-zggjyg5z.js} +221 -23
- 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 +2 -2
- package/dist/builtin/workflows/src/extension/index.bundle.mjs +56236 -25199
- package/dist/builtin/workflows/src/index.js +1217 -547
- 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 +5 -4
- 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.map +1 -1
- package/dist/core/agent-session-custom-message-commit.d.ts +1 -1
- 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 +1 -1
- package/dist/core/agent-session-message-queue.js.map +1 -1
- package/dist/core/agent-session-methods.d.ts +14 -7
- package/dist/core/agent-session-methods.d.ts.map +1 -1
- package/dist/core/agent-session-methods.js.map +1 -1
- package/dist/core/agent-session-prompt.d.ts +2 -2
- package/dist/core/agent-session-prompt.d.ts.map +1 -1
- package/dist/core/agent-session-prompt.js +22 -18
- package/dist/core/agent-session-prompt.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 +9 -0
- package/dist/core/agent-session-tasks.d.ts.map +1 -0
- package/dist/core/agent-session-tasks.js +113 -0
- package/dist/core/agent-session-tasks.js.map +1 -0
- 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 +30 -5
- package/dist/core/agent-session-tool-registry.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 +2 -2
- package/dist/core/agent-session-types.js.map +1 -1
- package/dist/core/agent-session.d.ts +4 -1
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +7 -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 +8 -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 +9 -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 +2 -1
- 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 +7 -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-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.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/runner-context.d.ts +11 -1
- package/dist/core/extensions/runner-context.d.ts.map +1 -1
- package/dist/core/extensions/runner-context.js +41 -2
- 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-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 +68 -18
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/runtime-types.d.ts +4 -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 +5 -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/keybindings.d.ts +27 -2
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +7 -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/sdk-exports.d.ts +2 -2
- 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-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-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 +11 -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 +2 -0
- 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 +32 -0
- package/dist/core/tasks/agent-adapter.d.ts.map +1 -0
- package/dist/core/tasks/agent-adapter.js +71 -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 +115 -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/supervisor.d.ts +121 -0
- package/dist/core/tasks/supervisor.d.ts.map +1 -0
- package/dist/core/tasks/supervisor.js +916 -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 +18 -3
- package/dist/core/tools/bash-pty-native.d.ts.map +1 -1
- package/dist/core/tools/bash-pty-native.js +116 -1
- package/dist/core/tools/bash-pty-native.js.map +1 -1
- package/dist/core/tools/bash.d.ts +11 -4
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +52 -8
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +1 -2
- package/dist/core/tools/edit.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/index.d.ts +2 -2
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/ls.js.map +1 -1
- package/dist/core/tools/powershell.d.ts +20 -10
- package/dist/core/tools/powershell.d.ts.map +1 -1
- package/dist/core/tools/powershell.js +32 -7
- package/dist/core/tools/powershell.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.map +1 -1
- package/dist/core/tools/resource-selectors.js +15 -7
- 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.map +1 -1
- package/dist/core/tools/write.js +1 -2
- package/dist/core/tools/write.js.map +1 -1
- package/dist/core/workflow-stage-admission.d.ts +10 -0
- package/dist/core/workflow-stage-admission.d.ts.map +1 -1
- package/dist/core/workflow-stage-admission.js +24 -0
- 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 +11 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -0
- 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 +97 -1
- 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/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 +33 -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 +158 -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 +1 -0
- 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 +6 -1
- package/dist/modes/interactive/interactive-mode-base.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode-base.js +4 -1
- 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 +2 -1
- 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 +2 -0
- 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-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/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 +5 -9
- package/dist/modes/interactive-engine/engine-custom-ui.d.ts.map +1 -1
- package/dist/modes/interactive-engine/engine-custom-ui.js +14 -5
- package/dist/modes/interactive-engine/engine-custom-ui.js.map +1 -1
- package/dist/modes/interactive-engine/engine-dialog-host.d.ts +2 -2
- 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 +6 -0
- 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 +40 -3
- package/dist/modes/interactive-engine/isolated-runtime.js.map +1 -1
- package/dist/modes/interactive-engine/protocol.d.ts +9 -0
- package/dist/modes/interactive-engine/protocol.d.ts.map +1 -1
- package/dist/modes/interactive-engine/protocol.js +8 -0
- 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 +3 -2
- 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-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 +20 -0
- 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.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +11 -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 +13 -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/docs/background-tasks.md +199 -0
- package/docs/compaction.md +2 -0
- package/docs/development.md +3 -1
- package/docs/docs.json +2 -0
- package/docs/environment-variables.md +1 -1
- package/docs/extensions.md +108 -6
- package/docs/herdr.md +106 -0
- package/docs/intercom.md +38 -35
- package/docs/keybindings.md +19 -2
- package/docs/models/evals.md +222 -147
- package/docs/models/model-selection.md +20 -14
- package/docs/models/pareto-efficiency.md +2 -2
- package/docs/providers.md +48 -46
- package/docs/quickstart.md +2 -2
- package/docs/sdk.md +244 -0
- package/docs/settings.md +15 -3
- package/docs/skills.md +23 -1
- package/docs/subagents.md +71 -9
- package/docs/themes.md +4 -0
- package/docs/tools.md +25 -0
- package/docs/tui.md +29 -2
- package/docs/usage.md +4 -0
- package/docs/windows.md +4 -4
- package/docs/workflows/api-reference.md +13 -4
- package/docs/workflows/operations.md +59 -5
- package/docs/workflows/reliable-design.md +35 -4
- package/docs/workflows/verification.md +21 -4
- package/docs/workflows.md +3 -1
- package/npm-shrinkwrap.json +781 -661
- package/package.json +10 -10
- /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 === "interrupt") && 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 {
|
|
@@ -3265,8 +3466,8 @@ function normalizeUIContext(adapter) {
|
|
|
3265
3466
|
};
|
|
3266
3467
|
}
|
|
3267
3468
|
function stringField(value, keys) {
|
|
3268
|
-
for (const
|
|
3269
|
-
const candidate = value[
|
|
3469
|
+
for (const key of keys) {
|
|
3470
|
+
const candidate = value[key];
|
|
3270
3471
|
if (typeof candidate === "string" && candidate.length > 0)
|
|
3271
3472
|
return candidate;
|
|
3272
3473
|
}
|
|
@@ -3463,17 +3664,17 @@ function schemaIsRequired(schema) {
|
|
|
3463
3664
|
import { Value as Value2 } from "typebox/value";
|
|
3464
3665
|
function validateInputs(schema, inputs) {
|
|
3465
3666
|
const errors = [];
|
|
3466
|
-
for (const
|
|
3467
|
-
if (!(
|
|
3468
|
-
errors.push({ key
|
|
3667
|
+
for (const key of Object.keys(inputs)) {
|
|
3668
|
+
if (!(key in schema)) {
|
|
3669
|
+
errors.push({ key, reason: "unknown input key (not declared by this workflow)" });
|
|
3469
3670
|
}
|
|
3470
3671
|
}
|
|
3471
|
-
for (const [
|
|
3472
|
-
const value = inputs[
|
|
3672
|
+
for (const [key, def] of Object.entries(schema)) {
|
|
3673
|
+
const value = inputs[key];
|
|
3473
3674
|
let hasTypeError = false;
|
|
3474
3675
|
if (value === undefined) {
|
|
3475
3676
|
if (schemaIsRequired(def)) {
|
|
3476
|
-
errors.push({ key
|
|
3677
|
+
errors.push({ key, reason: "required input is missing" });
|
|
3477
3678
|
}
|
|
3478
3679
|
continue;
|
|
3479
3680
|
}
|
|
@@ -3481,25 +3682,25 @@ function validateInputs(schema, inputs) {
|
|
|
3481
3682
|
switch (kind) {
|
|
3482
3683
|
case "text":
|
|
3483
3684
|
if (typeof value !== "string") {
|
|
3484
|
-
errors.push({ key
|
|
3685
|
+
errors.push({ key, reason: `expected string, got ${workflowSerializableTypeName(value)}` });
|
|
3485
3686
|
hasTypeError = true;
|
|
3486
3687
|
}
|
|
3487
3688
|
break;
|
|
3488
3689
|
case "number":
|
|
3489
3690
|
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
3490
|
-
errors.push({ key
|
|
3691
|
+
errors.push({ key, reason: `expected finite number, got ${workflowSerializableTypeName(value)}` });
|
|
3491
3692
|
hasTypeError = true;
|
|
3492
3693
|
}
|
|
3493
3694
|
break;
|
|
3494
3695
|
case "integer":
|
|
3495
3696
|
if (typeof value !== "number" || !Number.isInteger(value)) {
|
|
3496
|
-
errors.push({ key
|
|
3697
|
+
errors.push({ key, reason: `expected integer, got ${workflowSerializableTypeName(value)}` });
|
|
3497
3698
|
hasTypeError = true;
|
|
3498
3699
|
}
|
|
3499
3700
|
break;
|
|
3500
3701
|
case "boolean":
|
|
3501
3702
|
if (typeof value !== "boolean") {
|
|
3502
|
-
errors.push({ key
|
|
3703
|
+
errors.push({ key, reason: `expected boolean, got ${workflowSerializableTypeName(value)}` });
|
|
3503
3704
|
hasTypeError = true;
|
|
3504
3705
|
}
|
|
3505
3706
|
break;
|
|
@@ -3507,24 +3708,24 @@ function validateInputs(schema, inputs) {
|
|
|
3507
3708
|
const choices = schemaChoices(def) ?? [];
|
|
3508
3709
|
const allowed = choices.join(", ");
|
|
3509
3710
|
if (typeof value !== "string") {
|
|
3510
|
-
errors.push({ key
|
|
3711
|
+
errors.push({ key, reason: `expected one of [${allowed}], got ${workflowSerializableTypeName(value)}` });
|
|
3511
3712
|
hasTypeError = true;
|
|
3512
3713
|
} else if (!choices.includes(value)) {
|
|
3513
|
-
errors.push({ key
|
|
3714
|
+
errors.push({ key, reason: `must be one of [${allowed}]` });
|
|
3514
3715
|
}
|
|
3515
3716
|
break;
|
|
3516
3717
|
}
|
|
3517
3718
|
default:
|
|
3518
3719
|
if (!Value2.Check(def, value)) {
|
|
3519
3720
|
const first = [...Value2.Errors(def, value)][0];
|
|
3520
|
-
errors.push({ key
|
|
3721
|
+
errors.push({ key, reason: first === undefined ? `does not match ${kind} schema` : first.message });
|
|
3521
3722
|
hasTypeError = true;
|
|
3522
3723
|
}
|
|
3523
3724
|
break;
|
|
3524
3725
|
}
|
|
3525
|
-
const serializableError = hasTypeError ? undefined : workflowSerializableValidationError(value, `input "${
|
|
3726
|
+
const serializableError = hasTypeError ? undefined : workflowSerializableValidationError(value, `input "${key}"`);
|
|
3526
3727
|
if (serializableError !== undefined) {
|
|
3527
|
-
errors.push({ key
|
|
3728
|
+
errors.push({ key, reason: serializableError.replace(/^input "[^"]+" /, "") });
|
|
3528
3729
|
}
|
|
3529
3730
|
}
|
|
3530
3731
|
return errors;
|
|
@@ -3533,18 +3734,19 @@ function validateInputs(schema, inputs) {
|
|
|
3533
3734
|
// dist/builtin/workflows/src/runs/foreground/executor-inputs.ts
|
|
3534
3735
|
function resolveInputs(schema, provided) {
|
|
3535
3736
|
const resolved = {};
|
|
3536
|
-
for (const [
|
|
3737
|
+
for (const [key, value] of Object.entries(provided)) {
|
|
3537
3738
|
if (value !== undefined)
|
|
3538
|
-
resolved[
|
|
3739
|
+
resolved[key] = value;
|
|
3539
3740
|
}
|
|
3540
|
-
const
|
|
3541
|
-
|
|
3741
|
+
const ownedInputs = Value3.Clone(resolved);
|
|
3742
|
+
const withDefaults = Value3.Default(Type2.Object(schema, { additionalProperties: true }), ownedInputs);
|
|
3743
|
+
for (const [key, value] of Object.entries(withDefaults)) {
|
|
3542
3744
|
if (value !== undefined)
|
|
3543
|
-
resolved[
|
|
3745
|
+
resolved[key] = value;
|
|
3544
3746
|
}
|
|
3545
|
-
for (const [
|
|
3546
|
-
if (schemaIsRequired(schemaDef) && resolved[
|
|
3547
|
-
throw new TypeError(`atomic-workflows: required input "${
|
|
3747
|
+
for (const [key, schemaDef] of Object.entries(schema)) {
|
|
3748
|
+
if (schemaIsRequired(schemaDef) && resolved[key] === undefined) {
|
|
3749
|
+
throw new TypeError(`atomic-workflows: required input "${key}" not provided`);
|
|
3548
3750
|
}
|
|
3549
3751
|
}
|
|
3550
3752
|
return resolved;
|
|
@@ -3590,12 +3792,12 @@ ${formatValidationErrors(errors)}`);
|
|
|
3590
3792
|
function asRecord(value) {
|
|
3591
3793
|
return value !== null && typeof value === "object" ? value : undefined;
|
|
3592
3794
|
}
|
|
3593
|
-
function field(value,
|
|
3594
|
-
return asRecord(value)?.[
|
|
3795
|
+
function field(value, key) {
|
|
3796
|
+
return asRecord(value)?.[key];
|
|
3595
3797
|
}
|
|
3596
|
-
function safeField(value,
|
|
3798
|
+
function safeField(value, key) {
|
|
3597
3799
|
try {
|
|
3598
|
-
return field(value,
|
|
3800
|
+
return field(value, key);
|
|
3599
3801
|
} catch {
|
|
3600
3802
|
return;
|
|
3601
3803
|
}
|
|
@@ -3625,8 +3827,8 @@ function findProcessFailureError(value, seen, depth) {
|
|
|
3625
3827
|
return value;
|
|
3626
3828
|
if (nonEmptyProcessOutput(safeField(value, "stderr")))
|
|
3627
3829
|
return value;
|
|
3628
|
-
for (const
|
|
3629
|
-
const selected = findProcessFailureError(safeField(value,
|
|
3830
|
+
for (const key of ["cause", "error", "response", "body"]) {
|
|
3831
|
+
const selected = findProcessFailureError(safeField(value, key), seen, depth + 1);
|
|
3630
3832
|
if (selected !== undefined)
|
|
3631
3833
|
return selected;
|
|
3632
3834
|
}
|
|
@@ -3654,8 +3856,8 @@ function selectProcessFailureError(error) {
|
|
|
3654
3856
|
function hasProcessFailureEvidence(error) {
|
|
3655
3857
|
return findProcessFailureError(error, new Set, 0) !== undefined;
|
|
3656
3858
|
}
|
|
3657
|
-
function stringField2(value,
|
|
3658
|
-
const raw = field(value,
|
|
3859
|
+
function stringField2(value, key) {
|
|
3860
|
+
const raw = field(value, key);
|
|
3659
3861
|
return typeof raw === "string" && raw.length > 0 ? raw : undefined;
|
|
3660
3862
|
}
|
|
3661
3863
|
function errorMessage(error) {
|
|
@@ -3837,15 +4039,15 @@ function redactSensitiveText(value) {
|
|
|
3837
4039
|
var TOOL_FAILURE_TEXT_LIMIT_BYTES = 16384;
|
|
3838
4040
|
var TRUNCATION_PREFIX = `[workflow tool output truncated; showing final bytes]
|
|
3839
4041
|
`;
|
|
3840
|
-
function safeField2(error,
|
|
4042
|
+
function safeField2(error, key) {
|
|
3841
4043
|
try {
|
|
3842
|
-
return field(error,
|
|
4044
|
+
return field(error, key);
|
|
3843
4045
|
} catch {
|
|
3844
4046
|
return;
|
|
3845
4047
|
}
|
|
3846
4048
|
}
|
|
3847
|
-
function exposedText(error,
|
|
3848
|
-
const value = safeField2(error,
|
|
4049
|
+
function exposedText(error, key) {
|
|
4050
|
+
const value = safeField2(error, key);
|
|
3849
4051
|
if (typeof value === "string")
|
|
3850
4052
|
return value;
|
|
3851
4053
|
try {
|
|
@@ -3954,7 +4156,7 @@ function canonicalJsonString(value) {
|
|
|
3954
4156
|
return `[${value.map(canonicalJsonString).join(",")}]`;
|
|
3955
4157
|
const object = value;
|
|
3956
4158
|
const keys = Object.keys(object).sort();
|
|
3957
|
-
return `{${keys.map((
|
|
4159
|
+
return `{${keys.map((key) => `${JSON.stringify(key)}:${canonicalJsonString(object[key])}`).join(",")}}`;
|
|
3958
4160
|
}
|
|
3959
4161
|
// dist/builtin/workflows/src/durable/backend.ts
|
|
3960
4162
|
function pendingStageMessagesForDurableRun(backend, logicalRunId, rootWorkflowId = logicalRunId) {
|
|
@@ -3993,13 +4195,13 @@ function cloneWorkflowChildReplaySnapshot(snapshot) {
|
|
|
3993
4195
|
}
|
|
3994
4196
|
function workflowChildReplaySnapshot(alias, childResult) {
|
|
3995
4197
|
const outputs = {};
|
|
3996
|
-
for (const [
|
|
4198
|
+
for (const [key, value] of Object.entries(childResult.outputs)) {
|
|
3997
4199
|
if (value === undefined)
|
|
3998
4200
|
continue;
|
|
3999
4201
|
try {
|
|
4000
|
-
outputs[
|
|
4202
|
+
outputs[key] = cloneWorkflowChildValue(value);
|
|
4001
4203
|
} catch (err) {
|
|
4002
|
-
throw new Error(`atomic-workflows: child workflow "${alias}" (${childResult.workflow}) exposed output "${
|
|
4204
|
+
throw new Error(`atomic-workflows: child workflow "${alias}" (${childResult.workflow}) exposed output "${key}" is not serializable for continuation replay: ${workflowChildSerializationMessage(err)}`, { cause: err });
|
|
4003
4205
|
}
|
|
4004
4206
|
}
|
|
4005
4207
|
const exitReason = childResult.exited === true ? childResult.exitReason : undefined;
|
|
@@ -4148,10 +4350,10 @@ function durableStageGroupKey(stage, stages = [stage]) {
|
|
|
4148
4350
|
function groupByDurableStageKey(stages) {
|
|
4149
4351
|
const groups = new Map;
|
|
4150
4352
|
for (const stage of stages) {
|
|
4151
|
-
const
|
|
4152
|
-
const group = groups.get(
|
|
4353
|
+
const key = durableStageGroupKey(stage, stages);
|
|
4354
|
+
const group = groups.get(key) ?? [];
|
|
4153
4355
|
group.push(stage);
|
|
4154
|
-
groups.set(
|
|
4356
|
+
groups.set(key, group);
|
|
4155
4357
|
}
|
|
4156
4358
|
return groups;
|
|
4157
4359
|
}
|
|
@@ -4193,13 +4395,13 @@ function hasCycle(topologies) {
|
|
|
4193
4395
|
function parseWorkflowChildResult(value) {
|
|
4194
4396
|
if (!isOrdinaryObject(value))
|
|
4195
4397
|
return;
|
|
4196
|
-
const
|
|
4398
|
+
const workflow = value.workflow;
|
|
4197
4399
|
const runId = value.runId;
|
|
4198
4400
|
const status = value.status;
|
|
4199
4401
|
const exited = value.exited;
|
|
4200
4402
|
const outputs = value.outputs;
|
|
4201
4403
|
const exitReason = value.exitReason;
|
|
4202
|
-
if (typeof
|
|
4404
|
+
if (typeof workflow !== "string" || typeof runId !== "string" || !isOrdinaryObject(outputs))
|
|
4203
4405
|
return;
|
|
4204
4406
|
if (exited === false) {
|
|
4205
4407
|
if (status !== "completed" || exitReason !== undefined)
|
|
@@ -4637,7 +4839,7 @@ function durableStageCheckpointMetadata(stage, run, sourceOrder) {
|
|
|
4637
4839
|
}
|
|
4638
4840
|
|
|
4639
4841
|
// dist/builtin/workflows/src/durable/tool-primitive.ts
|
|
4640
|
-
import { runCallback } from "@bastani/atomic";
|
|
4842
|
+
import { collectAgentTasks, runCallback } from "@bastani/atomic";
|
|
4641
4843
|
|
|
4642
4844
|
// dist/builtin/workflows/src/engine/workflow-tool-abort.ts
|
|
4643
4845
|
class WorkflowToolAbortError extends Error {
|
|
@@ -4767,6 +4969,58 @@ function captureCallbackSource(fn) {
|
|
|
4767
4969
|
return;
|
|
4768
4970
|
}
|
|
4769
4971
|
}
|
|
4972
|
+
async function awaitTerminalTask(task) {
|
|
4973
|
+
for (;; ) {
|
|
4974
|
+
const observed = await task.host.waitForTask(task.taskId);
|
|
4975
|
+
if (!observed.ok)
|
|
4976
|
+
throw new Error(`${observed.error.code}: ${observed.error.message}`);
|
|
4977
|
+
if (observed.value.kind === "settled")
|
|
4978
|
+
return observed.value.result;
|
|
4979
|
+
}
|
|
4980
|
+
}
|
|
4981
|
+
function replaceTaskObservations(value, terminal) {
|
|
4982
|
+
if (!value || typeof value !== "object")
|
|
4983
|
+
return value;
|
|
4984
|
+
if (Array.isArray(value)) {
|
|
4985
|
+
const next = value.map((item) => replaceTaskObservations(item, terminal));
|
|
4986
|
+
return next.some((item, index) => item !== value[index]) ? next : value;
|
|
4987
|
+
}
|
|
4988
|
+
const object = value;
|
|
4989
|
+
if (object.kind === "yielded" && typeof object.taskId === "string") {
|
|
4990
|
+
const result = terminal.get(object.taskId);
|
|
4991
|
+
if (result)
|
|
4992
|
+
return { kind: "settled", taskId: object.taskId, result };
|
|
4993
|
+
}
|
|
4994
|
+
let changed = false;
|
|
4995
|
+
const next = {};
|
|
4996
|
+
for (const [key, item] of Object.entries(object)) {
|
|
4997
|
+
next[key] = replaceTaskObservations(item, terminal);
|
|
4998
|
+
changed ||= next[key] !== item;
|
|
4999
|
+
}
|
|
5000
|
+
if (changed && next.details !== object.details && next.details && typeof next.details === "object" && !Array.isArray(next.details) && Array.isArray(object.content)) {
|
|
5001
|
+
const details = next.details;
|
|
5002
|
+
const original = object.details;
|
|
5003
|
+
if (details.taskResponse !== undefined && details.taskResponse !== original.taskResponse) {
|
|
5004
|
+
const before = JSON.stringify(original.taskResponse);
|
|
5005
|
+
next.content = object.content.map((part) => {
|
|
5006
|
+
if (!part || typeof part !== "object" || Array.isArray(part))
|
|
5007
|
+
return part;
|
|
5008
|
+
const content = part;
|
|
5009
|
+
return content.type === "text" && content.text === before ? { ...content, text: JSON.stringify(details.taskResponse) } : part;
|
|
5010
|
+
});
|
|
5011
|
+
}
|
|
5012
|
+
}
|
|
5013
|
+
return changed ? next : value;
|
|
5014
|
+
}
|
|
5015
|
+
function invokeTaskCallback(fn, signal) {
|
|
5016
|
+
return collectAgentTasks(signal, () => fn({ signal }), async (value, tasks) => {
|
|
5017
|
+
if (tasks.length === 0)
|
|
5018
|
+
return value;
|
|
5019
|
+
const terminal = new Map;
|
|
5020
|
+
await Promise.all(tasks.map(async (task) => terminal.set(task.taskId, await awaitTerminalTask(task))));
|
|
5021
|
+
return replaceTaskObservations(value, terminal);
|
|
5022
|
+
});
|
|
5023
|
+
}
|
|
4770
5024
|
function createToolPrimitive(input) {
|
|
4771
5025
|
const ordinals = new Map;
|
|
4772
5026
|
return (name, args, fn, options) => {
|
|
@@ -4883,11 +5137,11 @@ async function executeToolInvocation(input, ordinals, name, args, fn, options, c
|
|
|
4883
5137
|
control.noteCancelled();
|
|
4884
5138
|
else
|
|
4885
5139
|
input.onFailureObserved?.(error, node.id);
|
|
4886
|
-
const
|
|
5140
|
+
const endedAt = Date.now();
|
|
4887
5141
|
input.onNodeEnd?.(node.id, {
|
|
4888
5142
|
status: cancelled ? "cancelled" : "failed",
|
|
4889
|
-
endedAt
|
|
4890
|
-
...node.startedAt !== undefined ? { durationMs: Math.max(0,
|
|
5143
|
+
endedAt,
|
|
5144
|
+
...node.startedAt !== undefined ? { durationMs: Math.max(0, endedAt - node.startedAt) } : {},
|
|
4891
5145
|
error: error instanceof Error ? error.message : String(error)
|
|
4892
5146
|
});
|
|
4893
5147
|
input.onNodeSettle?.(node.id);
|
|
@@ -4942,7 +5196,7 @@ async function executeTimedToolAttempt(toolName, runId, fn, baseSignal, timeoutM
|
|
|
4942
5196
|
const timeoutController = new AbortController;
|
|
4943
5197
|
const attemptSignal = AbortSignal.any([baseSignal, timeoutController.signal]);
|
|
4944
5198
|
return runCallback({ kind: "workflow.ctx_tool", name: toolName, runId }, async () => {
|
|
4945
|
-
const callbackResult = Promise.resolve().then(() => fn
|
|
5199
|
+
const callbackResult = Promise.resolve().then(() => invokeTaskCallback(fn, attemptSignal)).then((value) => ({ kind: "value", value }), (error) => ({ kind: "error", error }));
|
|
4946
5200
|
let cancelDeadline;
|
|
4947
5201
|
let onAbort;
|
|
4948
5202
|
let timeoutError;
|
|
@@ -4997,7 +5251,7 @@ async function executeLiveToolInvocation(live) {
|
|
|
4997
5251
|
try {
|
|
4998
5252
|
const result = await executeWithRetries(() => {
|
|
4999
5253
|
attempts += 1;
|
|
5000
|
-
const callback = options?.timeoutMs === undefined ? runCallback({ kind: "workflow.ctx_tool", name, runId: input.workflowId }, () => fn
|
|
5254
|
+
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
5255
|
return callback.catch((error) => {
|
|
5002
5256
|
callbackError = error;
|
|
5003
5257
|
throw error;
|
|
@@ -5060,12 +5314,12 @@ async function executeLiveToolInvocation(live) {
|
|
|
5060
5314
|
const callbackFailure = callbackError ?? error;
|
|
5061
5315
|
if (returnFailure && !callbackCompleted && isExplicitCallbackCancellation(callbackFailure)) {
|
|
5062
5316
|
input.onFailureObserved?.(callbackFailure, node.id);
|
|
5063
|
-
const
|
|
5317
|
+
const failure = await recordThrowingToolFailure(input, node, { name, args, ...source !== undefined ? { source } : {}, argsHash, ordinal, startedAt }, callbackFailure, attempts);
|
|
5064
5318
|
input.onNodeEnd?.(node.id, {
|
|
5065
5319
|
status: "failed",
|
|
5066
|
-
endedAt:
|
|
5067
|
-
durationMs: Math.max(0,
|
|
5068
|
-
error:
|
|
5320
|
+
endedAt: failure.failedAt,
|
|
5321
|
+
durationMs: Math.max(0, failure.failedAt - startedAt),
|
|
5322
|
+
error: failure.message
|
|
5069
5323
|
});
|
|
5070
5324
|
input.onNodeSettle?.(node.id);
|
|
5071
5325
|
throw callbackFailure;
|
|
@@ -5123,12 +5377,12 @@ async function executeLiveToolInvocation(live) {
|
|
|
5123
5377
|
}
|
|
5124
5378
|
const reportedFailure = timeoutFailure ? callbackError : error;
|
|
5125
5379
|
input.onFailureObserved?.(reportedFailure, node.id);
|
|
5126
|
-
const
|
|
5380
|
+
const failure = await recordThrowingToolFailure(input, node, { name, args, ...source !== undefined ? { source } : {}, argsHash, ordinal, startedAt }, reportedFailure, attempts);
|
|
5127
5381
|
input.onNodeEnd?.(node.id, {
|
|
5128
5382
|
status: "failed",
|
|
5129
|
-
endedAt:
|
|
5130
|
-
durationMs: Math.max(0,
|
|
5131
|
-
error:
|
|
5383
|
+
endedAt: failure.failedAt,
|
|
5384
|
+
durationMs: Math.max(0, failure.failedAt - startedAt),
|
|
5385
|
+
error: failure.message
|
|
5132
5386
|
});
|
|
5133
5387
|
input.onNodeSettle?.(node.id);
|
|
5134
5388
|
throw reportedFailure;
|
|
@@ -5184,9 +5438,9 @@ var CALLBACK_CANCELLATION_CODES = new Set([
|
|
|
5184
5438
|
"err_cancelled"
|
|
5185
5439
|
]);
|
|
5186
5440
|
var CALLBACK_CANCELLATION_STOP_REASONS = new Set(["aborted", "canceled", "cancelled"]);
|
|
5187
|
-
function safeCancellationField(error,
|
|
5441
|
+
function safeCancellationField(error, key) {
|
|
5188
5442
|
try {
|
|
5189
|
-
return field(error,
|
|
5443
|
+
return field(error, key);
|
|
5190
5444
|
} catch {
|
|
5191
5445
|
return;
|
|
5192
5446
|
}
|
|
@@ -5213,16 +5467,16 @@ function isExplicitCallbackCancellation(error) {
|
|
|
5213
5467
|
return true;
|
|
5214
5468
|
if (!hasProcessFailure && hasCancellationMarker(CALLBACK_CANCELLATION_CODES, safeCancellationField(current.value, "code")))
|
|
5215
5469
|
return true;
|
|
5216
|
-
for (const
|
|
5217
|
-
pending.push({ value: safeCancellationField(current.value,
|
|
5470
|
+
for (const key of ["cause", "error", "response", "body"]) {
|
|
5471
|
+
pending.push({ value: safeCancellationField(current.value, key), depth: current.depth + 1 });
|
|
5218
5472
|
}
|
|
5219
|
-
for (const
|
|
5220
|
-
const entries = safeCancellationField(current.value,
|
|
5473
|
+
for (const key of ["diagnostics", "errors"]) {
|
|
5474
|
+
const entries = safeCancellationField(current.value, key);
|
|
5221
5475
|
if (!Array.isArray(entries))
|
|
5222
5476
|
continue;
|
|
5223
5477
|
for (const entry of entries) {
|
|
5224
5478
|
pending.push({
|
|
5225
|
-
value:
|
|
5479
|
+
value: key === "diagnostics" ? safeCancellationField(entry, "error") ?? entry : entry,
|
|
5226
5480
|
depth: current.depth + 1
|
|
5227
5481
|
});
|
|
5228
5482
|
}
|
|
@@ -5387,8 +5641,8 @@ function pendingStageIdForReplay(backend, workflowId, replayKey, stageName) {
|
|
|
5387
5641
|
return candidates.size === 1 ? candidates.values().next().value : undefined;
|
|
5388
5642
|
}
|
|
5389
5643
|
function createDurableStagePrimitive(input) {
|
|
5390
|
-
return (name, options) => {
|
|
5391
|
-
const replayKey = input.nextReplayKey(name);
|
|
5644
|
+
return (name, options, reservedReplayKey) => {
|
|
5645
|
+
const replayKey = reservedReplayKey ?? input.nextReplayKey(name);
|
|
5392
5646
|
const cached = stageCheckpointWithOutput(input.backend, input.workflowId, replayKey);
|
|
5393
5647
|
if (cached !== undefined) {
|
|
5394
5648
|
input.recordCachedStage?.(name, replayKey, cached);
|
|
@@ -5702,11 +5956,11 @@ function preferredHydrationTopology(replayValueCheckpoint, checkpoints) {
|
|
|
5702
5956
|
}
|
|
5703
5957
|
return replayValueCheckpoint.topology === undefined ? metadataValue(checkpoints, "topology") : {};
|
|
5704
5958
|
}
|
|
5705
|
-
function metadataValue(checkpoints,
|
|
5959
|
+
function metadataValue(checkpoints, key) {
|
|
5706
5960
|
for (let index = checkpoints.length - 1;index >= 0; index -= 1) {
|
|
5707
|
-
const value = checkpoints[index]?.[
|
|
5961
|
+
const value = checkpoints[index]?.[key];
|
|
5708
5962
|
if (value !== undefined)
|
|
5709
|
-
return { [
|
|
5963
|
+
return { [key]: value };
|
|
5710
5964
|
}
|
|
5711
5965
|
return {};
|
|
5712
5966
|
}
|
|
@@ -5741,7 +5995,7 @@ function stageMetadataCheckpointId(replayKey, stage) {
|
|
|
5741
5995
|
result: stage.result ?? ""
|
|
5742
5996
|
})}`;
|
|
5743
5997
|
}
|
|
5744
|
-
function recordCachedStageIntoStore(
|
|
5998
|
+
function recordCachedStageIntoStore(store, runId, name, replayKey, output, completedStageReplayKeys, parentIds, checkpoint) {
|
|
5745
5999
|
const now = Date.now();
|
|
5746
6000
|
const sourceStageId = checkpoint?.topology?.run?.runId === runId ? checkpoint.topology.stageId : undefined;
|
|
5747
6001
|
const stageId = sourceStageId ?? cachedStageId(runId, replayKey);
|
|
@@ -5777,16 +6031,16 @@ function recordCachedStageIntoStore(store2, runId, name, replayKey, output, comp
|
|
|
5777
6031
|
...checkpoint?.artifacts !== undefined ? { artifacts: checkpoint.artifacts } : {},
|
|
5778
6032
|
...checkpoint?.warnings !== undefined ? { warnings: checkpoint.warnings } : {}
|
|
5779
6033
|
};
|
|
5780
|
-
|
|
5781
|
-
|
|
6034
|
+
store.recordStageStart(runId, snapshot);
|
|
6035
|
+
store.recordStageEnd(runId, snapshot);
|
|
5782
6036
|
completedStageReplayKeys.set(stageId, replayKey);
|
|
5783
6037
|
}
|
|
5784
|
-
function recordCachedStageWithTracker(
|
|
6038
|
+
function recordCachedStageWithTracker(store, tracker, runId, name, replayKey, checkpoint, completedStageReplayKeys, stageFailFastScope, sourceToReplayedNodeIds) {
|
|
5785
6039
|
const sourceStageId = checkpoint.topology?.run?.runId === runId ? checkpoint.topology.stageId : undefined;
|
|
5786
6040
|
const stageId = sourceStageId ?? cachedStageId(runId, replayKey);
|
|
5787
6041
|
let parentIds = tracker.onSpawn(stageId, name);
|
|
5788
6042
|
const sourceParents = sourceStageId === undefined ? undefined : checkpoint.topology?.parentIds;
|
|
5789
|
-
const run =
|
|
6043
|
+
const run = store.runs().find((candidate) => candidate.id === runId);
|
|
5790
6044
|
const restored = sourceParents?.map((sourceId) => sourceToReplayedNodeIds?.get(sourceId) ?? run?.stages.find((stage) => stage.id === sourceId || stage.replayedFromStageId === sourceId)?.id);
|
|
5791
6045
|
if (restored?.every((id) => id !== undefined)) {
|
|
5792
6046
|
parentIds = restored;
|
|
@@ -5797,7 +6051,7 @@ function recordCachedStageWithTracker(store2, tracker, runId, name, replayKey, c
|
|
|
5797
6051
|
}
|
|
5798
6052
|
if (checkpoint.topology?.run?.runId === runId)
|
|
5799
6053
|
sourceToReplayedNodeIds?.set(checkpoint.topology.stageId, stageId);
|
|
5800
|
-
recordCachedStageIntoStore(
|
|
6054
|
+
recordCachedStageIntoStore(store, runId, name, replayKey, checkpoint.output, completedStageReplayKeys, parentIds, checkpoint);
|
|
5801
6055
|
tracker.onSettle(stageId);
|
|
5802
6056
|
}
|
|
5803
6057
|
function isWorkflowTaskResult(value) {
|
|
@@ -6467,6 +6721,11 @@ function classifyWorkflowFailure(error) {
|
|
|
6467
6721
|
}
|
|
6468
6722
|
return failureForDecision(unknownDecision(), message, error);
|
|
6469
6723
|
}
|
|
6724
|
+
// dist/builtin/workflows/src/durable/workflow-status-transition.ts
|
|
6725
|
+
async function transitionDurableWorkflowStatus(backend, workflowId, expectedStatuses, status, pendingPrompts, resumable) {
|
|
6726
|
+
return await backend.transitionWorkflowStatus(workflowId, expectedStatuses, status, pendingPrompts, resumable);
|
|
6727
|
+
}
|
|
6728
|
+
|
|
6470
6729
|
// dist/builtin/workflows/src/durable/dbos-process-owner.ts
|
|
6471
6730
|
var DBOS_PROCESS_OWNER_KEY = Symbol.for("atomic-workflows/dbos-process-owner@1");
|
|
6472
6731
|
function emptyOwner2() {
|
|
@@ -6540,9 +6799,9 @@ function isMemoizedBackendUsable(backend) {
|
|
|
6540
6799
|
return !backend.persistent || dbosLifecycleState() === "ready";
|
|
6541
6800
|
}
|
|
6542
6801
|
function getDurableBackend() {
|
|
6543
|
-
const
|
|
6544
|
-
const memoized =
|
|
6545
|
-
const backend =
|
|
6802
|
+
const owner = getDurableBackendProcessOwner();
|
|
6803
|
+
const memoized = owner.initializedBackend !== undefined && isMemoizedBackendUsable(owner.initializedBackend) ? owner.initializedBackend : undefined;
|
|
6804
|
+
const backend = owner.injectedBackend ?? memoized ?? getReadyDbosBackendSync();
|
|
6546
6805
|
if (backend === undefined)
|
|
6547
6806
|
throw new DbosNotReadyError;
|
|
6548
6807
|
return backend;
|
|
@@ -6575,7 +6834,7 @@ function restoreBudgetState(value) {
|
|
|
6575
6834
|
if (restored !== undefined)
|
|
6576
6835
|
warnings[dimension] = restored;
|
|
6577
6836
|
}
|
|
6578
|
-
const requiredNumbers = (candidate, fields) => isRecord(candidate) && fields.every((
|
|
6837
|
+
const requiredNumbers = (candidate, fields) => isRecord(candidate) && fields.every((field) => numericDuration(candidate[field]) !== undefined);
|
|
6579
6838
|
const accountingValue = value.accounting;
|
|
6580
6839
|
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
6840
|
const state = {
|
|
@@ -6807,8 +7066,8 @@ class ScopedDurableBackend {
|
|
|
6807
7066
|
scope
|
|
6808
7067
|
};
|
|
6809
7068
|
}
|
|
6810
|
-
scopeKey(
|
|
6811
|
-
return `${this.scope.scopePrefix}:${
|
|
7069
|
+
scopeKey(key) {
|
|
7070
|
+
return `${this.scope.scopePrefix}:${key}`;
|
|
6812
7071
|
}
|
|
6813
7072
|
remap(checkpoint) {
|
|
6814
7073
|
const workflowId = this.scope.rootWorkflowId;
|
|
@@ -7313,31 +7572,31 @@ function createGitWorktreeSetupCache() {
|
|
|
7313
7572
|
get(options) {
|
|
7314
7573
|
if (disposed)
|
|
7315
7574
|
throw new Error("Git worktree setup cache is already disposed");
|
|
7316
|
-
const
|
|
7317
|
-
const cached = results.get(
|
|
7575
|
+
const key = gitWorktreeSetupCacheKey(options);
|
|
7576
|
+
const cached = results.get(key);
|
|
7318
7577
|
if (cached !== undefined) {
|
|
7319
7578
|
assertCachedGitWorktreeIdentity(cached, options);
|
|
7320
7579
|
return cached.result;
|
|
7321
7580
|
}
|
|
7322
7581
|
const result = setupGitWorktree(options);
|
|
7323
|
-
results.set(
|
|
7582
|
+
results.set(key, { result, identity: captureGitWorktreeIdentity(result) });
|
|
7324
7583
|
return result;
|
|
7325
7584
|
},
|
|
7326
7585
|
dispose() {
|
|
7327
7586
|
if (disposed)
|
|
7328
7587
|
return;
|
|
7329
7588
|
disposed = true;
|
|
7330
|
-
let
|
|
7589
|
+
let firstError;
|
|
7331
7590
|
for (const cached of results.values()) {
|
|
7332
7591
|
try {
|
|
7333
7592
|
cached.identity.generation.dispose();
|
|
7334
7593
|
} catch (error) {
|
|
7335
|
-
|
|
7594
|
+
firstError ??= error instanceof Error ? error : new Error(String(error));
|
|
7336
7595
|
}
|
|
7337
7596
|
}
|
|
7338
7597
|
results.clear();
|
|
7339
|
-
if (
|
|
7340
|
-
throw
|
|
7598
|
+
if (firstError !== undefined)
|
|
7599
|
+
throw firstError;
|
|
7341
7600
|
}
|
|
7342
7601
|
};
|
|
7343
7602
|
}
|
|
@@ -7637,24 +7896,24 @@ function safePatchAgentName(agent) {
|
|
|
7637
7896
|
}
|
|
7638
7897
|
function removeSyntheticPath(worktree, syntheticPath) {
|
|
7639
7898
|
const resolved = path4.resolve(worktree.path, syntheticPath);
|
|
7640
|
-
const
|
|
7641
|
-
if (!
|
|
7899
|
+
const relative = path4.relative(worktree.path, resolved);
|
|
7900
|
+
if (!relative || relative === "." || relative === ".." || relative.startsWith(`..${path4.sep}`) || path4.isAbsolute(relative)) {
|
|
7642
7901
|
return;
|
|
7643
7902
|
}
|
|
7644
|
-
let
|
|
7903
|
+
let stat;
|
|
7645
7904
|
try {
|
|
7646
|
-
|
|
7905
|
+
stat = fs4.lstatSync(resolved);
|
|
7647
7906
|
} catch (error) {
|
|
7648
7907
|
const code = error && typeof error === "object" && "code" in error ? error.code : undefined;
|
|
7649
7908
|
if (code === "ENOENT")
|
|
7650
7909
|
return;
|
|
7651
7910
|
throw error;
|
|
7652
7911
|
}
|
|
7653
|
-
if (
|
|
7912
|
+
if (stat.isSymbolicLink()) {
|
|
7654
7913
|
fs4.unlinkSync(resolved);
|
|
7655
7914
|
return;
|
|
7656
7915
|
}
|
|
7657
|
-
if (
|
|
7916
|
+
if (stat.isDirectory()) {
|
|
7658
7917
|
fs4.rmSync(resolved, { recursive: true, force: true });
|
|
7659
7918
|
return;
|
|
7660
7919
|
}
|
|
@@ -8018,14 +8277,14 @@ function normalizeSyntheticPath(worktreePath, rawPath) {
|
|
|
8018
8277
|
if (path6.isAbsolute(trimmed))
|
|
8019
8278
|
throw new Error(`synthetic path must be relative: ${rawPath}`);
|
|
8020
8279
|
const resolved = path6.resolve(worktreePath, trimmed);
|
|
8021
|
-
const
|
|
8022
|
-
if (!
|
|
8280
|
+
const relative = path6.relative(worktreePath, resolved);
|
|
8281
|
+
if (!relative || relative === ".") {
|
|
8023
8282
|
throw new Error(`synthetic path cannot target the worktree root: ${rawPath}`);
|
|
8024
8283
|
}
|
|
8025
|
-
if (
|
|
8284
|
+
if (relative === ".." || relative.startsWith(`..${path6.sep}`) || path6.isAbsolute(relative)) {
|
|
8026
8285
|
throw new Error(`synthetic path escapes the worktree root: ${rawPath}`);
|
|
8027
8286
|
}
|
|
8028
|
-
return path6.normalize(
|
|
8287
|
+
return path6.normalize(relative);
|
|
8029
8288
|
}
|
|
8030
8289
|
function hasTrackedEntries(worktreePath, relativePath) {
|
|
8031
8290
|
const result = runGit(worktreePath, ["ls-files", "--", relativePath]);
|
|
@@ -8168,15 +8427,15 @@ function cleanupWorktrees(setup) {
|
|
|
8168
8427
|
import { lstatSync as lstatSync4, realpathSync as realpathSync4 } from "node:fs";
|
|
8169
8428
|
import { dirname as dirname6, isAbsolute as isAbsolute5, relative as relative4, resolve as resolve6, sep as sep5 } from "node:path";
|
|
8170
8429
|
function relativePathWithin(root, candidate) {
|
|
8171
|
-
const
|
|
8172
|
-
return
|
|
8430
|
+
const path = relative4(root, candidate);
|
|
8431
|
+
return path === ".." || path.startsWith(`..${sep5}`) || isAbsolute5(path) ? undefined : path;
|
|
8173
8432
|
}
|
|
8174
|
-
function existingRealPath(
|
|
8433
|
+
function existingRealPath(path, description) {
|
|
8175
8434
|
try {
|
|
8176
|
-
return realpathSync4.native(
|
|
8435
|
+
return realpathSync4.native(path);
|
|
8177
8436
|
} catch (error) {
|
|
8178
8437
|
const message = error instanceof Error ? error.message : String(error);
|
|
8179
|
-
throw new Error(`atomic-workflows: cannot resolve ${description} ${
|
|
8438
|
+
throw new Error(`atomic-workflows: cannot resolve ${description} ${path}: ${message}`);
|
|
8180
8439
|
}
|
|
8181
8440
|
}
|
|
8182
8441
|
function resolveWorktreeStageCwd(cwd, setup) {
|
|
@@ -8394,7 +8653,7 @@ function truncateTaskOutput(text, maxOutput) {
|
|
|
8394
8653
|
[workflow output truncated; limits: ${limits.bytes} bytes, ${limits.lines} lines]`;
|
|
8395
8654
|
}
|
|
8396
8655
|
function withoutUndefinedProperties(value) {
|
|
8397
|
-
return Object.fromEntries(Object.entries(value).filter(([,
|
|
8656
|
+
return Object.fromEntries(Object.entries(value).filter(([, field]) => field !== undefined));
|
|
8398
8657
|
}
|
|
8399
8658
|
function sharedTaskDefaultsFromOptions(options) {
|
|
8400
8659
|
const {
|
|
@@ -8500,7 +8759,7 @@ async function mapParallelSteps(steps, concurrency, failFast, mapper, onFirstFai
|
|
|
8500
8759
|
if (selectedFailure !== undefined)
|
|
8501
8760
|
throw selectedFailure;
|
|
8502
8761
|
}
|
|
8503
|
-
throw new AggregateError(failures.map((
|
|
8762
|
+
throw new AggregateError(failures.map((failure) => failure.error), `atomic-workflows: ${failures.length} parallel ${failures.length === 1 ? "step" : "steps"} failed`);
|
|
8504
8763
|
}
|
|
8505
8764
|
return results;
|
|
8506
8765
|
}
|
|
@@ -8773,32 +9032,32 @@ function reconcileTerminalRunResult(runId, runSnapshot, activeStore, fallback, o
|
|
|
8773
9032
|
onRunEnd?.(runId, result.status, result.result, result.error, result.exitReason);
|
|
8774
9033
|
return result;
|
|
8775
9034
|
}
|
|
8776
|
-
function applyFailureToStage(stage,
|
|
9035
|
+
function applyFailureToStage(stage, failure) {
|
|
8777
9036
|
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(
|
|
9037
|
+
stage.error = failure.userMessage;
|
|
9038
|
+
stage.failureKind = failure.kind;
|
|
9039
|
+
stage.failureCode = failure.code;
|
|
9040
|
+
stage.failureRecoverability = failure.recoverability;
|
|
9041
|
+
stage.failureDisposition = failure.disposition;
|
|
9042
|
+
stage.retryAfterMs = failure.retryAfterMs;
|
|
9043
|
+
stage.failureMessage = failure.message;
|
|
9044
|
+
}
|
|
9045
|
+
function runFailureMetadata(failure, stages) {
|
|
8787
9046
|
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 ??
|
|
9047
|
+
const failureKind = failedStage?.failureKind ?? failure.kind;
|
|
9048
|
+
const failureCode = failedStage?.failureCode ?? failure.code;
|
|
9049
|
+
const failureRecoverability = failedStage?.failureRecoverability ?? failure.recoverability;
|
|
9050
|
+
const failureDisposition = failedStage?.failureDisposition ?? failure.disposition;
|
|
9051
|
+
const retryAfterMs = failedStage?.retryAfterMs ?? failure.retryAfterMs;
|
|
8793
9052
|
return {
|
|
8794
|
-
errorMessage: failedStage?.error ??
|
|
9053
|
+
errorMessage: failedStage?.error ?? failure.userMessage,
|
|
8795
9054
|
failureKind,
|
|
8796
9055
|
...failureCode !== undefined ? { failureCode } : {},
|
|
8797
9056
|
failureRecoverability,
|
|
8798
9057
|
failureDisposition,
|
|
8799
|
-
failureMessage: failedStage?.failureMessage ??
|
|
9058
|
+
failureMessage: failedStage?.failureMessage ?? failure.message,
|
|
8800
9059
|
...failedStage !== undefined ? { failedStageId: failedStage.id } : {},
|
|
8801
|
-
resumable:
|
|
9060
|
+
resumable: failure.resumable,
|
|
8802
9061
|
...retryAfterMs !== undefined ? { retryAfterMs } : {}
|
|
8803
9062
|
};
|
|
8804
9063
|
}
|
|
@@ -8827,17 +9086,17 @@ function runFailureMetadataFromStage(fallbackFailure, stage) {
|
|
|
8827
9086
|
...retryAfterMs !== undefined ? { retryAfterMs } : {}
|
|
8828
9087
|
};
|
|
8829
9088
|
}
|
|
8830
|
-
function runFailureMetadataFromFailure(
|
|
9089
|
+
function runFailureMetadataFromFailure(failure, failedStage) {
|
|
8831
9090
|
return {
|
|
8832
|
-
errorMessage: failedStage?.error ??
|
|
8833
|
-
failureKind:
|
|
8834
|
-
...
|
|
8835
|
-
failureRecoverability:
|
|
8836
|
-
failureDisposition:
|
|
8837
|
-
failureMessage: failedStage?.failureMessage ??
|
|
9091
|
+
errorMessage: failedStage?.error ?? failure.userMessage,
|
|
9092
|
+
failureKind: failure.kind,
|
|
9093
|
+
...failure.code !== undefined ? { failureCode: failure.code } : {},
|
|
9094
|
+
failureRecoverability: failure.recoverability,
|
|
9095
|
+
failureDisposition: failure.disposition,
|
|
9096
|
+
failureMessage: failedStage?.failureMessage ?? failure.message,
|
|
8838
9097
|
...failedStage !== undefined ? { failedStageId: failedStage.id } : {},
|
|
8839
|
-
resumable:
|
|
8840
|
-
...
|
|
9098
|
+
resumable: failure.resumable,
|
|
9099
|
+
...failure.retryAfterMs !== undefined ? { retryAfterMs: failure.retryAfterMs } : {}
|
|
8841
9100
|
};
|
|
8842
9101
|
}
|
|
8843
9102
|
function aggregateInnerFailures(error, classifyFailure) {
|
|
@@ -8851,20 +9110,20 @@ function stageFailureCandidate(stage) {
|
|
|
8851
9110
|
recoverability: stage.failureRecoverability ?? "unknown"
|
|
8852
9111
|
};
|
|
8853
9112
|
}
|
|
8854
|
-
function aggregateFailureCandidate(
|
|
9113
|
+
function aggregateFailureCandidate(failure) {
|
|
8855
9114
|
return {
|
|
8856
9115
|
source: "aggregate",
|
|
8857
|
-
failure
|
|
8858
|
-
disposition:
|
|
8859
|
-
recoverability:
|
|
9116
|
+
failure,
|
|
9117
|
+
disposition: failure.disposition,
|
|
9118
|
+
recoverability: failure.recoverability
|
|
8860
9119
|
};
|
|
8861
9120
|
}
|
|
8862
|
-
function outerFailureCandidate(
|
|
9121
|
+
function outerFailureCandidate(failure) {
|
|
8863
9122
|
return {
|
|
8864
9123
|
source: "outer",
|
|
8865
|
-
failure
|
|
8866
|
-
disposition:
|
|
8867
|
-
recoverability:
|
|
9124
|
+
failure,
|
|
9125
|
+
disposition: failure.disposition,
|
|
9126
|
+
recoverability: failure.recoverability
|
|
8868
9127
|
};
|
|
8869
9128
|
}
|
|
8870
9129
|
function isRecoverableActiveBlockedCandidate(candidate) {
|
|
@@ -8951,24 +9210,24 @@ function stageReplayFields(stage) {
|
|
|
8951
9210
|
};
|
|
8952
9211
|
}
|
|
8953
9212
|
function finalizeKilled(runId, runSnapshot, activeStore, persistence, onRunEnd) {
|
|
8954
|
-
const
|
|
9213
|
+
const errorMessage = "workflow killed";
|
|
8955
9214
|
const metadata = {
|
|
8956
9215
|
failureKind: "cancelled",
|
|
8957
9216
|
failureCode: "cancelled",
|
|
8958
9217
|
failureRecoverability: "non_recoverable",
|
|
8959
9218
|
failureDisposition: "terminal_killed",
|
|
8960
|
-
failureMessage:
|
|
9219
|
+
failureMessage: errorMessage,
|
|
8961
9220
|
resumable: false
|
|
8962
9221
|
};
|
|
8963
|
-
const recorded = activeStore.recordRunEnd(runId, "killed", undefined,
|
|
9222
|
+
const recorded = activeStore.recordRunEnd(runId, "killed", undefined, errorMessage, metadata);
|
|
8964
9223
|
appendRunEndWhenRecorded(persistence, recorded, {
|
|
8965
9224
|
runId,
|
|
8966
9225
|
status: "killed",
|
|
8967
|
-
error:
|
|
9226
|
+
error: errorMessage,
|
|
8968
9227
|
...metadata,
|
|
8969
9228
|
ts: Date.now()
|
|
8970
9229
|
});
|
|
8971
|
-
return reconcileTerminalRunResult(runId, runSnapshot, activeStore, { status: "killed", error:
|
|
9230
|
+
return reconcileTerminalRunResult(runId, runSnapshot, activeStore, { status: "killed", error: errorMessage }, onRunEnd);
|
|
8972
9231
|
}
|
|
8973
9232
|
function finalizeKilledByFailure(runId, runSnapshot, activeStore, persistence, onRunEnd, metadata) {
|
|
8974
9233
|
const recorded = activeStore.recordRunEnd(runId, "killed", undefined, metadata.errorMessage, metadata);
|
|
@@ -9035,32 +9294,32 @@ function recordActiveBlockedFailure(runId, runSnapshot, activeStore, persistence
|
|
|
9035
9294
|
|
|
9036
9295
|
// dist/builtin/workflows/src/runs/foreground/executor-outputs.ts
|
|
9037
9296
|
import { Value as Value5 } from "typebox/value";
|
|
9038
|
-
function hasOwnWorkflowOutput(record,
|
|
9039
|
-
return Object.hasOwn(record,
|
|
9297
|
+
function hasOwnWorkflowOutput(record, key) {
|
|
9298
|
+
return Object.hasOwn(record, key);
|
|
9040
9299
|
}
|
|
9041
9300
|
function assertWorkflowOutputsExplicit(scope, sourceOutput, declarations, missingOutputSuffix = "") {
|
|
9042
|
-
for (const
|
|
9043
|
-
if (!hasOwnWorkflowOutput(declarations,
|
|
9044
|
-
throw new Error(`atomic-workflows: ${scope} returned undeclared output "${
|
|
9301
|
+
for (const key of Object.keys(sourceOutput)) {
|
|
9302
|
+
if (!hasOwnWorkflowOutput(declarations, key)) {
|
|
9303
|
+
throw new Error(`atomic-workflows: ${scope} returned undeclared output "${key}"; declare it in outputs: { "${key}": Type.... } or remove it from the .run() return`);
|
|
9045
9304
|
}
|
|
9046
9305
|
}
|
|
9047
|
-
for (const [
|
|
9048
|
-
if (!(
|
|
9306
|
+
for (const [key, schema] of Object.entries(declarations)) {
|
|
9307
|
+
if (!(key in sourceOutput)) {
|
|
9049
9308
|
if (schemaIsRequired(schema)) {
|
|
9050
|
-
throw new Error(`atomic-workflows: ${scope} missing output "${
|
|
9309
|
+
throw new Error(`atomic-workflows: ${scope} missing output "${key}"${missingOutputSuffix}`);
|
|
9051
9310
|
}
|
|
9052
9311
|
continue;
|
|
9053
9312
|
}
|
|
9054
|
-
const value = sourceOutput[
|
|
9313
|
+
const value = sourceOutput[key];
|
|
9055
9314
|
const kind = schemaFieldKind(schema);
|
|
9056
9315
|
if (!Value5.Check(schema, value)) {
|
|
9057
9316
|
const choices = schemaChoices(schema);
|
|
9058
9317
|
if (kind === "select" && choices !== undefined && typeof value === "string") {
|
|
9059
|
-
throw new Error(`atomic-workflows: ${scope} output "${
|
|
9318
|
+
throw new Error(`atomic-workflows: ${scope} output "${key}" must be one of [${choices.join(", ")}], got ${JSON.stringify(value)}`);
|
|
9060
9319
|
}
|
|
9061
|
-
throw new Error(`atomic-workflows: ${scope} output "${
|
|
9320
|
+
throw new Error(`atomic-workflows: ${scope} output "${key}" expected ${kind}, got ${workflowSerializableTypeName(value)}`);
|
|
9062
9321
|
}
|
|
9063
|
-
const serializableError = workflowSerializableValidationError(value, `${scope} output "${
|
|
9322
|
+
const serializableError = workflowSerializableValidationError(value, `${scope} output "${key}"`);
|
|
9064
9323
|
if (serializableError !== undefined)
|
|
9065
9324
|
throw new Error(`atomic-workflows: ${serializableError}`);
|
|
9066
9325
|
}
|
|
@@ -9093,27 +9352,27 @@ function assertWorkflowExitOutputs(workflowName, result, declaredOutputs) {
|
|
|
9093
9352
|
const declarations = declaredOutputs ?? {};
|
|
9094
9353
|
const sourceOutput = result ?? {};
|
|
9095
9354
|
const scope = `workflow "${workflowName}" ctx.exit()`;
|
|
9096
|
-
for (const
|
|
9097
|
-
if (!hasOwnWorkflowOutput(declarations,
|
|
9098
|
-
throw new Error(`atomic-workflows: ${scope} provided undeclared output "${
|
|
9355
|
+
for (const key of Object.keys(sourceOutput)) {
|
|
9356
|
+
if (!hasOwnWorkflowOutput(declarations, key)) {
|
|
9357
|
+
throw new Error(`atomic-workflows: ${scope} provided undeclared output "${key}"; declare it in outputs: { "${key}": Type.... } or remove it from ctx.exit({ outputs })`);
|
|
9099
9358
|
}
|
|
9100
9359
|
}
|
|
9101
|
-
for (const [
|
|
9102
|
-
if (!(
|
|
9360
|
+
for (const [key, schema] of Object.entries(declarations)) {
|
|
9361
|
+
if (!(key in sourceOutput))
|
|
9103
9362
|
continue;
|
|
9104
|
-
const value = sourceOutput[
|
|
9105
|
-
const invalidSnapshotValue = workflowExitSnapshotInvalidValueMessage(`${scope} output "${
|
|
9363
|
+
const value = sourceOutput[key];
|
|
9364
|
+
const invalidSnapshotValue = workflowExitSnapshotInvalidValueMessage(`${scope} output "${key}"`, value);
|
|
9106
9365
|
if (invalidSnapshotValue !== undefined)
|
|
9107
9366
|
throw new Error(`atomic-workflows: ${invalidSnapshotValue}`);
|
|
9108
9367
|
const kind = schemaFieldKind(schema);
|
|
9109
9368
|
if (!Value5.Check(schema, value)) {
|
|
9110
9369
|
const choices = schemaChoices(schema);
|
|
9111
9370
|
if (kind === "select" && choices !== undefined && typeof value === "string") {
|
|
9112
|
-
throw new Error(`atomic-workflows: ${scope} output "${
|
|
9371
|
+
throw new Error(`atomic-workflows: ${scope} output "${key}" must be one of [${choices.join(", ")}], got ${JSON.stringify(value)}`);
|
|
9113
9372
|
}
|
|
9114
|
-
throw new Error(`atomic-workflows: ${scope} output "${
|
|
9373
|
+
throw new Error(`atomic-workflows: ${scope} output "${key}" expected ${kind}, got ${workflowSerializableTypeName(value)}`);
|
|
9115
9374
|
}
|
|
9116
|
-
const serializableError = workflowSerializableValidationError(value, `${scope} output "${
|
|
9375
|
+
const serializableError = workflowSerializableValidationError(value, `${scope} output "${key}"`);
|
|
9117
9376
|
if (serializableError !== undefined)
|
|
9118
9377
|
throw new Error(`atomic-workflows: ${serializableError}`);
|
|
9119
9378
|
}
|
|
@@ -9122,10 +9381,10 @@ function selectWorkflowOutputs(child, rawOutput) {
|
|
|
9122
9381
|
const declarations = child.outputs ?? {};
|
|
9123
9382
|
const sourceOutput = rawOutput ?? {};
|
|
9124
9383
|
const selected = {};
|
|
9125
|
-
for (const
|
|
9126
|
-
const value = sourceOutput[
|
|
9384
|
+
for (const key of Object.keys(declarations)) {
|
|
9385
|
+
const value = sourceOutput[key];
|
|
9127
9386
|
if (value !== undefined)
|
|
9128
|
-
selected[
|
|
9387
|
+
selected[key] = value;
|
|
9129
9388
|
}
|
|
9130
9389
|
return selected;
|
|
9131
9390
|
}
|
|
@@ -9540,8 +9799,8 @@ function buildPromptNodeUiAdapter(input) {
|
|
|
9540
9799
|
try {
|
|
9541
9800
|
if (mergedSignal.signal.aborted)
|
|
9542
9801
|
throw hilAbortError(mergedSignal.signal);
|
|
9543
|
-
const
|
|
9544
|
-
if (!
|
|
9802
|
+
const accepted = input.activeStore.recordStageAwaitingInput(input.runId, stageId, true, prompt.createdAt);
|
|
9803
|
+
if (!accepted) {
|
|
9545
9804
|
const error = new Error("atomic-workflows: ctx.ui.custom prompt node is unavailable");
|
|
9546
9805
|
stageSnapshot.skippedReason = "prompt-unavailable";
|
|
9547
9806
|
await finalizePromptStage("skipped");
|
|
@@ -9571,15 +9830,15 @@ function buildPromptNodeUiAdapter(input) {
|
|
|
9571
9830
|
mergedSignal.dispose();
|
|
9572
9831
|
}
|
|
9573
9832
|
}
|
|
9574
|
-
const
|
|
9575
|
-
if (!
|
|
9833
|
+
const accepted = input.activeStore.recordStagePendingPrompt(input.runId, stageId, prompt);
|
|
9834
|
+
if (!accepted) {
|
|
9576
9835
|
stageSnapshot.skippedReason = "prompt-unavailable";
|
|
9577
9836
|
await finalizePromptStage("skipped");
|
|
9578
9837
|
return fallbackForPromptDescriptor(descriptor);
|
|
9579
9838
|
}
|
|
9580
9839
|
const waiter = input.activeStore.awaitStagePendingPrompt(input.runId, stageId, prompt.id);
|
|
9581
9840
|
try {
|
|
9582
|
-
const response = await new Promise((
|
|
9841
|
+
const response = await new Promise((resolve, reject) => {
|
|
9583
9842
|
const onAbort = () => {
|
|
9584
9843
|
input.activeStore.resolveStagePendingPrompt(input.runId, stageId, prompt.id, fallbackForPromptDescriptor(descriptor), { recordAnswer: false });
|
|
9585
9844
|
reject(hilAbortError(input.signal));
|
|
@@ -9591,7 +9850,7 @@ function buildPromptNodeUiAdapter(input) {
|
|
|
9591
9850
|
input.signal.addEventListener("abort", onAbort, { once: true });
|
|
9592
9851
|
waiter.then((value) => {
|
|
9593
9852
|
input.signal.removeEventListener("abort", onAbort);
|
|
9594
|
-
|
|
9853
|
+
resolve(value);
|
|
9595
9854
|
}, (err) => {
|
|
9596
9855
|
input.signal.removeEventListener("abort", onAbort);
|
|
9597
9856
|
reject(err);
|
|
@@ -9652,8 +9911,8 @@ function buildPromptNodeUiAdapter(input) {
|
|
|
9652
9911
|
// dist/builtin/workflows/src/runs/foreground/executor-run-finalizers.ts
|
|
9653
9912
|
function createRunFinalizers(input) {
|
|
9654
9913
|
const finalizeWorkflowExitValidationFailure = (err, exitReason) => {
|
|
9655
|
-
const
|
|
9656
|
-
const classifiedMetadata = runFailureMetadata(
|
|
9914
|
+
const failure = input.classifyExecutorFailure(err);
|
|
9915
|
+
const classifiedMetadata = runFailureMetadata(failure, input.runSnapshot.stages);
|
|
9657
9916
|
const metadata = {
|
|
9658
9917
|
...classifiedMetadata,
|
|
9659
9918
|
resumable: false,
|
|
@@ -9718,8 +9977,8 @@ function createRunFinalizers(input) {
|
|
|
9718
9977
|
...signal.reason !== undefined ? { exitReason: signal.reason } : {}
|
|
9719
9978
|
}, input.opts.onRunEnd);
|
|
9720
9979
|
};
|
|
9721
|
-
const finalizeParentWorkflowExitCancellation = async (
|
|
9722
|
-
const parentReason =
|
|
9980
|
+
const finalizeParentWorkflowExitCancellation = async (abortReason) => {
|
|
9981
|
+
const parentReason = abortReason.workflowExitReason;
|
|
9723
9982
|
await input.drainWorkflowExitCleanups(parentReason);
|
|
9724
9983
|
const exitReason = parentWorkflowExitRunReason(parentReason);
|
|
9725
9984
|
const metadata = { resumable: false, exited: true, exitReason };
|
|
@@ -9748,6 +10007,7 @@ function isTerminalStage(stage) {
|
|
|
9748
10007
|
function createStageScheduler(input) {
|
|
9749
10008
|
const releaseBarriers = new Map;
|
|
9750
10009
|
const cascadePauseOwners = new Map;
|
|
10010
|
+
let runBarrier;
|
|
9751
10011
|
const makeReleaseBarrier = () => {
|
|
9752
10012
|
const resolver = Promise.withResolvers();
|
|
9753
10013
|
resolver.promise.catch(() => {});
|
|
@@ -9869,6 +10129,8 @@ function createStageScheduler(input) {
|
|
|
9869
10129
|
}
|
|
9870
10130
|
};
|
|
9871
10131
|
const rejectReleaseBarriers = (reason) => {
|
|
10132
|
+
runBarrier?.reject(reason);
|
|
10133
|
+
runBarrier = undefined;
|
|
9872
10134
|
cascadePauseOwners.clear();
|
|
9873
10135
|
for (const [stageId, barrier] of releaseBarriers) {
|
|
9874
10136
|
releaseBarriers.delete(stageId);
|
|
@@ -9891,6 +10153,19 @@ function createStageScheduler(input) {
|
|
|
9891
10153
|
};
|
|
9892
10154
|
return {
|
|
9893
10155
|
tracker: input.tracker,
|
|
10156
|
+
isRunPaused: () => runBarrier !== undefined,
|
|
10157
|
+
pauseRun: () => {
|
|
10158
|
+
runBarrier ??= makeReleaseBarrier();
|
|
10159
|
+
},
|
|
10160
|
+
releaseRun: () => {
|
|
10161
|
+
const barrier = runBarrier;
|
|
10162
|
+
runBarrier = undefined;
|
|
10163
|
+
barrier?.resolve();
|
|
10164
|
+
},
|
|
10165
|
+
waitForRunRelease: async () => {
|
|
10166
|
+
while (runBarrier !== undefined)
|
|
10167
|
+
await runBarrier.promise;
|
|
10168
|
+
},
|
|
9894
10169
|
stageById,
|
|
9895
10170
|
setStageParentIds,
|
|
9896
10171
|
descendantsOf,
|
|
@@ -10165,8 +10440,8 @@ class ConcurrencyLimiter {
|
|
|
10165
10440
|
this._running++;
|
|
10166
10441
|
return Promise.resolve();
|
|
10167
10442
|
}
|
|
10168
|
-
return new Promise((
|
|
10169
|
-
this._queue.push(
|
|
10443
|
+
return new Promise((resolve) => {
|
|
10444
|
+
this._queue.push(resolve);
|
|
10170
10445
|
});
|
|
10171
10446
|
}
|
|
10172
10447
|
release() {
|
|
@@ -10190,6 +10465,24 @@ function createRunLimiter(defaultConcurrency) {
|
|
|
10190
10465
|
return new ConcurrencyLimiter(defaultConcurrency ?? 4);
|
|
10191
10466
|
}
|
|
10192
10467
|
|
|
10468
|
+
// dist/builtin/workflows/src/shared/abort.ts
|
|
10469
|
+
function raceAbort2(operation, signal) {
|
|
10470
|
+
if (signal === undefined)
|
|
10471
|
+
return operation;
|
|
10472
|
+
if (signal.aborted) {
|
|
10473
|
+
operation.catch(() => {});
|
|
10474
|
+
return Promise.reject(signal.reason ?? new DOMException("Workflow request aborted", "AbortError"));
|
|
10475
|
+
}
|
|
10476
|
+
const abort = Promise.withResolvers();
|
|
10477
|
+
const onAbort = () => {
|
|
10478
|
+
abort.reject(signal.reason ?? new DOMException("Workflow request aborted", "AbortError"));
|
|
10479
|
+
};
|
|
10480
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
10481
|
+
return Promise.race([operation, abort.promise]).finally(() => {
|
|
10482
|
+
signal.removeEventListener("abort", onAbort);
|
|
10483
|
+
});
|
|
10484
|
+
}
|
|
10485
|
+
|
|
10193
10486
|
// dist/builtin/workflows/src/engine/primitives/chain.ts
|
|
10194
10487
|
function createChainPrimitive(input) {
|
|
10195
10488
|
return async (steps, options = {}) => {
|
|
@@ -10234,11 +10527,11 @@ function createWorkflowExitManager(input) {
|
|
|
10234
10527
|
const trackWorkflowExitCleanup = (operation) => {
|
|
10235
10528
|
if (operation === undefined)
|
|
10236
10529
|
return;
|
|
10237
|
-
let
|
|
10238
|
-
|
|
10239
|
-
workflowExitCleanupPromises.delete(
|
|
10530
|
+
let tracked;
|
|
10531
|
+
tracked = Promise.resolve(operation).catch(() => {}).finally(() => {
|
|
10532
|
+
workflowExitCleanupPromises.delete(tracked);
|
|
10240
10533
|
});
|
|
10241
|
-
workflowExitCleanupPromises.add(
|
|
10534
|
+
workflowExitCleanupPromises.add(tracked);
|
|
10242
10535
|
};
|
|
10243
10536
|
const invokeWorkflowExitCleanup = (cleanup, reason) => {
|
|
10244
10537
|
try {
|
|
@@ -10364,10 +10657,10 @@ function createWorkflowExitManager(input) {
|
|
|
10364
10657
|
};
|
|
10365
10658
|
}
|
|
10366
10659
|
// dist/builtin/workflows/src/engine/primitives/parallel.ts
|
|
10367
|
-
import { randomUUID as
|
|
10660
|
+
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
10368
10661
|
|
|
10369
10662
|
// dist/builtin/workflows/src/shared/intercom-group.ts
|
|
10370
|
-
import { randomUUID as
|
|
10663
|
+
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
10371
10664
|
var DEFAULT_INTERCOM_GROUP = "default";
|
|
10372
10665
|
function workflowInvocationIntercomGroup(rootRunId) {
|
|
10373
10666
|
return `workflow:${rootRunId}`;
|
|
@@ -10390,22 +10683,22 @@ function resolveStageGroup(stageOptions, workflowGroup) {
|
|
|
10390
10683
|
const group = stageOptions.group;
|
|
10391
10684
|
if (group === undefined)
|
|
10392
10685
|
return workflowGroup;
|
|
10393
|
-
const authored = group === true ?
|
|
10686
|
+
const authored = group === true ? randomUUID3() : group.trim();
|
|
10394
10687
|
if (authored.length === 0)
|
|
10395
10688
|
return;
|
|
10396
10689
|
if (workflowGroup === undefined || authored === DEFAULT_INTERCOM_GROUP)
|
|
10397
10690
|
return authored;
|
|
10398
|
-
const
|
|
10399
|
-
if (authored ===
|
|
10691
|
+
const owner = normalizeGroup(workflowGroup);
|
|
10692
|
+
if (authored === owner || authored.startsWith(`${owner}/`))
|
|
10400
10693
|
return authored;
|
|
10401
|
-
return `${
|
|
10694
|
+
return `${owner}/${authored}`;
|
|
10402
10695
|
}
|
|
10403
10696
|
function workflowInvocationOwnsGroup(workflowGroup, candidate) {
|
|
10404
10697
|
if (workflowGroup === undefined || candidate === undefined)
|
|
10405
10698
|
return false;
|
|
10406
|
-
const
|
|
10699
|
+
const owner = normalizeGroup(workflowGroup);
|
|
10407
10700
|
const group = normalizeGroup(candidate);
|
|
10408
|
-
return group ===
|
|
10701
|
+
return group === owner || group.startsWith(`${owner}/`);
|
|
10409
10702
|
}
|
|
10410
10703
|
function stageHasIntercomAccess(_stageOptions) {
|
|
10411
10704
|
return true;
|
|
@@ -10448,7 +10741,7 @@ function fold_usage(results) {
|
|
|
10448
10741
|
|
|
10449
10742
|
// dist/builtin/workflows/src/shared/budget-meter.ts
|
|
10450
10743
|
var usageFields = ["input", "output", "cacheRead", "cacheWrite", "cost"];
|
|
10451
|
-
var addUsage = (left, right) => Object.fromEntries(usageFields.map((
|
|
10744
|
+
var addUsage = (left, right) => Object.fromEntries(usageFields.map((field) => [field, left[field] + right[field]]));
|
|
10452
10745
|
function foldTreeUsage(tree) {
|
|
10453
10746
|
const run = "run" in tree ? tree.run : tree;
|
|
10454
10747
|
const folded = fold_usage(run.stages.filter((stage) => stage.replayed !== true).map((stage) => ({ stageName: stage.name, text: stage.result ?? "", modelAttempts: stage.modelAttempts })));
|
|
@@ -10460,7 +10753,7 @@ function meter_run(tree, now) {
|
|
|
10460
10753
|
durationMs: elapsedRunMs("run" in tree ? tree.run : tree, now),
|
|
10461
10754
|
tokens: usage.input + usage.output,
|
|
10462
10755
|
cost: usage.cost,
|
|
10463
|
-
perCounter: Object.fromEntries(usageFields.filter((
|
|
10756
|
+
perCounter: Object.fromEntries(usageFields.filter((field) => field !== "cost").map((field) => [field, usage[field]]))
|
|
10464
10757
|
};
|
|
10465
10758
|
}
|
|
10466
10759
|
|
|
@@ -10479,7 +10772,7 @@ class WorkflowBudgetExceededError extends Error {
|
|
|
10479
10772
|
var withFrontier = (report, frontierStage, summary, usage) => Object.assign({ ...report, frontierStage: frontierStage ?? "workflow frontier" }, summary === undefined ? {} : { wrapUpSummary: summary }, usage === undefined ? {} : { wrapUpUsage: usage });
|
|
10480
10773
|
var usageFields2 = ["input", "output", "cacheRead", "cacheWrite", "cost"];
|
|
10481
10774
|
var counterFields = ["input", "output", "cacheRead", "cacheWrite"];
|
|
10482
|
-
var mapFields = (fields, fn = () => 0) => Object.fromEntries(fields.map((
|
|
10775
|
+
var mapFields = (fields, fn = () => 0) => Object.fromEntries(fields.map((field) => [field, fn(field)]));
|
|
10483
10776
|
function createRunBudgetController(input) {
|
|
10484
10777
|
const { run, budget } = input;
|
|
10485
10778
|
const ownEnabled = budget.maxDurationMs > 0 || budget.maxTokens > 0 || budget.maxCost > 0;
|
|
@@ -10490,7 +10783,7 @@ function createRunBudgetController(input) {
|
|
|
10490
10783
|
const previousAccounting = state?.accounting;
|
|
10491
10784
|
const initial = previousAccounting && usageEnabled ? meter_run(input.usageTree?.() ?? { run }, Date.now()) : undefined;
|
|
10492
10785
|
const initialAccounting = initial === undefined ? undefined : { ...initial.perCounter, cost: initial.cost };
|
|
10493
|
-
let baseline = mapFields(usageFields2, (
|
|
10786
|
+
let baseline = mapFields(usageFields2, (field) => initialAccounting?.[field] ?? 0);
|
|
10494
10787
|
let charged = {
|
|
10495
10788
|
baseline,
|
|
10496
10789
|
tokens: previousAccounting?.tokens ?? 0,
|
|
@@ -10508,13 +10801,13 @@ function createRunBudgetController(input) {
|
|
|
10508
10801
|
};
|
|
10509
10802
|
const accountUsage = (meters) => {
|
|
10510
10803
|
const current = { ...meters.perCounter, cost: meters.cost };
|
|
10511
|
-
const delta = mapFields(usageFields2, (
|
|
10512
|
-
baseline = mapFields(usageFields2, (
|
|
10804
|
+
const delta = mapFields(usageFields2, (field) => Math.max(0, current[field] - baseline[field]));
|
|
10805
|
+
baseline = mapFields(usageFields2, (field) => Math.max(baseline[field], current[field]));
|
|
10513
10806
|
charged = {
|
|
10514
10807
|
baseline,
|
|
10515
10808
|
tokens: charged.tokens + delta.input + delta.output,
|
|
10516
10809
|
cost: charged.cost + delta.cost,
|
|
10517
|
-
perCounter: mapFields(counterFields, (
|
|
10810
|
+
perCounter: mapFields(counterFields, (field) => charged.perCounter[field] + delta[field])
|
|
10518
10811
|
};
|
|
10519
10812
|
updateState({ accounting: charged });
|
|
10520
10813
|
return Object.assign(meters, { tokens: charged.tokens, cost: charged.cost, perCounter: charged.perCounter });
|
|
@@ -10591,21 +10884,21 @@ function createRunBudgetController(input) {
|
|
|
10591
10884
|
return { check: ownCheckpoint(frontierStage) };
|
|
10592
10885
|
};
|
|
10593
10886
|
const checkpoint = (frontierStage) => boundaryCheckpoint(frontierStage).check;
|
|
10594
|
-
const finishBoundary = (
|
|
10595
|
-
throw
|
|
10887
|
+
const finishBoundary = (owner, frontierStage) => {
|
|
10888
|
+
throw owner?.finishWrapUp(frontierStage, undefined, undefined, false) ?? finishWrapUp(frontierStage, undefined, undefined, false);
|
|
10596
10889
|
};
|
|
10597
|
-
const deliverBoundary = (
|
|
10598
|
-
|
|
10890
|
+
const deliverBoundary = (owner, frontierStage) => {
|
|
10891
|
+
owner?.deliverWrapUp(frontierStage) ?? deliverWrapUp(frontierStage);
|
|
10599
10892
|
};
|
|
10600
10893
|
const stopAtBoundary = (frontierStage) => {
|
|
10601
10894
|
const resolvedFrontierStage = frontierStage ?? handlers.at(-1)?.frontierStage;
|
|
10602
|
-
const { check, owner
|
|
10895
|
+
const { check, owner } = boundaryCheckpoint(resolvedFrontierStage);
|
|
10603
10896
|
if (check.kind === "wrap_up") {
|
|
10604
|
-
deliverBoundary(
|
|
10605
|
-
finishBoundary(
|
|
10897
|
+
deliverBoundary(owner, resolvedFrontierStage ?? "workflow frontier");
|
|
10898
|
+
finishBoundary(owner, resolvedFrontierStage);
|
|
10606
10899
|
}
|
|
10607
10900
|
if (check.kind === "exhausted")
|
|
10608
|
-
finishBoundary(
|
|
10901
|
+
finishBoundary(owner, resolvedFrontierStage);
|
|
10609
10902
|
};
|
|
10610
10903
|
const rethrowIfSystemOwnedStop = (frontierStage) => {
|
|
10611
10904
|
root?.rethrowIfSystemOwnedStop(frontierStage);
|
|
@@ -10699,11 +10992,11 @@ function createRunBudgetController(input) {
|
|
|
10699
10992
|
function createParallelPrimitive(input) {
|
|
10700
10993
|
return async (steps, options = {}) => {
|
|
10701
10994
|
input.runtime.exit.throwIfWorkflowExitSelected();
|
|
10702
|
-
const
|
|
10703
|
-
const normalizedOptions =
|
|
10704
|
-
const normalizedSteps = steps.map(
|
|
10995
|
+
const normalizeGroup = (value) => value.group === undefined ? value : { ...value, group: normalizeAutoGroupSentinel(value.group) };
|
|
10996
|
+
const normalizedOptions = normalizeGroup(options);
|
|
10997
|
+
const normalizedSteps = steps.map(normalizeGroup);
|
|
10705
10998
|
const needsAutoGroup = normalizedOptions.group === true || normalizedSteps.some((step) => step.group === true);
|
|
10706
|
-
const autoGroup = needsAutoGroup ?
|
|
10999
|
+
const autoGroup = needsAutoGroup ? randomUUID4() : undefined;
|
|
10707
11000
|
const resolveAutoGroup = (value) => value.group === true && autoGroup ? { ...value, group: autoGroup } : value;
|
|
10708
11001
|
const resolvedOptions = resolveAutoGroup(normalizedOptions);
|
|
10709
11002
|
const resolvedSteps = normalizedSteps.map(resolveAutoGroup);
|
|
@@ -10744,9 +11037,9 @@ function createParallelPrimitive(input) {
|
|
|
10744
11037
|
beforeMap: input.runtime.exit.throwIfWorkflowExitSelected,
|
|
10745
11038
|
isControlSignal: (error) => findWorkflowExitSignal(error, input.runtime.exit.exitScope) !== undefined,
|
|
10746
11039
|
selectSettledFailure: (failures) => {
|
|
10747
|
-
if (!everyStepCompleted() || !failures.every((
|
|
11040
|
+
if (!everyStepCompleted() || !failures.every((failure) => failure.error instanceof WorkflowBudgetExceededError))
|
|
10748
11041
|
return;
|
|
10749
|
-
return failures.reduce((selected,
|
|
11042
|
+
return failures.reduce((selected, failure) => failure.index < selected.index ? failure : selected).error;
|
|
10750
11043
|
}
|
|
10751
11044
|
});
|
|
10752
11045
|
};
|
|
@@ -10896,6 +11189,8 @@ function wrapUiWithDurable(base, deps) {
|
|
|
10896
11189
|
return {
|
|
10897
11190
|
async input(promptText) {
|
|
10898
11191
|
const callerStack = new Error().stack;
|
|
11192
|
+
for (let wait = deps.beforeCall?.();wait !== undefined; wait = deps.beforeCall?.())
|
|
11193
|
+
await wait;
|
|
10899
11194
|
const identity = nextIdentity("input", promptText, callerStack);
|
|
10900
11195
|
const hit = cached(identity);
|
|
10901
11196
|
if (typeof hit === "string") {
|
|
@@ -10915,6 +11210,8 @@ function wrapUiWithDurable(base, deps) {
|
|
|
10915
11210
|
},
|
|
10916
11211
|
async confirm(message) {
|
|
10917
11212
|
const callerStack = new Error().stack;
|
|
11213
|
+
for (let wait = deps.beforeCall?.();wait !== undefined; wait = deps.beforeCall?.())
|
|
11214
|
+
await wait;
|
|
10918
11215
|
const identity = nextIdentity("confirm", message, callerStack);
|
|
10919
11216
|
const hit = cached(identity);
|
|
10920
11217
|
if (typeof hit === "boolean") {
|
|
@@ -10934,6 +11231,8 @@ function wrapUiWithDurable(base, deps) {
|
|
|
10934
11231
|
},
|
|
10935
11232
|
async select(message, options) {
|
|
10936
11233
|
const callerStack = new Error().stack;
|
|
11234
|
+
for (let wait = deps.beforeCall?.();wait !== undefined; wait = deps.beforeCall?.())
|
|
11235
|
+
await wait;
|
|
10937
11236
|
const identity = nextIdentity("select", message, callerStack, [...options]);
|
|
10938
11237
|
const hit = cached(identity);
|
|
10939
11238
|
if (typeof hit === "string") {
|
|
@@ -10953,6 +11252,8 @@ function wrapUiWithDurable(base, deps) {
|
|
|
10953
11252
|
},
|
|
10954
11253
|
async editor(initial) {
|
|
10955
11254
|
const callerStack = new Error().stack;
|
|
11255
|
+
for (let wait = deps.beforeCall?.();wait !== undefined; wait = deps.beforeCall?.())
|
|
11256
|
+
await wait;
|
|
10956
11257
|
const identity = nextIdentity("editor", initial ?? "", callerStack, initial ?? null);
|
|
10957
11258
|
const hit = cached(identity);
|
|
10958
11259
|
if (typeof hit === "string") {
|
|
@@ -10972,6 +11273,8 @@ function wrapUiWithDurable(base, deps) {
|
|
|
10972
11273
|
},
|
|
10973
11274
|
async custom(factory, options) {
|
|
10974
11275
|
const callerStack = new Error().stack;
|
|
11276
|
+
for (let wait = deps.beforeCall?.();wait !== undefined; wait = deps.beforeCall?.())
|
|
11277
|
+
await wait;
|
|
10975
11278
|
const replayIdentity = options?.replayIdentity ?? factory?.name ?? "custom";
|
|
10976
11279
|
const identity = nextIdentity("custom", replayIdentity, callerStack, { replayIdentity });
|
|
10977
11280
|
const hit = cachedCustom(identity);
|
|
@@ -11004,26 +11307,32 @@ function buildExitGatedUiContext(input) {
|
|
|
11004
11307
|
const base = input.opts.usePromptNodesForUi === true ? input.baseFromPromptNodes() : input.opts.executionMode === "non_interactive" && input.opts.ui === undefined ? makeHeadlessUnavailableUIContext() : normalizeUIContext(input.opts.ui);
|
|
11005
11308
|
const promptNodeReplay = input.opts.usePromptNodesForUi === true && input.opts.continuation !== undefined;
|
|
11006
11309
|
const durableBase = input.durableUi !== undefined && !promptNodeReplay ? wrapUiWithDurable(base, input.durableUi) : base;
|
|
11310
|
+
const invoke = (call) => {
|
|
11311
|
+
input.throwIfWorkflowExitSelected();
|
|
11312
|
+
if (!promptNodeReplay || input.durableUi?.beforeCall === undefined)
|
|
11313
|
+
return call();
|
|
11314
|
+
return withPromptCallerStack(new Error().stack, async () => {
|
|
11315
|
+
for (let wait = input.durableUi?.beforeCall?.();wait !== undefined; wait = input.durableUi?.beforeCall?.())
|
|
11316
|
+
await wait;
|
|
11317
|
+
input.throwIfWorkflowExitSelected();
|
|
11318
|
+
return call();
|
|
11319
|
+
});
|
|
11320
|
+
};
|
|
11007
11321
|
return {
|
|
11008
11322
|
async input(promptText) {
|
|
11009
|
-
input
|
|
11010
|
-
return await durableBase.input(promptText);
|
|
11323
|
+
return await invoke(() => durableBase.input(promptText));
|
|
11011
11324
|
},
|
|
11012
11325
|
async confirm(message) {
|
|
11013
|
-
|
|
11014
|
-
return await durableBase.confirm(message);
|
|
11326
|
+
return await invoke(() => durableBase.confirm(message));
|
|
11015
11327
|
},
|
|
11016
11328
|
async select(message, options) {
|
|
11017
|
-
|
|
11018
|
-
return await durableBase.select(message, options);
|
|
11329
|
+
return await invoke(() => durableBase.select(message, options));
|
|
11019
11330
|
},
|
|
11020
11331
|
async editor(initial) {
|
|
11021
|
-
|
|
11022
|
-
return await durableBase.editor(initial);
|
|
11332
|
+
return await invoke(() => durableBase.editor(initial));
|
|
11023
11333
|
},
|
|
11024
11334
|
async custom(factory, options) {
|
|
11025
|
-
|
|
11026
|
-
return await durableBase.custom(factory, options);
|
|
11335
|
+
return await invoke(() => durableBase.custom(factory, options));
|
|
11027
11336
|
}
|
|
11028
11337
|
};
|
|
11029
11338
|
}
|
|
@@ -11273,8 +11582,8 @@ function structuredRecoverableFailureFromSnapshot(snapshot, failedStageId) {
|
|
|
11273
11582
|
function isRecoverableProviderFailureKind(kind) {
|
|
11274
11583
|
return kind === "auth" || kind === "rate_limit" || kind === "provider";
|
|
11275
11584
|
}
|
|
11276
|
-
function stringResultField(result,
|
|
11277
|
-
const value = result?.[
|
|
11585
|
+
function stringResultField(result, key) {
|
|
11586
|
+
const value = result?.[key];
|
|
11278
11587
|
return typeof value === "string" && value.trim().length > 0 ? value.trim() : undefined;
|
|
11279
11588
|
}
|
|
11280
11589
|
|
|
@@ -11292,7 +11601,7 @@ async function finalizeDurableTerminalStatus(input) {
|
|
|
11292
11601
|
if (durableStatus === "failed" || durableStatus === "blocked") {
|
|
11293
11602
|
recordRunTimingCheckpoint(input.durableBackend, input.runSnapshot);
|
|
11294
11603
|
}
|
|
11295
|
-
const
|
|
11604
|
+
const failure = durableStatus === "failed" ? {
|
|
11296
11605
|
...input.runSnapshot.error !== undefined ? { error: input.runSnapshot.error } : {},
|
|
11297
11606
|
...input.runSnapshot.exited === true ? {
|
|
11298
11607
|
exited: true,
|
|
@@ -11304,7 +11613,7 @@ async function finalizeDurableTerminalStatus(input) {
|
|
|
11304
11613
|
...input.runSnapshot.failureDisposition !== undefined ? { failureDisposition: input.runSnapshot.failureDisposition } : {},
|
|
11305
11614
|
...input.runSnapshot.failedToolNodeId !== undefined ? { failedToolNodeId: input.runSnapshot.failedToolNodeId } : {}
|
|
11306
11615
|
} : undefined;
|
|
11307
|
-
input.durableBackend.setWorkflowStatus(input.runId, durableStatus, undefined, input.runSnapshot.resumable,
|
|
11616
|
+
input.durableBackend.setWorkflowStatus(input.runId, durableStatus, undefined, input.runSnapshot.resumable, failure);
|
|
11308
11617
|
}
|
|
11309
11618
|
await input.durableBackend.flush(input.runId);
|
|
11310
11619
|
}
|
|
@@ -11561,17 +11870,17 @@ function childRunIdFromDraft(draft) {
|
|
|
11561
11870
|
}
|
|
11562
11871
|
function boundaryOwner(grouped, childRunId) {
|
|
11563
11872
|
for (const drafts of grouped.values()) {
|
|
11564
|
-
const
|
|
11565
|
-
if (
|
|
11566
|
-
return
|
|
11873
|
+
const owner = drafts.find((draft) => childRunIdFromDraft(draft) === childRunId);
|
|
11874
|
+
if (owner !== undefined)
|
|
11875
|
+
return owner;
|
|
11567
11876
|
}
|
|
11568
11877
|
return;
|
|
11569
11878
|
}
|
|
11570
|
-
function childRunStatus(
|
|
11571
|
-
const child = workflowChildFromDraft(
|
|
11879
|
+
function childRunStatus(owner) {
|
|
11880
|
+
const child = workflowChildFromDraft(owner);
|
|
11572
11881
|
if (child !== undefined)
|
|
11573
11882
|
return child.status;
|
|
11574
|
-
const status =
|
|
11883
|
+
const status = owner.topology?.boundary?.status;
|
|
11575
11884
|
return status === "failed" || status === "skipped" || status === "completed" ? status : "running";
|
|
11576
11885
|
}
|
|
11577
11886
|
function mergeStageGroup(records, allStages, allCheckpoints) {
|
|
@@ -11621,12 +11930,12 @@ function mergeStageDraft(existing, checkpoint, sequence) {
|
|
|
11621
11930
|
...checkpoint.topology !== undefined ? { topology: checkpoint.topology } : existing?.topology !== undefined ? { topology: existing.topology } : {}
|
|
11622
11931
|
};
|
|
11623
11932
|
}
|
|
11624
|
-
function valueOrExisting(
|
|
11625
|
-
const checkpointValue = checkpoint[
|
|
11933
|
+
function valueOrExisting(key, checkpoint, existing) {
|
|
11934
|
+
const checkpointValue = checkpoint[key];
|
|
11626
11935
|
if (checkpointValue !== undefined)
|
|
11627
|
-
return { [
|
|
11628
|
-
const existingValue = existing?.[
|
|
11629
|
-
return existingValue === undefined ? {} : { [
|
|
11936
|
+
return { [key]: checkpointValue };
|
|
11937
|
+
const existingValue = existing?.[key];
|
|
11938
|
+
return existingValue === undefined ? {} : { [key]: existingValue };
|
|
11630
11939
|
}
|
|
11631
11940
|
function workflowChildFromDraft(draft) {
|
|
11632
11941
|
const strict = parseWorkflowChildResult(draft.output);
|
|
@@ -11702,7 +12011,7 @@ function durableNestedRunSnapshots(backend, rootWorkflowId) {
|
|
|
11702
12011
|
const handle = backend.getWorkflow(rootWorkflowId);
|
|
11703
12012
|
if (handle === undefined)
|
|
11704
12013
|
return [];
|
|
11705
|
-
return runSnapshotsFromCheckpoints(backend.listCheckpoints(rootWorkflowId), rootWorkflowId, handle.name, handle.updatedAt, LEGACY_ACTIVE_RECONSTRUCTION).filter((
|
|
12014
|
+
return runSnapshotsFromCheckpoints(backend.listCheckpoints(rootWorkflowId), rootWorkflowId, handle.name, handle.updatedAt, LEGACY_ACTIVE_RECONSTRUCTION).filter((run) => run.id !== rootWorkflowId);
|
|
11706
12015
|
}
|
|
11707
12016
|
function checkpointDrafts(checkpoints) {
|
|
11708
12017
|
const stageByReplayKey = new Map;
|
|
@@ -11711,8 +12020,8 @@ function checkpointDrafts(checkpoints) {
|
|
|
11711
12020
|
checkpoints.forEach((checkpoint, index) => {
|
|
11712
12021
|
const sequence = index + 1;
|
|
11713
12022
|
if (checkpoint.kind === "stage") {
|
|
11714
|
-
const
|
|
11715
|
-
stageByReplayKey.set(checkpoint.replayKey, mergeStageDraft(
|
|
12023
|
+
const existing = stageByReplayKey.get(checkpoint.replayKey);
|
|
12024
|
+
stageByReplayKey.set(checkpoint.replayKey, mergeStageDraft(existing, checkpoint, sequence));
|
|
11716
12025
|
return;
|
|
11717
12026
|
}
|
|
11718
12027
|
if (checkpoint.kind !== "tool" || isReservedRunCheckpointHash(checkpoint.argsHash))
|
|
@@ -11913,29 +12222,29 @@ function runSnapshotsFromCheckpoints(checkpoints, rootRunId, rootRunName, fallba
|
|
|
11913
12222
|
}
|
|
11914
12223
|
const stages = runDrafts.map((draft) => stageSnapshotFromDraft(draft, ids.get(draft.topology.stageId), draft.topology.parentIds.map((parentId) => ids.get(parentId))));
|
|
11915
12224
|
const toolNodes = completedToolNodes(toolCheckpoints, runId, rootRunId, ids, drafts.firstToolSequenceByHash);
|
|
11916
|
-
const
|
|
12225
|
+
const run = runTopologyFor(runDrafts, ownedTools);
|
|
11917
12226
|
const startedAt = Math.min(...stages.map((stage) => stage.startedAt ?? fallbackCompletedAt), ...toolNodes.map((tool) => tool.startedAt ?? tool.endedAt ?? fallbackCompletedAt));
|
|
11918
12227
|
const endedAt = Math.max(...stages.map((stage) => stage.endedAt ?? fallbackCompletedAt), ...toolNodes.map((tool) => tool.endedAt ?? fallbackCompletedAt));
|
|
11919
|
-
const
|
|
11920
|
-
const status =
|
|
12228
|
+
const owner = runId === rootRunId ? undefined : boundaryOwner(grouped, runId);
|
|
12229
|
+
const status = owner === undefined ? "completed" : childRunStatus(owner);
|
|
11921
12230
|
const terminal = status !== "running" && status !== "pending" && status !== "paused" && status !== "blocked";
|
|
11922
|
-
const parentRunId =
|
|
12231
|
+
const parentRunId = run?.parentRunId ?? rootRunId;
|
|
11923
12232
|
const boundarySourceId = grouped.get(parentRunId)?.find((draft) => childRunIdFromDraft(draft) === runId)?.topology?.stageId;
|
|
11924
|
-
const declaredParentStageId =
|
|
12233
|
+
const declaredParentStageId = run?.parentStageId === undefined ? undefined : idMaps.get(parentRunId)?.get(run.parentStageId);
|
|
11925
12234
|
const parentStageId = declaredParentStageId ?? (boundarySourceId === undefined ? undefined : idMaps.get(parentRunId)?.get(boundarySourceId));
|
|
11926
|
-
const ownerChild =
|
|
12235
|
+
const ownerChild = owner === undefined ? undefined : workflowChildFromDraft(owner);
|
|
11927
12236
|
runs.push({
|
|
11928
12237
|
id: runId,
|
|
11929
|
-
name:
|
|
12238
|
+
name: run?.runName ?? rootRunName,
|
|
11930
12239
|
inputs: {},
|
|
11931
12240
|
status,
|
|
11932
12241
|
stages,
|
|
11933
12242
|
toolNodes,
|
|
11934
12243
|
startedAt,
|
|
11935
12244
|
...terminal ? { endedAt, durationMs: Math.max(0, endedAt - startedAt) } : {},
|
|
11936
|
-
...
|
|
12245
|
+
...run?.parentRunId !== undefined ? { parentRunId: run.parentRunId } : {},
|
|
11937
12246
|
...parentStageId !== undefined ? { parentStageId } : {},
|
|
11938
|
-
...
|
|
12247
|
+
...run?.rootRunId !== undefined ? { rootRunId: run.rootRunId } : {},
|
|
11939
12248
|
...ownerChild?.exited === true ? {
|
|
11940
12249
|
result: ownerChild.outputs,
|
|
11941
12250
|
exited: true,
|
|
@@ -11945,13 +12254,13 @@ function runSnapshotsFromCheckpoints(checkpoints, rootRunId, rootRunName, fallba
|
|
|
11945
12254
|
});
|
|
11946
12255
|
emittedRunIds.add(runId);
|
|
11947
12256
|
}
|
|
11948
|
-
for (const { parentRunId, owner
|
|
12257
|
+
for (const { parentRunId, owner, child } of syntheticChildren) {
|
|
11949
12258
|
if (!emittedRunIds.has(parentRunId)) {
|
|
11950
12259
|
if (policy.failClosed)
|
|
11951
12260
|
return [];
|
|
11952
12261
|
continue;
|
|
11953
12262
|
}
|
|
11954
|
-
const topology =
|
|
12263
|
+
const topology = owner.topology;
|
|
11955
12264
|
const boundary = topology.boundary;
|
|
11956
12265
|
const parentStageId = idMaps.get(parentRunId)?.get(topology.stageId);
|
|
11957
12266
|
if (parentStageId === undefined) {
|
|
@@ -11959,8 +12268,8 @@ function runSnapshotsFromCheckpoints(checkpoints, rootRunId, rootRunName, fallba
|
|
|
11959
12268
|
return [];
|
|
11960
12269
|
continue;
|
|
11961
12270
|
}
|
|
11962
|
-
const startedAt =
|
|
11963
|
-
const endedAt =
|
|
12271
|
+
const startedAt = owner.startedAt ?? owner.firstCompletedAt;
|
|
12272
|
+
const endedAt = owner.endedAt ?? owner.firstCompletedAt;
|
|
11964
12273
|
runs.push({
|
|
11965
12274
|
id: child.runId,
|
|
11966
12275
|
name: boundary.child.runName,
|
|
@@ -12068,7 +12377,7 @@ function syntheticCheckpointStage(checkpointCount, completedAt) {
|
|
|
12068
12377
|
// dist/builtin/workflows/src/durable/completed-subtree.ts
|
|
12069
12378
|
function durableCompletedNestedRunSubtree(backend, rootWorkflowId, childRunId) {
|
|
12070
12379
|
const nested = durableNestedRunSnapshots(backend, rootWorkflowId);
|
|
12071
|
-
if (!nested.some((
|
|
12380
|
+
if (!nested.some((run) => run.id === childRunId))
|
|
12072
12381
|
return;
|
|
12073
12382
|
const intentionalExitStatuses = new Map;
|
|
12074
12383
|
for (const checkpoint of backend.listCheckpoints(rootWorkflowId)) {
|
|
@@ -12082,22 +12391,22 @@ function durableCompletedNestedRunSubtree(backend, rootWorkflowId, childRunId) {
|
|
|
12082
12391
|
let priorSize = -1;
|
|
12083
12392
|
while (priorSize !== included.size) {
|
|
12084
12393
|
priorSize = included.size;
|
|
12085
|
-
for (const
|
|
12086
|
-
if (
|
|
12087
|
-
included.add(
|
|
12394
|
+
for (const run of nested) {
|
|
12395
|
+
if (run.parentRunId !== undefined && included.has(run.parentRunId))
|
|
12396
|
+
included.add(run.id);
|
|
12088
12397
|
}
|
|
12089
12398
|
}
|
|
12090
|
-
const subtree = nested.filter((
|
|
12091
|
-
const complete = subtree.length === included.size && subtree.every((
|
|
12399
|
+
const subtree = nested.filter((run) => included.has(run.id));
|
|
12400
|
+
const complete = subtree.length === included.size && subtree.every((run) => isCompleteCachedRun(run, intentionalExitStatuses));
|
|
12092
12401
|
return complete ? subtree : undefined;
|
|
12093
12402
|
}
|
|
12094
|
-
function isCompleteCachedRun(
|
|
12095
|
-
if (
|
|
12403
|
+
function isCompleteCachedRun(run, intentionalExitStatuses) {
|
|
12404
|
+
if (run.endedAt === undefined || !run.stages.every((stage) => isTerminalStage2(stage.status) && stage.endedAt !== undefined)) {
|
|
12096
12405
|
return false;
|
|
12097
12406
|
}
|
|
12098
|
-
if (
|
|
12407
|
+
if (run.status === "completed" || run.exited === true)
|
|
12099
12408
|
return true;
|
|
12100
|
-
return intentionalExitStatuses.get(
|
|
12409
|
+
return intentionalExitStatuses.get(run.id) === run.status;
|
|
12101
12410
|
}
|
|
12102
12411
|
function isTerminalStage2(status) {
|
|
12103
12412
|
return status === "completed" || status === "failed" || status === "skipped";
|
|
@@ -12142,13 +12451,13 @@ function reciprocalWorkflowRootRunId(runById, runId) {
|
|
|
12142
12451
|
}
|
|
12143
12452
|
|
|
12144
12453
|
// dist/builtin/workflows/src/engine/run-durable-topology.ts
|
|
12145
|
-
function durableRunTopology(
|
|
12454
|
+
function durableRunTopology(run) {
|
|
12146
12455
|
return {
|
|
12147
|
-
runId:
|
|
12148
|
-
runName:
|
|
12149
|
-
...
|
|
12150
|
-
...
|
|
12151
|
-
...
|
|
12456
|
+
runId: run.id,
|
|
12457
|
+
runName: run.name,
|
|
12458
|
+
...run.parentRunId !== undefined ? { parentRunId: run.parentRunId } : {},
|
|
12459
|
+
...run.parentStageId !== undefined ? { parentStageId: run.parentStageId } : {},
|
|
12460
|
+
...run.rootRunId !== undefined ? { rootRunId: run.rootRunId } : {}
|
|
12152
12461
|
};
|
|
12153
12462
|
}
|
|
12154
12463
|
function createDurableStageDeps(input) {
|
|
@@ -12223,7 +12532,7 @@ function createDurableCachedStageRecorder(input) {
|
|
|
12223
12532
|
return {
|
|
12224
12533
|
record(name, replayKey, checkpoint, scope) {
|
|
12225
12534
|
const cachedChildRunId = workflowChildRunId(checkpoint);
|
|
12226
|
-
const runById = new Map(input.store.runs().map((
|
|
12535
|
+
const runById = new Map(input.store.runs().map((run) => [run.id, run]));
|
|
12227
12536
|
if (!runById.has(input.run.id))
|
|
12228
12537
|
runById.set(input.run.id, input.run);
|
|
12229
12538
|
const durableRootId = reciprocalWorkflowRootRunId(runById, input.run.id);
|
|
@@ -12239,7 +12548,7 @@ function createDurableCachedStageRecorder(input) {
|
|
|
12239
12548
|
replaySourceOrders.set(replayedStage.id, sourceOrder);
|
|
12240
12549
|
input.run.stages.sort((left, right) => (replaySourceOrders.get(left.id) ?? Number.MAX_SAFE_INTEGER) - (replaySourceOrders.get(right.id) ?? Number.MAX_SAFE_INTEGER));
|
|
12241
12550
|
}
|
|
12242
|
-
const stage = input.store.runs().find((
|
|
12551
|
+
const stage = input.store.runs().find((run) => run.id === input.run.id)?.stages.find((candidate) => candidate.replayKey === replayKey);
|
|
12243
12552
|
if (stage !== undefined) {
|
|
12244
12553
|
input.backend.recordCheckpoint({
|
|
12245
12554
|
kind: "stage",
|
|
@@ -12277,10 +12586,10 @@ function createDurableCachedStageRecorder(input) {
|
|
|
12277
12586
|
};
|
|
12278
12587
|
}
|
|
12279
12588
|
function reconcileCachedDirectChildParentStage(input) {
|
|
12280
|
-
const existingRun = input.store.runs().find((
|
|
12589
|
+
const existingRun = input.store.runs().find((run) => run.id === input.checkpointChildRunId);
|
|
12281
12590
|
if (existingRun === undefined)
|
|
12282
12591
|
return false;
|
|
12283
|
-
const runById = new Map(input.store.runs().map((
|
|
12592
|
+
const runById = new Map(input.store.runs().map((run) => [run.id, run]));
|
|
12284
12593
|
const storedParentRun = runById.get(input.parentRun.id);
|
|
12285
12594
|
if (storedParentRun !== undefined && (storedParentRun.parentRunId !== input.parentRun.parentRunId || storedParentRun.parentStageId !== input.parentRun.parentStageId))
|
|
12286
12595
|
return false;
|
|
@@ -12304,6 +12613,61 @@ function workflowChildRunId(checkpoint) {
|
|
|
12304
12613
|
return (parseWorkflowChildResult(checkpoint.output) ?? (hasCurrentIdentity ? undefined : parseLegacyWorkflowChildResult(checkpoint.output)))?.runId;
|
|
12305
12614
|
}
|
|
12306
12615
|
|
|
12616
|
+
// dist/builtin/workflows/src/engine/run-paused-stage.ts
|
|
12617
|
+
function deferStageUntilRunRelease(input) {
|
|
12618
|
+
let stage;
|
|
12619
|
+
const current = () => {
|
|
12620
|
+
input.signal.throwIfAborted();
|
|
12621
|
+
if (input.isPaused())
|
|
12622
|
+
throw new Error(`Workflow is paused; resume before synchronous access to stage ${input.name}`);
|
|
12623
|
+
stage ??= input.create();
|
|
12624
|
+
return stage;
|
|
12625
|
+
};
|
|
12626
|
+
const invoke = async (call) => {
|
|
12627
|
+
while (input.isPaused())
|
|
12628
|
+
await input.waitForRelease();
|
|
12629
|
+
return call(current());
|
|
12630
|
+
};
|
|
12631
|
+
return {
|
|
12632
|
+
name: input.name,
|
|
12633
|
+
prompt: (...args) => invoke((stage) => stage.prompt(...args)),
|
|
12634
|
+
complete: (...args) => invoke((stage) => stage.complete(...args)),
|
|
12635
|
+
sendUserMessage: (...args) => invoke((stage) => stage.sendUserMessage(...args)),
|
|
12636
|
+
steer: (...args) => invoke((stage) => stage.steer(...args)),
|
|
12637
|
+
followUp: (...args) => invoke((stage) => stage.followUp(...args)),
|
|
12638
|
+
subscribe: (...args) => current().subscribe(...args),
|
|
12639
|
+
get sessionFile() {
|
|
12640
|
+
return current().sessionFile;
|
|
12641
|
+
},
|
|
12642
|
+
get sessionId() {
|
|
12643
|
+
return current().sessionId;
|
|
12644
|
+
},
|
|
12645
|
+
setModel: (...args) => invoke((stage) => stage.setModel(...args)),
|
|
12646
|
+
setThinkingLevel: (...args) => current().setThinkingLevel(...args),
|
|
12647
|
+
cycleModel: () => invoke((stage) => stage.cycleModel()),
|
|
12648
|
+
cycleThinkingLevel: () => current().cycleThinkingLevel(),
|
|
12649
|
+
get agent() {
|
|
12650
|
+
return current().agent;
|
|
12651
|
+
},
|
|
12652
|
+
get model() {
|
|
12653
|
+
return current().model;
|
|
12654
|
+
},
|
|
12655
|
+
get thinkingLevel() {
|
|
12656
|
+
return current().thinkingLevel;
|
|
12657
|
+
},
|
|
12658
|
+
get messages() {
|
|
12659
|
+
return current().messages;
|
|
12660
|
+
},
|
|
12661
|
+
get isStreaming() {
|
|
12662
|
+
return current().isStreaming;
|
|
12663
|
+
},
|
|
12664
|
+
navigateTree: (...args) => invoke((stage) => stage.navigateTree(...args)),
|
|
12665
|
+
compact: () => invoke((stage) => stage.compact()),
|
|
12666
|
+
abortCompaction: () => current().abortCompaction(),
|
|
12667
|
+
abort: () => invoke((stage) => stage.abort())
|
|
12668
|
+
};
|
|
12669
|
+
}
|
|
12670
|
+
|
|
12307
12671
|
// dist/builtin/workflows/src/engine/run-returned-status.ts
|
|
12308
12672
|
function classifyReturnedRunStatus(result, runSnapshot) {
|
|
12309
12673
|
const structuredFailure = runSnapshot !== undefined ? structuredRecoverableWorkflowFailure(runSnapshot) : undefined;
|
|
@@ -12384,9 +12748,9 @@ function createRunTerminalEventArbiter(runId) {
|
|
|
12384
12748
|
|
|
12385
12749
|
// dist/builtin/workflows/src/engine/run-terminal-failure.ts
|
|
12386
12750
|
function finalizeTerminalFailure(input) {
|
|
12387
|
-
const { runId, runSnapshot, store
|
|
12751
|
+
const { runId, runSnapshot, store, persistence, metadata, onRunEnd } = input;
|
|
12388
12752
|
const failedToolNode = metadata.failedToolNodeId === undefined ? undefined : runSnapshot.toolNodes?.find((node) => node.id === metadata.failedToolNodeId);
|
|
12389
|
-
const recorded =
|
|
12753
|
+
const recorded = store.recordRunEnd(runId, "failed", undefined, metadata.errorMessage, metadata);
|
|
12390
12754
|
appendRunEndWhenRecorded(persistence, recorded, {
|
|
12391
12755
|
runId,
|
|
12392
12756
|
status: "failed",
|
|
@@ -12405,7 +12769,7 @@ function finalizeTerminalFailure(input) {
|
|
|
12405
12769
|
...runSnapshot.durationMs !== undefined ? { durationMs: runSnapshot.durationMs } : {},
|
|
12406
12770
|
ts: Date.now()
|
|
12407
12771
|
});
|
|
12408
|
-
return reconcileTerminalRunResult(runId, runSnapshot,
|
|
12772
|
+
return reconcileTerminalRunResult(runId, runSnapshot, store, { status: "failed", error: metadata.errorMessage }, onRunEnd);
|
|
12409
12773
|
}
|
|
12410
12774
|
|
|
12411
12775
|
// dist/builtin/workflows/src/engine/run-tool-admission-boundary.ts
|
|
@@ -12459,6 +12823,7 @@ function createToolAdmissionBoundary() {
|
|
|
12459
12823
|
function createToolControlRegistry() {
|
|
12460
12824
|
const byRun = new Map;
|
|
12461
12825
|
const admissionByRun = new Map;
|
|
12826
|
+
const runControls = new Map;
|
|
12462
12827
|
const makeHandle = (registration) => ({
|
|
12463
12828
|
runId: registration.runId,
|
|
12464
12829
|
nodeId: registration.nodeId,
|
|
@@ -12517,9 +12882,18 @@ function createToolControlRegistry() {
|
|
|
12517
12882
|
admissionBoundary(runId) {
|
|
12518
12883
|
return admissionByRun.get(runId);
|
|
12519
12884
|
},
|
|
12885
|
+
registerRun(runId, handle) {
|
|
12886
|
+
runControls.set(runId, handle);
|
|
12887
|
+
return () => {
|
|
12888
|
+
if (runControls.get(runId) === handle)
|
|
12889
|
+
runControls.delete(runId);
|
|
12890
|
+
};
|
|
12891
|
+
},
|
|
12892
|
+
runControl: (runId) => runControls.get(runId),
|
|
12520
12893
|
clear() {
|
|
12521
12894
|
byRun.clear();
|
|
12522
12895
|
admissionByRun.clear();
|
|
12896
|
+
runControls.clear();
|
|
12523
12897
|
}
|
|
12524
12898
|
};
|
|
12525
12899
|
}
|
|
@@ -12533,7 +12907,7 @@ function createAdmittedToolExecutionTracker(options = {}) {
|
|
|
12533
12907
|
const admissions = [];
|
|
12534
12908
|
const failures = [];
|
|
12535
12909
|
const cancellations = [];
|
|
12536
|
-
let
|
|
12910
|
+
let nextAdmissionOrder = 0;
|
|
12537
12911
|
let state = "OPEN";
|
|
12538
12912
|
let closing;
|
|
12539
12913
|
const abandonment = Promise.withResolvers();
|
|
@@ -12542,17 +12916,17 @@ function createAdmittedToolExecutionTracker(options = {}) {
|
|
|
12542
12916
|
const recordFailure = (admission, error, nodeId) => {
|
|
12543
12917
|
if (admission.failure !== undefined)
|
|
12544
12918
|
return;
|
|
12545
|
-
const
|
|
12546
|
-
admission.failure =
|
|
12547
|
-
failures.push(
|
|
12548
|
-
options.onFailureObserved?.(
|
|
12919
|
+
const failure = { admissionOrder: admission.admissionOrder, error, ...nodeId === undefined ? {} : { nodeId } };
|
|
12920
|
+
admission.failure = failure;
|
|
12921
|
+
failures.push(failure);
|
|
12922
|
+
options.onFailureObserved?.(failure);
|
|
12549
12923
|
};
|
|
12550
12924
|
const reportDrainFailure = () => {
|
|
12551
|
-
const
|
|
12552
|
-
if (state !== "DRAINING" ||
|
|
12925
|
+
const failure = failures[0];
|
|
12926
|
+
if (state !== "DRAINING" || failure === undefined || drainFailureReported)
|
|
12553
12927
|
return;
|
|
12554
12928
|
drainFailureReported = true;
|
|
12555
|
-
options.onFailureDuringDrain?.(
|
|
12929
|
+
options.onFailureDuringDrain?.(failure);
|
|
12556
12930
|
};
|
|
12557
12931
|
const drainRecordedFailures = () => Promise.all(admissions.flatMap((admission) => admission.failure !== undefined && admission.observed !== undefined ? [admission.observed] : []));
|
|
12558
12932
|
const closeAtFixedPoint = async () => {
|
|
@@ -12576,7 +12950,7 @@ function createAdmittedToolExecutionTracker(options = {}) {
|
|
|
12576
12950
|
};
|
|
12577
12951
|
return {
|
|
12578
12952
|
track(execution) {
|
|
12579
|
-
if (state === "CLOSED") {
|
|
12953
|
+
if (state === "CLOSED" || options.signal?.aborted) {
|
|
12580
12954
|
const error = new Error("atomic-workflows: ctx.tool admission is closed for this run");
|
|
12581
12955
|
execution.catch(() => {
|
|
12582
12956
|
return;
|
|
@@ -12584,7 +12958,7 @@ function createAdmittedToolExecutionTracker(options = {}) {
|
|
|
12584
12958
|
return { accepted: false, error, bindNode() {}, noteCancelled() {} };
|
|
12585
12959
|
}
|
|
12586
12960
|
const admission = {
|
|
12587
|
-
admissionOrder: ++
|
|
12961
|
+
admissionOrder: ++nextAdmissionOrder,
|
|
12588
12962
|
nodeId: undefined,
|
|
12589
12963
|
failure: undefined,
|
|
12590
12964
|
cancelled: false,
|
|
@@ -12644,7 +13018,7 @@ function createAdmittedToolExecutionTracker(options = {}) {
|
|
|
12644
13018
|
return failures[0];
|
|
12645
13019
|
},
|
|
12646
13020
|
uniqueFailureFor(error) {
|
|
12647
|
-
const matching = [...failures, ...cancellations].filter((
|
|
13021
|
+
const matching = [...failures, ...cancellations].filter((failure) => Object.is(failure.error, error));
|
|
12648
13022
|
return matching.length === 1 ? matching[0] : undefined;
|
|
12649
13023
|
}
|
|
12650
13024
|
};
|
|
@@ -12652,8 +13026,8 @@ function createAdmittedToolExecutionTracker(options = {}) {
|
|
|
12652
13026
|
|
|
12653
13027
|
// dist/builtin/workflows/src/engine/run-tool-node-lifecycle.ts
|
|
12654
13028
|
function createToolNodeLifecycle(input) {
|
|
12655
|
-
const { store
|
|
12656
|
-
const ownsCurrentRun = () =>
|
|
13029
|
+
const { store, tracker, run, sourceToContinuationNodeIds } = input;
|
|
13030
|
+
const ownsCurrentRun = () => store.runs().some((candidate) => candidate === run);
|
|
12657
13031
|
const replayedToolNodeIds = new Set;
|
|
12658
13032
|
let pendingFrontier = input.resumeToolNode;
|
|
12659
13033
|
return {
|
|
@@ -12671,11 +13045,11 @@ function createToolNodeLifecycle(input) {
|
|
|
12671
13045
|
const sourceParents = frontier?.parentIds ?? (node.replayed === true && node.topologyState !== "unavailable" ? node.parentIds : undefined);
|
|
12672
13046
|
const restored = sourceParents?.map((sourceId) => sourceToContinuationNodeIds.get(sourceId));
|
|
12673
13047
|
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 ${
|
|
13048
|
+
if (run.resumedFromRunId !== undefined && sourceParents !== undefined && translated === undefined) {
|
|
13049
|
+
throw new Error(`${REPLAY_TOPOLOGY_MISMATCH_MESSAGE} for tool "${node.name}" (node "${node.id}") in source run ${run.resumedFromRunId}`);
|
|
12676
13050
|
}
|
|
12677
|
-
if (translated !== undefined &&
|
|
12678
|
-
throw new Error(`${REPLAY_TOPOLOGY_MISMATCH_MESSAGE} for tool "${node.name}" (node "${node.id}") in source run ${
|
|
13051
|
+
if (translated !== undefined && run.resumedFromRunId !== undefined && !compatibleReplayedToolParents(tracker, translated, inferredParents, (parentId) => isReplayedContinuationNode(store, run, replayedToolNodeIds, parentId))) {
|
|
13052
|
+
throw new Error(`${REPLAY_TOPOLOGY_MISMATCH_MESSAGE} for tool "${node.name}" (node "${node.id}") in source run ${run.resumedFromRunId}`);
|
|
12679
13053
|
}
|
|
12680
13054
|
const parentIds = translated ?? inferredParents;
|
|
12681
13055
|
tracker.replaceParents(node.id, parentIds);
|
|
@@ -12684,28 +13058,28 @@ function createToolNodeLifecycle(input) {
|
|
|
12684
13058
|
if (node.replayed === true)
|
|
12685
13059
|
replayedToolNodeIds.add(node.id);
|
|
12686
13060
|
if (ownsCurrentRun())
|
|
12687
|
-
|
|
13061
|
+
store.recordToolNodeStart(run.id, node);
|
|
12688
13062
|
if (frontier !== undefined)
|
|
12689
13063
|
pendingFrontier = undefined;
|
|
12690
13064
|
},
|
|
12691
13065
|
onNodeRunning: (nodeId, startedAt) => {
|
|
12692
13066
|
if (ownsCurrentRun())
|
|
12693
|
-
|
|
13067
|
+
store.recordToolNodeRunning(run.id, nodeId, startedAt);
|
|
12694
13068
|
},
|
|
12695
13069
|
onNodeEnd: (nodeId, update) => {
|
|
12696
13070
|
if (ownsCurrentRun())
|
|
12697
|
-
|
|
13071
|
+
store.recordToolNodeEnd(run.id, nodeId, update);
|
|
12698
13072
|
},
|
|
12699
13073
|
onNodeSettle: (nodeId) => {
|
|
12700
13074
|
tracker.onSettle(nodeId);
|
|
12701
13075
|
},
|
|
12702
|
-
runTopology: durableRunTopology(
|
|
13076
|
+
runTopology: durableRunTopology(run)
|
|
12703
13077
|
};
|
|
12704
13078
|
}
|
|
12705
|
-
function isReplayedContinuationNode(
|
|
13079
|
+
function isReplayedContinuationNode(store, run, replayedToolNodeIds, nodeId) {
|
|
12706
13080
|
if (replayedToolNodeIds.has(nodeId))
|
|
12707
13081
|
return true;
|
|
12708
|
-
const live =
|
|
13082
|
+
const live = store.runs().find((candidate) => candidate === run);
|
|
12709
13083
|
return live?.stages.some((stage) => stage.id === nodeId && stage.replayed === true) === true;
|
|
12710
13084
|
}
|
|
12711
13085
|
function compatibleReplayedToolParents(tracker, translated, inferredParents, isReplayedNode) {
|
|
@@ -12718,12 +13092,13 @@ function compatibleReplayedToolParents(tracker, translated, inferredParents, isR
|
|
|
12718
13092
|
function createTrackedToolPrimitive(input) {
|
|
12719
13093
|
let observedQuit;
|
|
12720
13094
|
const admittedTools = createAdmittedToolExecutionTracker({
|
|
13095
|
+
signal: input.controller.signal,
|
|
12721
13096
|
onFailureObserved: ({ error, nodeId }) => {
|
|
12722
13097
|
input.terminalEvents.selectFailure(error, nodeId);
|
|
12723
13098
|
},
|
|
12724
|
-
onFailureDuringDrain: (
|
|
13099
|
+
onFailureDuringDrain: (failure) => {
|
|
12725
13100
|
if (input.terminalEvents.winner()?.kind === "failure")
|
|
12726
|
-
input.controller.abort(
|
|
13101
|
+
input.controller.abort(failure.error);
|
|
12727
13102
|
}
|
|
12728
13103
|
});
|
|
12729
13104
|
const lifecycle = createToolNodeLifecycle(input);
|
|
@@ -13102,7 +13477,7 @@ function createTrackedStageCaller(input) {
|
|
|
13102
13477
|
if (suppressQueuedContinuation)
|
|
13103
13478
|
runtime.state.suppressQueuedUserMessageContinuation = true;
|
|
13104
13479
|
try {
|
|
13105
|
-
result = await runtime.raceStageSessionHeartbeat(raceAbort(runtime.innerCtx.
|
|
13480
|
+
result = await runtime.raceStageSessionHeartbeat(raceAbort(runtime.innerCtx.__continuePrompt(RESUME_CONTINUATION_PROMPT), runtime.signal));
|
|
13106
13481
|
} finally {
|
|
13107
13482
|
if (suppressQueuedContinuation)
|
|
13108
13483
|
runtime.state.suppressQueuedUserMessageContinuation = false;
|
|
@@ -13207,9 +13582,9 @@ function createTrackedStageCaller(input) {
|
|
|
13207
13582
|
let resolveNextTurnEnd = null;
|
|
13208
13583
|
const unsubscribeTurnWatcher = runtime.innerCtx.subscribe((event) => {
|
|
13209
13584
|
if (event.type === "agent_end" && resolveNextTurnEnd) {
|
|
13210
|
-
const
|
|
13585
|
+
const resolve = resolveNextTurnEnd;
|
|
13211
13586
|
resolveNextTurnEnd = null;
|
|
13212
|
-
|
|
13587
|
+
resolve();
|
|
13213
13588
|
}
|
|
13214
13589
|
});
|
|
13215
13590
|
try {
|
|
@@ -13222,15 +13597,15 @@ function createTrackedStageCaller(input) {
|
|
|
13222
13597
|
runtime.state.askUserQuestionObservedThisTurn = false;
|
|
13223
13598
|
runtime.state.chatAnswerObservedThisTurn = false;
|
|
13224
13599
|
if (decision.message !== undefined) {
|
|
13225
|
-
result = await runtime.raceStageSessionHeartbeat(raceAbort(runtime.innerCtx.
|
|
13600
|
+
result = await runtime.raceStageSessionHeartbeat(raceAbort(runtime.innerCtx.__continuePrompt(decision.message), runtime.signal));
|
|
13226
13601
|
if (runtime.budget.enabled && typeof result === "string")
|
|
13227
13602
|
stageResultBeforeBudget = result;
|
|
13228
13603
|
} else {
|
|
13229
13604
|
runtime.state.waitingForStageChatTurn = true;
|
|
13230
13605
|
try {
|
|
13231
|
-
await runtime.raceStageSessionHeartbeat(raceAbort(new Promise((
|
|
13232
|
-
resolveNextTurnEnd =
|
|
13233
|
-
runtime.state.wakeWaitingForStageChatTurn =
|
|
13606
|
+
await runtime.raceStageSessionHeartbeat(raceAbort(new Promise((resolve) => {
|
|
13607
|
+
resolveNextTurnEnd = resolve;
|
|
13608
|
+
runtime.state.wakeWaitingForStageChatTurn = resolve;
|
|
13234
13609
|
}), runtime.signal));
|
|
13235
13610
|
} finally {
|
|
13236
13611
|
runtime.state.wakeWaitingForStageChatTurn = undefined;
|
|
@@ -13270,7 +13645,9 @@ function createTrackedStageCaller(input) {
|
|
|
13270
13645
|
await runtime.budget.deliverWrapUp(runtime.name);
|
|
13271
13646
|
if (afterBudget.kind === "exhausted" && runtime.budget.enabled)
|
|
13272
13647
|
await runtime.budget.stopAtBoundaryAsync(runtime.name);
|
|
13273
|
-
await runtime.innerCtx.__closeGeneration();
|
|
13648
|
+
const finalizedArtifact = await runtime.innerCtx.__closeGeneration();
|
|
13649
|
+
if (typeof result === "string" && finalizedArtifact !== undefined)
|
|
13650
|
+
result = finalizedArtifact;
|
|
13274
13651
|
await runtime.captureStageSessionMeta({ awaitDurable: true });
|
|
13275
13652
|
if (trackStageLifecycle && runtime.stageFailFastScope?.failed === true && runtime.stageFailFastScope.activeStages.has(runtime.stageId)) {
|
|
13276
13653
|
runtime.markSkippedForParallelFailFast();
|
|
@@ -13299,7 +13676,7 @@ function createTrackedStageCaller(input) {
|
|
|
13299
13676
|
const budgetError = err instanceof WorkflowBudgetExceededError ? err : undefined;
|
|
13300
13677
|
if (budgetError !== undefined && trackStageLifecycle && !runtime.state.skippedForParallelFailFast) {
|
|
13301
13678
|
let selectedBudgetError = budgetError;
|
|
13302
|
-
if (runtime.activeStore.runs().find((
|
|
13679
|
+
if (runtime.activeStore.runs().find((run) => run.id === runtime.runId)?.budgetState?.wrapUpCompleted !== true) {
|
|
13303
13680
|
try {
|
|
13304
13681
|
await runtime.budget.deliverWrapUp(runtime.name);
|
|
13305
13682
|
} catch (wrapUpError) {
|
|
@@ -13327,8 +13704,8 @@ function createTrackedStageCaller(input) {
|
|
|
13327
13704
|
};
|
|
13328
13705
|
}
|
|
13329
13706
|
} else if (trackStageLifecycle && !runtime.signal.aborted && !runtime.state.skippedForParallelFailFast) {
|
|
13330
|
-
const
|
|
13331
|
-
applyTerminalStageState = () => applyFailureToStage(runtime.stageSnapshot,
|
|
13707
|
+
const failure = runtime.classifyExecutorFailure(err);
|
|
13708
|
+
applyTerminalStageState = () => applyFailureToStage(runtime.stageSnapshot, failure);
|
|
13332
13709
|
}
|
|
13333
13710
|
throw err;
|
|
13334
13711
|
} finally {
|
|
@@ -13354,8 +13731,8 @@ function createTrackedStageCaller(input) {
|
|
|
13354
13731
|
finalizationError ??= durableCheckpointError;
|
|
13355
13732
|
if (trackStageLifecycle) {
|
|
13356
13733
|
if (durableCheckpointError !== undefined && terminalStateIsSuccess) {
|
|
13357
|
-
const
|
|
13358
|
-
applyTerminalStageState = () => applyFailureToStage(runtime.stageSnapshot,
|
|
13734
|
+
const failure = runtime.classifyExecutorFailure(durableCheckpointError.error);
|
|
13735
|
+
applyTerminalStageState = () => applyFailureToStage(runtime.stageSnapshot, failure);
|
|
13359
13736
|
}
|
|
13360
13737
|
if (!runtime.state.stageFinalized)
|
|
13361
13738
|
applyTerminalStageState?.();
|
|
@@ -13613,8 +13990,8 @@ class StageToolExecutionBuffer {
|
|
|
13613
13990
|
// dist/builtin/workflows/src/runs/foreground/executor-stage-control.ts
|
|
13614
13991
|
function createStageControlHandle(runtime) {
|
|
13615
13992
|
const messagePreparation = () => {
|
|
13616
|
-
const
|
|
13617
|
-
if (
|
|
13993
|
+
const meta = runtime.innerCtx.__sessionMeta();
|
|
13994
|
+
if (meta.sessionId !== undefined || meta.sessionFile !== undefined) {
|
|
13618
13995
|
return { beforePreparation: runtime.throwIfStageMutationBlocked };
|
|
13619
13996
|
}
|
|
13620
13997
|
if (runtime.stageSnapshot.sessionFile !== undefined) {
|
|
@@ -13744,8 +14121,8 @@ function createStageControlHandle(runtime) {
|
|
|
13744
14121
|
if (changed) {
|
|
13745
14122
|
runtime.scheduler.ensureReleaseBarrier(runtime.stageId);
|
|
13746
14123
|
await runtime.scheduler.cascadePauseFrom(runtime.stageId);
|
|
13747
|
-
const
|
|
13748
|
-
const stillActive =
|
|
14124
|
+
const run = runtime.activeStore.runs().find((candidate) => candidate.id === runtime.runId);
|
|
14125
|
+
const stillActive = run?.stages.some((stage) => stage.status === "running" && stage.id !== runtime.stageId) ?? false;
|
|
13749
14126
|
if (!stillActive)
|
|
13750
14127
|
runtime.activeStore.recordRunPaused(runtime.runId);
|
|
13751
14128
|
}
|
|
@@ -13812,6 +14189,7 @@ function createStageControlHandle(runtime) {
|
|
|
13812
14189
|
// dist/builtin/workflows/src/runs/foreground/executor-stage-replay.ts
|
|
13813
14190
|
function createReplayStageContext(input) {
|
|
13814
14191
|
const { runId, name, stageId, stageSnapshot, replaySource } = input;
|
|
14192
|
+
workflowObservationRuntime(input.activeStore).replayStageIds.add(workflowActivityNodeKey(runId, stageId));
|
|
13815
14193
|
let replayFinalized = false;
|
|
13816
14194
|
let unregisterWorkflowExitCleanup = () => {};
|
|
13817
14195
|
let stageStartEntryAppended = false;
|
|
@@ -13881,6 +14259,7 @@ function createReplayStageContext(input) {
|
|
|
13881
14259
|
return {
|
|
13882
14260
|
name,
|
|
13883
14261
|
prompt: replayText,
|
|
14262
|
+
__continuePrompt: replayText,
|
|
13884
14263
|
complete: replayText,
|
|
13885
14264
|
sendUserMessage: async () => rejectReplayMutation("send a user message"),
|
|
13886
14265
|
__sendUserMessage: async () => rejectReplayMutation("send a user message"),
|
|
@@ -13943,13 +14322,13 @@ function createReplayStageContext(input) {
|
|
|
13943
14322
|
|
|
13944
14323
|
// dist/builtin/workflows/src/durable/run-owner-backend.ts
|
|
13945
14324
|
function durableRootRunIdForRun(runs, runId) {
|
|
13946
|
-
return reciprocalWorkflowRootRunId(new Map(runs.map((
|
|
14325
|
+
return reciprocalWorkflowRootRunId(new Map(runs.map((run) => [run.id, run])), runId);
|
|
13947
14326
|
}
|
|
13948
14327
|
function durableBackendForRun(backend, runs, runId) {
|
|
13949
14328
|
const rootRunId = durableRootRunIdForRun(runs, runId);
|
|
13950
14329
|
if (rootRunId === undefined)
|
|
13951
14330
|
return;
|
|
13952
|
-
const runById = new Map(runs.map((
|
|
14331
|
+
const runById = new Map(runs.map((run) => [run.id, run]));
|
|
13953
14332
|
if (rootRunId === runId)
|
|
13954
14333
|
return backend;
|
|
13955
14334
|
const scopes = [];
|
|
@@ -13972,17 +14351,17 @@ function durableBackendForRun(backend, runs, runId) {
|
|
|
13972
14351
|
}
|
|
13973
14352
|
|
|
13974
14353
|
// dist/builtin/workflows/src/shared/pending-stage-route-capability.ts
|
|
13975
|
-
import { randomUUID as
|
|
14354
|
+
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
13976
14355
|
var routeCapabilities = new WeakMap;
|
|
13977
|
-
function workflowPendingStageRouteCapability(
|
|
13978
|
-
let capabilities = routeCapabilities.get(
|
|
14356
|
+
function workflowPendingStageRouteCapability(store, runId) {
|
|
14357
|
+
let capabilities = routeCapabilities.get(store);
|
|
13979
14358
|
if (capabilities === undefined) {
|
|
13980
14359
|
capabilities = new Map;
|
|
13981
|
-
routeCapabilities.set(
|
|
14360
|
+
routeCapabilities.set(store, capabilities);
|
|
13982
14361
|
}
|
|
13983
14362
|
let capability = capabilities.get(runId);
|
|
13984
14363
|
if (capability === undefined) {
|
|
13985
|
-
capability =
|
|
14364
|
+
capability = randomUUID5();
|
|
13986
14365
|
capabilities.set(runId, capability);
|
|
13987
14366
|
}
|
|
13988
14367
|
return capability;
|
|
@@ -14066,7 +14445,7 @@ function parseWorkflowStageTarget(target) {
|
|
|
14066
14445
|
|
|
14067
14446
|
// dist/builtin/workflows/src/shared/pending-stage-status.ts
|
|
14068
14447
|
function workflowBoundaryHops(runs, runId) {
|
|
14069
|
-
const runById = new Map(runs.map((
|
|
14448
|
+
const runById = new Map(runs.map((run) => [run.id, run]));
|
|
14070
14449
|
const hops = [];
|
|
14071
14450
|
let current = runById.get(runId);
|
|
14072
14451
|
while (current !== undefined && current.parentRunId !== undefined) {
|
|
@@ -14125,8 +14504,8 @@ function createWorkflowPendingStageDelivery(activeStore, runId, stageId, stageNa
|
|
|
14125
14504
|
let drainPromise;
|
|
14126
14505
|
const pendingReady = () => {
|
|
14127
14506
|
if (readyPromise === undefined) {
|
|
14128
|
-
readyPromise = new Promise((
|
|
14129
|
-
resolveReady =
|
|
14507
|
+
readyPromise = new Promise((resolve, reject) => {
|
|
14508
|
+
resolveReady = resolve;
|
|
14130
14509
|
rejectReady = reject;
|
|
14131
14510
|
});
|
|
14132
14511
|
}
|
|
@@ -14182,7 +14561,7 @@ async function deliverPendingStageMessages(activeStore, runId, stageId, stageNam
|
|
|
14182
14561
|
].map((entry) => entry.id));
|
|
14183
14562
|
const runs = activeStore.runs();
|
|
14184
14563
|
const entries = [
|
|
14185
|
-
...(runs.find((
|
|
14564
|
+
...(runs.find((run) => run.id === runId)?.pendingStageMessages ?? []).map((entry, index) => ({ entry, index })).filter(({ entry }) => candidateIds.has(entry.id) && entry.sticky !== true),
|
|
14186
14565
|
...stickyEntries.map((entry) => ({ entry, index: Number.MAX_SAFE_INTEGER }))
|
|
14187
14566
|
].sort((left, right) => (left.entry.admissionOrder ?? left.index + 1) - (right.entry.admissionOrder ?? right.index + 1) || left.index - right.index).map(({ entry }) => entry);
|
|
14188
14567
|
const rootBackend = getDurableBackend();
|
|
@@ -14226,7 +14605,7 @@ function stickyPendingStageEntriesForStage(activeStore, runId, stageId, stageNam
|
|
|
14226
14605
|
const rootRunId = durableRootRunIdForRun(runs, runId);
|
|
14227
14606
|
if (rootRunId === undefined)
|
|
14228
14607
|
return [];
|
|
14229
|
-
const rootRun = runs.find((
|
|
14608
|
+
const rootRun = runs.find((run) => run.id === rootRunId);
|
|
14230
14609
|
if (rootRun === undefined)
|
|
14231
14610
|
return [];
|
|
14232
14611
|
const hops = workflowBoundaryHops(runs, runId);
|
|
@@ -14244,20 +14623,20 @@ function stickyPendingStageEntriesForStage(activeStore, runId, stageId, stageNam
|
|
|
14244
14623
|
return stageMatchesPathPattern(parsed.segments, hops, [stageId, stageName]);
|
|
14245
14624
|
});
|
|
14246
14625
|
}
|
|
14247
|
-
function claimPendingDelivery(
|
|
14248
|
-
let claims = pendingDeliveryClaims.get(
|
|
14626
|
+
function claimPendingDelivery(store, runId, stageKey, messageId) {
|
|
14627
|
+
let claims = pendingDeliveryClaims.get(store);
|
|
14249
14628
|
if (claims === undefined) {
|
|
14250
14629
|
claims = new Set;
|
|
14251
|
-
pendingDeliveryClaims.set(
|
|
14630
|
+
pendingDeliveryClaims.set(store, claims);
|
|
14252
14631
|
}
|
|
14253
|
-
const
|
|
14254
|
-
if (claims.has(
|
|
14632
|
+
const key = JSON.stringify([runId, stageKey, messageId]);
|
|
14633
|
+
if (claims.has(key))
|
|
14255
14634
|
return;
|
|
14256
|
-
claims.add(
|
|
14635
|
+
claims.add(key);
|
|
14257
14636
|
return () => {
|
|
14258
|
-
claims?.delete(
|
|
14637
|
+
claims?.delete(key);
|
|
14259
14638
|
if (claims?.size === 0)
|
|
14260
|
-
pendingDeliveryClaims.delete(
|
|
14639
|
+
pendingDeliveryClaims.delete(store);
|
|
14261
14640
|
};
|
|
14262
14641
|
}
|
|
14263
14642
|
function toPendingStageSender(entry) {
|
|
@@ -14321,8 +14700,8 @@ class WorkflowModelValidationError extends Error {
|
|
|
14321
14700
|
}
|
|
14322
14701
|
function formatModelValidationError(failures) {
|
|
14323
14702
|
const lines = ["workflows: model validation failed before starting workflow.", "Unavailable or ambiguous models:"];
|
|
14324
|
-
for (const
|
|
14325
|
-
lines.push(`- ${
|
|
14703
|
+
for (const failure of failures) {
|
|
14704
|
+
lines.push(`- ${failure.input} (${failure.reason})`);
|
|
14326
14705
|
}
|
|
14327
14706
|
return lines.join(`
|
|
14328
14707
|
`);
|
|
@@ -14430,10 +14809,10 @@ function buildModelCandidates(input) {
|
|
|
14430
14809
|
failures.push(resolved);
|
|
14431
14810
|
continue;
|
|
14432
14811
|
}
|
|
14433
|
-
const
|
|
14434
|
-
if (seen.has(
|
|
14812
|
+
const key = candidateKey(resolved);
|
|
14813
|
+
if (seen.has(key))
|
|
14435
14814
|
continue;
|
|
14436
|
-
seen.add(
|
|
14815
|
+
seen.add(key);
|
|
14437
14816
|
candidates.push(resolved);
|
|
14438
14817
|
}
|
|
14439
14818
|
if (failures.length > 0)
|
|
@@ -14526,6 +14905,89 @@ class StageDeliveryActivity {
|
|
|
14526
14905
|
}
|
|
14527
14906
|
}
|
|
14528
14907
|
|
|
14908
|
+
// dist/builtin/workflows/src/runs/foreground/stage-runner-artifact-capture.ts
|
|
14909
|
+
class StageArtifactCapture {
|
|
14910
|
+
session;
|
|
14911
|
+
seen = new WeakSet;
|
|
14912
|
+
accepted = [];
|
|
14913
|
+
provisional;
|
|
14914
|
+
receivesMessageEvents = false;
|
|
14915
|
+
closed = false;
|
|
14916
|
+
reset() {
|
|
14917
|
+
this.session = undefined;
|
|
14918
|
+
this.seen = new WeakSet;
|
|
14919
|
+
this.accepted = [];
|
|
14920
|
+
this.provisional = undefined;
|
|
14921
|
+
this.receivesMessageEvents = false;
|
|
14922
|
+
this.closed = false;
|
|
14923
|
+
}
|
|
14924
|
+
beginAttempt(session) {
|
|
14925
|
+
if (this.closed)
|
|
14926
|
+
return;
|
|
14927
|
+
if (this.session === session)
|
|
14928
|
+
this.scan();
|
|
14929
|
+
else {
|
|
14930
|
+
this.session = session;
|
|
14931
|
+
this.receivesMessageEvents = false;
|
|
14932
|
+
this.rememberContext();
|
|
14933
|
+
}
|
|
14934
|
+
this.provisional = [];
|
|
14935
|
+
}
|
|
14936
|
+
settleAttempt(success) {
|
|
14937
|
+
if (this.closed)
|
|
14938
|
+
return;
|
|
14939
|
+
this.scan();
|
|
14940
|
+
if (success)
|
|
14941
|
+
this.accepted.push(...this.provisional ?? []);
|
|
14942
|
+
this.provisional = undefined;
|
|
14943
|
+
}
|
|
14944
|
+
close() {
|
|
14945
|
+
this.scan();
|
|
14946
|
+
this.closed = true;
|
|
14947
|
+
this.session = undefined;
|
|
14948
|
+
this.seen = new WeakSet;
|
|
14949
|
+
this.provisional = undefined;
|
|
14950
|
+
}
|
|
14951
|
+
onEvent(session, event) {
|
|
14952
|
+
if (session !== this.session)
|
|
14953
|
+
return;
|
|
14954
|
+
if (event.type === "message_end") {
|
|
14955
|
+
this.receivesMessageEvents = true;
|
|
14956
|
+
this.capture(event.message);
|
|
14957
|
+
}
|
|
14958
|
+
if (event.type === "compaction_end")
|
|
14959
|
+
this.rememberContext();
|
|
14960
|
+
}
|
|
14961
|
+
messages() {
|
|
14962
|
+
this.scan();
|
|
14963
|
+
return this.accepted;
|
|
14964
|
+
}
|
|
14965
|
+
rememberContext(session = this.session) {
|
|
14966
|
+
if (session !== this.session)
|
|
14967
|
+
return;
|
|
14968
|
+
for (const message of this.session?.messages ?? [])
|
|
14969
|
+
this.seen.add(message);
|
|
14970
|
+
}
|
|
14971
|
+
scan() {
|
|
14972
|
+
if (this.receivesMessageEvents)
|
|
14973
|
+
return;
|
|
14974
|
+
for (const message of this.session?.messages ?? [])
|
|
14975
|
+
this.capture(message);
|
|
14976
|
+
}
|
|
14977
|
+
capture(message) {
|
|
14978
|
+
if (this.seen.has(message))
|
|
14979
|
+
return;
|
|
14980
|
+
this.seen.add(message);
|
|
14981
|
+
if (message.role !== "assistant")
|
|
14982
|
+
return;
|
|
14983
|
+
if (message.stopReason !== "stop" && message.stopReason !== "length")
|
|
14984
|
+
return;
|
|
14985
|
+
if (message.content.some((block) => block.type === "toolCall"))
|
|
14986
|
+
return;
|
|
14987
|
+
(this.provisional ?? this.accepted).push(structuredClone(message));
|
|
14988
|
+
}
|
|
14989
|
+
}
|
|
14990
|
+
|
|
14529
14991
|
// dist/builtin/workflows/src/runs/foreground/stage-runner-candidate.ts
|
|
14530
14992
|
function effectiveCandidateReasoning(candidate, fallback) {
|
|
14531
14993
|
return candidate.reasoningLevel ?? fallback;
|
|
@@ -14731,6 +15193,23 @@ function extractMessageText(message) {
|
|
|
14731
15193
|
}
|
|
14732
15194
|
return "";
|
|
14733
15195
|
}
|
|
15196
|
+
function assistantArtifactTextForGeneration(messages) {
|
|
15197
|
+
const answers = messages.flatMap((message) => {
|
|
15198
|
+
if (message.role !== "assistant")
|
|
15199
|
+
return [];
|
|
15200
|
+
if (message.stopReason !== "stop" && message.stopReason !== "length")
|
|
15201
|
+
return [];
|
|
15202
|
+
if (message.content.some((block) => block.type === "toolCall"))
|
|
15203
|
+
return [];
|
|
15204
|
+
const text = extractMessageText(message);
|
|
15205
|
+
return text.length > 0 ? [text] : [];
|
|
15206
|
+
});
|
|
15207
|
+
return answers.map((text, index) => index === 0 ? text : `
|
|
15208
|
+
|
|
15209
|
+
## Supplement ${index}
|
|
15210
|
+
|
|
15211
|
+
${text}`).join("");
|
|
15212
|
+
}
|
|
14734
15213
|
function lastAssistantTextFromMessages(messages) {
|
|
14735
15214
|
for (let index = messages.length - 1;index >= 0; index -= 1) {
|
|
14736
15215
|
const message = messages[index];
|
|
@@ -14751,7 +15230,7 @@ function structuredOutputTurnDetail(messages, startIndex) {
|
|
|
14751
15230
|
}
|
|
14752
15231
|
return "The model produced no assistant message after the prompt";
|
|
14753
15232
|
}
|
|
14754
|
-
function assistantArtifactTextForToolCall(messages,
|
|
15233
|
+
function assistantArtifactTextForToolCall(messages, toolCallId) {
|
|
14755
15234
|
for (let index = messages.length - 1;index >= 0; index -= 1) {
|
|
14756
15235
|
const message = messages[index];
|
|
14757
15236
|
if (message?.role !== "assistant")
|
|
@@ -14759,7 +15238,7 @@ function assistantArtifactTextForToolCall(messages, toolCallId2) {
|
|
|
14759
15238
|
const { content } = message;
|
|
14760
15239
|
if (!Array.isArray(content))
|
|
14761
15240
|
continue;
|
|
14762
|
-
if (!content.some((block) => block.type === "toolCall" && block.id ===
|
|
15241
|
+
if (!content.some((block) => block.type === "toolCall" && block.id === toolCallId))
|
|
14763
15242
|
continue;
|
|
14764
15243
|
const text = extractMessageText(message);
|
|
14765
15244
|
if (text.trim().length > 0)
|
|
@@ -14834,8 +15313,8 @@ function terminatingToolResultText(messages, terminatingToolCallIds) {
|
|
|
14834
15313
|
if (!message)
|
|
14835
15314
|
continue;
|
|
14836
15315
|
if (message.role === "toolResult") {
|
|
14837
|
-
const
|
|
14838
|
-
if (typeof
|
|
15316
|
+
const toolCallId = message.toolCallId;
|
|
15317
|
+
if (typeof toolCallId !== "string" || !terminatingToolCallIds.has(toolCallId)) {
|
|
14839
15318
|
return;
|
|
14840
15319
|
}
|
|
14841
15320
|
const text = extractMessageText(message).trim();
|
|
@@ -14868,27 +15347,27 @@ function assistantMessage(text) {
|
|
|
14868
15347
|
|
|
14869
15348
|
// dist/builtin/workflows/src/runs/foreground/stage-runner-options.ts
|
|
14870
15349
|
import { SessionManager } from "@bastani/atomic";
|
|
14871
|
-
function workflowSessionOptions(
|
|
15350
|
+
function workflowSessionOptions(meta) {
|
|
14872
15351
|
return {
|
|
14873
15352
|
internal: true,
|
|
14874
|
-
workflow: { runId:
|
|
15353
|
+
workflow: { runId: meta.runId, stageId: meta.stageId, stageName: meta.stageName }
|
|
14875
15354
|
};
|
|
14876
15355
|
}
|
|
14877
|
-
function workflowOrchestrationContext(
|
|
15356
|
+
function workflowOrchestrationContext(meta, stageOptions, pendingStageDelivery) {
|
|
14878
15357
|
const base = {
|
|
14879
15358
|
kind: "workflow-stage",
|
|
14880
|
-
workflowRunId:
|
|
14881
|
-
workflowStageId:
|
|
14882
|
-
workflowStageName:
|
|
15359
|
+
workflowRunId: meta.runId,
|
|
15360
|
+
workflowStageId: meta.stageId,
|
|
15361
|
+
workflowStageName: meta.stageName,
|
|
14883
15362
|
constraints: { disableWorkflowTool: true }
|
|
14884
15363
|
};
|
|
14885
|
-
const intercomGroup = stageHasIntercomAccess(stageOptions) ? resolveStageGroup(stageOptions,
|
|
15364
|
+
const intercomGroup = stageHasIntercomAccess(stageOptions) ? resolveStageGroup(stageOptions, meta.workflowIntercomGroup) : undefined;
|
|
14886
15365
|
const context = intercomGroup ? { ...base, intercomGroup } : base;
|
|
14887
15366
|
return pendingStageDelivery === undefined ? context : { ...context, pendingStageDelivery };
|
|
14888
15367
|
}
|
|
14889
|
-
function stripWorkflowOnlyOptions(options, defaultSessionDir,
|
|
14890
|
-
const classification = workflowSessionOptions(
|
|
14891
|
-
const orchestrationContext = workflowOrchestrationContext(
|
|
15368
|
+
function stripWorkflowOnlyOptions(options, defaultSessionDir, meta, pendingStageDelivery) {
|
|
15369
|
+
const classification = workflowSessionOptions(meta);
|
|
15370
|
+
const orchestrationContext = workflowOrchestrationContext(meta, options, pendingStageDelivery);
|
|
14892
15371
|
if (!options) {
|
|
14893
15372
|
return defaultSessionDir === undefined ? { orchestrationContext } : {
|
|
14894
15373
|
orchestrationContext,
|
|
@@ -15227,30 +15706,31 @@ async function sendStageUserMessage(activeSession, content, options, beforeDeliv
|
|
|
15227
15706
|
if (activeSession.sendUserMessage !== undefined) {
|
|
15228
15707
|
beforeDelivery?.();
|
|
15229
15708
|
let reportedAction;
|
|
15230
|
-
const
|
|
15231
|
-
|
|
15232
|
-
const
|
|
15709
|
+
const ownership = streaming ? undefined : admission === undefined ? createLocalPromptOwnershipObserver(activeSession, promptStarted) : coordinatedPromptOwnershipObserver(admission.startTurn(activeSession, promptStarted ?? (() => {})));
|
|
15710
|
+
ownership?.arm();
|
|
15711
|
+
const deliveryId = streaming ? undefined : activity?.start();
|
|
15233
15712
|
try {
|
|
15234
15713
|
const delivery = activeSession.sendUserMessage(content, {
|
|
15235
15714
|
...deliverAs === undefined ? {} : { deliverAs },
|
|
15715
|
+
...options?.expandPromptTemplates === undefined ? {} : { expandPromptTemplates: options.expandPromptTemplates },
|
|
15236
15716
|
__workflowDelivery: {
|
|
15237
|
-
promptStarted:
|
|
15238
|
-
delivered(
|
|
15239
|
-
reportedAction =
|
|
15717
|
+
promptStarted: ownership?.observe ?? promptStarted,
|
|
15718
|
+
delivered(action) {
|
|
15719
|
+
reportedAction = action;
|
|
15240
15720
|
}
|
|
15241
15721
|
}
|
|
15242
15722
|
});
|
|
15243
|
-
|
|
15723
|
+
ownership?.observeStreaming();
|
|
15244
15724
|
await delivery;
|
|
15245
15725
|
const action = reportedAction ?? (streaming ? deliverAs ?? "followUp" : "prompt");
|
|
15246
|
-
|
|
15726
|
+
ownership?.settle(action);
|
|
15247
15727
|
return action;
|
|
15248
15728
|
} catch (error) {
|
|
15249
|
-
|
|
15729
|
+
ownership?.settle();
|
|
15250
15730
|
throw error;
|
|
15251
15731
|
} finally {
|
|
15252
|
-
|
|
15253
|
-
activity?.settle(
|
|
15732
|
+
ownership?.dispose();
|
|
15733
|
+
activity?.settle(deliveryId);
|
|
15254
15734
|
}
|
|
15255
15735
|
}
|
|
15256
15736
|
if (typeof content !== "string")
|
|
@@ -15550,9 +16030,25 @@ class StageSessionController {
|
|
|
15550
16030
|
pendingCreationResumeMessage;
|
|
15551
16031
|
messageAdmission = new StageMessageAdmission;
|
|
15552
16032
|
deliveryActivity = new StageDeliveryActivity;
|
|
15553
|
-
|
|
16033
|
+
artifactCapture = new StageArtifactCapture;
|
|
16034
|
+
beginOutputGeneration() {
|
|
16035
|
+
this.artifactCapture.reset();
|
|
16036
|
+
}
|
|
16037
|
+
outputGenerationMessages() {
|
|
16038
|
+
return this.artifactCapture.messages();
|
|
16039
|
+
}
|
|
16040
|
+
async navigateTree(...args) {
|
|
16041
|
+
const session = await this.ensureSession();
|
|
16042
|
+
this.artifactCapture.messages();
|
|
16043
|
+
try {
|
|
16044
|
+
return await session.navigateTree(...args);
|
|
16045
|
+
} finally {
|
|
16046
|
+
this.artifactCapture.rememberContext(session);
|
|
16047
|
+
}
|
|
16048
|
+
}
|
|
16049
|
+
constructor(opts, meta, effectiveStageOptions, structuredOutputCapture) {
|
|
15554
16050
|
this.opts = opts;
|
|
15555
|
-
this.meta =
|
|
16051
|
+
this.meta = meta;
|
|
15556
16052
|
this.effectiveStageOptions = effectiveStageOptions;
|
|
15557
16053
|
this.structuredOutputCapture = structuredOutputCapture;
|
|
15558
16054
|
this.hasExplicitModelFallbackConfig = effectiveStageOptions?.model !== undefined || (effectiveStageOptions?.fallbackModels?.length ?? 0) > 0;
|
|
@@ -15675,10 +16171,10 @@ class StageSessionController {
|
|
|
15675
16171
|
const sessionFile = preparation?.sessionFile;
|
|
15676
16172
|
const deliver = async (activity) => {
|
|
15677
16173
|
const activeSession = sessionFile === undefined ? await this.ensureSession("prompt") : await this.ensureSessionFromFile(sessionFile, "prompt");
|
|
15678
|
-
const
|
|
15679
|
-
if (
|
|
16174
|
+
const pausedDelivery = this.pauseControl.deferRunnerOwnedDelivery(() => sendStageUserMessage(activeSession, content, options, beforeDelivery, release, this.messageAdmission, activity));
|
|
16175
|
+
if (pausedDelivery !== undefined) {
|
|
15680
16176
|
release();
|
|
15681
|
-
return
|
|
16177
|
+
return pausedDelivery;
|
|
15682
16178
|
}
|
|
15683
16179
|
return sendStageUserMessage(activeSession, content, options, beforeDelivery, release, this.messageAdmission, activity);
|
|
15684
16180
|
};
|
|
@@ -15700,18 +16196,19 @@ class StageSessionController {
|
|
|
15700
16196
|
const pending = this.activeCreation ?? this.sessionPromise;
|
|
15701
16197
|
const session = pending ? await pending : this.session;
|
|
15702
16198
|
await session?.closeWorkflowStageGeneration?.();
|
|
16199
|
+
this.artifactCapture.close();
|
|
15703
16200
|
}
|
|
15704
16201
|
async promptWithFallback(text, sdkOptions, consumer = "prompt") {
|
|
15705
16202
|
if (!this.hasExplicitModelFallbackConfig) {
|
|
15706
16203
|
try {
|
|
15707
16204
|
const activeSession = await this.ensureSession(consumer);
|
|
15708
|
-
const
|
|
16205
|
+
const resumedText = this.pendingCreationResumeMessage;
|
|
15709
16206
|
this.pendingCreationResumeMessage = undefined;
|
|
15710
16207
|
const value = activeSession.model ?? "default";
|
|
15711
16208
|
const candidate = { id: workflowModelId(value) ?? "default", value };
|
|
15712
16209
|
this.beginAttemptUsage(activeSession);
|
|
15713
16210
|
try {
|
|
15714
|
-
await this.promptWithThrownErrorRetry(activeSession,
|
|
16211
|
+
await this.promptWithThrownErrorRetry(activeSession, resumedText ?? text, sdkOptions);
|
|
15715
16212
|
} catch (error) {
|
|
15716
16213
|
await this.handleCandidateFailure(error, candidate, [candidate], 0);
|
|
15717
16214
|
throw error;
|
|
@@ -15728,10 +16225,12 @@ class StageSessionController {
|
|
|
15728
16225
|
if (candidates.length === 0) {
|
|
15729
16226
|
try {
|
|
15730
16227
|
const activeSession = await this.ensureSession(consumer);
|
|
15731
|
-
const
|
|
16228
|
+
const resumedText = this.pendingCreationResumeMessage;
|
|
15732
16229
|
this.pendingCreationResumeMessage = undefined;
|
|
15733
|
-
await this.promptWithThrownErrorRetry(activeSession,
|
|
16230
|
+
await this.promptWithThrownErrorRetry(activeSession, resumedText ?? text, sdkOptions);
|
|
16231
|
+
this.artifactCapture.settleAttempt(true);
|
|
15734
16232
|
} catch (error) {
|
|
16233
|
+
this.artifactCapture.settleAttempt(false);
|
|
15735
16234
|
if (error instanceof StageSessionCreationCancelled)
|
|
15736
16235
|
return;
|
|
15737
16236
|
throw error;
|
|
@@ -15779,10 +16278,10 @@ class StageSessionController {
|
|
|
15779
16278
|
this.recordSuccessfulAttempt(candidate);
|
|
15780
16279
|
return;
|
|
15781
16280
|
} catch (err) {
|
|
15782
|
-
const
|
|
15783
|
-
if (
|
|
16281
|
+
const failure = await this.handleCandidateFailure(err, candidate, candidates, index);
|
|
16282
|
+
if (failure === "handled")
|
|
15784
16283
|
return;
|
|
15785
|
-
if (
|
|
16284
|
+
if (failure === "throw")
|
|
15786
16285
|
throw err;
|
|
15787
16286
|
index += 1;
|
|
15788
16287
|
}
|
|
@@ -15876,14 +16375,14 @@ class StageSessionController {
|
|
|
15876
16375
|
const { signal } = this.opts;
|
|
15877
16376
|
if (!signal)
|
|
15878
16377
|
return;
|
|
15879
|
-
const
|
|
16378
|
+
const abortReason = () => {
|
|
15880
16379
|
const reason = signal.reason;
|
|
15881
16380
|
if (reason instanceof Error || reason instanceof DOMException || typeof reason === "string")
|
|
15882
16381
|
return reason;
|
|
15883
16382
|
return new DOMException("workflow killed", "AbortError");
|
|
15884
16383
|
};
|
|
15885
16384
|
const onAbort = () => {
|
|
15886
|
-
const reason =
|
|
16385
|
+
const reason = abortReason();
|
|
15887
16386
|
this.markAbort(reason);
|
|
15888
16387
|
this.session?.abort().catch(() => {});
|
|
15889
16388
|
this.pauseControl.reject(reason);
|
|
@@ -16023,6 +16522,7 @@ class StageSessionController {
|
|
|
16023
16522
|
let retainedPrompt;
|
|
16024
16523
|
let terminalScanStartIndex;
|
|
16025
16524
|
while (true) {
|
|
16525
|
+
this.artifactCapture.beginAttempt(activeSession);
|
|
16026
16526
|
const messagesBeforeAttempt = [...activeSession.messages];
|
|
16027
16527
|
try {
|
|
16028
16528
|
if (retryAdmittedPrompt) {
|
|
@@ -16065,6 +16565,7 @@ class StageSessionController {
|
|
|
16065
16565
|
const willRetry = decision !== undefined && !this.disposed && this.opts.signal?.aborted !== true && !this.capturedStructuredOutputForAttempt();
|
|
16066
16566
|
const willContinue = continuationSession !== undefined && admittedMessages;
|
|
16067
16567
|
if (retryableFailure && willRetry) {
|
|
16568
|
+
this.artifactCapture.settleAttempt(false);
|
|
16068
16569
|
retainedPrompt = this.restoreSessionMessages(activeSession, messagesBeforeAttempt, nextText, willContinue) ?? retainedPrompt;
|
|
16069
16570
|
}
|
|
16070
16571
|
if (!willRetry)
|
|
@@ -16231,9 +16732,9 @@ class StageSessionController {
|
|
|
16231
16732
|
while (true) {
|
|
16232
16733
|
try {
|
|
16233
16734
|
if (pendingFailure !== undefined) {
|
|
16234
|
-
const
|
|
16735
|
+
const failure = pendingFailure;
|
|
16235
16736
|
pendingFailure = undefined;
|
|
16236
|
-
throw
|
|
16737
|
+
throw failure.error;
|
|
16237
16738
|
}
|
|
16238
16739
|
return await this.createSessionObservingPause(candidate, consumer);
|
|
16239
16740
|
} catch (error) {
|
|
@@ -16350,6 +16851,7 @@ class StageSessionController {
|
|
|
16350
16851
|
}
|
|
16351
16852
|
this.unsubscribeTerminateWatcher?.();
|
|
16352
16853
|
this.unsubscribeTerminateWatcher = result.session.subscribe((event) => {
|
|
16854
|
+
this.artifactCapture.onEvent(result.session, event);
|
|
16353
16855
|
const terminatingId = terminatingToolCallId(event);
|
|
16354
16856
|
if (terminatingId !== undefined)
|
|
16355
16857
|
this.terminatingToolCallIds.add(terminatingId);
|
|
@@ -16433,6 +16935,7 @@ class StageSessionController {
|
|
|
16433
16935
|
const { terminalScanStartIndex } = await this.promptWithThrownErrorRetry(resumedSession, text, sdkOptions);
|
|
16434
16936
|
const terminalFailure = latestTerminalAssistantFailureSince(resumedSession.messages, terminalScanStartIndex);
|
|
16435
16937
|
if (terminalFailure === undefined || this.capturedStructuredOutputForAttempt()) {
|
|
16938
|
+
this.artifactCapture.settleAttempt(true);
|
|
16436
16939
|
const usage = this.takeAttemptUsage(resumedSession);
|
|
16437
16940
|
this.modelAttempts.push({
|
|
16438
16941
|
model: resumedLabel,
|
|
@@ -16447,17 +16950,19 @@ class StageSessionController {
|
|
|
16447
16950
|
throw new WorkflowPromptModelFailure(terminalFailure);
|
|
16448
16951
|
} catch (err) {
|
|
16449
16952
|
if (this.capturedStructuredOutputForAttempt() && isRetryableModelFailure(err)) {
|
|
16450
|
-
|
|
16953
|
+
this.artifactCapture.settleAttempt(true);
|
|
16954
|
+
const usage = this.takeAttemptUsage(resumedSession);
|
|
16451
16955
|
this.modelAttempts.push({
|
|
16452
16956
|
model: resumedLabel,
|
|
16453
16957
|
success: true,
|
|
16454
|
-
...
|
|
16958
|
+
...usage === undefined ? {} : { usage }
|
|
16455
16959
|
});
|
|
16456
16960
|
this.pendingFallbackWarnings.length = 0;
|
|
16457
16961
|
this.resumeCurrentSession = true;
|
|
16458
16962
|
this.notifySuccessfulModelFallbackMeta();
|
|
16459
16963
|
return true;
|
|
16460
16964
|
}
|
|
16965
|
+
this.artifactCapture.settleAttempt(false);
|
|
16461
16966
|
const message = errorMessage2(err);
|
|
16462
16967
|
const usage = this.takeAttemptUsage(resumedSession);
|
|
16463
16968
|
this.modelAttempts.push({
|
|
@@ -16492,6 +16997,7 @@ class StageSessionController {
|
|
|
16492
16997
|
this.recordSuccessfulAttempt(candidate);
|
|
16493
16998
|
return "handled";
|
|
16494
16999
|
}
|
|
17000
|
+
this.artifactCapture.settleAttempt(false);
|
|
16495
17001
|
const usage = this.takeAttemptUsage(this.session);
|
|
16496
17002
|
this.modelAttempts.push({
|
|
16497
17003
|
model: candidate.id,
|
|
@@ -16515,6 +17021,7 @@ class StageSessionController {
|
|
|
16515
17021
|
return this.structuredOutputCapture?.called === true && this.opts.signal?.aborted !== true;
|
|
16516
17022
|
}
|
|
16517
17023
|
recordSuccessfulAttempt(candidate) {
|
|
17024
|
+
this.artifactCapture.settleAttempt(true);
|
|
16518
17025
|
const usage = this.takeAttemptUsage(this.session);
|
|
16519
17026
|
this.modelAttempts.push({
|
|
16520
17027
|
model: candidate.id,
|
|
@@ -16722,7 +17229,7 @@ function stageOutputInstruction(outputOptions, hasStructuredOutput = false) {
|
|
|
16722
17229
|
}
|
|
16723
17230
|
return `
|
|
16724
17231
|
|
|
16725
|
-
[This stage's
|
|
17232
|
+
[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
17233
|
}
|
|
16727
17234
|
async function finalizePromptOutput(fullOutput, outputOptions, runtimeCwd, runId, messages) {
|
|
16728
17235
|
const outputPath = resolveOutputPath(outputOptions.output, runtimeCwd, outputOptions.cwd);
|
|
@@ -16768,7 +17275,7 @@ function createStageContext2(opts) {
|
|
|
16768
17275
|
const structuredOutputCapture = stageOptions?.schema ? createStructuredOutputCapture() : undefined;
|
|
16769
17276
|
const structuredOutputExecutionCapture = stageOptions?.schema ? {} : undefined;
|
|
16770
17277
|
const effectiveStageOptions = stageOptionsWithStructuredOutput(stageOptions, structuredOutputCapture, structuredOutputExecutionCapture);
|
|
16771
|
-
const
|
|
17278
|
+
const meta = {
|
|
16772
17279
|
runId,
|
|
16773
17280
|
stageId,
|
|
16774
17281
|
stageName,
|
|
@@ -16777,21 +17284,40 @@ function createStageContext2(opts) {
|
|
|
16777
17284
|
stageOptions: effectiveStageOptions,
|
|
16778
17285
|
executionMode
|
|
16779
17286
|
};
|
|
16780
|
-
const controller = new StageSessionController(opts,
|
|
17287
|
+
const controller = new StageSessionController(opts, meta, effectiveStageOptions, structuredOutputCapture);
|
|
16781
17288
|
let lastAssistantText;
|
|
16782
17289
|
let lastFinalizedOutput;
|
|
16783
17290
|
let lastFinalizedMessageCount;
|
|
16784
17291
|
let structuredArtifactFinalized = false;
|
|
16785
17292
|
let adapterMessages = [];
|
|
17293
|
+
let artifactOptions;
|
|
17294
|
+
let artifactClosed = false;
|
|
17295
|
+
let artifactText;
|
|
17296
|
+
let continuing = false;
|
|
17297
|
+
async function exportArtifact() {
|
|
17298
|
+
const text = assistantArtifactTextForGeneration(controller.outputGenerationMessages());
|
|
17299
|
+
if (text !== artifactText || lastFinalizedOutput === undefined) {
|
|
17300
|
+
lastFinalizedOutput = await finalizePromptOutput(text, artifactOptions, runtimeCwd(), runId, controller.currentSession?.messages);
|
|
17301
|
+
artifactText = text;
|
|
17302
|
+
lastAssistantText = lastFinalizedOutput;
|
|
17303
|
+
}
|
|
17304
|
+
return lastFinalizedOutput;
|
|
17305
|
+
}
|
|
16786
17306
|
function runtimeCwd() {
|
|
16787
17307
|
return typeof effectiveStageOptions?.cwd === "string" ? effectiveStageOptions.cwd : process.cwd();
|
|
16788
17308
|
}
|
|
16789
17309
|
function finalizedOutputIsCurrent() {
|
|
16790
|
-
|
|
17310
|
+
if (lastFinalizedOutput === undefined)
|
|
17311
|
+
return false;
|
|
17312
|
+
if (artifactOptions !== undefined || structuredArtifactFinalized)
|
|
17313
|
+
return true;
|
|
17314
|
+
return lastFinalizedMessageCount === undefined || controller.currentSession?.messages.length === lastFinalizedMessageCount;
|
|
16791
17315
|
}
|
|
16792
17316
|
return {
|
|
16793
17317
|
name: stageName,
|
|
16794
17318
|
async prompt(text, options) {
|
|
17319
|
+
if (continuing && artifactOptions)
|
|
17320
|
+
options = { ...options, ...artifactOptions };
|
|
16795
17321
|
const { sdkOptions, outputOptions } = splitPromptOptions(options);
|
|
16796
17322
|
validatePromptOutputOptions(outputOptions);
|
|
16797
17323
|
const hasOutputArtifact = typeof outputOptions.output === "string" && outputOptions.output.length > 0;
|
|
@@ -16799,15 +17325,23 @@ function createStageContext2(opts) {
|
|
|
16799
17325
|
if (structuredOutputCapture?.called) {
|
|
16800
17326
|
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
17327
|
}
|
|
17328
|
+
if (!continuing) {
|
|
17329
|
+
controller.beginOutputGeneration();
|
|
17330
|
+
artifactOptions = undefined;
|
|
17331
|
+
artifactClosed = false;
|
|
17332
|
+
artifactText = undefined;
|
|
17333
|
+
}
|
|
17334
|
+
if (hasOutputArtifact && !structuredOutputCapture && !adapters.prompt)
|
|
17335
|
+
artifactOptions = outputOptions;
|
|
16802
17336
|
if (adapters.prompt) {
|
|
16803
17337
|
if (structuredOutputCapture) {
|
|
16804
17338
|
throw new Error("atomic-workflows: stage schema requires an AgentSessionAdapter so the structured_output tool can be registered.");
|
|
16805
17339
|
}
|
|
16806
|
-
const
|
|
16807
|
-
if (typeof
|
|
16808
|
-
return
|
|
16809
|
-
adapterMessages = assistantMessage(
|
|
16810
|
-
lastAssistantText = await finalizePromptOutput(
|
|
17340
|
+
const rawText = await runCallback2({ kind: "workflow.stage_adapter", name: `prompt:${stageName}`, runId, stageId }, () => adapters.prompt.prompt(promptText, meta));
|
|
17341
|
+
if (typeof rawText !== "string")
|
|
17342
|
+
return rawText;
|
|
17343
|
+
adapterMessages = assistantMessage(rawText);
|
|
17344
|
+
lastAssistantText = await finalizePromptOutput(rawText, outputOptions, runtimeCwd(), runId, adapterMessages);
|
|
16811
17345
|
lastFinalizedOutput = lastAssistantText;
|
|
16812
17346
|
lastFinalizedMessageCount = controller.currentSession?.messages.length;
|
|
16813
17347
|
return lastAssistantText;
|
|
@@ -16849,17 +17383,28 @@ function createStageContext2(opts) {
|
|
|
16849
17383
|
return executionSnapshot.value;
|
|
16850
17384
|
}
|
|
16851
17385
|
await controller.promptWithFallback(promptText, sdkOptions);
|
|
17386
|
+
if (artifactOptions)
|
|
17387
|
+
return await exportArtifact();
|
|
16852
17388
|
const rawText = controller.lastAssistantText(lastAssistantText) ?? "";
|
|
16853
17389
|
lastAssistantText = await finalizePromptOutput(rawText, outputOptions, runtimeCwd(), runId, controller.currentSession?.messages);
|
|
16854
17390
|
lastFinalizedOutput = lastAssistantText;
|
|
16855
17391
|
lastFinalizedMessageCount = controller.currentSession?.messages.length;
|
|
16856
17392
|
return lastAssistantText;
|
|
16857
17393
|
},
|
|
17394
|
+
async __continuePrompt(text) {
|
|
17395
|
+
continuing = true;
|
|
17396
|
+
try {
|
|
17397
|
+
return await this.prompt(text);
|
|
17398
|
+
} finally {
|
|
17399
|
+
continuing = false;
|
|
17400
|
+
}
|
|
17401
|
+
},
|
|
16858
17402
|
async complete(text, completeOpts) {
|
|
17403
|
+
artifactOptions = undefined;
|
|
16859
17404
|
if (adapters.complete) {
|
|
16860
17405
|
lastFinalizedOutput = undefined;
|
|
16861
17406
|
lastFinalizedMessageCount = undefined;
|
|
16862
|
-
lastAssistantText = await runCallback2({ kind: "workflow.stage_adapter", name: `complete:${stageName}`, runId, stageId }, () => adapters.complete.complete(text, completeOpts,
|
|
17407
|
+
lastAssistantText = await runCallback2({ kind: "workflow.stage_adapter", name: `complete:${stageName}`, runId, stageId }, () => adapters.complete.complete(text, completeOpts, meta));
|
|
16863
17408
|
adapterMessages = assistantMessage(lastAssistantText);
|
|
16864
17409
|
return lastAssistantText;
|
|
16865
17410
|
}
|
|
@@ -16924,7 +17469,7 @@ function createStageContext2(opts) {
|
|
|
16924
17469
|
return controller.currentSession?.isStreaming ?? false;
|
|
16925
17470
|
},
|
|
16926
17471
|
async navigateTree(targetId, options) {
|
|
16927
|
-
return
|
|
17472
|
+
return controller.navigateTree(targetId, options);
|
|
16928
17473
|
},
|
|
16929
17474
|
async compact() {
|
|
16930
17475
|
return (await controller.ensureSession()).compact();
|
|
@@ -16955,6 +17500,11 @@ function createStageContext2(opts) {
|
|
|
16955
17500
|
},
|
|
16956
17501
|
async __closeGeneration() {
|
|
16957
17502
|
await controller.closeGeneration();
|
|
17503
|
+
if (artifactOptions && !artifactClosed) {
|
|
17504
|
+
await exportArtifact();
|
|
17505
|
+
artifactClosed = true;
|
|
17506
|
+
}
|
|
17507
|
+
return artifactOptions ? lastFinalizedOutput : undefined;
|
|
16958
17508
|
},
|
|
16959
17509
|
__sessionMeta() {
|
|
16960
17510
|
return controller.sessionMeta();
|
|
@@ -16989,7 +17539,7 @@ function createStageSessionHeartbeat(checkpoint, intervalMs = STAGE_SESSION_HEAR
|
|
|
16989
17539
|
let timer;
|
|
16990
17540
|
let generation = 0;
|
|
16991
17541
|
let nextDeadline = 0;
|
|
16992
|
-
let
|
|
17542
|
+
let failure;
|
|
16993
17543
|
let inFlight;
|
|
16994
17544
|
let rejectFailure;
|
|
16995
17545
|
const failureSignal = new Promise((_resolve, reject) => {
|
|
@@ -17006,14 +17556,14 @@ function createStageSessionHeartbeat(checkpoint, intervalMs = STAGE_SESSION_HEAR
|
|
|
17006
17556
|
timer = undefined;
|
|
17007
17557
|
};
|
|
17008
17558
|
const fail = (error) => {
|
|
17009
|
-
if (
|
|
17559
|
+
if (failure !== undefined)
|
|
17010
17560
|
return;
|
|
17011
|
-
|
|
17561
|
+
failure = error;
|
|
17012
17562
|
stopScheduling();
|
|
17013
17563
|
rejectFailure(error);
|
|
17014
17564
|
};
|
|
17015
17565
|
const schedule = (scheduledGeneration) => {
|
|
17016
|
-
if (!active ||
|
|
17566
|
+
if (!active || failure !== undefined || scheduledGeneration !== generation)
|
|
17017
17567
|
return;
|
|
17018
17568
|
const delayMs = Math.max(0, nextDeadline - Date.now());
|
|
17019
17569
|
timer = setTimeout(() => {
|
|
@@ -17034,12 +17584,12 @@ function createStageSessionHeartbeat(checkpoint, intervalMs = STAGE_SESSION_HEAR
|
|
|
17034
17584
|
const drain = async () => {
|
|
17035
17585
|
stopScheduling();
|
|
17036
17586
|
await inFlight;
|
|
17037
|
-
if (
|
|
17038
|
-
throw
|
|
17587
|
+
if (failure !== undefined)
|
|
17588
|
+
throw failure;
|
|
17039
17589
|
};
|
|
17040
17590
|
return {
|
|
17041
17591
|
start() {
|
|
17042
|
-
if (active ||
|
|
17592
|
+
if (active || failure !== undefined)
|
|
17043
17593
|
return;
|
|
17044
17594
|
active = true;
|
|
17045
17595
|
generation += 1;
|
|
@@ -17050,8 +17600,8 @@ function createStageSessionHeartbeat(checkpoint, intervalMs = STAGE_SESSION_HEAR
|
|
|
17050
17600
|
drain,
|
|
17051
17601
|
fail,
|
|
17052
17602
|
race(work) {
|
|
17053
|
-
if (
|
|
17054
|
-
return Promise.reject(
|
|
17603
|
+
if (failure !== undefined)
|
|
17604
|
+
return Promise.reject(failure);
|
|
17055
17605
|
return Promise.race([work, failureSignal]);
|
|
17056
17606
|
}
|
|
17057
17607
|
};
|
|
@@ -17132,16 +17682,16 @@ function createWorkflowStageFactory(input) {
|
|
|
17132
17682
|
throwIfWorkflowExitSelected: input.exit.throwIfWorkflowExitSelected
|
|
17133
17683
|
});
|
|
17134
17684
|
}
|
|
17135
|
-
const applyModelFallbackMeta = (
|
|
17136
|
-
if (
|
|
17137
|
-
stageSnapshot.model =
|
|
17138
|
-
if (
|
|
17139
|
-
stageSnapshot.attemptedModels =
|
|
17140
|
-
if (
|
|
17141
|
-
stageSnapshot.modelAttempts =
|
|
17142
|
-
if (
|
|
17143
|
-
if (
|
|
17144
|
-
stageSnapshot.warnings =
|
|
17685
|
+
const applyModelFallbackMeta = (meta) => {
|
|
17686
|
+
if (meta.model !== undefined)
|
|
17687
|
+
stageSnapshot.model = meta.model;
|
|
17688
|
+
if (meta.attemptedModels !== undefined)
|
|
17689
|
+
stageSnapshot.attemptedModels = meta.attemptedModels;
|
|
17690
|
+
if (meta.modelAttempts !== undefined)
|
|
17691
|
+
stageSnapshot.modelAttempts = meta.modelAttempts;
|
|
17692
|
+
if (meta.warnings !== undefined) {
|
|
17693
|
+
if (meta.warnings.length > 0)
|
|
17694
|
+
stageSnapshot.warnings = meta.warnings;
|
|
17145
17695
|
else
|
|
17146
17696
|
delete stageSnapshot.warnings;
|
|
17147
17697
|
}
|
|
@@ -17169,8 +17719,8 @@ function createWorkflowStageFactory(input) {
|
|
|
17169
17719
|
models: input.opts.models,
|
|
17170
17720
|
executionMode: input.opts.executionMode,
|
|
17171
17721
|
defaultSessionDir: input.opts.defaultSessionDir,
|
|
17172
|
-
onModelFallbackMetaChange(
|
|
17173
|
-
applyModelFallbackMeta(
|
|
17722
|
+
onModelFallbackMetaChange(meta) {
|
|
17723
|
+
applyModelFallbackMeta(meta);
|
|
17174
17724
|
if (stageSnapshot.status === "running")
|
|
17175
17725
|
input.activeStore.recordStageStart(input.runId, stageSnapshot);
|
|
17176
17726
|
},
|
|
@@ -17242,13 +17792,13 @@ function createWorkflowStageFactory(input) {
|
|
|
17242
17792
|
await innerCtx.__dispose();
|
|
17243
17793
|
};
|
|
17244
17794
|
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,
|
|
17795
|
+
const meta = innerCtx.__sessionMeta();
|
|
17796
|
+
if (meta.sessionId !== undefined)
|
|
17797
|
+
stageSnapshot.sessionId = meta.sessionId;
|
|
17798
|
+
if (meta.sessionFile !== undefined)
|
|
17799
|
+
stageSnapshot.sessionFile = meta.sessionFile;
|
|
17800
|
+
if (meta.sessionId !== undefined || meta.sessionFile !== undefined)
|
|
17801
|
+
input.activeStore.recordStageSession(input.runId, stageId, meta);
|
|
17252
17802
|
const pending = input.opts.onStageSession?.(input.runId, stageSnapshot, checkpointOptions);
|
|
17253
17803
|
if (checkpointOptions?.forceDurable === true || checkpointOptions?.awaitDurable === true) {
|
|
17254
17804
|
await pending;
|
|
@@ -17588,7 +18138,7 @@ class EngineRuntime {
|
|
|
17588
18138
|
// dist/builtin/workflows/src/engine/workflow-activity.ts
|
|
17589
18139
|
import { runCallback as runCallback4 } from "@bastani/atomic";
|
|
17590
18140
|
function nextEventLoopTurn() {
|
|
17591
|
-
return new Promise((
|
|
18141
|
+
return new Promise((resolve) => setTimeout(resolve, 0));
|
|
17592
18142
|
}
|
|
17593
18143
|
function runWorkflowDefinitionCallback(name, runId, callback) {
|
|
17594
18144
|
return runCallback4({ kind: "workflow.run", name, runId }, callback);
|
|
@@ -17616,7 +18166,7 @@ async function run(def, inputs, opts = {}) {
|
|
|
17616
18166
|
}
|
|
17617
18167
|
const resolvedInputs = resolveAndValidateInputs(def.inputs, inputs, `workflow "${def.name}"`);
|
|
17618
18168
|
const runId = opts.runId ?? crypto.randomUUID();
|
|
17619
|
-
const declaresBudget = (
|
|
18169
|
+
const declaresBudget = (budget) => (budget?.maxDurationMs ?? 0) > 0 || (budget?.maxTokens ?? 0) > 0 || (budget?.maxCost ?? 0) > 0;
|
|
17620
18170
|
const hasBudgetDeclaration = declaresBudget(opts.budget) || declaresBudget(def.budget) || declaresBudget(opts.config?.budget);
|
|
17621
18171
|
const priorRun = hasBudgetDeclaration && opts.rootBudget === undefined && opts.continuation === undefined && opts.runId !== undefined ? activeStore.runs().find((candidate) => candidate.id === runId) : undefined;
|
|
17622
18172
|
const continuedBudget = opts.continuation?.source.budget ?? priorRun?.budget;
|
|
@@ -17629,21 +18179,17 @@ async function run(def, inputs, opts = {}) {
|
|
|
17629
18179
|
terminalEvents.selectCancellation(ownController.signal.reason);
|
|
17630
18180
|
}, { once: true });
|
|
17631
18181
|
const callerSignal = opts.signal;
|
|
17632
|
-
|
|
17633
|
-
|
|
17634
|
-
|
|
17635
|
-
|
|
17636
|
-
callerSignal.addEventListener("abort", () => {
|
|
17637
|
-
ownController.abort(callerSignal.reason);
|
|
17638
|
-
}, { once: true });
|
|
17639
|
-
}
|
|
18182
|
+
const onCallerAbort = () => {
|
|
18183
|
+
workflowObservationRuntime(activeStore).control(runId, "kill");
|
|
18184
|
+
ownController.abort(callerSignal?.reason);
|
|
18185
|
+
};
|
|
17640
18186
|
const exit = createWorkflowExitManager({ runId, exitScope, controller: ownController });
|
|
17641
18187
|
const backendView = opts.durableBackend ?? getDurableBackend();
|
|
17642
18188
|
const rootBackend = opts.durableRootBackend ?? backendView;
|
|
17643
18189
|
const durableBackend = opts.durableScope !== undefined ? new ScopedDurableBackend(backendView, opts.durableScope) : backendView;
|
|
17644
18190
|
const inheritedElapsedMs = opts.parentRun === undefined ? inheritedRunElapsedMs({ backend: durableBackend, runId, continuationSource: opts.continuation?.source }) : undefined;
|
|
17645
18191
|
const continuationOrigin = opts.continuation !== undefined ? opts.continuation.source.origin : opts.origin;
|
|
17646
|
-
const snapshotField = (
|
|
18192
|
+
const snapshotField = (field) => resolvedBudget[field] > 0 || opts.budget?.[field] !== undefined || def.budget?.[field] !== undefined ? resolvedBudget[field] : undefined;
|
|
17647
18193
|
const budgetSnapshot = resolvedBudget.maxDurationMs > 0 || resolvedBudget.maxTokens > 0 || resolvedBudget.maxCost > 0 ? {
|
|
17648
18194
|
maxDurationMs: resolvedBudget.maxDurationMs,
|
|
17649
18195
|
...snapshotField("maxTokens") !== undefined ? { maxTokens: snapshotField("maxTokens") } : {},
|
|
@@ -17652,7 +18198,7 @@ async function run(def, inputs, opts = {}) {
|
|
|
17652
18198
|
} : undefined;
|
|
17653
18199
|
const durableAccounting = hasBudgetDeclaration && opts.parentRun === undefined && opts.continuation === undefined && priorRun === undefined ? priorRunAccounting(durableBackend, runId) : undefined;
|
|
17654
18200
|
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((
|
|
18201
|
+
const sameBudget = budgetSnapshot !== undefined && continuedBudget?.warnAtPercent === budgetSnapshot.warnAtPercent && ["maxDurationMs", "maxTokens", "maxCost"].every((field) => (continuedBudget?.[field] ?? 0) === (budgetSnapshot[field] ?? 0));
|
|
17656
18202
|
const continuationBudgetState = continuedBudgetState === undefined || !sameBudget && continuedBudgetState.accounting === undefined ? undefined : sameBudget ? continuedBudgetState : { accounting: continuedBudgetState.accounting };
|
|
17657
18203
|
const continuationSourceRunId = opts.continuation?.source.id;
|
|
17658
18204
|
const persistedPossibleStages = coercePossibleStages(opts.possibleStages) ?? (continuationSourceRunId !== undefined ? coercePossibleStages(rootBackend.getWorkflow(continuationSourceRunId)?.possibleStages) : undefined);
|
|
@@ -17694,9 +18240,9 @@ async function run(def, inputs, opts = {}) {
|
|
|
17694
18240
|
children.push(snapshot);
|
|
17695
18241
|
childrenByParent.set(snapshot.parentRunId, children);
|
|
17696
18242
|
}
|
|
17697
|
-
const build = (
|
|
17698
|
-
const children = (childrenByParent.get(
|
|
17699
|
-
return children.length === 0 ? { run
|
|
18243
|
+
const build = (run) => {
|
|
18244
|
+
const children = (childrenByParent.get(run.id) ?? []).map(build);
|
|
18245
|
+
return children.length === 0 ? { run } : { run, children };
|
|
17700
18246
|
};
|
|
17701
18247
|
return build(snapshots.find((snapshot) => snapshot.id === runSnapshot.id) ?? runSnapshot);
|
|
17702
18248
|
};
|
|
@@ -17730,28 +18276,7 @@ async function run(def, inputs, opts = {}) {
|
|
|
17730
18276
|
classifiedFailures.set(error, classified);
|
|
17731
18277
|
return classified;
|
|
17732
18278
|
};
|
|
17733
|
-
activeStore.recordRunStart(runSnapshot);
|
|
17734
18279
|
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
18280
|
const tracker = new GraphFrontierTracker;
|
|
17756
18281
|
const inputConcurrency = resolveInputConcurrency(def.inputs, resolvedInputs);
|
|
17757
18282
|
const inputRuntimeDefaults = resolveInputRuntimeDefaults(def, resolvedInputs), gitWorktreeSetupCacheOwner = createGitWorktreeSetupCacheOwner(opts.gitWorktreeSetupCache);
|
|
@@ -17773,6 +18298,17 @@ async function run(def, inputs, opts = {}) {
|
|
|
17773
18298
|
tracker,
|
|
17774
18299
|
stageRegistry: () => stageRegistry
|
|
17775
18300
|
});
|
|
18301
|
+
const waitForRunRelease = async () => {
|
|
18302
|
+
await scheduler.waitForRunRelease();
|
|
18303
|
+
ownController.signal.throwIfAborted();
|
|
18304
|
+
};
|
|
18305
|
+
const whenRunning = (call) => {
|
|
18306
|
+
if (scheduler.isRunPaused())
|
|
18307
|
+
return waitForRunRelease().then(() => whenRunning(call));
|
|
18308
|
+
if (ownController.signal.aborted)
|
|
18309
|
+
return Promise.reject(ownController.signal.reason);
|
|
18310
|
+
return call();
|
|
18311
|
+
};
|
|
17776
18312
|
ownController.signal.addEventListener("abort", () => scheduler.rejectReleaseBarriers(ownController.signal.reason ?? new Error("atomic-workflows: run aborted")), { once: true });
|
|
17777
18313
|
const finalizers = createRunFinalizers({
|
|
17778
18314
|
def,
|
|
@@ -17901,7 +18437,7 @@ async function run(def, inputs, opts = {}) {
|
|
|
17901
18437
|
};
|
|
17902
18438
|
const taskRunners = createWorkflowTaskRunners({ runtime });
|
|
17903
18439
|
let pendingChildDurableInvocation;
|
|
17904
|
-
const
|
|
18440
|
+
const workflow = createChildWorkflowRunner({
|
|
17905
18441
|
runtime,
|
|
17906
18442
|
resolveWorkflowCwd,
|
|
17907
18443
|
nextWorkflowBoundaryReplayKey,
|
|
@@ -17974,6 +18510,10 @@ async function run(def, inputs, opts = {}) {
|
|
|
17974
18510
|
workflowId: runId,
|
|
17975
18511
|
backend: durableBackend,
|
|
17976
18512
|
nextCheckpointId: checkpointIdGenerator,
|
|
18513
|
+
beforeCall: () => {
|
|
18514
|
+
ownController.signal.throwIfAborted();
|
|
18515
|
+
return scheduler.isRunPaused() ? waitForRunRelease() : undefined;
|
|
18516
|
+
},
|
|
17977
18517
|
...opts.usePromptNodesForUi === true ? {
|
|
17978
18518
|
onReplay: async (request) => getPromptNodeUi().replayDurable(request)
|
|
17979
18519
|
} : {}
|
|
@@ -17987,6 +18527,10 @@ async function run(def, inputs, opts = {}) {
|
|
|
17987
18527
|
completedStageReplayKeys,
|
|
17988
18528
|
sourceToReplayedNodeIds: sourceToContinuationNodeIds
|
|
17989
18529
|
});
|
|
18530
|
+
const recordCachedStage = (...args) => {
|
|
18531
|
+
ownController.signal.throwIfAborted();
|
|
18532
|
+
cachedStage.record(...args);
|
|
18533
|
+
};
|
|
17990
18534
|
const durableIntercomGroup = (replayKey, stageId) => {
|
|
17991
18535
|
const stages = activeStore.runs().find((candidate) => candidate.id === runId)?.stages ?? [];
|
|
17992
18536
|
return stages.find((stage) => stageId !== undefined && stage.id === stageId || stage.replayKey === replayKey)?.intercomGroup;
|
|
@@ -17998,7 +18542,7 @@ async function run(def, inputs, opts = {}) {
|
|
|
17998
18542
|
nextReplayKey: (stageName) => stageReplayKeyGenerator(stageName),
|
|
17999
18543
|
durableIntercomGroup,
|
|
18000
18544
|
task: taskRunners.task,
|
|
18001
|
-
recordCachedTask:
|
|
18545
|
+
recordCachedTask: recordCachedStage,
|
|
18002
18546
|
signal: ownController.signal,
|
|
18003
18547
|
registerTailControl: (registration) => {
|
|
18004
18548
|
registration.controller.signal.addEventListener("abort", () => {
|
|
@@ -18024,60 +18568,153 @@ async function run(def, inputs, opts = {}) {
|
|
|
18024
18568
|
setChildDurableInvocation: (invocation) => {
|
|
18025
18569
|
pendingChildDurableInvocation = invocation;
|
|
18026
18570
|
},
|
|
18027
|
-
recordCachedStage
|
|
18571
|
+
recordCachedStage,
|
|
18028
18572
|
runTopology: durableRunTopology(runSnapshot),
|
|
18029
|
-
workflow
|
|
18573
|
+
workflow
|
|
18030
18574
|
});
|
|
18575
|
+
const pendingChildWorkflows = new Set;
|
|
18576
|
+
const durableStage = createDurableStagePrimitive({
|
|
18577
|
+
workflowId: runId,
|
|
18578
|
+
backend: durableBackend,
|
|
18579
|
+
nextReplayKey: (stageName) => stageReplayKeyGenerator(stageName),
|
|
18580
|
+
durableIntercomGroup,
|
|
18581
|
+
recordCachedStage,
|
|
18582
|
+
stage: (name, options, replayKey) => {
|
|
18583
|
+
const stage = runtime.stage(name, options);
|
|
18584
|
+
const stageId = activeStore.runs().find((r) => r.id === runId)?.stages.at(-1)?.id;
|
|
18585
|
+
if (stageId !== undefined)
|
|
18586
|
+
completedStageReplayKeys.set(stageId, replayKey);
|
|
18587
|
+
return stage;
|
|
18588
|
+
}
|
|
18589
|
+
});
|
|
18590
|
+
const gatedTask = (...args) => whenRunning(() => durableTask(...args));
|
|
18591
|
+
const chain = createChainPrimitive({ runtime, task: gatedTask });
|
|
18592
|
+
const parallel = createParallelPrimitive({ runtime, task: gatedTask });
|
|
18593
|
+
const ui = buildExitGatedUiContext({
|
|
18594
|
+
opts,
|
|
18595
|
+
throwIfWorkflowExitSelected: exit.throwIfWorkflowExitSelected,
|
|
18596
|
+
durableUi: durableUiDeps,
|
|
18597
|
+
baseFromPromptNodes: getPromptNodeUi
|
|
18598
|
+
});
|
|
18599
|
+
let pausedExit;
|
|
18031
18600
|
const ctx = {
|
|
18032
18601
|
inputs: resolvedInputs,
|
|
18033
18602
|
runId,
|
|
18034
18603
|
get cwd() {
|
|
18035
18604
|
return resolveWorkflowCwd();
|
|
18036
18605
|
},
|
|
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;
|
|
18606
|
+
exit: (options) => {
|
|
18607
|
+
if (scheduler.isRunPaused()) {
|
|
18608
|
+
pausedExit ??= whenRunning(async () => exit.exit(options));
|
|
18609
|
+
pausedExit.catch(() => {});
|
|
18610
|
+
throw new Error("Workflow exit is waiting for explicit resume");
|
|
18056
18611
|
}
|
|
18612
|
+
return exit.exit(options);
|
|
18613
|
+
},
|
|
18614
|
+
ui,
|
|
18615
|
+
stage: (name, options) => {
|
|
18616
|
+
ownController.signal.throwIfAborted();
|
|
18617
|
+
if (!scheduler.isRunPaused())
|
|
18618
|
+
return durableStage(name, options);
|
|
18619
|
+
const replayKey = stageReplayKeyGenerator(name);
|
|
18620
|
+
return deferStageUntilRunRelease({
|
|
18621
|
+
name,
|
|
18622
|
+
create: () => durableStage(name, options, replayKey),
|
|
18623
|
+
isPaused: scheduler.isRunPaused,
|
|
18624
|
+
waitForRelease: waitForRunRelease,
|
|
18625
|
+
signal: ownController.signal
|
|
18626
|
+
});
|
|
18627
|
+
},
|
|
18628
|
+
task: gatedTask,
|
|
18629
|
+
chain: (...args) => whenRunning(() => chain(...args)),
|
|
18630
|
+
parallel: (...args) => whenRunning(() => parallel(...args)),
|
|
18631
|
+
workflow: (...args) => whenRunning(() => {
|
|
18632
|
+
const pending = durableWorkflow(...args);
|
|
18633
|
+
pendingChildWorkflows.add(pending);
|
|
18634
|
+
const settled = () => {
|
|
18635
|
+
pendingChildWorkflows.delete(pending);
|
|
18636
|
+
};
|
|
18637
|
+
pending.then(settled, settled);
|
|
18638
|
+
return pending;
|
|
18057
18639
|
}),
|
|
18058
|
-
|
|
18059
|
-
|
|
18060
|
-
|
|
18061
|
-
|
|
18062
|
-
|
|
18640
|
+
tool: (...args) => {
|
|
18641
|
+
if (!scheduler.isRunPaused())
|
|
18642
|
+
return tool(...args);
|
|
18643
|
+
const pending = whenRunning(() => tool(...args));
|
|
18644
|
+
pending.catch(() => {});
|
|
18645
|
+
return pending;
|
|
18646
|
+
},
|
|
18063
18647
|
...opts.models !== undefined ? { models: opts.models } : {}
|
|
18064
18648
|
};
|
|
18649
|
+
const runtimeSettled = Promise.withResolvers();
|
|
18650
|
+
let pausePersistence;
|
|
18651
|
+
const persistRunControl = async (status) => {
|
|
18652
|
+
ownController.signal.throwIfAborted();
|
|
18653
|
+
if (opts.parentRun !== undefined || durableBackend.getWorkflow(runId) === undefined)
|
|
18654
|
+
return;
|
|
18655
|
+
if (!await transitionDurableWorkflowStatus(durableBackend, runId, ["running", "paused"], status, undefined, true)) {
|
|
18656
|
+
throw new Error(`Workflow ${runId} refused the durable ${status} transition`);
|
|
18657
|
+
}
|
|
18658
|
+
recordRunTimingCheckpoint(durableBackend, runSnapshot);
|
|
18659
|
+
await durableBackend.flush(runId);
|
|
18660
|
+
};
|
|
18661
|
+
const unregisterRunControl = toolControls.registerRun(runId, {
|
|
18662
|
+
get paused() {
|
|
18663
|
+
return scheduler.isRunPaused();
|
|
18664
|
+
},
|
|
18665
|
+
pause: () => {
|
|
18666
|
+
ownController.signal.throwIfAborted();
|
|
18667
|
+
scheduler.pauseRun();
|
|
18668
|
+
activeStore.recordRunPaused(runId, undefined, { resumable: true });
|
|
18669
|
+
pausePersistence = persistRunControl("paused");
|
|
18670
|
+
return pausePersistence;
|
|
18671
|
+
},
|
|
18672
|
+
resume: async () => {
|
|
18673
|
+
await pausePersistence;
|
|
18674
|
+
await persistRunControl("running");
|
|
18675
|
+
ownController.signal.throwIfAborted();
|
|
18676
|
+
activeStore.recordRunResumed(runId, undefined, { source: "run_control" });
|
|
18677
|
+
scheduler.releaseRun();
|
|
18678
|
+
},
|
|
18679
|
+
quit: () => {
|
|
18680
|
+
ownController.abort(new WorkflowGracefulQuitError(runId, "workflow runtime"));
|
|
18681
|
+
return runtimeSettled.promise;
|
|
18682
|
+
}
|
|
18683
|
+
});
|
|
18065
18684
|
terminalEvents.register();
|
|
18066
18685
|
try {
|
|
18067
|
-
|
|
18068
|
-
|
|
18069
|
-
|
|
18070
|
-
|
|
18071
|
-
|
|
18072
|
-
|
|
18073
|
-
|
|
18074
|
-
|
|
18075
|
-
|
|
18076
|
-
|
|
18077
|
-
|
|
18078
|
-
|
|
18686
|
+
workflowObservationRuntime(activeStore).startRun(runId);
|
|
18687
|
+
activeStore.recordRunStart(runSnapshot);
|
|
18688
|
+
if (callerSignal?.aborted)
|
|
18689
|
+
onCallerAbort();
|
|
18690
|
+
else
|
|
18691
|
+
callerSignal?.addEventListener("abort", onCallerAbort, { once: true });
|
|
18692
|
+
if (ownsCancellationRegistration)
|
|
18693
|
+
opts.cancellation?.register(runId, ownController);
|
|
18694
|
+
opts.onRunStart?.(runSnapshot);
|
|
18695
|
+
if (opts.persistence) {
|
|
18696
|
+
appendRunStart(opts.persistence, {
|
|
18697
|
+
runId,
|
|
18698
|
+
name: def.name,
|
|
18699
|
+
inputs: resolvedInputs,
|
|
18700
|
+
...runSnapshot.parentRunId !== undefined ? { parentRunId: runSnapshot.parentRunId } : {},
|
|
18701
|
+
...runSnapshot.parentStageId !== undefined ? { parentStageId: runSnapshot.parentStageId } : {},
|
|
18702
|
+
...runSnapshot.rootRunId !== undefined ? { rootRunId: runSnapshot.rootRunId } : {},
|
|
18703
|
+
...runSnapshot.resumedFromRunId !== undefined ? { resumedFromRunId: runSnapshot.resumedFromRunId } : {},
|
|
18704
|
+
...runSnapshot.origin !== undefined ? { origin: runSnapshot.origin } : {},
|
|
18705
|
+
...runSnapshot.resumeFromStageId !== undefined ? { resumeFromStageId: runSnapshot.resumeFromStageId } : {},
|
|
18706
|
+
...runSnapshot.accumulatedDurationMs !== undefined ? { accumulatedDurationMs: runSnapshot.accumulatedDurationMs } : {},
|
|
18707
|
+
...runSnapshot.budget !== undefined ? { budget: runSnapshot.budget } : {},
|
|
18708
|
+
...runSnapshot.budgetState !== undefined ? { budgetState: runSnapshot.budgetState } : {},
|
|
18709
|
+
ts: runSnapshot.startedAt
|
|
18710
|
+
});
|
|
18079
18711
|
}
|
|
18080
|
-
|
|
18712
|
+
if (opts.deferWorkflowStart === true)
|
|
18713
|
+
await raceAbort2(nextEventLoopTurn(), ownController.signal);
|
|
18714
|
+
while (scheduler.isRunPaused())
|
|
18715
|
+
await waitForRunRelease();
|
|
18716
|
+
ownController.signal.throwIfAborted();
|
|
18717
|
+
await raceAbort2(admitDurableRootRun({
|
|
18081
18718
|
backend: durableBackend,
|
|
18082
18719
|
runId,
|
|
18083
18720
|
isChildRun: opts.parentRun !== undefined,
|
|
@@ -18085,7 +18722,10 @@ async function run(def, inputs, opts = {}) {
|
|
|
18085
18722
|
...durableRootRegistration,
|
|
18086
18723
|
...workflowInvocationMetadata(inputRuntimeDefaults, workflowInvocationCwd, gitWorktreeSetupCache, runSnapshot.origin)
|
|
18087
18724
|
}
|
|
18088
|
-
});
|
|
18725
|
+
}), ownController.signal);
|
|
18726
|
+
while (scheduler.isRunPaused())
|
|
18727
|
+
await waitForRunRelease();
|
|
18728
|
+
ownController.signal.throwIfAborted();
|
|
18089
18729
|
if (opts.deferWorkflowStart === true)
|
|
18090
18730
|
opts.onWorkflowStartReady?.();
|
|
18091
18731
|
const sourceFrontierStage = opts.continuation?.source;
|
|
@@ -18093,8 +18733,17 @@ async function run(def, inputs, opts = {}) {
|
|
|
18093
18733
|
const startupFrontierStage = sourceFrontierStage?.stages.find((stage) => stage.id === sourceFrontierId)?.name ?? "workflow frontier";
|
|
18094
18734
|
if (budget.enabled)
|
|
18095
18735
|
await budget.stopAtBoundaryAsync(startupFrontierStage);
|
|
18096
|
-
|
|
18736
|
+
while (scheduler.isRunPaused())
|
|
18737
|
+
await waitForRunRelease();
|
|
18738
|
+
ownController.signal.throwIfAborted();
|
|
18739
|
+
const rawResult = await raceAbort2(runWorkflowDefinitionCallback(def.name, runId, () => def.run(ctx)), ownController.signal);
|
|
18740
|
+
while (scheduler.isRunPaused())
|
|
18741
|
+
await waitForRunRelease();
|
|
18097
18742
|
await admittedTools.closeAndDrain();
|
|
18743
|
+
while (scheduler.isRunPaused())
|
|
18744
|
+
await waitForRunRelease();
|
|
18745
|
+
if (pausedExit !== undefined)
|
|
18746
|
+
await pausedExit;
|
|
18098
18747
|
budget.rethrowIfSystemOwnedStop(runSnapshot.stages.at(-1)?.name ?? startupFrontierStage);
|
|
18099
18748
|
const normalTerminalEvent = terminalEvents.winner();
|
|
18100
18749
|
if (normalTerminalEvent?.kind === "cancellation") {
|
|
@@ -18115,7 +18764,10 @@ async function run(def, inputs, opts = {}) {
|
|
|
18115
18764
|
const result = normalizeWorkflowRunOutput(def.name, rawResult);
|
|
18116
18765
|
assertWorkflowRunOutputs(def.name, result, def.outputs);
|
|
18117
18766
|
assertWorkflowCreatedExecution(runSnapshot);
|
|
18118
|
-
await durableBackend.flush(runId);
|
|
18767
|
+
await raceAbort2(durableBackend.flush(runId), ownController.signal);
|
|
18768
|
+
while (scheduler.isRunPaused())
|
|
18769
|
+
await waitForRunRelease();
|
|
18770
|
+
ownController.signal.throwIfAborted();
|
|
18119
18771
|
const returned = classifyReturnedRunStatus(result, runSnapshot);
|
|
18120
18772
|
if (returned.status === "completed")
|
|
18121
18773
|
assertFrontierConsumed();
|
|
@@ -18135,12 +18787,26 @@ async function run(def, inputs, opts = {}) {
|
|
|
18135
18787
|
durableBackend.setWorkflowStatus(runId, returned.status, undefined, returned.metadata?.resumable);
|
|
18136
18788
|
await durableBackend.flush(runId);
|
|
18137
18789
|
return reconcileTerminalRunResult(runId, runSnapshot, activeStore, { status: returned.status, result, error: returned.error }, opts.onRunEnd);
|
|
18138
|
-
} catch (
|
|
18139
|
-
|
|
18790
|
+
} catch (error) {
|
|
18791
|
+
let err = error;
|
|
18792
|
+
try {
|
|
18793
|
+
while (scheduler.isRunPaused())
|
|
18794
|
+
await waitForRunRelease();
|
|
18795
|
+
if (pausedExit !== undefined)
|
|
18796
|
+
await pausedExit;
|
|
18797
|
+
} catch (stop) {
|
|
18798
|
+
err = stop;
|
|
18799
|
+
}
|
|
18800
|
+
const selectedTerminalEvent = terminalEvents.selectFailure(err);
|
|
18801
|
+
if (selectedTerminalEvent.kind === "failure" && ownController.signal.aborted && Object.is(err, ownController.signal.reason)) {
|
|
18802
|
+
err = selectedTerminalEvent.error;
|
|
18803
|
+
}
|
|
18140
18804
|
const gracefulQuit = observedQuitCancellation() ?? observedTaskTailQuit ?? findWorkflowGracefulQuit(err) ?? findWorkflowGracefulQuit(ownController.signal.reason);
|
|
18141
18805
|
if (gracefulQuit !== undefined)
|
|
18142
18806
|
return suspendForGracefulQuit(gracefulQuit);
|
|
18143
18807
|
await admittedTools.closeAndDrain();
|
|
18808
|
+
if (ownController.signal.aborted)
|
|
18809
|
+
await Promise.allSettled([...pendingChildWorkflows]);
|
|
18144
18810
|
if (err instanceof WorkflowBudgetExceededError) {
|
|
18145
18811
|
const pendingBudgetError = await budget.awaitPendingWrapUp();
|
|
18146
18812
|
const selectedBudgetError = pendingBudgetError ?? err;
|
|
@@ -18173,15 +18839,15 @@ async function run(def, inputs, opts = {}) {
|
|
|
18173
18839
|
return await finalizers.finalizeParentWorkflowExitCancellation(parentExit);
|
|
18174
18840
|
return finalizeKilled(runId, runSnapshot, activeStore, opts.persistence, opts.onRunEnd);
|
|
18175
18841
|
}
|
|
18176
|
-
const
|
|
18177
|
-
const
|
|
18178
|
-
outerFailure:
|
|
18842
|
+
const failure = classifyExecutorFailure(err);
|
|
18843
|
+
const selectedMetadata = normalizeFailureWinnerMetadata(normalizeStageLessFailureMetadata(selectRunFailureDisposition({
|
|
18844
|
+
outerFailure: failure,
|
|
18179
18845
|
thrownError: err,
|
|
18180
18846
|
stages: runSnapshot.stages,
|
|
18181
18847
|
classifyFailure: classifyExecutorFailure
|
|
18182
18848
|
}), runSnapshot.stages.length));
|
|
18183
|
-
const failedToolNodeId =
|
|
18184
|
-
const metadata = failedToolNodeId === undefined ?
|
|
18849
|
+
const failedToolNodeId = selectedMetadata.failedStageId === undefined && selectedMetadata.failureDisposition !== "terminal_killed" ? catchTerminalEvent?.kind === "failure" && Object.is(catchTerminalEvent.error, err) ? catchTerminalEvent.nodeId ?? observedAdmittedToolFailure?.nodeId : observedAdmittedToolFailure?.nodeId : undefined;
|
|
18850
|
+
const metadata = failedToolNodeId === undefined ? selectedMetadata : { ...selectedMetadata, failedToolNodeId };
|
|
18185
18851
|
if (metadata.failureDisposition === "terminal_killed") {
|
|
18186
18852
|
for (const failedStageId of metadata.failedStageIds)
|
|
18187
18853
|
scheduler.blockKnownNonTerminalDescendants(failedStageId);
|
|
@@ -18209,6 +18875,10 @@ async function run(def, inputs, opts = {}) {
|
|
|
18209
18875
|
onRunEnd: opts.onRunEnd
|
|
18210
18876
|
});
|
|
18211
18877
|
} finally {
|
|
18878
|
+
callerSignal?.removeEventListener("abort", onCallerAbort);
|
|
18879
|
+
workflowObservationRuntime(activeStore).finishRun(runId);
|
|
18880
|
+
runtimeSettled.resolve();
|
|
18881
|
+
unregisterRunControl();
|
|
18212
18882
|
try {
|
|
18213
18883
|
await finalizeDurableTerminalStatus({
|
|
18214
18884
|
runId,
|
|
@@ -18246,45 +18916,45 @@ var NON_INTERACTIVE_WORKFLOW_POLICY = Object.freeze({
|
|
|
18246
18916
|
allowInputPicker: false
|
|
18247
18917
|
});
|
|
18248
18918
|
// dist/builtin/workflows/src/workflows/registry.ts
|
|
18249
|
-
function makeRegistry(
|
|
18919
|
+
function makeRegistry(store) {
|
|
18250
18920
|
return {
|
|
18251
18921
|
register(definition) {
|
|
18252
|
-
const next = new Map(
|
|
18922
|
+
const next = new Map(store);
|
|
18253
18923
|
next.set(definition.normalizedName, definition);
|
|
18254
18924
|
return makeRegistry(next);
|
|
18255
18925
|
},
|
|
18256
18926
|
merge(other) {
|
|
18257
|
-
const next = new Map(
|
|
18927
|
+
const next = new Map(store);
|
|
18258
18928
|
for (const def of other.all()) {
|
|
18259
18929
|
next.set(def.normalizedName, def);
|
|
18260
18930
|
}
|
|
18261
18931
|
return makeRegistry(next);
|
|
18262
18932
|
},
|
|
18263
18933
|
get(name) {
|
|
18264
|
-
return
|
|
18934
|
+
return store.get(normalizeWorkflowName(name));
|
|
18265
18935
|
},
|
|
18266
18936
|
has(name) {
|
|
18267
|
-
return
|
|
18937
|
+
return store.has(normalizeWorkflowName(name));
|
|
18268
18938
|
},
|
|
18269
18939
|
remove(name) {
|
|
18270
|
-
const
|
|
18271
|
-
if (!
|
|
18940
|
+
const key = normalizeWorkflowName(name);
|
|
18941
|
+
if (!store.has(key))
|
|
18272
18942
|
return this;
|
|
18273
|
-
const next = new Map(
|
|
18274
|
-
next.delete(
|
|
18943
|
+
const next = new Map(store);
|
|
18944
|
+
next.delete(key);
|
|
18275
18945
|
return makeRegistry(next);
|
|
18276
18946
|
},
|
|
18277
18947
|
names() {
|
|
18278
|
-
return [...
|
|
18948
|
+
return [...store.keys()];
|
|
18279
18949
|
},
|
|
18280
18950
|
all() {
|
|
18281
|
-
return [...
|
|
18951
|
+
return [...store.values()];
|
|
18282
18952
|
}
|
|
18283
18953
|
};
|
|
18284
18954
|
}
|
|
18285
18955
|
function createRegistry(initial = []) {
|
|
18286
|
-
const
|
|
18287
|
-
return makeRegistry(
|
|
18956
|
+
const store = new Map(initial.map((d) => [d.normalizedName, d]));
|
|
18957
|
+
return makeRegistry(store);
|
|
18288
18958
|
}
|
|
18289
18959
|
|
|
18290
18960
|
// dist/builtin/workflows/src/sdk-surface.ts
|