@bastani/atomic 0.9.13-alpha.2 → 0.9.13-alpha.4
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 +30 -0
- package/README.md +1 -1
- package/dist/builtin/i-have-adhd/package.json +1 -1
- package/dist/builtin/intercom/CHANGELOG.md +14 -0
- package/dist/builtin/intercom/README.md +12 -12
- package/dist/builtin/intercom/incoming-message-delivery.ts +1 -1
- package/dist/builtin/intercom/index.ts +1 -1
- package/dist/builtin/intercom/intercom-tool.ts +1 -1
- package/dist/builtin/intercom/intercom-utils.ts +3 -6
- package/dist/builtin/intercom/package.json +1 -1
- package/dist/builtin/intercom/result-renderers.ts +1 -1
- package/dist/builtin/intercom/session-target.ts +1 -15
- package/dist/builtin/intercom/skills/intercom/SKILL.md +6 -6
- package/dist/builtin/intercom/terminal-ordering-barrier.ts +2 -2
- package/dist/builtin/intercom/ui/inline-message.ts +7 -5
- package/dist/builtin/intercom/ui/session-list.ts +23 -10
- package/dist/builtin/mcp/package.json +1 -1
- package/dist/builtin/subagents/CHANGELOG.md +19 -0
- package/dist/builtin/subagents/README.md +29 -73
- package/dist/builtin/subagents/package.json +2 -2
- package/dist/builtin/subagents/prompts/parallel-cleanup.md +1 -1
- package/dist/builtin/subagents/prompts/parallel-review.md +1 -1
- package/dist/builtin/subagents/prompts/review-loop.md +2 -2
- package/dist/builtin/subagents/skills/subagent/SKILL.md +23 -59
- package/dist/builtin/subagents/skills/tmux/SKILL.md +1 -1
- package/dist/builtin/subagents/src/extension/control-notices.ts +2 -3
- package/dist/builtin/subagents/src/extension/doctor.ts +2 -14
- package/dist/builtin/subagents/src/extension/fanout-child.ts +1 -17
- package/dist/builtin/subagents/src/extension/index.ts +9 -70
- package/dist/builtin/subagents/src/extension/notification-content.ts +1 -1
- package/dist/builtin/subagents/src/extension/prompt-guidance.ts +2 -2
- package/dist/builtin/subagents/src/extension/schemas.ts +2 -8
- package/dist/builtin/subagents/src/extension/tool-description.ts +2 -3
- package/dist/builtin/subagents/src/intercom/intercom-bridge.ts +1 -1
- package/dist/builtin/subagents/src/intercom/result-intercom.ts +5 -46
- package/dist/builtin/subagents/src/runs/{background → foreground}/completion-notification.ts +2 -2
- package/dist/builtin/subagents/src/runs/foreground/inprocess-run-sync.ts +25 -88
- package/dist/builtin/subagents/src/runs/{background → foreground}/notify.ts +5 -5
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-context.ts +11 -28
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-parallel-task.ts +3 -0
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-parallel.ts +2 -0
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-runtime.ts +0 -5
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-single.ts +30 -20
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-status.ts +4 -4
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-types.ts +0 -13
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor.ts +104 -48
- package/dist/builtin/subagents/src/runs/inprocess/index.ts +1 -1
- package/dist/builtin/subagents/src/runs/inprocess/runner.ts +5 -5
- package/dist/builtin/subagents/src/runs/inprocess/runtime-support/nested-api.ts +0 -7
- package/dist/builtin/subagents/src/runs/inprocess/runtime-support/nested-core.ts +0 -10
- package/dist/builtin/subagents/src/runs/inprocess/runtime-support/nested-projection.ts +3 -108
- package/dist/builtin/subagents/src/runs/inprocess/runtime-support/nested-sanitize.ts +0 -4
- package/dist/builtin/subagents/src/runs/shared/subagent-control.ts +1 -1
- package/dist/builtin/subagents/src/shared/formatters.ts +3 -5
- package/dist/builtin/subagents/src/shared/model-resolution.ts +78 -0
- package/dist/builtin/subagents/src/shared/status-format.ts +4 -11
- package/dist/builtin/subagents/src/shared/types-config.ts +10 -9
- package/dist/builtin/subagents/src/shared/types-nested.ts +127 -0
- package/dist/builtin/subagents/src/shared/types-results.ts +2 -8
- package/dist/builtin/subagents/src/shared/types-runtime.ts +0 -9
- package/dist/builtin/subagents/src/shared/types.ts +1 -1
- package/dist/builtin/subagents/src/shared/utils.ts +1 -109
- package/dist/builtin/subagents/src/slash/slash-commands.ts +7 -17
- package/dist/builtin/subagents/src/tui/render-event-formatting.ts +2 -252
- package/dist/builtin/subagents/src/tui/render-layout.ts +4 -4
- package/dist/builtin/subagents/src/tui/render-result.ts +0 -9
- package/dist/builtin/subagents/src/tui/render-stable-output.ts +1 -34
- package/dist/builtin/subagents/src/tui/render.ts +0 -2
- package/dist/builtin/web-access/package.json +1 -1
- package/dist/builtin/workflows/CHANGELOG.md +23 -0
- package/dist/builtin/workflows/README.md +3 -3
- package/dist/builtin/workflows/package.json +1 -1
- package/dist/builtin/workflows/src/durable/backend.ts +11 -0
- package/dist/builtin/workflows/src/durable/completed-catalog-stage-groups.ts +63 -25
- package/dist/builtin/workflows/src/durable/completed-catalog.ts +166 -25
- package/dist/builtin/workflows/src/durable/dbos-backend.ts +42 -24
- package/dist/builtin/workflows/src/durable/dbos-envelope.ts +2 -1
- package/dist/builtin/workflows/src/durable/run-timing.ts +28 -7
- package/dist/builtin/workflows/src/durable/scoped-backend.ts +4 -0
- package/dist/builtin/workflows/src/durable/targeted-inspection.ts +110 -0
- package/dist/builtin/workflows/src/engine/run-durable-stage-session.ts +2 -2
- package/dist/builtin/workflows/src/engine/runtime.ts +19 -2
- package/dist/builtin/workflows/src/extension/extension-runtime-state.ts +3 -0
- package/dist/builtin/workflows/src/extension/index.bundle.mjs +750 -168
- package/dist/builtin/workflows/src/extension/runtime-durable-resume.ts +6 -0
- package/dist/builtin/workflows/src/extension/ui-surface.ts +4 -0
- package/dist/builtin/workflows/src/extension/workflow-command-registration.ts +6 -1
- package/dist/builtin/workflows/src/extension/workflow-targets.ts +18 -10
- package/dist/builtin/workflows/src/extension/workflow-tool-inspection.ts +31 -16
- package/dist/builtin/workflows/src/extension/workflow-tool-send.ts +75 -3
- package/dist/builtin/workflows/src/extension/workflow-tool.ts +53 -6
- package/dist/builtin/workflows/src/runs/background/run-inspect.ts +5 -1
- package/dist/builtin/workflows/src/runs/foreground/executor-stage-call.ts +94 -60
- package/dist/builtin/workflows/src/runs/foreground/executor-stage-context.ts +1 -1
- package/dist/builtin/workflows/src/runs/foreground/executor-stage-control.ts +7 -7
- package/dist/builtin/workflows/src/runs/foreground/executor-stage-factory.ts +25 -4
- package/dist/builtin/workflows/src/runs/foreground/executor-stage-types.ts +4 -1
- package/dist/builtin/workflows/src/runs/foreground/executor-types.ts +2 -0
- package/dist/builtin/workflows/src/runs/foreground/stage-runner-controller.ts +142 -4
- package/dist/builtin/workflows/src/runs/foreground/stage-runner-types.ts +2 -0
- package/dist/builtin/workflows/src/runs/foreground/stage-session-heartbeat.ts +88 -0
- package/dist/builtin/workflows/src/tui/keybindings-adapter.ts +1 -0
- package/dist/builtin/workflows/src/tui/overlay-adapter.ts +1 -0
- package/dist/builtin/workflows/src/tui/run-detail.ts +25 -12
- package/dist/builtin/workflows/src/tui/stage-chat-view-archive-history.ts +27 -8
- package/dist/builtin/workflows/src/tui/stage-chat-view-input.ts +17 -1
- package/dist/builtin/workflows/src/tui/stage-chat-view.ts +20 -3
- package/dist/builtin/workflows/src/tui/workflow-attach-pane.ts +10 -1
- package/dist/builtin/workflows/src/tui/workflow-resume-selector.ts +1 -0
- package/dist/core/agent-session-events.d.ts.map +1 -1
- package/dist/core/agent-session-events.js +22 -5
- package/dist/core/agent-session-events.js.map +1 -1
- package/dist/core/agent-session-export.d.ts.map +1 -1
- package/dist/core/agent-session-export.js +2 -1
- package/dist/core/agent-session-export.js.map +1 -1
- package/dist/core/agent-session-methods.d.ts +10 -4
- package/dist/core/agent-session-methods.d.ts.map +1 -1
- package/dist/core/agent-session-methods.js.map +1 -1
- package/dist/core/agent-session-prompt.d.ts.map +1 -1
- package/dist/core/agent-session-prompt.js +68 -0
- package/dist/core/agent-session-prompt.js.map +1 -1
- package/dist/core/agent-session-queue-pause.d.ts.map +1 -1
- package/dist/core/agent-session-queue-pause.js +6 -0
- package/dist/core/agent-session-queue-pause.js.map +1 -1
- package/dist/core/agent-session-summary.d.ts +21 -0
- package/dist/core/agent-session-summary.d.ts.map +1 -0
- package/dist/core/agent-session-summary.js +156 -0
- package/dist/core/agent-session-summary.js.map +1 -0
- package/dist/core/agent-session-tool-registry.d.ts.map +1 -1
- package/dist/core/agent-session-tool-registry.js +0 -4
- package/dist/core/agent-session-tool-registry.js.map +1 -1
- package/dist/core/agent-session-transfer.d.ts.map +1 -1
- package/dist/core/agent-session-transfer.js +0 -2
- package/dist/core/agent-session-transfer.js.map +1 -1
- package/dist/core/agent-session-tree.d.ts.map +1 -1
- package/dist/core/agent-session-tree.js +6 -0
- package/dist/core/agent-session-tree.js.map +1 -1
- package/dist/core/agent-session.d.ts +21 -3
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +22 -5
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/atomic-guide-command.js +2 -2
- package/dist/core/atomic-guide-command.js.map +1 -1
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js +1 -0
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/compaction/index.d.ts +1 -0
- package/dist/core/compaction/index.d.ts.map +1 -1
- package/dist/core/compaction/index.js +1 -0
- package/dist/core/compaction/index.js.map +1 -1
- package/dist/core/compaction/session-summarization.d.ts +41 -0
- package/dist/core/compaction/session-summarization.d.ts.map +1 -0
- package/dist/core/compaction/session-summarization.js +97 -0
- package/dist/core/compaction/session-summarization.js.map +1 -0
- package/dist/core/extensions/ui-types.d.ts +4 -0
- package/dist/core/extensions/ui-types.d.ts.map +1 -1
- package/dist/core/extensions/ui-types.js.map +1 -1
- package/dist/core/keybindings.d.ts +0 -5
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +0 -2
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/session-manager-core.d.ts +3 -1
- package/dist/core/session-manager-core.d.ts.map +1 -1
- package/dist/core/session-manager-core.js +9 -1
- package/dist/core/session-manager-core.js.map +1 -1
- package/dist/core/session-manager-entries.d.ts +24 -1
- package/dist/core/session-manager-entries.d.ts.map +1 -1
- package/dist/core/session-manager-entries.js +48 -0
- package/dist/core/session-manager-entries.js.map +1 -1
- package/dist/core/session-manager-list.d.ts.map +1 -1
- package/dist/core/session-manager-list.js +10 -0
- package/dist/core/session-manager-list.js.map +1 -1
- package/dist/core/session-manager-types.d.ts +10 -1
- package/dist/core/session-manager-types.d.ts.map +1 -1
- package/dist/core/session-manager-types.js.map +1 -1
- package/dist/core/settings-manager-basic-accessors.d.ts +3 -0
- package/dist/core/settings-manager-basic-accessors.d.ts.map +1 -1
- package/dist/core/settings-manager-basic-accessors.js +5 -0
- package/dist/core/settings-manager-basic-accessors.js.map +1 -1
- package/dist/core/settings-manager.d.ts +1 -1
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/settings-types.d.ts +4 -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.js +2 -2
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/tools/bash.d.ts +0 -15
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +3 -81
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/fetch-url.d.ts +12 -0
- package/dist/core/tools/fetch-url.d.ts.map +1 -1
- package/dist/core/tools/fetch-url.js +76 -10
- package/dist/core/tools/fetch-url.js.map +1 -1
- package/dist/core/tools/index.js +4 -4
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/session-temp-dir.d.ts +2 -2
- package/dist/core/tools/session-temp-dir.d.ts.map +1 -1
- package/dist/core/tools/session-temp-dir.js +6 -7
- package/dist/core/tools/session-temp-dir.js.map +1 -1
- package/dist/core/usage-totals.js +1 -1
- package/dist/core/usage-totals.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/modes/interactive/components/footer.js +1 -1
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/host-session-picker.d.ts.map +1 -1
- package/dist/modes/interactive/components/host-session-picker.js +1 -0
- package/dist/modes/interactive/components/host-session-picker.js.map +1 -1
- package/dist/modes/interactive/components/index.d.ts +1 -0
- package/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/dist/modes/interactive/components/index.js +1 -0
- package/dist/modes/interactive/components/index.js.map +1 -1
- package/dist/modes/interactive/components/session-selector-list.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector-list.js +29 -4
- package/dist/modes/interactive/components/session-selector-list.js.map +1 -1
- package/dist/modes/interactive/components/session-selector-search.js +1 -1
- package/dist/modes/interactive/components/session-selector-search.js.map +1 -1
- package/dist/modes/interactive/components/transcript-follow-indicator.d.ts +14 -0
- package/dist/modes/interactive/components/transcript-follow-indicator.d.ts.map +1 -0
- package/dist/modes/interactive/components/transcript-follow-indicator.js +36 -0
- package/dist/modes/interactive/components/transcript-follow-indicator.js.map +1 -0
- package/dist/modes/interactive/components/tree-selector-content.d.ts.map +1 -1
- package/dist/modes/interactive/components/tree-selector-content.js +6 -0
- package/dist/modes/interactive/components/tree-selector-content.js.map +1 -1
- package/dist/modes/interactive/interactive-extension-custom-ui.js +3 -0
- package/dist/modes/interactive/interactive-extension-custom-ui.js.map +1 -1
- package/dist/modes/interactive/interactive-input-handling.js +0 -3
- package/dist/modes/interactive/interactive-input-handling.js.map +1 -1
- package/dist/modes/interactive/interactive-mode-base.d.ts +1 -0
- package/dist/modes/interactive/interactive-mode-base.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode-base.js +7 -1
- package/dist/modes/interactive/interactive-mode-base.js.map +1 -1
- package/dist/modes/interactive/interactive-mode-surface.d.ts +3 -3
- 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 +1 -0
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/interactive-slash-commands.js +2 -5
- package/dist/modes/interactive/interactive-slash-commands.js.map +1 -1
- package/dist/modes/interactive/interactive-startup.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-startup.js +6 -0
- package/dist/modes/interactive/interactive-startup.js.map +1 -1
- package/dist/modes/interactive/interactive-transcript-follow.d.ts +2 -0
- package/dist/modes/interactive/interactive-transcript-follow.d.ts.map +1 -0
- package/dist/modes/interactive/interactive-transcript-follow.js +6 -0
- package/dist/modes/interactive/interactive-transcript-follow.js.map +1 -0
- package/dist/modes/interactive/interactive-tui.d.ts +13 -1
- package/dist/modes/interactive/interactive-tui.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-tui.js +59 -1
- package/dist/modes/interactive/interactive-tui.js.map +1 -1
- package/dist/modes/interactive-engine/engine-custom-ui.d.ts +2 -0
- package/dist/modes/interactive-engine/engine-custom-ui.d.ts.map +1 -1
- package/dist/modes/interactive-engine/engine-custom-ui.js +1 -0
- package/dist/modes/interactive-engine/engine-custom-ui.js.map +1 -1
- package/dist/modes/interactive-engine/protocol.d.ts +1 -0
- package/dist/modes/interactive-engine/protocol.d.ts.map +1 -1
- package/dist/modes/interactive-engine/protocol.js +5 -1
- package/dist/modes/interactive-engine/protocol.js.map +1 -1
- package/dist/modes/interactive-engine/remote-component.d.ts.map +1 -1
- package/dist/modes/interactive-engine/remote-component.js +21 -9
- package/dist/modes/interactive-engine/remote-component.js.map +1 -1
- package/docs/environment-variables.md +1 -1
- package/docs/intercom.md +20 -21
- package/docs/keybindings.md +2 -5
- package/docs/quickstart.md +5 -1
- package/docs/sdk.md +1 -1
- package/docs/session-format.md +15 -0
- package/docs/sessions.md +8 -0
- package/docs/settings.md +6 -0
- package/docs/subagents.md +19 -31
- package/docs/tools.md +3 -5
- package/docs/usage.md +3 -1
- package/docs/windows.md +1 -1
- package/docs/workflows.md +60 -32
- package/npm-shrinkwrap.json +29 -29
- package/package.json +2 -2
- package/dist/builtin/subagents/src/runs/background/async-job-tracker.ts +0 -331
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-async.ts +0 -161
- package/dist/builtin/subagents/src/runs/inprocess/background-single.ts +0 -195
- package/dist/builtin/subagents/src/runs/inprocess/background.ts +0 -90
- package/dist/builtin/subagents/src/shared/types-async.ts +0 -247
- package/dist/builtin/subagents/src/tui/render-widget-graph.ts +0 -217
- package/dist/builtin/subagents/src/tui/render-widget.ts +0 -366
- package/dist/core/async/format.d.ts +0 -3
- package/dist/core/async/format.d.ts.map +0 -1
- package/dist/core/async/format.js +0 -52
- package/dist/core/async/format.js.map +0 -1
- package/dist/core/async/job-manager.d.ts +0 -40
- package/dist/core/async/job-manager.d.ts.map +0 -1
- package/dist/core/async/job-manager.js +0 -293
- package/dist/core/async/job-manager.js.map +0 -1
- package/dist/core/async/session-manager.d.ts +0 -16
- package/dist/core/async/session-manager.d.ts.map +0 -1
- package/dist/core/async/session-manager.js +0 -34
- package/dist/core/async/session-manager.js.map +0 -1
- package/dist/core/async/types.d.ts +0 -23
- package/dist/core/async/types.d.ts.map +0 -1
- package/dist/core/async/types.js +0 -2
- package/dist/core/async/types.js.map +0 -1
- package/dist/core/tools/bash-async-execution.d.ts +0 -27
- package/dist/core/tools/bash-async-execution.d.ts.map +0 -1
- package/dist/core/tools/bash-async-execution.js +0 -81
- package/dist/core/tools/bash-async-execution.js.map +0 -1
- package/dist/core/tools/bash-async-jobs.d.ts +0 -30
- package/dist/core/tools/bash-async-jobs.d.ts.map +0 -1
- package/dist/core/tools/bash-async-jobs.js +0 -87
- package/dist/core/tools/bash-async-jobs.js.map +0 -1
- package/dist/core/tools/bash-async-output.d.ts +0 -13
- package/dist/core/tools/bash-async-output.d.ts.map +0 -1
- package/dist/core/tools/bash-async-output.js +0 -122
- package/dist/core/tools/bash-async-output.js.map +0 -1
|
@@ -37555,6 +37555,8 @@ function summaryRows(detail, now) {
|
|
|
37555
37555
|
rows.push(["error", detail.error.split(`
|
|
37556
37556
|
`)[0] ?? ""]);
|
|
37557
37557
|
}
|
|
37558
|
+
if (detail.resumeGuidance)
|
|
37559
|
+
rows.push(["guidance", detail.resumeGuidance]);
|
|
37558
37560
|
return rows;
|
|
37559
37561
|
}
|
|
37560
37562
|
function artifactRowsFor(detail) {
|
|
@@ -37668,6 +37670,8 @@ function stateBadges(detail, theme) {
|
|
|
37668
37670
|
switch (detail.status) {
|
|
37669
37671
|
case "running":
|
|
37670
37672
|
return [{ text: "● running", fg: theme.warning }];
|
|
37673
|
+
case "crashed":
|
|
37674
|
+
return [{ text: detail.resumable === true ? "✗ crashed · resumable" : "✗ crashed", fg: theme.error }];
|
|
37671
37675
|
case "paused":
|
|
37672
37676
|
return [{ text: "❚❚ paused", fg: theme.warning }];
|
|
37673
37677
|
case "completed":
|
|
@@ -37690,6 +37694,8 @@ function stateLabel(detail) {
|
|
|
37690
37694
|
switch (detail.status) {
|
|
37691
37695
|
case "running":
|
|
37692
37696
|
return "● running";
|
|
37697
|
+
case "crashed":
|
|
37698
|
+
return detail.resumable === true ? "✗ crashed · resumable" : "✗ crashed";
|
|
37693
37699
|
case "paused":
|
|
37694
37700
|
return "❚❚ paused";
|
|
37695
37701
|
case "completed":
|
|
@@ -37729,8 +37735,10 @@ function renderIdentifierRows2(id, width, theme) {
|
|
|
37729
37735
|
});
|
|
37730
37736
|
}
|
|
37731
37737
|
function renderDetailHintRows(detail, width, theme) {
|
|
37732
|
-
const
|
|
37733
|
-
const
|
|
37738
|
+
const resumable = detail.status === "paused" && detail.resumable !== false || detail.resumable === true && (detail.status === "crashed" || detail.status === "failed" || detail.status === "blocked");
|
|
37739
|
+
const inspectOnly = detail.ownerActiveElsewhere === true || detail.status === "crashed" && !resumable || detail.endedAt !== undefined && !resumable;
|
|
37740
|
+
const prefix = inspectOnly ? " ▸ workflow status id=" : resumable ? " ▸ workflow resume id=" : " ▸ workflow interrupt id=";
|
|
37741
|
+
const suffix = inspectOnly ? detail.ownerActiveElsewhere === true ? " inspect; owner active elsewhere " : " inspect retained state " : resumable ? " continue workflow " : " cancel ";
|
|
37734
37742
|
const continuation = " ";
|
|
37735
37743
|
const rows = wrapIdentifierLines(detail.runId, width, prefix, continuation);
|
|
37736
37744
|
const last = rows[rows.length - 1];
|
|
@@ -38943,6 +38951,7 @@ var APP_ACTION = {
|
|
|
38943
38951
|
thinkingToggle: "app.thinking.toggle"
|
|
38944
38952
|
};
|
|
38945
38953
|
var TUI_ACTION = {
|
|
38954
|
+
altScreenBottom: "tui.altScreen.bottom",
|
|
38946
38955
|
editorCursorUp: "tui.editor.cursorUp",
|
|
38947
38956
|
editorCursorDown: "tui.editor.cursorDown",
|
|
38948
38957
|
editorCursorLeft: "tui.editor.cursorLeft",
|
|
@@ -40598,6 +40607,11 @@ function remoteTerminalControlFrom(tui) {
|
|
|
40598
40607
|
return { setAutowrap: terminal.setAutowrap.bind(terminal) };
|
|
40599
40608
|
}
|
|
40600
40609
|
|
|
40610
|
+
// dist/builtin/workflows/src/tui/workflow-attach-pane.ts
|
|
40611
|
+
import {
|
|
40612
|
+
TRANSCRIPT_JUMP_TO_END_URL as TRANSCRIPT_JUMP_TO_END_URL2
|
|
40613
|
+
} from "@bastani/atomic";
|
|
40614
|
+
|
|
40601
40615
|
// dist/builtin/workflows/src/runs/foreground/stage-queued-user-messages.ts
|
|
40602
40616
|
var EMPTY_STAGE_QUEUED_USER_MESSAGES = Object.freeze({
|
|
40603
40617
|
steering: Object.freeze([]),
|
|
@@ -43788,6 +43802,9 @@ class StageChatComposerDrafts {
|
|
|
43788
43802
|
}
|
|
43789
43803
|
}
|
|
43790
43804
|
|
|
43805
|
+
// dist/builtin/workflows/src/tui/stage-chat-view.ts
|
|
43806
|
+
import { keyText as keyText2, TranscriptFollowIndicator } from "@bastani/atomic";
|
|
43807
|
+
|
|
43791
43808
|
// dist/builtin/workflows/src/tui/stage-chat-layout.ts
|
|
43792
43809
|
function resolveStageChatViewportRows(reported, fallbackRows) {
|
|
43793
43810
|
if (typeof reported !== "number" || !Number.isFinite(reported)) {
|
|
@@ -44122,7 +44139,7 @@ function postMortemUnavailableMessage(reason) {
|
|
|
44122
44139
|
return;
|
|
44123
44140
|
}
|
|
44124
44141
|
}
|
|
44125
|
-
function renderReadOnlyArchiveBody(ctx, width, budget, stage) {
|
|
44142
|
+
function renderReadOnlyArchiveBody(ctx, width, budget, stage, indicatorLines = [], renderIndicator = () => indicatorLines) {
|
|
44126
44143
|
if (stage?.promptFootprint) {
|
|
44127
44144
|
return renderReadOnlyPromptArchiveBody(ctx, width, budget, stage);
|
|
44128
44145
|
}
|
|
@@ -44133,8 +44150,13 @@ function renderReadOnlyArchiveBody(ctx, width, budget, stage) {
|
|
|
44133
44150
|
callout.push(...bannerLines(ctx, width, unavailableMessage === undefined ? "info" : "warning", unavailableMessage === undefined ? "◌" : "!", unavailableMessage === undefined ? "READ-ONLY SESSION" : "SESSION UNAVAILABLE", unavailableMessage === undefined ? stage?.sessionFile ? "archived transcript" : "no live chat session" : "post-mortem chat cannot be reopened"));
|
|
44134
44151
|
callout.push(...new Text2(paint2(unavailableMessage ?? "This node is no longer attached to a live chat session.", t.textMuted), 2, 0).render(width));
|
|
44135
44152
|
const transcriptBudget = Math.max(0, budget - callout.length);
|
|
44136
|
-
const
|
|
44137
|
-
|
|
44153
|
+
const reservedIndicatorRows = indicatorLines.length > 0 && transcriptBudget > indicatorLines.length ? indicatorLines.length : 0;
|
|
44154
|
+
const transcriptRows = transcriptBudget - reservedIndicatorRows;
|
|
44155
|
+
const lines = transcriptRows > 0 ? ctx.chatHost.renderBody(width, transcriptRows) : [];
|
|
44156
|
+
const visibleIndicatorLines = reservedIndicatorRows > 0 ? [...renderIndicator().slice(0, reservedIndicatorRows)] : [];
|
|
44157
|
+
while (visibleIndicatorLines.length < reservedIndicatorRows)
|
|
44158
|
+
visibleIndicatorLines.push(blankLine(width));
|
|
44159
|
+
lines.push(...visibleIndicatorLines, ...callout);
|
|
44138
44160
|
while (lines.length < budget)
|
|
44139
44161
|
lines.push(blankLine(width));
|
|
44140
44162
|
if (lines.length > budget)
|
|
@@ -44210,16 +44232,21 @@ function formatReadOnlyPromptAnswer(value2, kind) {
|
|
|
44210
44232
|
return String(value2);
|
|
44211
44233
|
}
|
|
44212
44234
|
}
|
|
44213
|
-
function renderPausedBody(ctx, width, budget) {
|
|
44235
|
+
function renderPausedBody(ctx, width, budget, indicatorLines = [], renderIndicator = () => indicatorLines) {
|
|
44214
44236
|
const t = ctx.theme;
|
|
44215
44237
|
const callout = [];
|
|
44216
44238
|
callout.push(blankLine(width));
|
|
44217
44239
|
callout.push(...bannerLines(ctx, width, "warning", "❚❚", "PAUSED", "enter resumes · ctrl+x return to graph"));
|
|
44218
44240
|
callout.push(...new Text2(paint2("This workflow stage is paused. Type a message below and press Enter to resume.", t.textMuted), 2, 0).render(width));
|
|
44219
|
-
const calloutRows = Math.min(callout.length, Math.max(0, budget
|
|
44220
|
-
const transcriptBudget = Math.max(
|
|
44221
|
-
const
|
|
44222
|
-
|
|
44241
|
+
const calloutRows = Math.min(callout.length, Math.max(0, budget));
|
|
44242
|
+
const transcriptBudget = Math.max(0, budget - calloutRows);
|
|
44243
|
+
const reservedIndicatorRows = indicatorLines.length > 0 && transcriptBudget > indicatorLines.length ? indicatorLines.length : 0;
|
|
44244
|
+
const transcriptRows = transcriptBudget - reservedIndicatorRows;
|
|
44245
|
+
const lines = transcriptRows > 0 ? ctx.chatHost.renderBody(width, transcriptRows) : [];
|
|
44246
|
+
const visibleIndicatorLines = reservedIndicatorRows > 0 ? [...renderIndicator().slice(0, reservedIndicatorRows)] : [];
|
|
44247
|
+
while (visibleIndicatorLines.length < reservedIndicatorRows)
|
|
44248
|
+
visibleIndicatorLines.push(blankLine(width));
|
|
44249
|
+
lines.push(...visibleIndicatorLines, ...callout.slice(0, calloutRows));
|
|
44223
44250
|
while (lines.length < budget)
|
|
44224
44251
|
lines.push(blankLine(width));
|
|
44225
44252
|
if (lines.length > budget)
|
|
@@ -44662,6 +44689,9 @@ function canSubmitPrompt(ctx, promptId) {
|
|
|
44662
44689
|
return ctx.canSubmitPrompt?.(ctx.runId, ctx.stageId, promptId) ?? true;
|
|
44663
44690
|
}
|
|
44664
44691
|
|
|
44692
|
+
// dist/builtin/workflows/src/tui/stage-chat-view-input.ts
|
|
44693
|
+
import { TRANSCRIPT_JUMP_TO_END_URL } from "@bastani/atomic";
|
|
44694
|
+
|
|
44665
44695
|
// dist/builtin/workflows/src/tui/stage-chat-view-state.ts
|
|
44666
44696
|
import { ChatSessionHost } from "@bastani/atomic";
|
|
44667
44697
|
import { Editor } from "@earendil-works/pi-tui";
|
|
@@ -45636,6 +45666,8 @@ function promptPageSize(ctx) {
|
|
|
45636
45666
|
|
|
45637
45667
|
// dist/builtin/workflows/src/tui/stage-chat-view-input.ts
|
|
45638
45668
|
function handleStageChatInput(ctx, data) {
|
|
45669
|
+
if (data === TRANSCRIPT_JUMP_TO_END_URL)
|
|
45670
|
+
return handleStageChatJumpToBottom(ctx, data);
|
|
45639
45671
|
const keybindings = isKeybindingsLike(ctx.piKeybindings) ? ctx.piKeybindings : undefined;
|
|
45640
45672
|
if (matchesKey(data, Key.ctrl("t")) && matchesAction(keybindings, data, APP_ACTION.thinkingToggle)) {
|
|
45641
45673
|
return false;
|
|
@@ -45669,6 +45701,8 @@ function handleStageChatInput(ctx, data) {
|
|
|
45669
45701
|
if (readOnlyPromptArchive && handlePromptScrollInput(ctx, data, true)) {
|
|
45670
45702
|
return true;
|
|
45671
45703
|
}
|
|
45704
|
+
if (handleStageChatJumpToBottom(ctx, data))
|
|
45705
|
+
return true;
|
|
45672
45706
|
if (ctx.chatHost.handleScrollInput(data))
|
|
45673
45707
|
return true;
|
|
45674
45708
|
if (matchesKey(data, Key.escape)) {
|
|
@@ -45699,6 +45733,13 @@ function handleStageChatInput(ctx, data) {
|
|
|
45699
45733
|
return true;
|
|
45700
45734
|
return ctx.chatHost.handleInput(data);
|
|
45701
45735
|
}
|
|
45736
|
+
function handleStageChatJumpToBottom(ctx, data) {
|
|
45737
|
+
const keybindings = isKeybindingsLike(ctx.piKeybindings) ? ctx.piKeybindings : undefined;
|
|
45738
|
+
if (data !== TRANSCRIPT_JUMP_TO_END_URL && !matchesAction(keybindings, data, TUI_ACTION.altScreenBottom))
|
|
45739
|
+
return false;
|
|
45740
|
+
ctx.chatHost.scrollToBottom();
|
|
45741
|
+
return true;
|
|
45742
|
+
}
|
|
45702
45743
|
function handleToolsExpandInput(ctx, data) {
|
|
45703
45744
|
const keybindings = isKeybindingsLike(ctx.piKeybindings) ? ctx.piKeybindings : undefined;
|
|
45704
45745
|
if (!matchesAction(keybindings, data, APP_ACTION.toolsExpand))
|
|
@@ -45722,6 +45763,10 @@ function handleMountedCustomUiInput(ctx, data) {
|
|
|
45722
45763
|
ctx.onClose();
|
|
45723
45764
|
return true;
|
|
45724
45765
|
}
|
|
45766
|
+
if (handleStageChatJumpToBottom(ctx, data)) {
|
|
45767
|
+
ctx.requestRender?.();
|
|
45768
|
+
return true;
|
|
45769
|
+
}
|
|
45725
45770
|
if (ctx.chatHost.handleScrollInput(data)) {
|
|
45726
45771
|
ctx.requestRender?.();
|
|
45727
45772
|
return true;
|
|
@@ -45896,6 +45941,12 @@ class StageChatView {
|
|
|
45896
45941
|
if (blocked)
|
|
45897
45942
|
this.chatHost.scrollToBottom();
|
|
45898
45943
|
let bodyLines;
|
|
45944
|
+
let transcriptBodyActive = false;
|
|
45945
|
+
let reservedIndicatorLines = [];
|
|
45946
|
+
const indicator = new TranscriptFollowIndicator({
|
|
45947
|
+
isFollowing: () => this.chatHost.bodyScrollFromBottom() === 0,
|
|
45948
|
+
keyLabel: () => keyText2("tui.altScreen.bottom")
|
|
45949
|
+
});
|
|
45899
45950
|
if (bodyBudget <= 0) {
|
|
45900
45951
|
bodyLines = [];
|
|
45901
45952
|
} else if (promptActive) {
|
|
@@ -45903,16 +45954,24 @@ class StageChatView {
|
|
|
45903
45954
|
} else if (blocked) {
|
|
45904
45955
|
bodyLines = renderBlockedBody(ctx, w, bodyBudget, stage);
|
|
45905
45956
|
} else if (!readOnlyArchive && isPaused(ctx, stage)) {
|
|
45906
|
-
|
|
45957
|
+
reservedIndicatorLines = bodyBudget > 1 ? indicator.render(w) : [];
|
|
45958
|
+
bodyLines = renderPausedBody(ctx, w, bodyBudget, reservedIndicatorLines, () => indicator.render(w));
|
|
45907
45959
|
} else if (readOnlyArchive) {
|
|
45908
|
-
|
|
45960
|
+
reservedIndicatorLines = bodyBudget > 1 ? indicator.render(w) : [];
|
|
45961
|
+
bodyLines = renderReadOnlyArchiveBody(ctx, w, bodyBudget, stage, reservedIndicatorLines, () => indicator.render(w));
|
|
45909
45962
|
} else {
|
|
45963
|
+
transcriptBodyActive = true;
|
|
45910
45964
|
bodyLines = this.chatHost.renderBody(w, bodyBudget);
|
|
45911
45965
|
}
|
|
45966
|
+
const indicatorLines = transcriptBodyActive && bodyBudget > 1 ? indicator.render(w) : [];
|
|
45967
|
+
const indicatorVisible = indicatorLines.length > 0;
|
|
45968
|
+
const dropBodyRow = transcriptBodyActive && indicatorVisible && bodyLines.length >= bodyBudget;
|
|
45969
|
+
const visibleBodyLines = bodyLines.slice(dropBodyRow ? 1 : 0, bodyBudget);
|
|
45912
45970
|
const lines = [
|
|
45913
45971
|
...headerLines,
|
|
45914
45972
|
...sepLines,
|
|
45915
|
-
...
|
|
45973
|
+
...visibleBodyLines,
|
|
45974
|
+
...indicatorLines,
|
|
45916
45975
|
...visiblePendingLines,
|
|
45917
45976
|
...visibleWorkingLines,
|
|
45918
45977
|
...visibleUsageLines,
|
|
@@ -46280,6 +46339,8 @@ class WorkflowAttachPane {
|
|
|
46280
46339
|
return true;
|
|
46281
46340
|
return this.chatView.handleInput(data);
|
|
46282
46341
|
}
|
|
46342
|
+
if (data === TRANSCRIPT_JUMP_TO_END_URL2)
|
|
46343
|
+
return false;
|
|
46283
46344
|
if (this._shouldQuarantineGraphEnter(data))
|
|
46284
46345
|
return true;
|
|
46285
46346
|
return this.graphView.handleInput(data);
|
|
@@ -46647,6 +46708,7 @@ function buildGraphOverlayAdapter(pi, store2, buildOpts = {}) {
|
|
|
46647
46708
|
overlay: true,
|
|
46648
46709
|
deferInlineCustomUiFocus: true,
|
|
46649
46710
|
handlesCtrlC: true,
|
|
46711
|
+
handlesInternalUiAction: true,
|
|
46650
46712
|
overlayOptions: FULLSCREEN_OVERLAY_OPTIONS,
|
|
46651
46713
|
onHandle: (handle) => {
|
|
46652
46714
|
currentHandle = handle;
|
|
@@ -47839,7 +47901,7 @@ function isModelUsage(value2) {
|
|
|
47839
47901
|
if (typeof value2 !== "object" || value2 === null || Array.isArray(value2))
|
|
47840
47902
|
return false;
|
|
47841
47903
|
const usage = value2;
|
|
47842
|
-
return ["input", "output", "cacheRead", "cacheWrite", "cost", "turns"].every((key2) => usage[key2] === undefined || typeof usage[key2] === "number" && Number.isFinite(usage[key2]));
|
|
47904
|
+
return ["input", "output", "cacheRead", "cacheWrite", "cost", "turns"].every((key2) => usage[key2] === undefined || typeof usage[key2] === "number" && Number.isFinite(usage[key2]) && usage[key2] >= 0);
|
|
47843
47905
|
}
|
|
47844
47906
|
function isUiPromptKind(value2) {
|
|
47845
47907
|
return value2 === "input" || value2 === "confirm" || value2 === "select" || value2 === "editor" || value2 === "custom";
|
|
@@ -48165,6 +48227,12 @@ class InMemoryDurableBackend {
|
|
|
48165
48227
|
return this.getWorkflow(workflowId);
|
|
48166
48228
|
}
|
|
48167
48229
|
async hydrateWorkflow(_workflowId) {}
|
|
48230
|
+
async hydrateWorkflowForInspection(workflowId) {
|
|
48231
|
+
const handle = this.getLoadableWorkflow(workflowId);
|
|
48232
|
+
if (handle !== undefined)
|
|
48233
|
+
return { kind: "current", handle };
|
|
48234
|
+
return { kind: this.deletedWorkflowIds.has(workflowId) ? "deleted" : "absent" };
|
|
48235
|
+
}
|
|
48168
48236
|
async hydrateResumableWorkflows() {}
|
|
48169
48237
|
async prepareWorkflowCatalog() {
|
|
48170
48238
|
return { resumable: this.listResumableWorkflows(), completed: this.listCompletedWorkflows() };
|
|
@@ -50300,17 +50368,24 @@ class DbosDurableBackend {
|
|
|
50300
50368
|
throw first;
|
|
50301
50369
|
}
|
|
50302
50370
|
async hydrateWorkflow(workflowId) {
|
|
50303
|
-
|
|
50304
|
-
|
|
50305
|
-
|
|
50306
|
-
if (
|
|
50307
|
-
|
|
50308
|
-
return;
|
|
50371
|
+
await this.hydrateWorkflowForInspection(workflowId);
|
|
50372
|
+
}
|
|
50373
|
+
async hydrateWorkflowForInspection(workflowId) {
|
|
50374
|
+
if (this.locallyRegistered.has(workflowId)) {
|
|
50375
|
+
const handle = this.getLoadableWorkflow(workflowId);
|
|
50376
|
+
return handle === undefined ? { kind: "malformed" } : { kind: "current", handle };
|
|
50309
50377
|
}
|
|
50378
|
+
const info = await this.sdk.retrieveWorkflow(workflowId);
|
|
50379
|
+
if (info !== undefined)
|
|
50380
|
+
return await this.hydrateInfo(info);
|
|
50310
50381
|
const records = await this.sdk.listStepRecords(workflowId);
|
|
50311
50382
|
const deletion = classifyDbosDeletionTombstone(records, workflowId);
|
|
50312
|
-
if (deletion
|
|
50313
|
-
|
|
50383
|
+
if (deletion === "absent" && records.length === 0)
|
|
50384
|
+
return { kind: "absent" };
|
|
50385
|
+
await this.suppressWorkflow(workflowId);
|
|
50386
|
+
if (deletion === "absent")
|
|
50387
|
+
return { kind: "malformed" };
|
|
50388
|
+
return { kind: deletion === "current" ? "deleted" : "malformed" };
|
|
50314
50389
|
}
|
|
50315
50390
|
async hydrateResumableWorkflows() {
|
|
50316
50391
|
const all = await this.sdk.listAllWorkflows();
|
|
@@ -50322,10 +50397,15 @@ class DbosDurableBackend {
|
|
|
50322
50397
|
}
|
|
50323
50398
|
async hydrateInfo(info) {
|
|
50324
50399
|
const records = await this.sdk.listStepRecords(info.workflowId);
|
|
50400
|
+
const deletion = classifyDbosDeletionTombstone(records, info.workflowId);
|
|
50401
|
+
if (deletion !== "absent") {
|
|
50402
|
+
await this.suppressWorkflow(info.workflowId);
|
|
50403
|
+
return { kind: deletion === "current" ? "deleted" : "malformed" };
|
|
50404
|
+
}
|
|
50325
50405
|
const metadata = classifyLatestMetadata(records, info.workflowId);
|
|
50326
50406
|
if (metadata.kind !== "current") {
|
|
50327
50407
|
await this.suppressWorkflow(info.workflowId);
|
|
50328
|
-
return;
|
|
50408
|
+
return { kind: "malformed" };
|
|
50329
50409
|
}
|
|
50330
50410
|
const checkpoints = [];
|
|
50331
50411
|
for (const record of records) {
|
|
@@ -50334,7 +50414,7 @@ class DbosDurableBackend {
|
|
|
50334
50414
|
const classified = classifyCheckpointPayload(info.workflowId, record.stepName, record.output);
|
|
50335
50415
|
if (classified.kind === "unknown") {
|
|
50336
50416
|
await this.suppressWorkflow(info.workflowId);
|
|
50337
|
-
return;
|
|
50417
|
+
return { kind: "malformed" };
|
|
50338
50418
|
}
|
|
50339
50419
|
checkpoints.push(classified.checkpoint);
|
|
50340
50420
|
}
|
|
@@ -50345,14 +50425,21 @@ class DbosDurableBackend {
|
|
|
50345
50425
|
for (const checkpoint of checkpoints)
|
|
50346
50426
|
this.mem.recordCheckpoint(checkpoint);
|
|
50347
50427
|
const current = this.mem.getWorkflow(info.workflowId);
|
|
50348
|
-
if (current
|
|
50349
|
-
|
|
50350
|
-
|
|
50351
|
-
...metadata.metadata,
|
|
50352
|
-
pendingPrompts: pendingPrompts2,
|
|
50353
|
-
completedCheckpoints: current.completedCheckpoints
|
|
50354
|
-
});
|
|
50428
|
+
if (current === undefined) {
|
|
50429
|
+
await this.suppressWorkflow(info.workflowId);
|
|
50430
|
+
return { kind: "malformed" };
|
|
50355
50431
|
}
|
|
50432
|
+
const pendingPrompts2 = this.promptReservations.hydrate(info.workflowId, metadata.metadata.pendingPrompts, records, metadata.metadata.promptReservationEpoch);
|
|
50433
|
+
this.applyMetadata(info.workflowId, {
|
|
50434
|
+
...metadata.metadata,
|
|
50435
|
+
pendingPrompts: pendingPrompts2,
|
|
50436
|
+
completedCheckpoints: current.completedCheckpoints
|
|
50437
|
+
});
|
|
50438
|
+
const handle = this.getLoadableWorkflow(info.workflowId);
|
|
50439
|
+
if (handle !== undefined)
|
|
50440
|
+
return { kind: "current", handle };
|
|
50441
|
+
await this.suppressWorkflow(info.workflowId);
|
|
50442
|
+
return { kind: "malformed" };
|
|
50356
50443
|
}
|
|
50357
50444
|
async suppressWorkflow(workflowId) {
|
|
50358
50445
|
this.invalid.add(workflowId);
|
|
@@ -51066,20 +51153,34 @@ function priorRunElapsedMs(backend, workflowId) {
|
|
|
51066
51153
|
return elapsedMs;
|
|
51067
51154
|
}
|
|
51068
51155
|
function recordRunTimingCheckpoint(backend, run, options) {
|
|
51156
|
+
const checkpoint = runTimingCheckpoint(backend, run, options);
|
|
51157
|
+
if (checkpoint === undefined)
|
|
51158
|
+
return false;
|
|
51159
|
+
backend.recordCheckpoint(checkpoint);
|
|
51160
|
+
return true;
|
|
51161
|
+
}
|
|
51162
|
+
async function recordRunTimingCheckpointAsync(backend, run, options) {
|
|
51163
|
+
const checkpoint = runTimingCheckpoint(backend, run, options);
|
|
51164
|
+
if (checkpoint === undefined)
|
|
51165
|
+
return false;
|
|
51166
|
+
await backend.recordCheckpointAsync(checkpoint);
|
|
51167
|
+
return true;
|
|
51168
|
+
}
|
|
51169
|
+
function runTimingCheckpoint(backend, run, options) {
|
|
51069
51170
|
const now = options?.now ?? Date.now();
|
|
51070
51171
|
const elapsedMs = elapsedRunMs(run, now);
|
|
51071
51172
|
if (elapsedMs <= 0)
|
|
51072
|
-
return
|
|
51173
|
+
return;
|
|
51073
51174
|
if (backend.listCheckpoints(run.id).length === 0)
|
|
51074
|
-
return
|
|
51175
|
+
return;
|
|
51075
51176
|
const recorded = priorRunElapsedMs(backend, run.id);
|
|
51076
51177
|
if (recorded !== undefined) {
|
|
51077
51178
|
if (elapsedMs <= recorded)
|
|
51078
|
-
return
|
|
51179
|
+
return;
|
|
51079
51180
|
if (options?.debounce === true && timingBucket(elapsedMs) === timingBucket(recorded))
|
|
51080
|
-
return
|
|
51181
|
+
return;
|
|
51081
51182
|
}
|
|
51082
|
-
|
|
51183
|
+
return {
|
|
51083
51184
|
kind: "tool",
|
|
51084
51185
|
workflowId: run.id,
|
|
51085
51186
|
checkpointId: `run-timing:${elapsedMs}`,
|
|
@@ -51088,8 +51189,6 @@ function recordRunTimingCheckpoint(backend, run, options) {
|
|
|
51088
51189
|
output: { elapsedMs },
|
|
51089
51190
|
completedAt: now
|
|
51090
51191
|
};
|
|
51091
|
-
backend.recordCheckpoint(checkpoint);
|
|
51092
|
-
return true;
|
|
51093
51192
|
}
|
|
51094
51193
|
function inheritedRunElapsedMs(input) {
|
|
51095
51194
|
const now = input.now ?? Date.now();
|
|
@@ -52992,33 +53091,33 @@ function isRunStatus(value2) {
|
|
|
52992
53091
|
return false;
|
|
52993
53092
|
}
|
|
52994
53093
|
}
|
|
52995
|
-
function resolveRunId(target) {
|
|
53094
|
+
function resolveRunId(target, activeStore = store) {
|
|
52996
53095
|
if (!isFullRunId(target))
|
|
52997
53096
|
return { kind: "malformed", message: malformedRunIdMessage(target) };
|
|
52998
|
-
const exact =
|
|
53097
|
+
const exact = activeStore.runs().find((r) => r.id === target);
|
|
52999
53098
|
if (exact)
|
|
53000
53099
|
return { kind: "exact", runId: exact.id };
|
|
53001
53100
|
return { kind: "not_found" };
|
|
53002
53101
|
}
|
|
53003
|
-
function resolveToolRunTarget(args, emptyMessage) {
|
|
53102
|
+
function resolveToolRunTarget(args, emptyMessage, activeStore = store) {
|
|
53004
53103
|
const rawTarget = args.runId?.trim() ?? "";
|
|
53005
53104
|
if (args.all === true || rawTarget === "--all")
|
|
53006
53105
|
return { kind: "all" };
|
|
53007
|
-
const target = rawTarget ||
|
|
53106
|
+
const target = rawTarget || activeStore.activeRunId() || "";
|
|
53008
53107
|
if (!target)
|
|
53009
53108
|
return { kind: "not_found", target: rawTarget, message: emptyMessage };
|
|
53010
|
-
const resolved = resolveRunId(target);
|
|
53109
|
+
const resolved = resolveRunId(target, activeStore);
|
|
53011
53110
|
if (resolved.kind === "exact")
|
|
53012
53111
|
return { kind: "run", runId: resolved.runId };
|
|
53013
53112
|
if (resolved.kind === "malformed")
|
|
53014
53113
|
return { kind: "malformed", target, message: resolved.message };
|
|
53015
53114
|
return { kind: "not_found", target, message: `Run not found: ${target}` };
|
|
53016
53115
|
}
|
|
53017
|
-
function resolveStageTarget(runId, stageTarget) {
|
|
53116
|
+
function resolveStageTarget(runId, stageTarget, activeStore = store) {
|
|
53018
53117
|
const target = stageTarget?.trim();
|
|
53019
53118
|
if (!target)
|
|
53020
53119
|
return { ok: true, runId };
|
|
53021
|
-
const graph = expandWorkflowGraph(readGraphStoreSnapshot(
|
|
53120
|
+
const graph = expandWorkflowGraph(readGraphStoreSnapshot(activeStore), runId);
|
|
53022
53121
|
const exactVirtualIds = graph.stages.filter((stage) => stage.id === target);
|
|
53023
53122
|
if (exactVirtualIds.length === 1)
|
|
53024
53123
|
return resolvedStageTarget(exactVirtualIds[0]);
|
|
@@ -53054,8 +53153,8 @@ function ambiguousStageTarget(target, stages) {
|
|
|
53054
53153
|
message: `Ambiguous stage identifier "${target}" matches: ${stages.map(expandedStageLabel).join(", ")}`
|
|
53055
53154
|
};
|
|
53056
53155
|
}
|
|
53057
|
-
function resolveToolStageTarget(runId, stageTarget) {
|
|
53058
|
-
return resolveStageTarget(runId, stageTarget);
|
|
53156
|
+
function resolveToolStageTarget(runId, stageTarget, activeStore = store) {
|
|
53157
|
+
return resolveStageTarget(runId, stageTarget, activeStore);
|
|
53059
53158
|
}
|
|
53060
53159
|
function resolveControlNodeTarget(runId, stageTarget) {
|
|
53061
53160
|
const target = stageTarget?.trim();
|
|
@@ -61101,6 +61200,9 @@ class ScopedDurableBackend {
|
|
|
61101
61200
|
hydrateWorkflow(_workflowId) {
|
|
61102
61201
|
return Promise.resolve();
|
|
61103
61202
|
}
|
|
61203
|
+
hydrateWorkflowForInspection(_workflowId) {
|
|
61204
|
+
return Promise.resolve({ kind: "absent" });
|
|
61205
|
+
}
|
|
61104
61206
|
hydrateResumableWorkflows() {
|
|
61105
61207
|
return Promise.resolve();
|
|
61106
61208
|
}
|
|
@@ -64784,7 +64886,7 @@ function createDurableStageSessionRecorder(input) {
|
|
|
64784
64886
|
if (stageRunId === input.runId) {
|
|
64785
64887
|
await recordStageSessionCheckpoint(input.deps, snapshot, { force: options?.forceDurable === true });
|
|
64786
64888
|
if (input.runSnapshot !== undefined) {
|
|
64787
|
-
|
|
64889
|
+
await recordRunTimingCheckpointAsync(input.deps.backend, input.runSnapshot, {
|
|
64788
64890
|
debounce: options?.forceDurable !== true
|
|
64789
64891
|
});
|
|
64790
64892
|
}
|
|
@@ -64833,7 +64935,7 @@ function hasUsableContentBlock(block) {
|
|
|
64833
64935
|
}
|
|
64834
64936
|
|
|
64835
64937
|
// dist/builtin/workflows/src/durable/completed-catalog-stage-groups.ts
|
|
64836
|
-
function validBoundaryRecordSet(checkpoints, strict) {
|
|
64938
|
+
function validBoundaryRecordSet(checkpoints, strict, requireActiveFingerprint = false) {
|
|
64837
64939
|
const stages = checkpoints.filter((item) => item.kind === "stage");
|
|
64838
64940
|
const boundaries = stages.filter((item) => item.topology?.boundary !== undefined);
|
|
64839
64941
|
const startsByReplay = new Map;
|
|
@@ -64848,42 +64950,59 @@ function validBoundaryRecordSet(checkpoints, strict) {
|
|
|
64848
64950
|
return false;
|
|
64849
64951
|
if (boundaries.some((checkpoint) => checkpoint.topology.boundary.event === "terminal" && startsByReplay.get(checkpoint.replayKey)?.length !== 1))
|
|
64850
64952
|
return false;
|
|
64851
|
-
return [...startsByReplay.values()].every((starts) =>
|
|
64953
|
+
return [...startsByReplay.values()].every((starts) => {
|
|
64954
|
+
const start = starts[0];
|
|
64955
|
+
if (boundaryTransitionError(start, stages, strict) !== undefined)
|
|
64956
|
+
return false;
|
|
64957
|
+
if (!requireActiveFingerprint || start.topology.boundary.invocationFingerprint !== undefined)
|
|
64958
|
+
return true;
|
|
64959
|
+
return stages.some((stage) => stage.replayKey === start.replayKey && stage.topology?.boundary?.event === "terminal" && stage.topology.boundary.status === "completed") && boundaryTransitionError(start, stages, true) === undefined;
|
|
64960
|
+
});
|
|
64852
64961
|
}
|
|
64853
|
-
function validStageGroup(drafts, runId,
|
|
64962
|
+
function validStageGroup(drafts, runId, rootRunId, tools = []) {
|
|
64854
64963
|
if (drafts.some((draft) => draft.topology.stageId.length === 0))
|
|
64855
64964
|
return false;
|
|
64856
|
-
|
|
64857
|
-
if (stageIds.size !== drafts.length)
|
|
64965
|
+
if (tools.some((tool) => tool.topology !== undefined && (tool.topology.version !== DURABLE_TOOL_TOPOLOGY_VERSION || tool.topology.nodeId.length === 0)))
|
|
64858
64966
|
return false;
|
|
64859
|
-
const
|
|
64860
|
-
|
|
64967
|
+
const stageIds = drafts.map((draft) => draft.topology.stageId);
|
|
64968
|
+
const toolIds = tools.map((tool) => tool.topology?.nodeId ?? tool.checkpointId);
|
|
64969
|
+
const ids = new Set([...stageIds, ...toolIds]);
|
|
64970
|
+
if (ids.size !== stageIds.length + toolIds.length)
|
|
64861
64971
|
return false;
|
|
64862
64972
|
const orders = drafts.flatMap((draft) => draft.topology.sourceOrder === undefined ? [] : [draft.topology.sourceOrder]);
|
|
64863
64973
|
if (new Set(orders).size !== orders.length)
|
|
64864
64974
|
return false;
|
|
64865
|
-
|
|
64975
|
+
const parentEntries = [
|
|
64976
|
+
...drafts.map((draft) => [draft.topology.stageId, draft.topology.parentIds]),
|
|
64977
|
+
...tools.map((tool) => [tool.topology?.nodeId ?? tool.checkpointId, tool.topology?.parentIds ?? []])
|
|
64978
|
+
];
|
|
64979
|
+
if (parentEntries.some(([, parentIds]) => parentIds.some((parentId) => !ids.has(parentId))))
|
|
64866
64980
|
return false;
|
|
64867
|
-
const runs =
|
|
64981
|
+
const runs = [
|
|
64982
|
+
...drafts.flatMap((draft) => draft.topology?.run === undefined ? [] : [draft.topology.run]),
|
|
64983
|
+
...tools.flatMap((tool) => tool.topology?.run === undefined ? [] : [tool.topology.run])
|
|
64984
|
+
];
|
|
64868
64985
|
const first = runs[0];
|
|
64869
64986
|
if (runs.some((run) => run.runId !== runId || first !== undefined && (run.runName !== first.runName || run.parentRunId !== first.parentRunId || run.parentStageId !== first.parentStageId || run.rootRunId !== first.rootRunId)))
|
|
64870
64987
|
return false;
|
|
64871
|
-
|
|
64988
|
+
if (runId === rootRunId && runs.some((run) => run.parentRunId !== undefined || run.parentStageId !== undefined || run.rootRunId !== undefined))
|
|
64989
|
+
return false;
|
|
64990
|
+
const parents = new Map(parentEntries);
|
|
64872
64991
|
const visiting = new Set;
|
|
64873
64992
|
const visited = new Set;
|
|
64874
|
-
const cyclic = (
|
|
64875
|
-
if (visiting.has(
|
|
64993
|
+
const cyclic = (nodeId) => {
|
|
64994
|
+
if (visiting.has(nodeId))
|
|
64876
64995
|
return true;
|
|
64877
|
-
if (visited.has(
|
|
64996
|
+
if (visited.has(nodeId))
|
|
64878
64997
|
return false;
|
|
64879
|
-
visiting.add(
|
|
64880
|
-
if ((parents.get(
|
|
64998
|
+
visiting.add(nodeId);
|
|
64999
|
+
if ((parents.get(nodeId) ?? []).some(cyclic))
|
|
64881
65000
|
return true;
|
|
64882
|
-
visiting.delete(
|
|
64883
|
-
visited.add(
|
|
65001
|
+
visiting.delete(nodeId);
|
|
65002
|
+
visited.add(nodeId);
|
|
64884
65003
|
return false;
|
|
64885
65004
|
};
|
|
64886
|
-
return ![...
|
|
65005
|
+
return ![...ids].some(cyclic);
|
|
64887
65006
|
}
|
|
64888
65007
|
function compareDraftSourceOrder(left, right) {
|
|
64889
65008
|
const leftOrder = left.topology?.sourceOrder;
|
|
@@ -65425,7 +65544,7 @@ function completedWorkflowRunSnapshots(backend, entry) {
|
|
|
65425
65544
|
const checkpoints = backend.listCheckpoints(entry.workflowId);
|
|
65426
65545
|
if (checkpoints.length === 0)
|
|
65427
65546
|
return [];
|
|
65428
|
-
const runs = runSnapshotsFromCheckpoints(checkpoints, handle.workflowId, handle.name, handle.updatedAt).map((run2) => ({ ...run2, stages: run2.stages.map(validatedStageTranscript) }));
|
|
65547
|
+
const runs = runSnapshotsFromCheckpoints(checkpoints, handle.workflowId, handle.name, handle.updatedAt, COMPLETED_RECONSTRUCTION).map((run2) => ({ ...run2, stages: run2.stages.map(validatedStageTranscript) }));
|
|
65429
65548
|
const rootIndex = runs.findIndex((run2) => run2.id === handle.workflowId);
|
|
65430
65549
|
if (rootIndex < 0)
|
|
65431
65550
|
return [];
|
|
@@ -65449,11 +65568,45 @@ function completedWorkflowRunSnapshots(backend, entry) {
|
|
|
65449
65568
|
};
|
|
65450
65569
|
return [root, ...runs.filter((_, index) => index !== rootIndex)];
|
|
65451
65570
|
}
|
|
65571
|
+
function durableWorkflowRunSnapshots(backend, handle) {
|
|
65572
|
+
const checkpoints = backend.listCheckpoints(handle.workflowId);
|
|
65573
|
+
if (checkpoints.length === 0) {
|
|
65574
|
+
return [rootSnapshot(backend, handle, { stages: [], toolNodes: [] })];
|
|
65575
|
+
}
|
|
65576
|
+
const requiresTerminalTopology = handle.status === "completed" || handle.status === "failed";
|
|
65577
|
+
const runs = runSnapshotsFromCheckpoints(checkpoints, handle.workflowId, handle.name, handle.updatedAt, requiresTerminalTopology ? COMPLETED_RECONSTRUCTION : ACTIVE_INSPECTION_RECONSTRUCTION);
|
|
65578
|
+
const rootIndex = runs.findIndex((run2) => run2.id === handle.workflowId);
|
|
65579
|
+
if (rootIndex < 0)
|
|
65580
|
+
return [];
|
|
65581
|
+
return [rootSnapshot(backend, handle, runs[rootIndex]), ...runs.filter((_, index) => index !== rootIndex)];
|
|
65582
|
+
}
|
|
65583
|
+
function rootSnapshot(backend, handle, graph) {
|
|
65584
|
+
const terminal = handle.status === "completed" || handle.status === "failed" || handle.status === "cancelled";
|
|
65585
|
+
const priorDurationMs = priorRunElapsedMs(backend, handle.workflowId);
|
|
65586
|
+
const terminalDurationMs = priorDurationMs ?? Math.max(0, handle.updatedAt - handle.createdAt);
|
|
65587
|
+
return {
|
|
65588
|
+
id: handle.workflowId,
|
|
65589
|
+
name: handle.name,
|
|
65590
|
+
inputs: { ...handle.inputs },
|
|
65591
|
+
status: handle.status,
|
|
65592
|
+
stages: graph.stages,
|
|
65593
|
+
toolNodes: graph.toolNodes,
|
|
65594
|
+
startedAt: handle.createdAt,
|
|
65595
|
+
...terminal ? { endedAt: handle.updatedAt, durationMs: terminalDurationMs } : priorDurationMs === undefined ? {} : { accumulatedDurationMs: priorDurationMs },
|
|
65596
|
+
...handle.error !== undefined ? { error: handle.error } : {},
|
|
65597
|
+
...handle.failureKind !== undefined ? { failureKind: handle.failureKind } : {},
|
|
65598
|
+
...handle.failureCode !== undefined ? { failureCode: handle.failureCode } : {},
|
|
65599
|
+
...handle.failureRecoverability !== undefined ? { failureRecoverability: handle.failureRecoverability } : {},
|
|
65600
|
+
...handle.failureDisposition !== undefined ? { failureDisposition: handle.failureDisposition } : {},
|
|
65601
|
+
...handle.failedToolNodeId !== undefined ? { failedToolNodeId: handle.failedToolNodeId } : {},
|
|
65602
|
+
resumable: isDurableWorkflowResumable(handle)
|
|
65603
|
+
};
|
|
65604
|
+
}
|
|
65452
65605
|
function durableNestedRunSnapshots(backend, rootWorkflowId) {
|
|
65453
65606
|
const handle = backend.getWorkflow(rootWorkflowId);
|
|
65454
65607
|
if (handle === undefined)
|
|
65455
65608
|
return [];
|
|
65456
|
-
return runSnapshotsFromCheckpoints(backend.listCheckpoints(rootWorkflowId), rootWorkflowId, handle.name, handle.updatedAt,
|
|
65609
|
+
return runSnapshotsFromCheckpoints(backend.listCheckpoints(rootWorkflowId), rootWorkflowId, handle.name, handle.updatedAt, LEGACY_ACTIVE_RECONSTRUCTION).filter((run2) => run2.id !== rootWorkflowId);
|
|
65457
65610
|
}
|
|
65458
65611
|
function validatedStageTranscript(stage) {
|
|
65459
65612
|
if (stage.sessionFile === undefined || isReopenableSessionTranscript(stage.sessionFile))
|
|
@@ -65523,15 +65676,36 @@ function summarizeCompletedToolResult(value2) {
|
|
|
65523
65676
|
return flattenTruncatedString(String(value2).slice(0, 240));
|
|
65524
65677
|
return serialized.length <= 240 ? serialized : `${flattenTruncatedString(serialized.slice(0, 237))}...`;
|
|
65525
65678
|
}
|
|
65526
|
-
|
|
65527
|
-
|
|
65679
|
+
var COMPLETED_RECONSTRUCTION = {
|
|
65680
|
+
requireTerminal: true,
|
|
65681
|
+
failClosed: true,
|
|
65682
|
+
retainActive: false,
|
|
65683
|
+
failOnUnreachable: false,
|
|
65684
|
+
requireActiveBoundaryFingerprint: false
|
|
65685
|
+
};
|
|
65686
|
+
var ACTIVE_INSPECTION_RECONSTRUCTION = {
|
|
65687
|
+
requireTerminal: false,
|
|
65688
|
+
failClosed: true,
|
|
65689
|
+
retainActive: true,
|
|
65690
|
+
failOnUnreachable: true,
|
|
65691
|
+
requireActiveBoundaryFingerprint: true
|
|
65692
|
+
};
|
|
65693
|
+
var LEGACY_ACTIVE_RECONSTRUCTION = {
|
|
65694
|
+
requireTerminal: false,
|
|
65695
|
+
failClosed: false,
|
|
65696
|
+
retainActive: true,
|
|
65697
|
+
failOnUnreachable: false,
|
|
65698
|
+
requireActiveBoundaryFingerprint: false
|
|
65699
|
+
};
|
|
65700
|
+
function runSnapshotsFromCheckpoints(checkpoints, rootRunId, rootRunName, fallbackCompletedAt, policy = COMPLETED_RECONSTRUCTION) {
|
|
65701
|
+
if (!validBoundaryRecordSet(checkpoints, policy.requireTerminal, policy.requireActiveBoundaryFingerprint))
|
|
65528
65702
|
return [];
|
|
65529
65703
|
const stageRecords = checkpoints.filter((checkpoint) => checkpoint.kind === "stage");
|
|
65530
65704
|
const identityRecords = stageRecords.filter((stage) => stage.topology?.sourceOrder !== undefined || stage.topology?.status !== undefined || stage.topology?.occurrenceKey !== undefined || stage.topology?.boundary !== undefined);
|
|
65531
65705
|
if (immutableStageGroupError(identityRecords) !== undefined)
|
|
65532
65706
|
return [];
|
|
65533
65707
|
const recordsByGroup = groupByDurableStageKey(stageRecords);
|
|
65534
|
-
const candidates = [...recordsByGroup.values()].map((records) => mergeStageGroup(records, stageRecords, checkpoints)).filter((draft) =>
|
|
65708
|
+
const candidates = [...recordsByGroup.values()].map((records) => mergeStageGroup(records, stageRecords, checkpoints)).filter((draft) => policy.retainActive || draft.topology?.run === undefined || draft.endedAt !== undefined || draft.output !== undefined).map((draft) => draft.topology !== undefined ? draft : {
|
|
65535
65709
|
...draft,
|
|
65536
65710
|
topology: {
|
|
65537
65711
|
version: DURABLE_STAGE_TOPOLOGY_VERSION,
|
|
@@ -65542,13 +65716,36 @@ function runSnapshotsFromCheckpoints(checkpoints, rootRunId, rootRunName, fallba
|
|
|
65542
65716
|
}).sort(compareDraftSourceOrder);
|
|
65543
65717
|
const drafts = checkpointDrafts(checkpoints);
|
|
65544
65718
|
const toolCheckpoints = drafts.tools;
|
|
65719
|
+
if (policy.failClosed) {
|
|
65720
|
+
for (const draft of candidates) {
|
|
65721
|
+
const boundary = draft.topology?.boundary;
|
|
65722
|
+
if (boundary === undefined || childRunIdFromDraft(draft) === undefined)
|
|
65723
|
+
continue;
|
|
65724
|
+
if (boundary.replayScope !== draft.replayKey)
|
|
65725
|
+
return [];
|
|
65726
|
+
const expectedChildRun = {
|
|
65727
|
+
runId: boundary.child.runId,
|
|
65728
|
+
runName: boundary.child.runName,
|
|
65729
|
+
parentRunId: boundary.child.parentRunId,
|
|
65730
|
+
parentStageId: boundary.child.parentStageId,
|
|
65731
|
+
rootRunId: boundary.child.rootRunId
|
|
65732
|
+
};
|
|
65733
|
+
const childToolIds = new Set(toolCheckpoints.flatMap((checkpoint) => checkpoint.topology?.run?.runId === expectedChildRun.runId ? [checkpoint.topology.nodeId] : []));
|
|
65734
|
+
if (directChildTopologyError(stageRecords, boundary.replayScope, expectedChildRun, true, childToolIds) !== undefined)
|
|
65735
|
+
return [];
|
|
65736
|
+
}
|
|
65737
|
+
}
|
|
65545
65738
|
if (candidates.length === 0 && toolCheckpoints.length === 0) {
|
|
65546
|
-
|
|
65739
|
+
const supportedNonGraphState = checkpoints.every((checkpoint) => checkpoint.kind === "ui" || checkpoint.kind === "tool" && checkpoint.argsHash === RUN_TIMING_CHECKPOINT_NAME);
|
|
65740
|
+
if (policy.failClosed && supportedNonGraphState) {
|
|
65741
|
+
return [emptyGraphRun(rootRunId, rootRunName, fallbackCompletedAt)];
|
|
65742
|
+
}
|
|
65743
|
+
return policy.failClosed ? [] : [syntheticRun(rootRunId, rootRunName, checkpoints.length, fallbackCompletedAt)];
|
|
65547
65744
|
}
|
|
65548
65745
|
const grouped = new Map;
|
|
65549
65746
|
for (const draft of candidates) {
|
|
65550
65747
|
if (draft.topology?.version !== DURABLE_STAGE_TOPOLOGY_VERSION) {
|
|
65551
|
-
if (
|
|
65748
|
+
if (policy.failClosed)
|
|
65552
65749
|
return [];
|
|
65553
65750
|
continue;
|
|
65554
65751
|
}
|
|
@@ -65564,7 +65761,10 @@ function runSnapshotsFromCheckpoints(checkpoints, rootRunId, rootRunName, fallba
|
|
|
65564
65761
|
}
|
|
65565
65762
|
for (const group of grouped.values())
|
|
65566
65763
|
group.sort(compareDraftSourceOrder);
|
|
65764
|
+
const groupedCount = grouped.size;
|
|
65567
65765
|
retainReachableRunGroups(grouped, rootRunId);
|
|
65766
|
+
if (policy.failOnUnreachable && grouped.size !== groupedCount)
|
|
65767
|
+
return [];
|
|
65568
65768
|
if (!validateRunGroups(grouped, rootRunId, toolCheckpoints, checkpoints))
|
|
65569
65769
|
return [];
|
|
65570
65770
|
const syntheticChildren = [];
|
|
@@ -65574,7 +65774,7 @@ function runSnapshotsFromCheckpoints(checkpoints, rootRunId, rootRunName, fallba
|
|
|
65574
65774
|
if (child?.exited !== true || grouped.has(child.runId))
|
|
65575
65775
|
continue;
|
|
65576
65776
|
if (!isSyntheticExitedChild(draft, parentRunId, child.runId, rootRunId) || childScopedEvidenceExists(checkpoints, draft.replayKey, child.runId)) {
|
|
65577
|
-
if (
|
|
65777
|
+
if (policy.failClosed)
|
|
65578
65778
|
return [];
|
|
65579
65779
|
continue;
|
|
65580
65780
|
}
|
|
@@ -65583,8 +65783,8 @@ function runSnapshotsFromCheckpoints(checkpoints, rootRunId, rootRunName, fallba
|
|
|
65583
65783
|
}
|
|
65584
65784
|
const idMaps = new Map;
|
|
65585
65785
|
for (const [runId, runDrafts] of grouped) {
|
|
65586
|
-
const
|
|
65587
|
-
if (!validStageGroup(runDrafts, runId,
|
|
65786
|
+
const ownedTools = toolCheckpoints.filter((checkpoint) => (checkpoint.topology?.run?.runId ?? rootRunId) === runId);
|
|
65787
|
+
if (!validStageGroup(runDrafts, runId, rootRunId, ownedTools))
|
|
65588
65788
|
return [];
|
|
65589
65789
|
const ids = new Map;
|
|
65590
65790
|
let hasIdentityConflict = false;
|
|
@@ -65600,7 +65800,7 @@ function runSnapshotsFromCheckpoints(checkpoints, rootRunId, rootRunName, fallba
|
|
|
65600
65800
|
}
|
|
65601
65801
|
});
|
|
65602
65802
|
if (hasIdentityConflict) {
|
|
65603
|
-
if (
|
|
65803
|
+
if (policy.failClosed)
|
|
65604
65804
|
return [];
|
|
65605
65805
|
grouped.delete(runId);
|
|
65606
65806
|
continue;
|
|
@@ -65620,7 +65820,7 @@ function runSnapshotsFromCheckpoints(checkpoints, rootRunId, rootRunName, fallba
|
|
|
65620
65820
|
const ownedTools = toolCheckpoints.filter((checkpoint) => (checkpoint.topology?.run?.runId ?? rootRunId) === runId);
|
|
65621
65821
|
const hasUnknownParents = runDrafts.some((draft) => draft.topology.parentIds.some((parentId) => !ids.has(parentId))) || ownedTools.some((checkpoint) => checkpoint.topology?.parentIds.some((parentId) => !ids.has(parentId)) === true);
|
|
65622
65822
|
if (hasUnknownParents) {
|
|
65623
|
-
if (
|
|
65823
|
+
if (policy.failClosed)
|
|
65624
65824
|
return [];
|
|
65625
65825
|
continue;
|
|
65626
65826
|
}
|
|
@@ -65630,6 +65830,8 @@ function runSnapshotsFromCheckpoints(checkpoints, rootRunId, rootRunName, fallba
|
|
|
65630
65830
|
const startedAt = Math.min(...stages.map((stage) => stage.startedAt ?? fallbackCompletedAt), ...toolNodes.map((tool) => tool.startedAt ?? tool.endedAt ?? fallbackCompletedAt));
|
|
65631
65831
|
const endedAt = Math.max(...stages.map((stage) => stage.endedAt ?? fallbackCompletedAt), ...toolNodes.map((tool) => tool.endedAt ?? fallbackCompletedAt));
|
|
65632
65832
|
const owner = runId === rootRunId ? undefined : boundaryOwner(grouped, runId);
|
|
65833
|
+
const status = owner === undefined ? "completed" : childRunStatus(owner);
|
|
65834
|
+
const terminal = status !== "running" && status !== "pending" && status !== "paused" && status !== "blocked";
|
|
65633
65835
|
const parentRunId = run2?.parentRunId ?? rootRunId;
|
|
65634
65836
|
const boundarySourceId = grouped.get(parentRunId)?.find((draft) => childRunIdFromDraft(draft) === runId)?.topology?.stageId;
|
|
65635
65837
|
const declaredParentStageId = run2?.parentStageId === undefined ? undefined : idMaps.get(parentRunId)?.get(run2.parentStageId);
|
|
@@ -65639,12 +65841,11 @@ function runSnapshotsFromCheckpoints(checkpoints, rootRunId, rootRunName, fallba
|
|
|
65639
65841
|
id: runId,
|
|
65640
65842
|
name: run2?.runName ?? rootRunName,
|
|
65641
65843
|
inputs: {},
|
|
65642
|
-
status
|
|
65844
|
+
status,
|
|
65643
65845
|
stages,
|
|
65644
65846
|
toolNodes,
|
|
65645
65847
|
startedAt,
|
|
65646
|
-
endedAt,
|
|
65647
|
-
durationMs: Math.max(0, endedAt - startedAt),
|
|
65848
|
+
...terminal ? { endedAt, durationMs: Math.max(0, endedAt - startedAt) } : {},
|
|
65648
65849
|
...run2?.parentRunId !== undefined ? { parentRunId: run2.parentRunId } : {},
|
|
65649
65850
|
...parentStageId !== undefined ? { parentStageId } : {},
|
|
65650
65851
|
...run2?.rootRunId !== undefined ? { rootRunId: run2.rootRunId } : {},
|
|
@@ -65659,7 +65860,7 @@ function runSnapshotsFromCheckpoints(checkpoints, rootRunId, rootRunName, fallba
|
|
|
65659
65860
|
}
|
|
65660
65861
|
for (const { parentRunId, owner, child } of syntheticChildren) {
|
|
65661
65862
|
if (!emittedRunIds.has(parentRunId)) {
|
|
65662
|
-
if (
|
|
65863
|
+
if (policy.failClosed)
|
|
65663
65864
|
return [];
|
|
65664
65865
|
continue;
|
|
65665
65866
|
}
|
|
@@ -65667,7 +65868,7 @@ function runSnapshotsFromCheckpoints(checkpoints, rootRunId, rootRunName, fallba
|
|
|
65667
65868
|
const boundary = topology.boundary;
|
|
65668
65869
|
const parentStageId = idMaps.get(parentRunId)?.get(topology.stageId);
|
|
65669
65870
|
if (parentStageId === undefined) {
|
|
65670
|
-
if (
|
|
65871
|
+
if (policy.failClosed)
|
|
65671
65872
|
return [];
|
|
65672
65873
|
continue;
|
|
65673
65874
|
}
|
|
@@ -65736,6 +65937,20 @@ function stageResult(draft) {
|
|
|
65736
65937
|
return;
|
|
65737
65938
|
return typeof draft.output === "string" ? draft.output : JSON.stringify(draft.output);
|
|
65738
65939
|
}
|
|
65940
|
+
function emptyGraphRun(runId, runName, completedAt) {
|
|
65941
|
+
return {
|
|
65942
|
+
id: runId,
|
|
65943
|
+
name: runName,
|
|
65944
|
+
inputs: {},
|
|
65945
|
+
status: "completed",
|
|
65946
|
+
stages: [],
|
|
65947
|
+
toolNodes: [],
|
|
65948
|
+
startedAt: completedAt,
|
|
65949
|
+
endedAt: completedAt,
|
|
65950
|
+
durationMs: 0,
|
|
65951
|
+
resumable: false
|
|
65952
|
+
};
|
|
65953
|
+
}
|
|
65739
65954
|
function syntheticRun(runId, runName, checkpointCount, completedAt) {
|
|
65740
65955
|
return {
|
|
65741
65956
|
id: runId,
|
|
@@ -66619,7 +66834,7 @@ function createTrackedStageCaller(input) {
|
|
|
66619
66834
|
if (suppressQueuedContinuation)
|
|
66620
66835
|
runtime.state.suppressQueuedUserMessageContinuation = true;
|
|
66621
66836
|
try {
|
|
66622
|
-
result = await raceAbort(runtime.innerCtx.prompt(RESUME_CONTINUATION_PROMPT), runtime.signal);
|
|
66837
|
+
result = await runtime.raceStageSessionHeartbeat(raceAbort(runtime.innerCtx.prompt(RESUME_CONTINUATION_PROMPT), runtime.signal));
|
|
66623
66838
|
} finally {
|
|
66624
66839
|
if (suppressQueuedContinuation)
|
|
66625
66840
|
runtime.state.suppressQueuedUserMessageContinuation = false;
|
|
@@ -66646,46 +66861,51 @@ function createTrackedStageCaller(input) {
|
|
|
66646
66861
|
throw err;
|
|
66647
66862
|
}
|
|
66648
66863
|
const trackStageLifecycle = !runtime.state.stageFinalized;
|
|
66649
|
-
let
|
|
66650
|
-
|
|
66651
|
-
|
|
66652
|
-
|
|
66653
|
-
if (!
|
|
66654
|
-
runtime.scheduler.tracker.
|
|
66655
|
-
|
|
66656
|
-
|
|
66657
|
-
|
|
66658
|
-
|
|
66659
|
-
const now = Date.now();
|
|
66660
|
-
const hasNoExplicitModelConfig = input.options?.model === undefined && input.options?.fallbackModels === undefined;
|
|
66661
|
-
const promptAdapterHandlesInitialPrompt = input.adapters.prompt !== undefined;
|
|
66662
|
-
if (callOptions.eagerSession && !promptAdapterHandlesInitialPrompt && (hasNoExplicitModelConfig || await hasExplicitFastModeCandidate({
|
|
66663
|
-
model: input.options?.model,
|
|
66664
|
-
fallbackModels: input.options?.fallbackModels,
|
|
66665
|
-
models: runtime.opts.models
|
|
66666
|
-
}))) {
|
|
66667
|
-
try {
|
|
66668
|
-
await runtime.innerCtx.__ensureSession();
|
|
66669
|
-
runtime.captureStageSessionMeta();
|
|
66670
|
-
} catch (err) {
|
|
66671
|
-
if (!(err instanceof Error && err.message.includes("prompt adapter not configured")))
|
|
66672
|
-
throw err;
|
|
66864
|
+
let applyTerminalStageState;
|
|
66865
|
+
let terminalStateIsSuccess = false;
|
|
66866
|
+
try {
|
|
66867
|
+
let refreshedParentIds;
|
|
66868
|
+
if (trackStageLifecycle && !input.hasContinuation && runtime.stageSnapshot.startedAt === undefined && !input.hasScopedParents) {
|
|
66869
|
+
const actualParentIds = runtime.scheduler.tracker.currentParents();
|
|
66870
|
+
const sameParents = actualParentIds.length === runtime.stageSnapshot.parentIds.length && actualParentIds.every((value2) => runtime.stageSnapshot.parentIds.includes(value2));
|
|
66871
|
+
if (!sameParents) {
|
|
66872
|
+
runtime.scheduler.tracker.replaceParents(runtime.stageId, actualParentIds);
|
|
66873
|
+
refreshedParentIds = actualParentIds;
|
|
66673
66874
|
}
|
|
66674
66875
|
}
|
|
66675
|
-
if (
|
|
66676
|
-
|
|
66876
|
+
if (trackStageLifecycle) {
|
|
66877
|
+
const now = Date.now();
|
|
66878
|
+
const hasNoExplicitModelConfig = input.options?.model === undefined && input.options?.fallbackModels === undefined;
|
|
66879
|
+
const promptAdapterHandlesInitialPrompt = input.adapters.prompt !== undefined;
|
|
66880
|
+
if (callOptions.eagerSession && !promptAdapterHandlesInitialPrompt && (hasNoExplicitModelConfig || await hasExplicitFastModeCandidate({
|
|
66881
|
+
model: input.options?.model,
|
|
66882
|
+
fallbackModels: input.options?.fallbackModels,
|
|
66883
|
+
models: runtime.opts.models
|
|
66884
|
+
}))) {
|
|
66885
|
+
try {
|
|
66886
|
+
await runtime.innerCtx.__ensureSession();
|
|
66887
|
+
} catch (err) {
|
|
66888
|
+
if (!(err instanceof Error && err.message.includes("prompt adapter not configured")))
|
|
66889
|
+
throw err;
|
|
66890
|
+
}
|
|
66891
|
+
}
|
|
66892
|
+
if (refreshedParentIds !== undefined) {
|
|
66893
|
+
runtime.scheduler.setStageParentIds(runtime.stageSnapshot, refreshedParentIds);
|
|
66894
|
+
}
|
|
66895
|
+
runtime.stageSnapshot.status = "running";
|
|
66896
|
+
runtime.stageSnapshot.startedAt ??= rebasedStageStartedAt(input.options?.durableAccumulatedDurationMs, now);
|
|
66897
|
+
runtime.applyModelFallbackMeta(runtime.innerCtx.__modelFallbackMeta());
|
|
66898
|
+
runtime.activeStore.recordStageStart(runtime.runId, runtime.stageSnapshot);
|
|
66899
|
+
runtime.appendStageStartOnce();
|
|
66900
|
+
const sessionMeta = runtime.innerCtx.__sessionMeta();
|
|
66901
|
+
if (sessionMeta.sessionId !== undefined || sessionMeta.sessionFile !== undefined) {
|
|
66902
|
+
await runtime.captureStageSessionMeta({ awaitDurable: true });
|
|
66903
|
+
}
|
|
66904
|
+
runtime.startStageSessionHeartbeat();
|
|
66905
|
+
} else {
|
|
66906
|
+
runtime.applyModelFallbackMeta(runtime.innerCtx.__modelFallbackMeta());
|
|
66677
66907
|
}
|
|
66678
|
-
runtime.
|
|
66679
|
-
runtime.stageSnapshot.startedAt ??= rebasedStageStartedAt(input.options?.durableAccumulatedDurationMs, now);
|
|
66680
|
-
runtime.applyModelFallbackMeta(runtime.innerCtx.__modelFallbackMeta());
|
|
66681
|
-
runtime.activeStore.recordStageStart(runtime.runId, runtime.stageSnapshot);
|
|
66682
|
-
runtime.appendStageStartOnce();
|
|
66683
|
-
} else {
|
|
66684
|
-
runtime.applyModelFallbackMeta(runtime.innerCtx.__modelFallbackMeta());
|
|
66685
|
-
}
|
|
66686
|
-
runtime.mcpScope.apply();
|
|
66687
|
-
let applyTerminalStageState;
|
|
66688
|
-
try {
|
|
66908
|
+
runtime.mcpScope.apply();
|
|
66689
66909
|
const abortSession = () => {
|
|
66690
66910
|
runtime.innerCtx.abort().catch(() => {});
|
|
66691
66911
|
};
|
|
@@ -66697,7 +66917,7 @@ function createTrackedStageCaller(input) {
|
|
|
66697
66917
|
try {
|
|
66698
66918
|
runtime.state.askUserQuestionObservedThisTurn = false;
|
|
66699
66919
|
runtime.state.chatAnswerObservedThisTurn = false;
|
|
66700
|
-
result = await raceAbort(call(), runtime.signal);
|
|
66920
|
+
result = await runtime.raceStageSessionHeartbeat(raceAbort(call(), runtime.signal));
|
|
66701
66921
|
const initialDrain = await drainResumeContinuations(result);
|
|
66702
66922
|
result = initialDrain.result;
|
|
66703
66923
|
let repeatReadinessAfterChatTurn = initialDrain.chatAnswerObserved;
|
|
@@ -66721,10 +66941,10 @@ function createTrackedStageCaller(input) {
|
|
|
66721
66941
|
runtime.state.chatAnswerObservedThisTurn = false;
|
|
66722
66942
|
runtime.state.waitingForStageChatTurn = true;
|
|
66723
66943
|
try {
|
|
66724
|
-
await raceAbort(new Promise((resolve12) => {
|
|
66944
|
+
await runtime.raceStageSessionHeartbeat(raceAbort(new Promise((resolve12) => {
|
|
66725
66945
|
resolveNextTurnEnd = resolve12;
|
|
66726
66946
|
runtime.state.wakeWaitingForStageChatTurn = resolve12;
|
|
66727
|
-
}), runtime.signal);
|
|
66947
|
+
}), runtime.signal));
|
|
66728
66948
|
} finally {
|
|
66729
66949
|
runtime.state.wakeWaitingForStageChatTurn = undefined;
|
|
66730
66950
|
runtime.state.waitingForStageChatTurn = false;
|
|
@@ -66748,7 +66968,7 @@ function createTrackedStageCaller(input) {
|
|
|
66748
66968
|
runtime.signal.removeEventListener("abort", abortSession);
|
|
66749
66969
|
}
|
|
66750
66970
|
await runtime.innerCtx.__closeGeneration();
|
|
66751
|
-
runtime.captureStageSessionMeta();
|
|
66971
|
+
await runtime.captureStageSessionMeta({ awaitDurable: true });
|
|
66752
66972
|
runtime.applyModelFallbackMeta(runtime.innerCtx.__modelFallbackMeta());
|
|
66753
66973
|
if (trackStageLifecycle && runtime.stageFailFastScope?.failed === true && runtime.stageFailFastScope.activeStages.has(runtime.stageId)) {
|
|
66754
66974
|
runtime.markSkippedForParallelFailFast();
|
|
@@ -66758,6 +66978,7 @@ function createTrackedStageCaller(input) {
|
|
|
66758
66978
|
throw runtime.parallelFailFastError();
|
|
66759
66979
|
if (trackStageLifecycle) {
|
|
66760
66980
|
const assistantText = runtime.innerCtx.__getLastAssistantText();
|
|
66981
|
+
terminalStateIsSuccess = true;
|
|
66761
66982
|
applyTerminalStageState = () => {
|
|
66762
66983
|
runtime.stageSnapshot.status = "completed";
|
|
66763
66984
|
if (assistantText !== undefined)
|
|
@@ -66782,15 +67003,30 @@ function createTrackedStageCaller(input) {
|
|
|
66782
67003
|
}
|
|
66783
67004
|
throw err;
|
|
66784
67005
|
} finally {
|
|
66785
|
-
runtime.mcpScope.clear();
|
|
66786
67006
|
let finalizationError;
|
|
67007
|
+
let durableCheckpointError;
|
|
66787
67008
|
try {
|
|
66788
|
-
|
|
66789
|
-
runtime.captureStageSessionMeta();
|
|
67009
|
+
runtime.mcpScope.clear();
|
|
66790
67010
|
} catch (err) {
|
|
66791
67011
|
finalizationError = { thrown: true, error: err };
|
|
66792
67012
|
}
|
|
67013
|
+
try {
|
|
67014
|
+
await runtime.drainStageSessionHeartbeat();
|
|
67015
|
+
} catch (err) {
|
|
67016
|
+
durableCheckpointError = { thrown: true, error: err };
|
|
67017
|
+
}
|
|
67018
|
+
try {
|
|
67019
|
+
await runtime.innerCtx.__closeGeneration();
|
|
67020
|
+
await runtime.captureStageSessionMeta({ awaitDurable: true });
|
|
67021
|
+
} catch (err) {
|
|
67022
|
+
durableCheckpointError ??= { thrown: true, error: err };
|
|
67023
|
+
}
|
|
67024
|
+
finalizationError ??= durableCheckpointError;
|
|
66793
67025
|
if (trackStageLifecycle) {
|
|
67026
|
+
if (durableCheckpointError !== undefined && terminalStateIsSuccess) {
|
|
67027
|
+
const failure3 = runtime.classifyExecutorFailure(durableCheckpointError.error);
|
|
67028
|
+
applyTerminalStageState = () => applyFailureToStage(runtime.stageSnapshot, failure3);
|
|
67029
|
+
}
|
|
66794
67030
|
if (!runtime.state.stageFinalized)
|
|
66795
67031
|
applyTerminalStageState?.();
|
|
66796
67032
|
try {
|
|
@@ -67027,7 +67263,7 @@ function createStageControlHandle(runtime) {
|
|
|
67027
67263
|
if (sessionFile === undefined)
|
|
67028
67264
|
return;
|
|
67029
67265
|
await runtime.innerCtx.__ensureSessionFromFile(sessionFile);
|
|
67030
|
-
runtime.captureStageSessionMeta();
|
|
67266
|
+
await runtime.captureStageSessionMeta({ awaitDurable: true });
|
|
67031
67267
|
};
|
|
67032
67268
|
const toolExecutions = new StageToolExecutionBuffer;
|
|
67033
67269
|
const queuedUserMessages = new StageQueuedUserMessageBuffer;
|
|
@@ -67071,7 +67307,7 @@ function createStageControlHandle(runtime) {
|
|
|
67071
67307
|
await ensureMessagingSession();
|
|
67072
67308
|
await runtime.innerCtx.__ensureSession();
|
|
67073
67309
|
runtime.throwIfStageMutationBlocked();
|
|
67074
|
-
runtime.captureStageSessionMeta();
|
|
67310
|
+
await runtime.captureStageSessionMeta({ awaitDurable: true });
|
|
67075
67311
|
},
|
|
67076
67312
|
async sendUserMessage(text, options, beforeDelivery) {
|
|
67077
67313
|
runtime.throwIfStageMutationBlocked();
|
|
@@ -68229,6 +68465,28 @@ function terminatingToolCallId(event) {
|
|
|
68229
68465
|
}
|
|
68230
68466
|
|
|
68231
68467
|
// dist/builtin/workflows/src/runs/foreground/stage-runner-controller.ts
|
|
68468
|
+
function hasMeaningfulUsage(usage) {
|
|
68469
|
+
if (usage === undefined)
|
|
68470
|
+
return false;
|
|
68471
|
+
const values = [usage.input, usage.output, usage.cacheRead, usage.cacheWrite, usage.totalTokens, usage.cost.total];
|
|
68472
|
+
return values.every((value2) => Number.isFinite(value2) && value2 >= 0) && values.some((value2) => value2 > 0);
|
|
68473
|
+
}
|
|
68474
|
+
function usageForAttempt(messages, start, discarded) {
|
|
68475
|
+
const totals = { ...discarded };
|
|
68476
|
+
let meaningful = totals.turns > 0;
|
|
68477
|
+
for (const message of messages.slice(start)) {
|
|
68478
|
+
if (message.role !== "assistant" || !hasMeaningfulUsage(message.usage))
|
|
68479
|
+
continue;
|
|
68480
|
+
totals.input += message.usage.input;
|
|
68481
|
+
totals.output += message.usage.output;
|
|
68482
|
+
totals.cacheRead += message.usage.cacheRead;
|
|
68483
|
+
totals.cacheWrite += message.usage.cacheWrite;
|
|
68484
|
+
totals.cost += message.usage.cost.total;
|
|
68485
|
+
totals.turns += 1;
|
|
68486
|
+
meaningful = true;
|
|
68487
|
+
}
|
|
68488
|
+
return meaningful ? totals : undefined;
|
|
68489
|
+
}
|
|
68232
68490
|
function isSessionCreationPauseResult(value2) {
|
|
68233
68491
|
return "kind" in value2 && value2.kind === "paused";
|
|
68234
68492
|
}
|
|
@@ -68291,6 +68549,15 @@ class StageSessionController {
|
|
|
68291
68549
|
sessionPromise;
|
|
68292
68550
|
reattachSessionFile;
|
|
68293
68551
|
lastPromptStartIndex;
|
|
68552
|
+
attemptUsageStartIndex;
|
|
68553
|
+
discardedAttemptUsage = {
|
|
68554
|
+
input: 0,
|
|
68555
|
+
output: 0,
|
|
68556
|
+
cacheRead: 0,
|
|
68557
|
+
cacheWrite: 0,
|
|
68558
|
+
cost: 0,
|
|
68559
|
+
turns: 0
|
|
68560
|
+
};
|
|
68294
68561
|
terminatingToolCallIds = new Set;
|
|
68295
68562
|
latestStructuredOutputToolErrorValue;
|
|
68296
68563
|
unsubscribeTerminateWatcher;
|
|
@@ -68490,6 +68757,7 @@ class StageSessionController {
|
|
|
68490
68757
|
this.activeCandidateIndex = index;
|
|
68491
68758
|
this.selectedModel = candidate.id;
|
|
68492
68759
|
this.notifyModelFallbackMetaChange();
|
|
68760
|
+
this.beginAttemptUsage(activeSession);
|
|
68493
68761
|
const { terminalScanStartIndex } = await this.promptWithThrownErrorRetry(activeSession, promptText, sdkOptions);
|
|
68494
68762
|
const terminalFailure = latestTerminalAssistantFailureSince(activeSession.messages, terminalScanStartIndex);
|
|
68495
68763
|
if (terminalFailure !== undefined) {
|
|
@@ -68628,9 +68896,38 @@ class StageSessionController {
|
|
|
68628
68896
|
}
|
|
68629
68897
|
return;
|
|
68630
68898
|
}
|
|
68899
|
+
beginAttemptUsage(session) {
|
|
68900
|
+
this.attemptUsageStartIndex = session.messages.length;
|
|
68901
|
+
this.discardedAttemptUsage = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: 0, turns: 0 };
|
|
68902
|
+
}
|
|
68903
|
+
takeAttemptUsage(session) {
|
|
68904
|
+
const start = this.attemptUsageStartIndex;
|
|
68905
|
+
const usage = session === undefined || start === undefined ? undefined : usageForAttempt(session.messages, start, this.discardedAttemptUsage);
|
|
68906
|
+
this.clearAttemptUsage();
|
|
68907
|
+
return usage;
|
|
68908
|
+
}
|
|
68909
|
+
clearAttemptUsage() {
|
|
68910
|
+
this.attemptUsageStartIndex = undefined;
|
|
68911
|
+
this.discardedAttemptUsage = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: 0, turns: 0 };
|
|
68912
|
+
}
|
|
68913
|
+
accrueDiscardedAttemptUsage(message) {
|
|
68914
|
+
if (!hasMeaningfulUsage(message.usage))
|
|
68915
|
+
return;
|
|
68916
|
+
this.discardedAttemptUsage.input += message.usage.input;
|
|
68917
|
+
this.discardedAttemptUsage.output += message.usage.output;
|
|
68918
|
+
this.discardedAttemptUsage.cacheRead += message.usage.cacheRead;
|
|
68919
|
+
this.discardedAttemptUsage.cacheWrite += message.usage.cacheWrite;
|
|
68920
|
+
this.discardedAttemptUsage.cost += message.usage.cost.total;
|
|
68921
|
+
this.discardedAttemptUsage.turns += 1;
|
|
68922
|
+
}
|
|
68631
68923
|
restoreSessionMessages(session, snapshot, promptText, keepPrompt) {
|
|
68632
68924
|
const snapshotMessages = new Set(snapshot);
|
|
68633
68925
|
const admitted = session.messages.filter((message) => !snapshotMessages.has(message));
|
|
68926
|
+
for (const message of admitted) {
|
|
68927
|
+
if (message.role !== "assistant" || message.stopReason !== "error")
|
|
68928
|
+
continue;
|
|
68929
|
+
this.accrueDiscardedAttemptUsage(message);
|
|
68930
|
+
}
|
|
68634
68931
|
const failedAssistantIndex = admitted.findLastIndex((message) => message.role === "assistant" && message.stopReason === "error");
|
|
68635
68932
|
const promptUser = admitted.slice(0, failedAssistantIndex < 0 ? admitted.length : failedAssistantIndex).findLast((message) => message.role === "user" && stageUserMessageText(message) === promptText);
|
|
68636
68933
|
const retainedMessages = admitted.filter((message) => {
|
|
@@ -68979,7 +69276,11 @@ class StageSessionController {
|
|
|
68979
69276
|
throw new Error(`atomic-workflows: stage "${this.opts.stageName}" session has been disposed`);
|
|
68980
69277
|
throw this.staleCreationReason(startGeneration);
|
|
68981
69278
|
}
|
|
68982
|
-
|
|
69279
|
+
const session = attachCreatedStageSession(created, this.disposed, this.opts.stageName, (result) => this.attachSession(result));
|
|
69280
|
+
if (session instanceof Promise)
|
|
69281
|
+
return await session;
|
|
69282
|
+
await this.opts.onSessionReady?.();
|
|
69283
|
+
return session;
|
|
68983
69284
|
}
|
|
68984
69285
|
attachSession(created) {
|
|
68985
69286
|
const result = normalizeSessionCreateResult(created);
|
|
@@ -69087,11 +69388,17 @@ class StageSessionController {
|
|
|
69087
69388
|
const resumedSession = this.session;
|
|
69088
69389
|
const resumedLabel = this.selectedModel ?? workflowModelId(resumedSession.model) ?? candidates[0].id;
|
|
69089
69390
|
this.notifyModelFallbackMetaChange();
|
|
69391
|
+
this.beginAttemptUsage(resumedSession);
|
|
69090
69392
|
try {
|
|
69091
69393
|
const { terminalScanStartIndex } = await this.promptWithThrownErrorRetry(resumedSession, text, sdkOptions);
|
|
69092
69394
|
const terminalFailure = latestTerminalAssistantFailureSince(resumedSession.messages, terminalScanStartIndex);
|
|
69093
69395
|
if (terminalFailure === undefined || this.capturedStructuredOutputForAttempt()) {
|
|
69094
|
-
this.
|
|
69396
|
+
const usage = this.takeAttemptUsage(resumedSession);
|
|
69397
|
+
this.modelAttempts.push({
|
|
69398
|
+
model: resumedLabel,
|
|
69399
|
+
success: true,
|
|
69400
|
+
...usage === undefined ? {} : { usage }
|
|
69401
|
+
});
|
|
69095
69402
|
this.pendingFallbackWarnings.length = 0;
|
|
69096
69403
|
this.resumeCurrentSession = true;
|
|
69097
69404
|
return true;
|
|
@@ -69099,13 +69406,24 @@ class StageSessionController {
|
|
|
69099
69406
|
throw new WorkflowPromptModelFailure(terminalFailure);
|
|
69100
69407
|
} catch (err) {
|
|
69101
69408
|
if (this.capturedStructuredOutputForAttempt() && isRetryableModelFailure(err)) {
|
|
69102
|
-
this.
|
|
69409
|
+
const usage2 = this.takeAttemptUsage(resumedSession);
|
|
69410
|
+
this.modelAttempts.push({
|
|
69411
|
+
model: resumedLabel,
|
|
69412
|
+
success: true,
|
|
69413
|
+
...usage2 === undefined ? {} : { usage: usage2 }
|
|
69414
|
+
});
|
|
69103
69415
|
this.pendingFallbackWarnings.length = 0;
|
|
69104
69416
|
this.resumeCurrentSession = true;
|
|
69105
69417
|
return true;
|
|
69106
69418
|
}
|
|
69107
69419
|
const message = errorMessage3(err);
|
|
69108
|
-
this.
|
|
69420
|
+
const usage = this.takeAttemptUsage(resumedSession);
|
|
69421
|
+
this.modelAttempts.push({
|
|
69422
|
+
model: resumedLabel,
|
|
69423
|
+
success: false,
|
|
69424
|
+
...usage === undefined ? {} : { usage },
|
|
69425
|
+
error: message
|
|
69426
|
+
});
|
|
69109
69427
|
if (this.opts.signal?.aborted || !isRetryableModelFailure(err)) {
|
|
69110
69428
|
this.modelWarnings.push(...this.pendingFallbackWarnings);
|
|
69111
69429
|
this.pendingFallbackWarnings.length = 0;
|
|
@@ -69131,10 +69449,12 @@ class StageSessionController {
|
|
|
69131
69449
|
this.recordSuccessfulAttempt(candidate);
|
|
69132
69450
|
return "handled";
|
|
69133
69451
|
}
|
|
69452
|
+
const usage = this.takeAttemptUsage(this.session);
|
|
69134
69453
|
this.modelAttempts.push({
|
|
69135
69454
|
model: candidate.id,
|
|
69136
69455
|
success: false,
|
|
69137
69456
|
...modelAttemptReasoning(candidate, this.effectiveStageOptions?.thinkingLevel),
|
|
69457
|
+
...usage === undefined ? {} : { usage },
|
|
69138
69458
|
error: message
|
|
69139
69459
|
});
|
|
69140
69460
|
if (this.opts.signal?.aborted || !isRetryableModelFailure(err) || index === candidates.length - 1) {
|
|
@@ -69152,10 +69472,12 @@ class StageSessionController {
|
|
|
69152
69472
|
return this.structuredOutputCapture?.called === true && this.opts.signal?.aborted !== true;
|
|
69153
69473
|
}
|
|
69154
69474
|
recordSuccessfulAttempt(candidate) {
|
|
69475
|
+
const usage = this.takeAttemptUsage(this.session);
|
|
69155
69476
|
this.modelAttempts.push({
|
|
69156
69477
|
model: candidate.id,
|
|
69157
69478
|
success: true,
|
|
69158
|
-
...modelAttemptReasoning(candidate, this.effectiveStageOptions?.thinkingLevel)
|
|
69479
|
+
...modelAttemptReasoning(candidate, this.effectiveStageOptions?.thinkingLevel),
|
|
69480
|
+
...usage === undefined ? {} : { usage }
|
|
69159
69481
|
});
|
|
69160
69482
|
this.pendingFallbackWarnings.length = 0;
|
|
69161
69483
|
this.resumeCurrentSession = true;
|
|
@@ -69592,6 +69914,81 @@ function createStageContext2(opts) {
|
|
|
69592
69914
|
}
|
|
69593
69915
|
};
|
|
69594
69916
|
}
|
|
69917
|
+
// dist/builtin/workflows/src/runs/foreground/stage-session-heartbeat.ts
|
|
69918
|
+
var STAGE_SESSION_HEARTBEAT_INTERVAL_MS = 30000;
|
|
69919
|
+
function createStageSessionHeartbeat(checkpoint, intervalMs = STAGE_SESSION_HEARTBEAT_INTERVAL_MS) {
|
|
69920
|
+
let active2 = false;
|
|
69921
|
+
let timer;
|
|
69922
|
+
let generation = 0;
|
|
69923
|
+
let nextDeadline = 0;
|
|
69924
|
+
let failure3;
|
|
69925
|
+
let inFlight;
|
|
69926
|
+
let rejectFailure;
|
|
69927
|
+
const failureSignal = new Promise((_resolve, reject) => {
|
|
69928
|
+
rejectFailure = reject;
|
|
69929
|
+
});
|
|
69930
|
+
failureSignal.catch(() => {
|
|
69931
|
+
return;
|
|
69932
|
+
});
|
|
69933
|
+
const stopScheduling = () => {
|
|
69934
|
+
active2 = false;
|
|
69935
|
+
generation += 1;
|
|
69936
|
+
if (timer !== undefined)
|
|
69937
|
+
clearTimeout(timer);
|
|
69938
|
+
timer = undefined;
|
|
69939
|
+
};
|
|
69940
|
+
const fail = (error) => {
|
|
69941
|
+
if (failure3 !== undefined)
|
|
69942
|
+
return;
|
|
69943
|
+
failure3 = error;
|
|
69944
|
+
stopScheduling();
|
|
69945
|
+
rejectFailure(error);
|
|
69946
|
+
};
|
|
69947
|
+
const schedule = (scheduledGeneration) => {
|
|
69948
|
+
if (!active2 || failure3 !== undefined || scheduledGeneration !== generation)
|
|
69949
|
+
return;
|
|
69950
|
+
const delayMs = Math.max(0, nextDeadline - Date.now());
|
|
69951
|
+
timer = setTimeout(() => {
|
|
69952
|
+
timer = undefined;
|
|
69953
|
+
const startedAt = Date.now();
|
|
69954
|
+
do
|
|
69955
|
+
nextDeadline += intervalMs;
|
|
69956
|
+
while (nextDeadline <= startedAt);
|
|
69957
|
+
const running = checkpoint().catch(fail).finally(() => {
|
|
69958
|
+
if (inFlight === running)
|
|
69959
|
+
inFlight = undefined;
|
|
69960
|
+
schedule(scheduledGeneration);
|
|
69961
|
+
});
|
|
69962
|
+
inFlight = running;
|
|
69963
|
+
}, delayMs);
|
|
69964
|
+
timer.unref?.();
|
|
69965
|
+
};
|
|
69966
|
+
const drain = async () => {
|
|
69967
|
+
stopScheduling();
|
|
69968
|
+
await inFlight;
|
|
69969
|
+
if (failure3 !== undefined)
|
|
69970
|
+
throw failure3;
|
|
69971
|
+
};
|
|
69972
|
+
return {
|
|
69973
|
+
start() {
|
|
69974
|
+
if (active2 || failure3 !== undefined)
|
|
69975
|
+
return;
|
|
69976
|
+
active2 = true;
|
|
69977
|
+
generation += 1;
|
|
69978
|
+
nextDeadline = Date.now() + intervalMs;
|
|
69979
|
+
schedule(generation);
|
|
69980
|
+
},
|
|
69981
|
+
stop: stopScheduling,
|
|
69982
|
+
drain,
|
|
69983
|
+
fail,
|
|
69984
|
+
race(work) {
|
|
69985
|
+
if (failure3 !== undefined)
|
|
69986
|
+
return Promise.reject(failure3);
|
|
69987
|
+
return Promise.race([work, failureSignal]);
|
|
69988
|
+
}
|
|
69989
|
+
};
|
|
69990
|
+
}
|
|
69991
|
+
|
|
69595
69992
|
// dist/builtin/workflows/src/runs/foreground/executor-stage-factory.ts
|
|
69596
69993
|
function createWorkflowStageFactory(input) {
|
|
69597
69994
|
return (name, options, stageFailFastScope) => {
|
|
@@ -69672,6 +70069,15 @@ function createWorkflowStageFactory(input) {
|
|
|
69672
70069
|
if (meta2.modelAttempts !== undefined)
|
|
69673
70070
|
stageSnapshot.modelAttempts = meta2.modelAttempts;
|
|
69674
70071
|
};
|
|
70072
|
+
let runtime;
|
|
70073
|
+
const stageSessionHeartbeat = createStageSessionHeartbeat(async () => {
|
|
70074
|
+
try {
|
|
70075
|
+
await runtime.captureStageSessionMeta({ awaitDurable: true });
|
|
70076
|
+
} catch (error) {
|
|
70077
|
+
await runtime.innerCtx.abort().catch(() => {});
|
|
70078
|
+
throw error;
|
|
70079
|
+
}
|
|
70080
|
+
});
|
|
69675
70081
|
const innerCtx = createStageContext2({
|
|
69676
70082
|
stageId,
|
|
69677
70083
|
stageName: name,
|
|
@@ -69687,6 +70093,12 @@ function createWorkflowStageFactory(input) {
|
|
|
69687
70093
|
applyModelFallbackMeta(meta2);
|
|
69688
70094
|
if (stageSnapshot.status === "running")
|
|
69689
70095
|
input.activeStore.recordStageStart(input.runId, stageSnapshot);
|
|
70096
|
+
},
|
|
70097
|
+
async onSessionReady() {
|
|
70098
|
+
if (stageSnapshot.status !== "running")
|
|
70099
|
+
return;
|
|
70100
|
+
await runtime.captureStageSessionMeta({ awaitDurable: true });
|
|
70101
|
+
runtime.startStageSessionHeartbeat();
|
|
69690
70102
|
}
|
|
69691
70103
|
});
|
|
69692
70104
|
const state2 = {
|
|
@@ -69749,8 +70161,7 @@ function createWorkflowStageFactory(input) {
|
|
|
69749
70161
|
stageUiBroker.clearStagePrompt(input.runId, stageId);
|
|
69750
70162
|
await innerCtx.__dispose();
|
|
69751
70163
|
};
|
|
69752
|
-
|
|
69753
|
-
const captureStageSessionMeta = (checkpointOptions) => {
|
|
70164
|
+
const captureStageSessionMeta = async (checkpointOptions) => {
|
|
69754
70165
|
const meta2 = innerCtx.__sessionMeta();
|
|
69755
70166
|
if (meta2.sessionId !== undefined)
|
|
69756
70167
|
stageSnapshot.sessionId = meta2.sessionId;
|
|
@@ -69759,15 +70170,17 @@ function createWorkflowStageFactory(input) {
|
|
|
69759
70170
|
if (meta2.sessionId !== undefined || meta2.sessionFile !== undefined)
|
|
69760
70171
|
input.activeStore.recordStageSession(input.runId, stageId, meta2);
|
|
69761
70172
|
const pending = input.opts.onStageSession?.(input.runId, stageSnapshot, checkpointOptions);
|
|
69762
|
-
if (checkpointOptions?.forceDurable === true)
|
|
69763
|
-
|
|
70173
|
+
if (checkpointOptions?.forceDurable === true || checkpointOptions?.awaitDurable === true) {
|
|
70174
|
+
await pending;
|
|
70175
|
+
return;
|
|
70176
|
+
}
|
|
69764
70177
|
Promise.resolve(pending).catch(() => {});
|
|
69765
|
-
return;
|
|
69766
70178
|
};
|
|
69767
70179
|
const releaseLiveHandle = async () => {
|
|
69768
70180
|
if (state2.liveHandleReleased)
|
|
69769
70181
|
return;
|
|
69770
70182
|
state2.liveHandleReleased = true;
|
|
70183
|
+
stageSessionHeartbeat.stop();
|
|
69771
70184
|
runtime.dropStageControlHandle();
|
|
69772
70185
|
runtime.unregisterStageHandle();
|
|
69773
70186
|
await disposeInnerContext();
|
|
@@ -69800,6 +70213,7 @@ function createWorkflowStageFactory(input) {
|
|
|
69800
70213
|
});
|
|
69801
70214
|
};
|
|
69802
70215
|
const finalizeStageSnapshot = async () => {
|
|
70216
|
+
stageSessionHeartbeat.stop();
|
|
69803
70217
|
if (state2.stageFinalized)
|
|
69804
70218
|
return false;
|
|
69805
70219
|
if (stageSnapshot.endedAt !== undefined && isTerminalStage(stageSnapshot)) {
|
|
@@ -69872,6 +70286,9 @@ function createWorkflowStageFactory(input) {
|
|
|
69872
70286
|
dropStageControlHandle: () => {},
|
|
69873
70287
|
unregisterWorkflowExitCleanup: () => {},
|
|
69874
70288
|
captureStageSessionMeta,
|
|
70289
|
+
startStageSessionHeartbeat: stageSessionHeartbeat.start,
|
|
70290
|
+
drainStageSessionHeartbeat: stageSessionHeartbeat.drain,
|
|
70291
|
+
raceStageSessionHeartbeat: stageSessionHeartbeat.race,
|
|
69875
70292
|
applyModelFallbackMeta,
|
|
69876
70293
|
appendStageStartOnce,
|
|
69877
70294
|
finalizeStageSnapshot,
|
|
@@ -70024,9 +70441,22 @@ class EngineRuntime {
|
|
|
70024
70441
|
apply: () => {
|
|
70025
70442
|
if (!this.childRunOptions.mcp || !hasScope)
|
|
70026
70443
|
return;
|
|
70027
|
-
if (depth
|
|
70444
|
+
if (depth > 0) {
|
|
70445
|
+
depth += 1;
|
|
70446
|
+
return;
|
|
70447
|
+
}
|
|
70448
|
+
depth = 1;
|
|
70449
|
+
try {
|
|
70028
70450
|
this.childRunOptions.mcp.setScope(stageId, allow, deny);
|
|
70029
|
-
|
|
70451
|
+
} catch (error) {
|
|
70452
|
+
depth = 0;
|
|
70453
|
+
try {
|
|
70454
|
+
this.childRunOptions.mcp.clearScope(stageId);
|
|
70455
|
+
} catch (cleanupError) {
|
|
70456
|
+
throw new AggregateError([error, cleanupError], "MCP scope setup failed and compensating cleanup failed");
|
|
70457
|
+
}
|
|
70458
|
+
throw error;
|
|
70459
|
+
}
|
|
70030
70460
|
},
|
|
70031
70461
|
clear: () => {
|
|
70032
70462
|
if (!this.childRunOptions.mcp || !hasScope)
|
|
@@ -71369,6 +71799,72 @@ function disposeCompletedChatHandle(handle) {
|
|
|
71369
71799
|
});
|
|
71370
71800
|
}
|
|
71371
71801
|
|
|
71802
|
+
// dist/builtin/workflows/src/durable/targeted-inspection.ts
|
|
71803
|
+
async function inspectTargetedDurableWorkflow(backend, workflowId, now = Date.now()) {
|
|
71804
|
+
const hydrated = backend.hydrateWorkflowForInspection ? await backend.hydrateWorkflowForInspection(workflowId) : await hydrateWithoutClassification(backend, workflowId);
|
|
71805
|
+
if (hydrated.kind !== "current")
|
|
71806
|
+
return hydrationFailure(workflowId, hydrated.kind);
|
|
71807
|
+
const handle = hydrated.handle;
|
|
71808
|
+
if (handle.rootWorkflowId !== undefined && handle.rootWorkflowId !== handle.workflowId) {
|
|
71809
|
+
return malformed(workflowId, "the requested id belongs to a nested workflow rather than a durable root");
|
|
71810
|
+
}
|
|
71811
|
+
const reconstructed = durableWorkflowRunSnapshots(backend, handle);
|
|
71812
|
+
if (reconstructed.length === 0)
|
|
71813
|
+
return malformed(workflowId, "durable checkpoint topology is malformed or incomplete");
|
|
71814
|
+
const runs = structuredClone(reconstructed);
|
|
71815
|
+
const inspectionStore = createStore();
|
|
71816
|
+
for (const run2 of runs)
|
|
71817
|
+
inspectionStore.recordRunStart(structuredClone(run2));
|
|
71818
|
+
const inspected = inspectRun(workflowId, { store: inspectionStore });
|
|
71819
|
+
if (!inspected.ok)
|
|
71820
|
+
return malformed(workflowId, "the durable checkpoint graph has no reciprocal root");
|
|
71821
|
+
const foreignLive = isForeignLiveWorkflow(handle, getAtomicExecutorId(), now);
|
|
71822
|
+
const live = isLiveRunningWorkflow(handle, now);
|
|
71823
|
+
const crashed = handle.status === "running" && !live;
|
|
71824
|
+
const resumeGuidance = crashed ? inspected.detail.resumable === true ? `This workflow appears to have crashed and is resumable. Resume it explicitly with /workflow resume ${workflowId}.` : "This workflow appears to have crashed, but its retained state is not resumable." : foreignLive ? "This workflow is actively running in another Atomic session. Inspect it here, but control it from its owner session." : live ? "This workflow still has a fresh durable heartbeat. Inspect it here without starting another executor." : terminalGuidance(handle.status, workflowId, inspected.detail.resumable === true);
|
|
71825
|
+
return {
|
|
71826
|
+
kind: "found",
|
|
71827
|
+
runs,
|
|
71828
|
+
store: inspectionStore,
|
|
71829
|
+
detail: {
|
|
71830
|
+
...inspected.detail,
|
|
71831
|
+
...crashed ? { status: "crashed" } : {},
|
|
71832
|
+
...live ? { resumable: false } : {},
|
|
71833
|
+
...foreignLive ? { ownerActiveElsewhere: true } : {},
|
|
71834
|
+
resumeGuidance
|
|
71835
|
+
}
|
|
71836
|
+
};
|
|
71837
|
+
}
|
|
71838
|
+
function terminalGuidance(status, workflowId, resumable) {
|
|
71839
|
+
if (resumable)
|
|
71840
|
+
return `This retained workflow is ${status} and resumable. Resume it explicitly with /workflow resume ${workflowId}.`;
|
|
71841
|
+
return `This retained workflow is ${status} and available for read-only inspection.`;
|
|
71842
|
+
}
|
|
71843
|
+
async function hydrateWithoutClassification(backend, workflowId) {
|
|
71844
|
+
await backend.hydrateWorkflow(workflowId);
|
|
71845
|
+
const handle = backend.getLoadableWorkflow(workflowId);
|
|
71846
|
+
return handle === undefined ? { kind: "absent" } : { kind: "current", handle };
|
|
71847
|
+
}
|
|
71848
|
+
function hydrationFailure(workflowId, kind) {
|
|
71849
|
+
switch (kind) {
|
|
71850
|
+
case "absent":
|
|
71851
|
+
return {
|
|
71852
|
+
kind,
|
|
71853
|
+
message: `Run not found: ${workflowId} (not present in the current session or durable store).`
|
|
71854
|
+
};
|
|
71855
|
+
case "deleted":
|
|
71856
|
+
return { kind, message: `Durable workflow was deleted: ${workflowId}` };
|
|
71857
|
+
case "malformed":
|
|
71858
|
+
return malformed(workflowId, "current DBOS metadata or checkpoints are malformed");
|
|
71859
|
+
}
|
|
71860
|
+
}
|
|
71861
|
+
function malformed(workflowId, reason) {
|
|
71862
|
+
return {
|
|
71863
|
+
kind: "malformed",
|
|
71864
|
+
message: `Durable workflow ${workflowId} cannot be inspected safely: ${reason}.`
|
|
71865
|
+
};
|
|
71866
|
+
}
|
|
71867
|
+
|
|
71372
71868
|
// dist/builtin/workflows/src/extension/runtime-durable-resume.ts
|
|
71373
71869
|
function createDurableResumeRuntime(deps) {
|
|
71374
71870
|
const hydrateStoredWorkflowCandidates = async (backend, target) => {
|
|
@@ -71378,6 +71874,10 @@ function createDurableResumeRuntime(deps) {
|
|
|
71378
71874
|
};
|
|
71379
71875
|
let preparedCatalog = [];
|
|
71380
71876
|
return {
|
|
71877
|
+
async inspectDurableWorkflow(workflowId) {
|
|
71878
|
+
await deps.ensureReady();
|
|
71879
|
+
return await inspectTargetedDurableWorkflow(getDurableBackend(), workflowId);
|
|
71880
|
+
},
|
|
71381
71881
|
async resumeDurableWorkflow(workflowId, options) {
|
|
71382
71882
|
await deps.ensureReady();
|
|
71383
71883
|
const backend = getDurableBackend();
|
|
@@ -72052,6 +72552,9 @@ function createWorkflowExtensionRuntimeState(pi, adapters, resolveCwd = () => pi
|
|
|
72052
72552
|
resumeDurableWorkflow(workflowId, options) {
|
|
72053
72553
|
return runtimeRef.current.resumeDurableWorkflow(workflowId, options);
|
|
72054
72554
|
},
|
|
72555
|
+
inspectDurableWorkflow(workflowId) {
|
|
72556
|
+
return runtimeRef.current.inspectDurableWorkflow(workflowId);
|
|
72557
|
+
},
|
|
72055
72558
|
listDurableResumable() {
|
|
72056
72559
|
return runtimeRef.current.listDurableResumable();
|
|
72057
72560
|
},
|
|
@@ -72986,7 +73489,7 @@ function openInputsPicker(ui, opts) {
|
|
|
72986
73489
|
}
|
|
72987
73490
|
|
|
72988
73491
|
// dist/builtin/workflows/src/tui/session-picker.ts
|
|
72989
|
-
import { keyText as
|
|
73492
|
+
import { keyText as keyText3 } from "@bastani/atomic";
|
|
72990
73493
|
var ESCAPE_CODE = 27;
|
|
72991
73494
|
function isQuitRun3(run2) {
|
|
72992
73495
|
return run2.endedAt === undefined && run2.status === "paused" && run2.exitReason === "quit";
|
|
@@ -73079,12 +73582,12 @@ function renderHintsRow(width, theme, state2) {
|
|
|
73079
73582
|
const muted = hexToAnsi(theme.textMuted);
|
|
73080
73583
|
const sep7 = `${dim} · ${RESET}`;
|
|
73081
73584
|
const hint = (key2, label) => `${text}${key2}${RESET} ${muted}${label}${RESET}`;
|
|
73082
|
-
const parts = state2.filterFocused ? [hint(
|
|
73083
|
-
hint(`${
|
|
73084
|
-
hint(
|
|
73585
|
+
const parts = state2.filterFocused ? [hint(keyText3("tui.select.confirm"), "Submit"), hint(keyText3("tui.select.cancel"), "Exit Filter")] : [
|
|
73586
|
+
hint(`${keyText3("tui.select.up")}/${keyText3("tui.select.down")}`, "Navigate"),
|
|
73587
|
+
hint(keyText3("tui.select.confirm"), "Connect"),
|
|
73085
73588
|
hint("a", state2.includeAll ? "Active Only" : "All"),
|
|
73086
73589
|
hint("/", "Filter"),
|
|
73087
|
-
hint(
|
|
73590
|
+
hint(keyText3("tui.select.cancel"), "Close")
|
|
73088
73591
|
];
|
|
73089
73592
|
const line = ` ${parts.join(sep7)}`;
|
|
73090
73593
|
const clipped = truncateToWidth(line, width, "…");
|
|
@@ -73721,6 +74224,7 @@ function toPickerRow(session) {
|
|
|
73721
74224
|
modifiedAt: session.modified.getTime(),
|
|
73722
74225
|
messageCount: session.messageCount,
|
|
73723
74226
|
firstMessage: session.firstMessage,
|
|
74227
|
+
...session.summary !== undefined ? { summary: session.summary } : {},
|
|
73724
74228
|
allMessagesText: session.allMessagesText,
|
|
73725
74229
|
...session.name !== undefined ? { name: session.name } : {},
|
|
73726
74230
|
...session.messageColor !== undefined ? { messageColor: session.messageColor } : {}
|
|
@@ -74570,8 +75074,13 @@ Available: ${formatAvailableWorkflowNames(deps.runtimeProxy.registry.names())}`)
|
|
|
74570
75074
|
const resolved = resolveRunId(target);
|
|
74571
75075
|
if (resolved.kind === "malformed")
|
|
74572
75076
|
return fail(resolved.message);
|
|
74573
|
-
if (resolved.kind === "not_found")
|
|
74574
|
-
|
|
75077
|
+
if (resolved.kind === "not_found") {
|
|
75078
|
+
const durable = await deps.runtimeForContext(ctx).inspectDurableWorkflow(target);
|
|
75079
|
+
if (durable.kind !== "found")
|
|
75080
|
+
return fail(durable.message);
|
|
75081
|
+
emitChatSurface(pi, { kind: "detail", detail: durable.detail });
|
|
75082
|
+
return;
|
|
75083
|
+
}
|
|
74575
75084
|
const inspected = inspectRun(resolved.runId);
|
|
74576
75085
|
if (!inspected.ok)
|
|
74577
75086
|
return fail(`Run not found: ${target}`);
|
|
@@ -75645,8 +76154,9 @@ function snapshotTranscriptEntryCount(snapshot) {
|
|
|
75645
76154
|
}
|
|
75646
76155
|
|
|
75647
76156
|
// dist/builtin/workflows/src/extension/workflow-tool-inspection.ts
|
|
75648
|
-
function workflowStagesResult(args) {
|
|
75649
|
-
const
|
|
76157
|
+
function workflowStagesResult(args, source) {
|
|
76158
|
+
const activeStore = source?.store ?? store;
|
|
76159
|
+
const target = resolveToolRunTarget(args, "No active run to inspect.", activeStore);
|
|
75650
76160
|
const filter = args.statusFilter ?? "all";
|
|
75651
76161
|
if (target.kind === "all") {
|
|
75652
76162
|
return {
|
|
@@ -75666,19 +76176,20 @@ function workflowStagesResult(args) {
|
|
|
75666
76176
|
error: target.message
|
|
75667
76177
|
};
|
|
75668
76178
|
}
|
|
75669
|
-
const
|
|
75670
|
-
const stages =
|
|
76179
|
+
const stageSnapshots = source?.store === undefined ? activeStore.runs().find((run2) => run2.id === target.runId)?.stages ?? [] : expandWorkflowGraph(readGraphStoreSnapshot(activeStore), target.runId).stages;
|
|
76180
|
+
const stages = stageSnapshots.filter((stage) => filter === "all" || stage.status === filter).map(summarizeStage);
|
|
75671
76181
|
return { action: "stages", runId: target.runId, filter, stages };
|
|
75672
76182
|
}
|
|
75673
|
-
function workflowStageResult(args) {
|
|
75674
|
-
const
|
|
76183
|
+
function workflowStageResult(args, source) {
|
|
76184
|
+
const activeStore = source?.store ?? store;
|
|
76185
|
+
const target = resolveToolRunTarget(args, "No active run to inspect.", activeStore);
|
|
75675
76186
|
if (target.kind === "all") {
|
|
75676
76187
|
return { action: "stage", runId: "--all", error: "Stage inspection requires a single run." };
|
|
75677
76188
|
}
|
|
75678
76189
|
if (target.kind === "malformed" || target.kind === "not_found") {
|
|
75679
76190
|
return { action: "stage", runId: target.target, error: target.message };
|
|
75680
76191
|
}
|
|
75681
|
-
const stage = resolveToolStageTarget(target.runId, args.stageId);
|
|
76192
|
+
const stage = resolveToolStageTarget(target.runId, args.stageId, activeStore);
|
|
75682
76193
|
if (!stage.ok || stage.stageId === undefined) {
|
|
75683
76194
|
return {
|
|
75684
76195
|
action: "stage",
|
|
@@ -75687,7 +76198,7 @@ function workflowStageResult(args) {
|
|
|
75687
76198
|
};
|
|
75688
76199
|
}
|
|
75689
76200
|
const stageRunId = stage.runId ?? target.runId;
|
|
75690
|
-
const run2 =
|
|
76201
|
+
const run2 = activeStore.runs().find((r) => r.id === stageRunId);
|
|
75691
76202
|
const snapshot = run2?.stages.find((s) => s.id === stage.stageId);
|
|
75692
76203
|
return snapshot ? { action: "stage", runId: stageRunId, stage: cloneStage(snapshot) } : {
|
|
75693
76204
|
action: "stage",
|
|
@@ -75695,8 +76206,9 @@ function workflowStageResult(args) {
|
|
|
75695
76206
|
error: `Stage not found in run ${stageRunId}: ${stage.stageId}`
|
|
75696
76207
|
};
|
|
75697
76208
|
}
|
|
75698
|
-
function workflowTranscriptResult(args) {
|
|
75699
|
-
const
|
|
76209
|
+
function workflowTranscriptResult(args, source) {
|
|
76210
|
+
const activeStore = source?.store ?? store;
|
|
76211
|
+
const target = resolveToolRunTarget(args, "No active run to inspect.", activeStore);
|
|
75700
76212
|
if (target.kind === "all") {
|
|
75701
76213
|
return {
|
|
75702
76214
|
action: "transcript",
|
|
@@ -75717,7 +76229,7 @@ function workflowTranscriptResult(args) {
|
|
|
75717
76229
|
truncated: false
|
|
75718
76230
|
};
|
|
75719
76231
|
}
|
|
75720
|
-
const stage = resolveToolStageTarget(target.runId, args.stageId);
|
|
76232
|
+
const stage = resolveToolStageTarget(target.runId, args.stageId, activeStore);
|
|
75721
76233
|
if (!stage.ok || stage.stageId === undefined) {
|
|
75722
76234
|
return {
|
|
75723
76235
|
action: "transcript",
|
|
@@ -75729,9 +76241,9 @@ function workflowTranscriptResult(args) {
|
|
|
75729
76241
|
};
|
|
75730
76242
|
}
|
|
75731
76243
|
const stageRunId = stage.runId ?? target.runId;
|
|
75732
|
-
const run2 =
|
|
76244
|
+
const run2 = activeStore.runs().find((r) => r.id === stageRunId);
|
|
75733
76245
|
const snapshot = run2?.stages.find((s) => s.id === stage.stageId);
|
|
75734
|
-
const liveHandle2 = stageControlRegistry.get(stageRunId, stage.stageId);
|
|
76246
|
+
const liveHandle2 = source?.allowLiveHandles === false ? undefined : stageControlRegistry.get(stageRunId, stage.stageId);
|
|
75735
76247
|
if (liveHandle2 !== undefined) {
|
|
75736
76248
|
const sessionFile = liveHandle2.sessionFile ?? snapshot?.sessionFile;
|
|
75737
76249
|
const sessionId = liveHandle2.sessionId ?? snapshot?.sessionId;
|
|
@@ -75791,6 +76303,41 @@ function brokerAnswerFromArgs(args) {
|
|
|
75791
76303
|
const text = textPayloadFromArgs(args);
|
|
75792
76304
|
return text !== undefined ? { text } : {};
|
|
75793
76305
|
}
|
|
76306
|
+
function answersPendingPrompt(delivery, promptId) {
|
|
76307
|
+
return delivery === "answer" || delivery === "auto" || promptId !== undefined;
|
|
76308
|
+
}
|
|
76309
|
+
function answerablePromptIds(stage) {
|
|
76310
|
+
const target = stage.workflowGraphTarget;
|
|
76311
|
+
const ids = [];
|
|
76312
|
+
const brokered = stageUiBroker.peekStagePrompt(target.runId, target.stageId);
|
|
76313
|
+
if (brokered !== undefined)
|
|
76314
|
+
ids.push(brokered.id);
|
|
76315
|
+
if (stage.pendingPrompt !== undefined)
|
|
76316
|
+
ids.push(stage.pendingPrompt.id);
|
|
76317
|
+
if (stage.status === "awaiting_input" && stage.promptFootprint?.kind === "custom") {
|
|
76318
|
+
ids.push(stage.promptFootprint.id);
|
|
76319
|
+
}
|
|
76320
|
+
return ids;
|
|
76321
|
+
}
|
|
76322
|
+
function inferPromptStageTarget(runId, delivery, promptId) {
|
|
76323
|
+
if (!answersPendingPrompt(delivery, promptId))
|
|
76324
|
+
return { ok: true, runId };
|
|
76325
|
+
const pending = expandWorkflowGraph(readGraphStoreSnapshot(store), runId).stages.filter((stage) => {
|
|
76326
|
+
const ids = answerablePromptIds(stage);
|
|
76327
|
+
return promptId === undefined ? ids.length > 0 : ids.includes(promptId);
|
|
76328
|
+
});
|
|
76329
|
+
const only = pending[0];
|
|
76330
|
+
if (pending.length === 1 && only !== undefined) {
|
|
76331
|
+
return { ok: true, runId: only.workflowGraphTarget.runId, stageId: only.workflowGraphTarget.stageId };
|
|
76332
|
+
}
|
|
76333
|
+
if (pending.length === 0) {
|
|
76334
|
+
return promptId === undefined ? { ok: true, runId } : { ok: false, message: `No pending prompt ${promptId} in run ${runId}.` };
|
|
76335
|
+
}
|
|
76336
|
+
return {
|
|
76337
|
+
ok: false,
|
|
76338
|
+
message: `${pending.length} prompts pending; pass stageId: ${pending.map(expandedStageLabel).join(", ")}`
|
|
76339
|
+
};
|
|
76340
|
+
}
|
|
75794
76341
|
function workflowSendResult(runId, stageId, delivery, status, message) {
|
|
75795
76342
|
return { action: "send", runId, stageId, delivery, status, message };
|
|
75796
76343
|
}
|
|
@@ -75851,7 +76398,8 @@ async function workflowSendAction(args, deps = {}) {
|
|
|
75851
76398
|
if (rootRun !== undefined && isTerminalRunStatus(rootRun.status)) {
|
|
75852
76399
|
return terminalWorkflowSendResult(rootRun.id, args.stageId?.trim() ?? "", rootRun.status);
|
|
75853
76400
|
}
|
|
75854
|
-
const
|
|
76401
|
+
const requested = resolveToolStageTarget(target.runId, args.stageId);
|
|
76402
|
+
const stage = requested.ok && requested.stageId === undefined ? inferPromptStageTarget(target.runId, requestedDelivery, args.promptId) : requested;
|
|
75855
76403
|
if (!stage.ok || stage.stageId === undefined) {
|
|
75856
76404
|
return workflowSendResult(target.runId, "", requestedDelivery, "noop", stage.ok ? "Stage id or name is required." : stage.message);
|
|
75857
76405
|
}
|
|
@@ -75992,6 +76540,32 @@ async function workflowSendAction(args, deps = {}) {
|
|
|
75992
76540
|
}
|
|
75993
76541
|
|
|
75994
76542
|
// dist/builtin/workflows/src/extension/workflow-tool.ts
|
|
76543
|
+
async function resolveDurableInspectionSource(args, runtime) {
|
|
76544
|
+
const target = args.runId?.trim();
|
|
76545
|
+
if (args.all === true || target === undefined || target.length === 0 || target === "--all")
|
|
76546
|
+
return { kind: "local" };
|
|
76547
|
+
const local = resolveRunId(target);
|
|
76548
|
+
if (local.kind !== "not_found")
|
|
76549
|
+
return { kind: "local" };
|
|
76550
|
+
const durable = await runtime.inspectDurableWorkflow(target);
|
|
76551
|
+
if (durable.kind !== "found")
|
|
76552
|
+
return { kind: "error", message: durable.message };
|
|
76553
|
+
return { kind: "durable", source: { store: durable.store, allowLiveHandles: false } };
|
|
76554
|
+
}
|
|
76555
|
+
function durableInspectionError(action, runId, message) {
|
|
76556
|
+
if (action === "stages")
|
|
76557
|
+
return { action, runId, filter: "all", stages: [], error: message };
|
|
76558
|
+
if (action === "stage")
|
|
76559
|
+
return { action, runId, error: message };
|
|
76560
|
+
return {
|
|
76561
|
+
action,
|
|
76562
|
+
runId,
|
|
76563
|
+
stageId: "",
|
|
76564
|
+
source: "error",
|
|
76565
|
+
entries: [{ role: "notice", text: message }],
|
|
76566
|
+
truncated: false
|
|
76567
|
+
};
|
|
76568
|
+
}
|
|
75995
76569
|
function makeExecuteWorkflowTool(runtime, reloadWorkflowResources, ensureWorkflowResourcesLoaded = () => {}, sendDeps = {}) {
|
|
75996
76570
|
return async function executeWorkflowTool(args, ctx) {
|
|
75997
76571
|
const action = args.action ?? "run";
|
|
@@ -76047,7 +76621,8 @@ function makeExecuteWorkflowTool(runtime, reloadWorkflowResources, ensureWorkflo
|
|
|
76047
76621
|
return { action: "statusDetail", runId: target, error: resolved.message };
|
|
76048
76622
|
}
|
|
76049
76623
|
if (resolved.kind === "not_found") {
|
|
76050
|
-
|
|
76624
|
+
const durable = await getRuntime().inspectDurableWorkflow(target);
|
|
76625
|
+
return durable.kind === "found" ? { action: "statusDetail", runId: target, detail: durable.detail } : { action: "statusDetail", runId: target, error: durable.message };
|
|
76051
76626
|
}
|
|
76052
76627
|
const result2 = inspectRun(resolved.runId);
|
|
76053
76628
|
return result2.ok ? { action: "statusDetail", runId: result2.runId, detail: result2.detail } : { action: "statusDetail", runId: target, error: `run not found: ${target}` };
|
|
@@ -76063,11 +76638,18 @@ function makeExecuteWorkflowTool(runtime, reloadWorkflowResources, ensureWorkflo
|
|
|
76063
76638
|
return result;
|
|
76064
76639
|
}
|
|
76065
76640
|
case "stages":
|
|
76066
|
-
return workflowStagesResult(args);
|
|
76067
76641
|
case "stage":
|
|
76068
|
-
|
|
76069
|
-
|
|
76070
|
-
|
|
76642
|
+
case "transcript": {
|
|
76643
|
+
const resolved = await resolveDurableInspectionSource(args, getRuntime());
|
|
76644
|
+
if (resolved.kind === "error")
|
|
76645
|
+
return durableInspectionError(action, args.runId ?? "", resolved.message);
|
|
76646
|
+
const source = resolved.kind === "durable" ? resolved.source : undefined;
|
|
76647
|
+
if (action === "stages")
|
|
76648
|
+
return workflowStagesResult(args, source);
|
|
76649
|
+
if (action === "stage")
|
|
76650
|
+
return workflowStageResult(args, source);
|
|
76651
|
+
return workflowTranscriptResult(args, source);
|
|
76652
|
+
}
|
|
76071
76653
|
case "send":
|
|
76072
76654
|
return workflowSendAction(args, sendDeps);
|
|
76073
76655
|
case "pause":
|