@bastani/atomic 0.9.13-alpha.2 → 0.9.13-alpha.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -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 +12 -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 +680 -152
- package/dist/builtin/workflows/src/extension/runtime-durable-resume.ts +6 -0
- package/dist/builtin/workflows/src/extension/ui-surface.ts +2 -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/run-detail.ts +25 -12
- 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 +16 -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 +8 -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 +5 -0
- package/dist/core/agent-session-prompt.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 +7 -3
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +8 -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 +2 -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/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/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/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/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-engine/protocol.d.ts.map +1 -1
- package/dist/modes/interactive-engine/protocol.js +4 -1
- package/dist/modes/interactive-engine/protocol.js.map +1 -1
- package/docs/environment-variables.md +1 -1
- package/docs/intercom.md +20 -21
- 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 +1 -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];
|
|
@@ -47839,7 +47847,7 @@ function isModelUsage(value2) {
|
|
|
47839
47847
|
if (typeof value2 !== "object" || value2 === null || Array.isArray(value2))
|
|
47840
47848
|
return false;
|
|
47841
47849
|
const usage = value2;
|
|
47842
|
-
return ["input", "output", "cacheRead", "cacheWrite", "cost", "turns"].every((key2) => usage[key2] === undefined || typeof usage[key2] === "number" && Number.isFinite(usage[key2]));
|
|
47850
|
+
return ["input", "output", "cacheRead", "cacheWrite", "cost", "turns"].every((key2) => usage[key2] === undefined || typeof usage[key2] === "number" && Number.isFinite(usage[key2]) && usage[key2] >= 0);
|
|
47843
47851
|
}
|
|
47844
47852
|
function isUiPromptKind(value2) {
|
|
47845
47853
|
return value2 === "input" || value2 === "confirm" || value2 === "select" || value2 === "editor" || value2 === "custom";
|
|
@@ -48165,6 +48173,12 @@ class InMemoryDurableBackend {
|
|
|
48165
48173
|
return this.getWorkflow(workflowId);
|
|
48166
48174
|
}
|
|
48167
48175
|
async hydrateWorkflow(_workflowId) {}
|
|
48176
|
+
async hydrateWorkflowForInspection(workflowId) {
|
|
48177
|
+
const handle = this.getLoadableWorkflow(workflowId);
|
|
48178
|
+
if (handle !== undefined)
|
|
48179
|
+
return { kind: "current", handle };
|
|
48180
|
+
return { kind: this.deletedWorkflowIds.has(workflowId) ? "deleted" : "absent" };
|
|
48181
|
+
}
|
|
48168
48182
|
async hydrateResumableWorkflows() {}
|
|
48169
48183
|
async prepareWorkflowCatalog() {
|
|
48170
48184
|
return { resumable: this.listResumableWorkflows(), completed: this.listCompletedWorkflows() };
|
|
@@ -50300,17 +50314,24 @@ class DbosDurableBackend {
|
|
|
50300
50314
|
throw first;
|
|
50301
50315
|
}
|
|
50302
50316
|
async hydrateWorkflow(workflowId) {
|
|
50303
|
-
|
|
50304
|
-
|
|
50305
|
-
|
|
50306
|
-
if (
|
|
50307
|
-
|
|
50308
|
-
return;
|
|
50317
|
+
await this.hydrateWorkflowForInspection(workflowId);
|
|
50318
|
+
}
|
|
50319
|
+
async hydrateWorkflowForInspection(workflowId) {
|
|
50320
|
+
if (this.locallyRegistered.has(workflowId)) {
|
|
50321
|
+
const handle = this.getLoadableWorkflow(workflowId);
|
|
50322
|
+
return handle === undefined ? { kind: "malformed" } : { kind: "current", handle };
|
|
50309
50323
|
}
|
|
50324
|
+
const info = await this.sdk.retrieveWorkflow(workflowId);
|
|
50325
|
+
if (info !== undefined)
|
|
50326
|
+
return await this.hydrateInfo(info);
|
|
50310
50327
|
const records = await this.sdk.listStepRecords(workflowId);
|
|
50311
50328
|
const deletion = classifyDbosDeletionTombstone(records, workflowId);
|
|
50312
|
-
if (deletion
|
|
50313
|
-
|
|
50329
|
+
if (deletion === "absent" && records.length === 0)
|
|
50330
|
+
return { kind: "absent" };
|
|
50331
|
+
await this.suppressWorkflow(workflowId);
|
|
50332
|
+
if (deletion === "absent")
|
|
50333
|
+
return { kind: "malformed" };
|
|
50334
|
+
return { kind: deletion === "current" ? "deleted" : "malformed" };
|
|
50314
50335
|
}
|
|
50315
50336
|
async hydrateResumableWorkflows() {
|
|
50316
50337
|
const all = await this.sdk.listAllWorkflows();
|
|
@@ -50322,10 +50343,15 @@ class DbosDurableBackend {
|
|
|
50322
50343
|
}
|
|
50323
50344
|
async hydrateInfo(info) {
|
|
50324
50345
|
const records = await this.sdk.listStepRecords(info.workflowId);
|
|
50346
|
+
const deletion = classifyDbosDeletionTombstone(records, info.workflowId);
|
|
50347
|
+
if (deletion !== "absent") {
|
|
50348
|
+
await this.suppressWorkflow(info.workflowId);
|
|
50349
|
+
return { kind: deletion === "current" ? "deleted" : "malformed" };
|
|
50350
|
+
}
|
|
50325
50351
|
const metadata = classifyLatestMetadata(records, info.workflowId);
|
|
50326
50352
|
if (metadata.kind !== "current") {
|
|
50327
50353
|
await this.suppressWorkflow(info.workflowId);
|
|
50328
|
-
return;
|
|
50354
|
+
return { kind: "malformed" };
|
|
50329
50355
|
}
|
|
50330
50356
|
const checkpoints = [];
|
|
50331
50357
|
for (const record of records) {
|
|
@@ -50334,7 +50360,7 @@ class DbosDurableBackend {
|
|
|
50334
50360
|
const classified = classifyCheckpointPayload(info.workflowId, record.stepName, record.output);
|
|
50335
50361
|
if (classified.kind === "unknown") {
|
|
50336
50362
|
await this.suppressWorkflow(info.workflowId);
|
|
50337
|
-
return;
|
|
50363
|
+
return { kind: "malformed" };
|
|
50338
50364
|
}
|
|
50339
50365
|
checkpoints.push(classified.checkpoint);
|
|
50340
50366
|
}
|
|
@@ -50345,14 +50371,21 @@ class DbosDurableBackend {
|
|
|
50345
50371
|
for (const checkpoint of checkpoints)
|
|
50346
50372
|
this.mem.recordCheckpoint(checkpoint);
|
|
50347
50373
|
const current = this.mem.getWorkflow(info.workflowId);
|
|
50348
|
-
if (current
|
|
50349
|
-
|
|
50350
|
-
|
|
50351
|
-
...metadata.metadata,
|
|
50352
|
-
pendingPrompts: pendingPrompts2,
|
|
50353
|
-
completedCheckpoints: current.completedCheckpoints
|
|
50354
|
-
});
|
|
50374
|
+
if (current === undefined) {
|
|
50375
|
+
await this.suppressWorkflow(info.workflowId);
|
|
50376
|
+
return { kind: "malformed" };
|
|
50355
50377
|
}
|
|
50378
|
+
const pendingPrompts2 = this.promptReservations.hydrate(info.workflowId, metadata.metadata.pendingPrompts, records, metadata.metadata.promptReservationEpoch);
|
|
50379
|
+
this.applyMetadata(info.workflowId, {
|
|
50380
|
+
...metadata.metadata,
|
|
50381
|
+
pendingPrompts: pendingPrompts2,
|
|
50382
|
+
completedCheckpoints: current.completedCheckpoints
|
|
50383
|
+
});
|
|
50384
|
+
const handle = this.getLoadableWorkflow(info.workflowId);
|
|
50385
|
+
if (handle !== undefined)
|
|
50386
|
+
return { kind: "current", handle };
|
|
50387
|
+
await this.suppressWorkflow(info.workflowId);
|
|
50388
|
+
return { kind: "malformed" };
|
|
50356
50389
|
}
|
|
50357
50390
|
async suppressWorkflow(workflowId) {
|
|
50358
50391
|
this.invalid.add(workflowId);
|
|
@@ -51066,20 +51099,34 @@ function priorRunElapsedMs(backend, workflowId) {
|
|
|
51066
51099
|
return elapsedMs;
|
|
51067
51100
|
}
|
|
51068
51101
|
function recordRunTimingCheckpoint(backend, run, options) {
|
|
51102
|
+
const checkpoint = runTimingCheckpoint(backend, run, options);
|
|
51103
|
+
if (checkpoint === undefined)
|
|
51104
|
+
return false;
|
|
51105
|
+
backend.recordCheckpoint(checkpoint);
|
|
51106
|
+
return true;
|
|
51107
|
+
}
|
|
51108
|
+
async function recordRunTimingCheckpointAsync(backend, run, options) {
|
|
51109
|
+
const checkpoint = runTimingCheckpoint(backend, run, options);
|
|
51110
|
+
if (checkpoint === undefined)
|
|
51111
|
+
return false;
|
|
51112
|
+
await backend.recordCheckpointAsync(checkpoint);
|
|
51113
|
+
return true;
|
|
51114
|
+
}
|
|
51115
|
+
function runTimingCheckpoint(backend, run, options) {
|
|
51069
51116
|
const now = options?.now ?? Date.now();
|
|
51070
51117
|
const elapsedMs = elapsedRunMs(run, now);
|
|
51071
51118
|
if (elapsedMs <= 0)
|
|
51072
|
-
return
|
|
51119
|
+
return;
|
|
51073
51120
|
if (backend.listCheckpoints(run.id).length === 0)
|
|
51074
|
-
return
|
|
51121
|
+
return;
|
|
51075
51122
|
const recorded = priorRunElapsedMs(backend, run.id);
|
|
51076
51123
|
if (recorded !== undefined) {
|
|
51077
51124
|
if (elapsedMs <= recorded)
|
|
51078
|
-
return
|
|
51125
|
+
return;
|
|
51079
51126
|
if (options?.debounce === true && timingBucket(elapsedMs) === timingBucket(recorded))
|
|
51080
|
-
return
|
|
51127
|
+
return;
|
|
51081
51128
|
}
|
|
51082
|
-
|
|
51129
|
+
return {
|
|
51083
51130
|
kind: "tool",
|
|
51084
51131
|
workflowId: run.id,
|
|
51085
51132
|
checkpointId: `run-timing:${elapsedMs}`,
|
|
@@ -51088,8 +51135,6 @@ function recordRunTimingCheckpoint(backend, run, options) {
|
|
|
51088
51135
|
output: { elapsedMs },
|
|
51089
51136
|
completedAt: now
|
|
51090
51137
|
};
|
|
51091
|
-
backend.recordCheckpoint(checkpoint);
|
|
51092
|
-
return true;
|
|
51093
51138
|
}
|
|
51094
51139
|
function inheritedRunElapsedMs(input) {
|
|
51095
51140
|
const now = input.now ?? Date.now();
|
|
@@ -52992,33 +53037,33 @@ function isRunStatus(value2) {
|
|
|
52992
53037
|
return false;
|
|
52993
53038
|
}
|
|
52994
53039
|
}
|
|
52995
|
-
function resolveRunId(target) {
|
|
53040
|
+
function resolveRunId(target, activeStore = store) {
|
|
52996
53041
|
if (!isFullRunId(target))
|
|
52997
53042
|
return { kind: "malformed", message: malformedRunIdMessage(target) };
|
|
52998
|
-
const exact =
|
|
53043
|
+
const exact = activeStore.runs().find((r) => r.id === target);
|
|
52999
53044
|
if (exact)
|
|
53000
53045
|
return { kind: "exact", runId: exact.id };
|
|
53001
53046
|
return { kind: "not_found" };
|
|
53002
53047
|
}
|
|
53003
|
-
function resolveToolRunTarget(args, emptyMessage) {
|
|
53048
|
+
function resolveToolRunTarget(args, emptyMessage, activeStore = store) {
|
|
53004
53049
|
const rawTarget = args.runId?.trim() ?? "";
|
|
53005
53050
|
if (args.all === true || rawTarget === "--all")
|
|
53006
53051
|
return { kind: "all" };
|
|
53007
|
-
const target = rawTarget ||
|
|
53052
|
+
const target = rawTarget || activeStore.activeRunId() || "";
|
|
53008
53053
|
if (!target)
|
|
53009
53054
|
return { kind: "not_found", target: rawTarget, message: emptyMessage };
|
|
53010
|
-
const resolved = resolveRunId(target);
|
|
53055
|
+
const resolved = resolveRunId(target, activeStore);
|
|
53011
53056
|
if (resolved.kind === "exact")
|
|
53012
53057
|
return { kind: "run", runId: resolved.runId };
|
|
53013
53058
|
if (resolved.kind === "malformed")
|
|
53014
53059
|
return { kind: "malformed", target, message: resolved.message };
|
|
53015
53060
|
return { kind: "not_found", target, message: `Run not found: ${target}` };
|
|
53016
53061
|
}
|
|
53017
|
-
function resolveStageTarget(runId, stageTarget) {
|
|
53062
|
+
function resolveStageTarget(runId, stageTarget, activeStore = store) {
|
|
53018
53063
|
const target = stageTarget?.trim();
|
|
53019
53064
|
if (!target)
|
|
53020
53065
|
return { ok: true, runId };
|
|
53021
|
-
const graph = expandWorkflowGraph(readGraphStoreSnapshot(
|
|
53066
|
+
const graph = expandWorkflowGraph(readGraphStoreSnapshot(activeStore), runId);
|
|
53022
53067
|
const exactVirtualIds = graph.stages.filter((stage) => stage.id === target);
|
|
53023
53068
|
if (exactVirtualIds.length === 1)
|
|
53024
53069
|
return resolvedStageTarget(exactVirtualIds[0]);
|
|
@@ -53054,8 +53099,8 @@ function ambiguousStageTarget(target, stages) {
|
|
|
53054
53099
|
message: `Ambiguous stage identifier "${target}" matches: ${stages.map(expandedStageLabel).join(", ")}`
|
|
53055
53100
|
};
|
|
53056
53101
|
}
|
|
53057
|
-
function resolveToolStageTarget(runId, stageTarget) {
|
|
53058
|
-
return resolveStageTarget(runId, stageTarget);
|
|
53102
|
+
function resolveToolStageTarget(runId, stageTarget, activeStore = store) {
|
|
53103
|
+
return resolveStageTarget(runId, stageTarget, activeStore);
|
|
53059
53104
|
}
|
|
53060
53105
|
function resolveControlNodeTarget(runId, stageTarget) {
|
|
53061
53106
|
const target = stageTarget?.trim();
|
|
@@ -61101,6 +61146,9 @@ class ScopedDurableBackend {
|
|
|
61101
61146
|
hydrateWorkflow(_workflowId) {
|
|
61102
61147
|
return Promise.resolve();
|
|
61103
61148
|
}
|
|
61149
|
+
hydrateWorkflowForInspection(_workflowId) {
|
|
61150
|
+
return Promise.resolve({ kind: "absent" });
|
|
61151
|
+
}
|
|
61104
61152
|
hydrateResumableWorkflows() {
|
|
61105
61153
|
return Promise.resolve();
|
|
61106
61154
|
}
|
|
@@ -64784,7 +64832,7 @@ function createDurableStageSessionRecorder(input) {
|
|
|
64784
64832
|
if (stageRunId === input.runId) {
|
|
64785
64833
|
await recordStageSessionCheckpoint(input.deps, snapshot, { force: options?.forceDurable === true });
|
|
64786
64834
|
if (input.runSnapshot !== undefined) {
|
|
64787
|
-
|
|
64835
|
+
await recordRunTimingCheckpointAsync(input.deps.backend, input.runSnapshot, {
|
|
64788
64836
|
debounce: options?.forceDurable !== true
|
|
64789
64837
|
});
|
|
64790
64838
|
}
|
|
@@ -64833,7 +64881,7 @@ function hasUsableContentBlock(block) {
|
|
|
64833
64881
|
}
|
|
64834
64882
|
|
|
64835
64883
|
// dist/builtin/workflows/src/durable/completed-catalog-stage-groups.ts
|
|
64836
|
-
function validBoundaryRecordSet(checkpoints, strict) {
|
|
64884
|
+
function validBoundaryRecordSet(checkpoints, strict, requireActiveFingerprint = false) {
|
|
64837
64885
|
const stages = checkpoints.filter((item) => item.kind === "stage");
|
|
64838
64886
|
const boundaries = stages.filter((item) => item.topology?.boundary !== undefined);
|
|
64839
64887
|
const startsByReplay = new Map;
|
|
@@ -64848,42 +64896,59 @@ function validBoundaryRecordSet(checkpoints, strict) {
|
|
|
64848
64896
|
return false;
|
|
64849
64897
|
if (boundaries.some((checkpoint) => checkpoint.topology.boundary.event === "terminal" && startsByReplay.get(checkpoint.replayKey)?.length !== 1))
|
|
64850
64898
|
return false;
|
|
64851
|
-
return [...startsByReplay.values()].every((starts) =>
|
|
64899
|
+
return [...startsByReplay.values()].every((starts) => {
|
|
64900
|
+
const start = starts[0];
|
|
64901
|
+
if (boundaryTransitionError(start, stages, strict) !== undefined)
|
|
64902
|
+
return false;
|
|
64903
|
+
if (!requireActiveFingerprint || start.topology.boundary.invocationFingerprint !== undefined)
|
|
64904
|
+
return true;
|
|
64905
|
+
return stages.some((stage) => stage.replayKey === start.replayKey && stage.topology?.boundary?.event === "terminal" && stage.topology.boundary.status === "completed") && boundaryTransitionError(start, stages, true) === undefined;
|
|
64906
|
+
});
|
|
64852
64907
|
}
|
|
64853
|
-
function validStageGroup(drafts, runId,
|
|
64908
|
+
function validStageGroup(drafts, runId, rootRunId, tools = []) {
|
|
64854
64909
|
if (drafts.some((draft) => draft.topology.stageId.length === 0))
|
|
64855
64910
|
return false;
|
|
64856
|
-
|
|
64857
|
-
if (stageIds.size !== drafts.length)
|
|
64911
|
+
if (tools.some((tool) => tool.topology !== undefined && (tool.topology.version !== DURABLE_TOOL_TOPOLOGY_VERSION || tool.topology.nodeId.length === 0)))
|
|
64858
64912
|
return false;
|
|
64859
|
-
const
|
|
64860
|
-
|
|
64913
|
+
const stageIds = drafts.map((draft) => draft.topology.stageId);
|
|
64914
|
+
const toolIds = tools.map((tool) => tool.topology?.nodeId ?? tool.checkpointId);
|
|
64915
|
+
const ids = new Set([...stageIds, ...toolIds]);
|
|
64916
|
+
if (ids.size !== stageIds.length + toolIds.length)
|
|
64861
64917
|
return false;
|
|
64862
64918
|
const orders = drafts.flatMap((draft) => draft.topology.sourceOrder === undefined ? [] : [draft.topology.sourceOrder]);
|
|
64863
64919
|
if (new Set(orders).size !== orders.length)
|
|
64864
64920
|
return false;
|
|
64865
|
-
|
|
64921
|
+
const parentEntries = [
|
|
64922
|
+
...drafts.map((draft) => [draft.topology.stageId, draft.topology.parentIds]),
|
|
64923
|
+
...tools.map((tool) => [tool.topology?.nodeId ?? tool.checkpointId, tool.topology?.parentIds ?? []])
|
|
64924
|
+
];
|
|
64925
|
+
if (parentEntries.some(([, parentIds]) => parentIds.some((parentId) => !ids.has(parentId))))
|
|
64866
64926
|
return false;
|
|
64867
|
-
const runs =
|
|
64927
|
+
const runs = [
|
|
64928
|
+
...drafts.flatMap((draft) => draft.topology?.run === undefined ? [] : [draft.topology.run]),
|
|
64929
|
+
...tools.flatMap((tool) => tool.topology?.run === undefined ? [] : [tool.topology.run])
|
|
64930
|
+
];
|
|
64868
64931
|
const first = runs[0];
|
|
64869
64932
|
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
64933
|
return false;
|
|
64871
|
-
|
|
64934
|
+
if (runId === rootRunId && runs.some((run) => run.parentRunId !== undefined || run.parentStageId !== undefined || run.rootRunId !== undefined))
|
|
64935
|
+
return false;
|
|
64936
|
+
const parents = new Map(parentEntries);
|
|
64872
64937
|
const visiting = new Set;
|
|
64873
64938
|
const visited = new Set;
|
|
64874
|
-
const cyclic = (
|
|
64875
|
-
if (visiting.has(
|
|
64939
|
+
const cyclic = (nodeId) => {
|
|
64940
|
+
if (visiting.has(nodeId))
|
|
64876
64941
|
return true;
|
|
64877
|
-
if (visited.has(
|
|
64942
|
+
if (visited.has(nodeId))
|
|
64878
64943
|
return false;
|
|
64879
|
-
visiting.add(
|
|
64880
|
-
if ((parents.get(
|
|
64944
|
+
visiting.add(nodeId);
|
|
64945
|
+
if ((parents.get(nodeId) ?? []).some(cyclic))
|
|
64881
64946
|
return true;
|
|
64882
|
-
visiting.delete(
|
|
64883
|
-
visited.add(
|
|
64947
|
+
visiting.delete(nodeId);
|
|
64948
|
+
visited.add(nodeId);
|
|
64884
64949
|
return false;
|
|
64885
64950
|
};
|
|
64886
|
-
return ![...
|
|
64951
|
+
return ![...ids].some(cyclic);
|
|
64887
64952
|
}
|
|
64888
64953
|
function compareDraftSourceOrder(left, right) {
|
|
64889
64954
|
const leftOrder = left.topology?.sourceOrder;
|
|
@@ -65425,7 +65490,7 @@ function completedWorkflowRunSnapshots(backend, entry) {
|
|
|
65425
65490
|
const checkpoints = backend.listCheckpoints(entry.workflowId);
|
|
65426
65491
|
if (checkpoints.length === 0)
|
|
65427
65492
|
return [];
|
|
65428
|
-
const runs = runSnapshotsFromCheckpoints(checkpoints, handle.workflowId, handle.name, handle.updatedAt).map((run2) => ({ ...run2, stages: run2.stages.map(validatedStageTranscript) }));
|
|
65493
|
+
const runs = runSnapshotsFromCheckpoints(checkpoints, handle.workflowId, handle.name, handle.updatedAt, COMPLETED_RECONSTRUCTION).map((run2) => ({ ...run2, stages: run2.stages.map(validatedStageTranscript) }));
|
|
65429
65494
|
const rootIndex = runs.findIndex((run2) => run2.id === handle.workflowId);
|
|
65430
65495
|
if (rootIndex < 0)
|
|
65431
65496
|
return [];
|
|
@@ -65449,11 +65514,45 @@ function completedWorkflowRunSnapshots(backend, entry) {
|
|
|
65449
65514
|
};
|
|
65450
65515
|
return [root, ...runs.filter((_, index) => index !== rootIndex)];
|
|
65451
65516
|
}
|
|
65517
|
+
function durableWorkflowRunSnapshots(backend, handle) {
|
|
65518
|
+
const checkpoints = backend.listCheckpoints(handle.workflowId);
|
|
65519
|
+
if (checkpoints.length === 0) {
|
|
65520
|
+
return [rootSnapshot(backend, handle, { stages: [], toolNodes: [] })];
|
|
65521
|
+
}
|
|
65522
|
+
const requiresTerminalTopology = handle.status === "completed" || handle.status === "failed";
|
|
65523
|
+
const runs = runSnapshotsFromCheckpoints(checkpoints, handle.workflowId, handle.name, handle.updatedAt, requiresTerminalTopology ? COMPLETED_RECONSTRUCTION : ACTIVE_INSPECTION_RECONSTRUCTION);
|
|
65524
|
+
const rootIndex = runs.findIndex((run2) => run2.id === handle.workflowId);
|
|
65525
|
+
if (rootIndex < 0)
|
|
65526
|
+
return [];
|
|
65527
|
+
return [rootSnapshot(backend, handle, runs[rootIndex]), ...runs.filter((_, index) => index !== rootIndex)];
|
|
65528
|
+
}
|
|
65529
|
+
function rootSnapshot(backend, handle, graph) {
|
|
65530
|
+
const terminal = handle.status === "completed" || handle.status === "failed" || handle.status === "cancelled";
|
|
65531
|
+
const priorDurationMs = priorRunElapsedMs(backend, handle.workflowId);
|
|
65532
|
+
const terminalDurationMs = priorDurationMs ?? Math.max(0, handle.updatedAt - handle.createdAt);
|
|
65533
|
+
return {
|
|
65534
|
+
id: handle.workflowId,
|
|
65535
|
+
name: handle.name,
|
|
65536
|
+
inputs: { ...handle.inputs },
|
|
65537
|
+
status: handle.status,
|
|
65538
|
+
stages: graph.stages,
|
|
65539
|
+
toolNodes: graph.toolNodes,
|
|
65540
|
+
startedAt: handle.createdAt,
|
|
65541
|
+
...terminal ? { endedAt: handle.updatedAt, durationMs: terminalDurationMs } : priorDurationMs === undefined ? {} : { accumulatedDurationMs: priorDurationMs },
|
|
65542
|
+
...handle.error !== undefined ? { error: handle.error } : {},
|
|
65543
|
+
...handle.failureKind !== undefined ? { failureKind: handle.failureKind } : {},
|
|
65544
|
+
...handle.failureCode !== undefined ? { failureCode: handle.failureCode } : {},
|
|
65545
|
+
...handle.failureRecoverability !== undefined ? { failureRecoverability: handle.failureRecoverability } : {},
|
|
65546
|
+
...handle.failureDisposition !== undefined ? { failureDisposition: handle.failureDisposition } : {},
|
|
65547
|
+
...handle.failedToolNodeId !== undefined ? { failedToolNodeId: handle.failedToolNodeId } : {},
|
|
65548
|
+
resumable: isDurableWorkflowResumable(handle)
|
|
65549
|
+
};
|
|
65550
|
+
}
|
|
65452
65551
|
function durableNestedRunSnapshots(backend, rootWorkflowId) {
|
|
65453
65552
|
const handle = backend.getWorkflow(rootWorkflowId);
|
|
65454
65553
|
if (handle === undefined)
|
|
65455
65554
|
return [];
|
|
65456
|
-
return runSnapshotsFromCheckpoints(backend.listCheckpoints(rootWorkflowId), rootWorkflowId, handle.name, handle.updatedAt,
|
|
65555
|
+
return runSnapshotsFromCheckpoints(backend.listCheckpoints(rootWorkflowId), rootWorkflowId, handle.name, handle.updatedAt, LEGACY_ACTIVE_RECONSTRUCTION).filter((run2) => run2.id !== rootWorkflowId);
|
|
65457
65556
|
}
|
|
65458
65557
|
function validatedStageTranscript(stage) {
|
|
65459
65558
|
if (stage.sessionFile === undefined || isReopenableSessionTranscript(stage.sessionFile))
|
|
@@ -65523,15 +65622,36 @@ function summarizeCompletedToolResult(value2) {
|
|
|
65523
65622
|
return flattenTruncatedString(String(value2).slice(0, 240));
|
|
65524
65623
|
return serialized.length <= 240 ? serialized : `${flattenTruncatedString(serialized.slice(0, 237))}...`;
|
|
65525
65624
|
}
|
|
65526
|
-
|
|
65527
|
-
|
|
65625
|
+
var COMPLETED_RECONSTRUCTION = {
|
|
65626
|
+
requireTerminal: true,
|
|
65627
|
+
failClosed: true,
|
|
65628
|
+
retainActive: false,
|
|
65629
|
+
failOnUnreachable: false,
|
|
65630
|
+
requireActiveBoundaryFingerprint: false
|
|
65631
|
+
};
|
|
65632
|
+
var ACTIVE_INSPECTION_RECONSTRUCTION = {
|
|
65633
|
+
requireTerminal: false,
|
|
65634
|
+
failClosed: true,
|
|
65635
|
+
retainActive: true,
|
|
65636
|
+
failOnUnreachable: true,
|
|
65637
|
+
requireActiveBoundaryFingerprint: true
|
|
65638
|
+
};
|
|
65639
|
+
var LEGACY_ACTIVE_RECONSTRUCTION = {
|
|
65640
|
+
requireTerminal: false,
|
|
65641
|
+
failClosed: false,
|
|
65642
|
+
retainActive: true,
|
|
65643
|
+
failOnUnreachable: false,
|
|
65644
|
+
requireActiveBoundaryFingerprint: false
|
|
65645
|
+
};
|
|
65646
|
+
function runSnapshotsFromCheckpoints(checkpoints, rootRunId, rootRunName, fallbackCompletedAt, policy = COMPLETED_RECONSTRUCTION) {
|
|
65647
|
+
if (!validBoundaryRecordSet(checkpoints, policy.requireTerminal, policy.requireActiveBoundaryFingerprint))
|
|
65528
65648
|
return [];
|
|
65529
65649
|
const stageRecords = checkpoints.filter((checkpoint) => checkpoint.kind === "stage");
|
|
65530
65650
|
const identityRecords = stageRecords.filter((stage) => stage.topology?.sourceOrder !== undefined || stage.topology?.status !== undefined || stage.topology?.occurrenceKey !== undefined || stage.topology?.boundary !== undefined);
|
|
65531
65651
|
if (immutableStageGroupError(identityRecords) !== undefined)
|
|
65532
65652
|
return [];
|
|
65533
65653
|
const recordsByGroup = groupByDurableStageKey(stageRecords);
|
|
65534
|
-
const candidates = [...recordsByGroup.values()].map((records) => mergeStageGroup(records, stageRecords, checkpoints)).filter((draft) =>
|
|
65654
|
+
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
65655
|
...draft,
|
|
65536
65656
|
topology: {
|
|
65537
65657
|
version: DURABLE_STAGE_TOPOLOGY_VERSION,
|
|
@@ -65542,13 +65662,36 @@ function runSnapshotsFromCheckpoints(checkpoints, rootRunId, rootRunName, fallba
|
|
|
65542
65662
|
}).sort(compareDraftSourceOrder);
|
|
65543
65663
|
const drafts = checkpointDrafts(checkpoints);
|
|
65544
65664
|
const toolCheckpoints = drafts.tools;
|
|
65665
|
+
if (policy.failClosed) {
|
|
65666
|
+
for (const draft of candidates) {
|
|
65667
|
+
const boundary = draft.topology?.boundary;
|
|
65668
|
+
if (boundary === undefined || childRunIdFromDraft(draft) === undefined)
|
|
65669
|
+
continue;
|
|
65670
|
+
if (boundary.replayScope !== draft.replayKey)
|
|
65671
|
+
return [];
|
|
65672
|
+
const expectedChildRun = {
|
|
65673
|
+
runId: boundary.child.runId,
|
|
65674
|
+
runName: boundary.child.runName,
|
|
65675
|
+
parentRunId: boundary.child.parentRunId,
|
|
65676
|
+
parentStageId: boundary.child.parentStageId,
|
|
65677
|
+
rootRunId: boundary.child.rootRunId
|
|
65678
|
+
};
|
|
65679
|
+
const childToolIds = new Set(toolCheckpoints.flatMap((checkpoint) => checkpoint.topology?.run?.runId === expectedChildRun.runId ? [checkpoint.topology.nodeId] : []));
|
|
65680
|
+
if (directChildTopologyError(stageRecords, boundary.replayScope, expectedChildRun, true, childToolIds) !== undefined)
|
|
65681
|
+
return [];
|
|
65682
|
+
}
|
|
65683
|
+
}
|
|
65545
65684
|
if (candidates.length === 0 && toolCheckpoints.length === 0) {
|
|
65546
|
-
|
|
65685
|
+
const supportedNonGraphState = checkpoints.every((checkpoint) => checkpoint.kind === "ui" || checkpoint.kind === "tool" && checkpoint.argsHash === RUN_TIMING_CHECKPOINT_NAME);
|
|
65686
|
+
if (policy.failClosed && supportedNonGraphState) {
|
|
65687
|
+
return [emptyGraphRun(rootRunId, rootRunName, fallbackCompletedAt)];
|
|
65688
|
+
}
|
|
65689
|
+
return policy.failClosed ? [] : [syntheticRun(rootRunId, rootRunName, checkpoints.length, fallbackCompletedAt)];
|
|
65547
65690
|
}
|
|
65548
65691
|
const grouped = new Map;
|
|
65549
65692
|
for (const draft of candidates) {
|
|
65550
65693
|
if (draft.topology?.version !== DURABLE_STAGE_TOPOLOGY_VERSION) {
|
|
65551
|
-
if (
|
|
65694
|
+
if (policy.failClosed)
|
|
65552
65695
|
return [];
|
|
65553
65696
|
continue;
|
|
65554
65697
|
}
|
|
@@ -65564,7 +65707,10 @@ function runSnapshotsFromCheckpoints(checkpoints, rootRunId, rootRunName, fallba
|
|
|
65564
65707
|
}
|
|
65565
65708
|
for (const group of grouped.values())
|
|
65566
65709
|
group.sort(compareDraftSourceOrder);
|
|
65710
|
+
const groupedCount = grouped.size;
|
|
65567
65711
|
retainReachableRunGroups(grouped, rootRunId);
|
|
65712
|
+
if (policy.failOnUnreachable && grouped.size !== groupedCount)
|
|
65713
|
+
return [];
|
|
65568
65714
|
if (!validateRunGroups(grouped, rootRunId, toolCheckpoints, checkpoints))
|
|
65569
65715
|
return [];
|
|
65570
65716
|
const syntheticChildren = [];
|
|
@@ -65574,7 +65720,7 @@ function runSnapshotsFromCheckpoints(checkpoints, rootRunId, rootRunName, fallba
|
|
|
65574
65720
|
if (child?.exited !== true || grouped.has(child.runId))
|
|
65575
65721
|
continue;
|
|
65576
65722
|
if (!isSyntheticExitedChild(draft, parentRunId, child.runId, rootRunId) || childScopedEvidenceExists(checkpoints, draft.replayKey, child.runId)) {
|
|
65577
|
-
if (
|
|
65723
|
+
if (policy.failClosed)
|
|
65578
65724
|
return [];
|
|
65579
65725
|
continue;
|
|
65580
65726
|
}
|
|
@@ -65583,8 +65729,8 @@ function runSnapshotsFromCheckpoints(checkpoints, rootRunId, rootRunName, fallba
|
|
|
65583
65729
|
}
|
|
65584
65730
|
const idMaps = new Map;
|
|
65585
65731
|
for (const [runId, runDrafts] of grouped) {
|
|
65586
|
-
const
|
|
65587
|
-
if (!validStageGroup(runDrafts, runId,
|
|
65732
|
+
const ownedTools = toolCheckpoints.filter((checkpoint) => (checkpoint.topology?.run?.runId ?? rootRunId) === runId);
|
|
65733
|
+
if (!validStageGroup(runDrafts, runId, rootRunId, ownedTools))
|
|
65588
65734
|
return [];
|
|
65589
65735
|
const ids = new Map;
|
|
65590
65736
|
let hasIdentityConflict = false;
|
|
@@ -65600,7 +65746,7 @@ function runSnapshotsFromCheckpoints(checkpoints, rootRunId, rootRunName, fallba
|
|
|
65600
65746
|
}
|
|
65601
65747
|
});
|
|
65602
65748
|
if (hasIdentityConflict) {
|
|
65603
|
-
if (
|
|
65749
|
+
if (policy.failClosed)
|
|
65604
65750
|
return [];
|
|
65605
65751
|
grouped.delete(runId);
|
|
65606
65752
|
continue;
|
|
@@ -65620,7 +65766,7 @@ function runSnapshotsFromCheckpoints(checkpoints, rootRunId, rootRunName, fallba
|
|
|
65620
65766
|
const ownedTools = toolCheckpoints.filter((checkpoint) => (checkpoint.topology?.run?.runId ?? rootRunId) === runId);
|
|
65621
65767
|
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
65768
|
if (hasUnknownParents) {
|
|
65623
|
-
if (
|
|
65769
|
+
if (policy.failClosed)
|
|
65624
65770
|
return [];
|
|
65625
65771
|
continue;
|
|
65626
65772
|
}
|
|
@@ -65630,6 +65776,8 @@ function runSnapshotsFromCheckpoints(checkpoints, rootRunId, rootRunName, fallba
|
|
|
65630
65776
|
const startedAt = Math.min(...stages.map((stage) => stage.startedAt ?? fallbackCompletedAt), ...toolNodes.map((tool) => tool.startedAt ?? tool.endedAt ?? fallbackCompletedAt));
|
|
65631
65777
|
const endedAt = Math.max(...stages.map((stage) => stage.endedAt ?? fallbackCompletedAt), ...toolNodes.map((tool) => tool.endedAt ?? fallbackCompletedAt));
|
|
65632
65778
|
const owner = runId === rootRunId ? undefined : boundaryOwner(grouped, runId);
|
|
65779
|
+
const status = owner === undefined ? "completed" : childRunStatus(owner);
|
|
65780
|
+
const terminal = status !== "running" && status !== "pending" && status !== "paused" && status !== "blocked";
|
|
65633
65781
|
const parentRunId = run2?.parentRunId ?? rootRunId;
|
|
65634
65782
|
const boundarySourceId = grouped.get(parentRunId)?.find((draft) => childRunIdFromDraft(draft) === runId)?.topology?.stageId;
|
|
65635
65783
|
const declaredParentStageId = run2?.parentStageId === undefined ? undefined : idMaps.get(parentRunId)?.get(run2.parentStageId);
|
|
@@ -65639,12 +65787,11 @@ function runSnapshotsFromCheckpoints(checkpoints, rootRunId, rootRunName, fallba
|
|
|
65639
65787
|
id: runId,
|
|
65640
65788
|
name: run2?.runName ?? rootRunName,
|
|
65641
65789
|
inputs: {},
|
|
65642
|
-
status
|
|
65790
|
+
status,
|
|
65643
65791
|
stages,
|
|
65644
65792
|
toolNodes,
|
|
65645
65793
|
startedAt,
|
|
65646
|
-
endedAt,
|
|
65647
|
-
durationMs: Math.max(0, endedAt - startedAt),
|
|
65794
|
+
...terminal ? { endedAt, durationMs: Math.max(0, endedAt - startedAt) } : {},
|
|
65648
65795
|
...run2?.parentRunId !== undefined ? { parentRunId: run2.parentRunId } : {},
|
|
65649
65796
|
...parentStageId !== undefined ? { parentStageId } : {},
|
|
65650
65797
|
...run2?.rootRunId !== undefined ? { rootRunId: run2.rootRunId } : {},
|
|
@@ -65659,7 +65806,7 @@ function runSnapshotsFromCheckpoints(checkpoints, rootRunId, rootRunName, fallba
|
|
|
65659
65806
|
}
|
|
65660
65807
|
for (const { parentRunId, owner, child } of syntheticChildren) {
|
|
65661
65808
|
if (!emittedRunIds.has(parentRunId)) {
|
|
65662
|
-
if (
|
|
65809
|
+
if (policy.failClosed)
|
|
65663
65810
|
return [];
|
|
65664
65811
|
continue;
|
|
65665
65812
|
}
|
|
@@ -65667,7 +65814,7 @@ function runSnapshotsFromCheckpoints(checkpoints, rootRunId, rootRunName, fallba
|
|
|
65667
65814
|
const boundary = topology.boundary;
|
|
65668
65815
|
const parentStageId = idMaps.get(parentRunId)?.get(topology.stageId);
|
|
65669
65816
|
if (parentStageId === undefined) {
|
|
65670
|
-
if (
|
|
65817
|
+
if (policy.failClosed)
|
|
65671
65818
|
return [];
|
|
65672
65819
|
continue;
|
|
65673
65820
|
}
|
|
@@ -65736,6 +65883,20 @@ function stageResult(draft) {
|
|
|
65736
65883
|
return;
|
|
65737
65884
|
return typeof draft.output === "string" ? draft.output : JSON.stringify(draft.output);
|
|
65738
65885
|
}
|
|
65886
|
+
function emptyGraphRun(runId, runName, completedAt) {
|
|
65887
|
+
return {
|
|
65888
|
+
id: runId,
|
|
65889
|
+
name: runName,
|
|
65890
|
+
inputs: {},
|
|
65891
|
+
status: "completed",
|
|
65892
|
+
stages: [],
|
|
65893
|
+
toolNodes: [],
|
|
65894
|
+
startedAt: completedAt,
|
|
65895
|
+
endedAt: completedAt,
|
|
65896
|
+
durationMs: 0,
|
|
65897
|
+
resumable: false
|
|
65898
|
+
};
|
|
65899
|
+
}
|
|
65739
65900
|
function syntheticRun(runId, runName, checkpointCount, completedAt) {
|
|
65740
65901
|
return {
|
|
65741
65902
|
id: runId,
|
|
@@ -66619,7 +66780,7 @@ function createTrackedStageCaller(input) {
|
|
|
66619
66780
|
if (suppressQueuedContinuation)
|
|
66620
66781
|
runtime.state.suppressQueuedUserMessageContinuation = true;
|
|
66621
66782
|
try {
|
|
66622
|
-
result = await raceAbort(runtime.innerCtx.prompt(RESUME_CONTINUATION_PROMPT), runtime.signal);
|
|
66783
|
+
result = await runtime.raceStageSessionHeartbeat(raceAbort(runtime.innerCtx.prompt(RESUME_CONTINUATION_PROMPT), runtime.signal));
|
|
66623
66784
|
} finally {
|
|
66624
66785
|
if (suppressQueuedContinuation)
|
|
66625
66786
|
runtime.state.suppressQueuedUserMessageContinuation = false;
|
|
@@ -66646,46 +66807,51 @@ function createTrackedStageCaller(input) {
|
|
|
66646
66807
|
throw err;
|
|
66647
66808
|
}
|
|
66648
66809
|
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;
|
|
66810
|
+
let applyTerminalStageState;
|
|
66811
|
+
let terminalStateIsSuccess = false;
|
|
66812
|
+
try {
|
|
66813
|
+
let refreshedParentIds;
|
|
66814
|
+
if (trackStageLifecycle && !input.hasContinuation && runtime.stageSnapshot.startedAt === undefined && !input.hasScopedParents) {
|
|
66815
|
+
const actualParentIds = runtime.scheduler.tracker.currentParents();
|
|
66816
|
+
const sameParents = actualParentIds.length === runtime.stageSnapshot.parentIds.length && actualParentIds.every((value2) => runtime.stageSnapshot.parentIds.includes(value2));
|
|
66817
|
+
if (!sameParents) {
|
|
66818
|
+
runtime.scheduler.tracker.replaceParents(runtime.stageId, actualParentIds);
|
|
66819
|
+
refreshedParentIds = actualParentIds;
|
|
66673
66820
|
}
|
|
66674
66821
|
}
|
|
66675
|
-
if (
|
|
66676
|
-
|
|
66822
|
+
if (trackStageLifecycle) {
|
|
66823
|
+
const now = Date.now();
|
|
66824
|
+
const hasNoExplicitModelConfig = input.options?.model === undefined && input.options?.fallbackModels === undefined;
|
|
66825
|
+
const promptAdapterHandlesInitialPrompt = input.adapters.prompt !== undefined;
|
|
66826
|
+
if (callOptions.eagerSession && !promptAdapterHandlesInitialPrompt && (hasNoExplicitModelConfig || await hasExplicitFastModeCandidate({
|
|
66827
|
+
model: input.options?.model,
|
|
66828
|
+
fallbackModels: input.options?.fallbackModels,
|
|
66829
|
+
models: runtime.opts.models
|
|
66830
|
+
}))) {
|
|
66831
|
+
try {
|
|
66832
|
+
await runtime.innerCtx.__ensureSession();
|
|
66833
|
+
} catch (err) {
|
|
66834
|
+
if (!(err instanceof Error && err.message.includes("prompt adapter not configured")))
|
|
66835
|
+
throw err;
|
|
66836
|
+
}
|
|
66837
|
+
}
|
|
66838
|
+
if (refreshedParentIds !== undefined) {
|
|
66839
|
+
runtime.scheduler.setStageParentIds(runtime.stageSnapshot, refreshedParentIds);
|
|
66840
|
+
}
|
|
66841
|
+
runtime.stageSnapshot.status = "running";
|
|
66842
|
+
runtime.stageSnapshot.startedAt ??= rebasedStageStartedAt(input.options?.durableAccumulatedDurationMs, now);
|
|
66843
|
+
runtime.applyModelFallbackMeta(runtime.innerCtx.__modelFallbackMeta());
|
|
66844
|
+
runtime.activeStore.recordStageStart(runtime.runId, runtime.stageSnapshot);
|
|
66845
|
+
runtime.appendStageStartOnce();
|
|
66846
|
+
const sessionMeta = runtime.innerCtx.__sessionMeta();
|
|
66847
|
+
if (sessionMeta.sessionId !== undefined || sessionMeta.sessionFile !== undefined) {
|
|
66848
|
+
await runtime.captureStageSessionMeta({ awaitDurable: true });
|
|
66849
|
+
}
|
|
66850
|
+
runtime.startStageSessionHeartbeat();
|
|
66851
|
+
} else {
|
|
66852
|
+
runtime.applyModelFallbackMeta(runtime.innerCtx.__modelFallbackMeta());
|
|
66677
66853
|
}
|
|
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 {
|
|
66854
|
+
runtime.mcpScope.apply();
|
|
66689
66855
|
const abortSession = () => {
|
|
66690
66856
|
runtime.innerCtx.abort().catch(() => {});
|
|
66691
66857
|
};
|
|
@@ -66697,7 +66863,7 @@ function createTrackedStageCaller(input) {
|
|
|
66697
66863
|
try {
|
|
66698
66864
|
runtime.state.askUserQuestionObservedThisTurn = false;
|
|
66699
66865
|
runtime.state.chatAnswerObservedThisTurn = false;
|
|
66700
|
-
result = await raceAbort(call(), runtime.signal);
|
|
66866
|
+
result = await runtime.raceStageSessionHeartbeat(raceAbort(call(), runtime.signal));
|
|
66701
66867
|
const initialDrain = await drainResumeContinuations(result);
|
|
66702
66868
|
result = initialDrain.result;
|
|
66703
66869
|
let repeatReadinessAfterChatTurn = initialDrain.chatAnswerObserved;
|
|
@@ -66721,10 +66887,10 @@ function createTrackedStageCaller(input) {
|
|
|
66721
66887
|
runtime.state.chatAnswerObservedThisTurn = false;
|
|
66722
66888
|
runtime.state.waitingForStageChatTurn = true;
|
|
66723
66889
|
try {
|
|
66724
|
-
await raceAbort(new Promise((resolve12) => {
|
|
66890
|
+
await runtime.raceStageSessionHeartbeat(raceAbort(new Promise((resolve12) => {
|
|
66725
66891
|
resolveNextTurnEnd = resolve12;
|
|
66726
66892
|
runtime.state.wakeWaitingForStageChatTurn = resolve12;
|
|
66727
|
-
}), runtime.signal);
|
|
66893
|
+
}), runtime.signal));
|
|
66728
66894
|
} finally {
|
|
66729
66895
|
runtime.state.wakeWaitingForStageChatTurn = undefined;
|
|
66730
66896
|
runtime.state.waitingForStageChatTurn = false;
|
|
@@ -66748,7 +66914,7 @@ function createTrackedStageCaller(input) {
|
|
|
66748
66914
|
runtime.signal.removeEventListener("abort", abortSession);
|
|
66749
66915
|
}
|
|
66750
66916
|
await runtime.innerCtx.__closeGeneration();
|
|
66751
|
-
runtime.captureStageSessionMeta();
|
|
66917
|
+
await runtime.captureStageSessionMeta({ awaitDurable: true });
|
|
66752
66918
|
runtime.applyModelFallbackMeta(runtime.innerCtx.__modelFallbackMeta());
|
|
66753
66919
|
if (trackStageLifecycle && runtime.stageFailFastScope?.failed === true && runtime.stageFailFastScope.activeStages.has(runtime.stageId)) {
|
|
66754
66920
|
runtime.markSkippedForParallelFailFast();
|
|
@@ -66758,6 +66924,7 @@ function createTrackedStageCaller(input) {
|
|
|
66758
66924
|
throw runtime.parallelFailFastError();
|
|
66759
66925
|
if (trackStageLifecycle) {
|
|
66760
66926
|
const assistantText = runtime.innerCtx.__getLastAssistantText();
|
|
66927
|
+
terminalStateIsSuccess = true;
|
|
66761
66928
|
applyTerminalStageState = () => {
|
|
66762
66929
|
runtime.stageSnapshot.status = "completed";
|
|
66763
66930
|
if (assistantText !== undefined)
|
|
@@ -66782,15 +66949,30 @@ function createTrackedStageCaller(input) {
|
|
|
66782
66949
|
}
|
|
66783
66950
|
throw err;
|
|
66784
66951
|
} finally {
|
|
66785
|
-
runtime.mcpScope.clear();
|
|
66786
66952
|
let finalizationError;
|
|
66953
|
+
let durableCheckpointError;
|
|
66787
66954
|
try {
|
|
66788
|
-
|
|
66789
|
-
runtime.captureStageSessionMeta();
|
|
66955
|
+
runtime.mcpScope.clear();
|
|
66790
66956
|
} catch (err) {
|
|
66791
66957
|
finalizationError = { thrown: true, error: err };
|
|
66792
66958
|
}
|
|
66959
|
+
try {
|
|
66960
|
+
await runtime.drainStageSessionHeartbeat();
|
|
66961
|
+
} catch (err) {
|
|
66962
|
+
durableCheckpointError = { thrown: true, error: err };
|
|
66963
|
+
}
|
|
66964
|
+
try {
|
|
66965
|
+
await runtime.innerCtx.__closeGeneration();
|
|
66966
|
+
await runtime.captureStageSessionMeta({ awaitDurable: true });
|
|
66967
|
+
} catch (err) {
|
|
66968
|
+
durableCheckpointError ??= { thrown: true, error: err };
|
|
66969
|
+
}
|
|
66970
|
+
finalizationError ??= durableCheckpointError;
|
|
66793
66971
|
if (trackStageLifecycle) {
|
|
66972
|
+
if (durableCheckpointError !== undefined && terminalStateIsSuccess) {
|
|
66973
|
+
const failure3 = runtime.classifyExecutorFailure(durableCheckpointError.error);
|
|
66974
|
+
applyTerminalStageState = () => applyFailureToStage(runtime.stageSnapshot, failure3);
|
|
66975
|
+
}
|
|
66794
66976
|
if (!runtime.state.stageFinalized)
|
|
66795
66977
|
applyTerminalStageState?.();
|
|
66796
66978
|
try {
|
|
@@ -67027,7 +67209,7 @@ function createStageControlHandle(runtime) {
|
|
|
67027
67209
|
if (sessionFile === undefined)
|
|
67028
67210
|
return;
|
|
67029
67211
|
await runtime.innerCtx.__ensureSessionFromFile(sessionFile);
|
|
67030
|
-
runtime.captureStageSessionMeta();
|
|
67212
|
+
await runtime.captureStageSessionMeta({ awaitDurable: true });
|
|
67031
67213
|
};
|
|
67032
67214
|
const toolExecutions = new StageToolExecutionBuffer;
|
|
67033
67215
|
const queuedUserMessages = new StageQueuedUserMessageBuffer;
|
|
@@ -67071,7 +67253,7 @@ function createStageControlHandle(runtime) {
|
|
|
67071
67253
|
await ensureMessagingSession();
|
|
67072
67254
|
await runtime.innerCtx.__ensureSession();
|
|
67073
67255
|
runtime.throwIfStageMutationBlocked();
|
|
67074
|
-
runtime.captureStageSessionMeta();
|
|
67256
|
+
await runtime.captureStageSessionMeta({ awaitDurable: true });
|
|
67075
67257
|
},
|
|
67076
67258
|
async sendUserMessage(text, options, beforeDelivery) {
|
|
67077
67259
|
runtime.throwIfStageMutationBlocked();
|
|
@@ -68229,6 +68411,28 @@ function terminatingToolCallId(event) {
|
|
|
68229
68411
|
}
|
|
68230
68412
|
|
|
68231
68413
|
// dist/builtin/workflows/src/runs/foreground/stage-runner-controller.ts
|
|
68414
|
+
function hasMeaningfulUsage(usage) {
|
|
68415
|
+
if (usage === undefined)
|
|
68416
|
+
return false;
|
|
68417
|
+
const values = [usage.input, usage.output, usage.cacheRead, usage.cacheWrite, usage.totalTokens, usage.cost.total];
|
|
68418
|
+
return values.every((value2) => Number.isFinite(value2) && value2 >= 0) && values.some((value2) => value2 > 0);
|
|
68419
|
+
}
|
|
68420
|
+
function usageForAttempt(messages, start, discarded) {
|
|
68421
|
+
const totals = { ...discarded };
|
|
68422
|
+
let meaningful = totals.turns > 0;
|
|
68423
|
+
for (const message of messages.slice(start)) {
|
|
68424
|
+
if (message.role !== "assistant" || !hasMeaningfulUsage(message.usage))
|
|
68425
|
+
continue;
|
|
68426
|
+
totals.input += message.usage.input;
|
|
68427
|
+
totals.output += message.usage.output;
|
|
68428
|
+
totals.cacheRead += message.usage.cacheRead;
|
|
68429
|
+
totals.cacheWrite += message.usage.cacheWrite;
|
|
68430
|
+
totals.cost += message.usage.cost.total;
|
|
68431
|
+
totals.turns += 1;
|
|
68432
|
+
meaningful = true;
|
|
68433
|
+
}
|
|
68434
|
+
return meaningful ? totals : undefined;
|
|
68435
|
+
}
|
|
68232
68436
|
function isSessionCreationPauseResult(value2) {
|
|
68233
68437
|
return "kind" in value2 && value2.kind === "paused";
|
|
68234
68438
|
}
|
|
@@ -68291,6 +68495,15 @@ class StageSessionController {
|
|
|
68291
68495
|
sessionPromise;
|
|
68292
68496
|
reattachSessionFile;
|
|
68293
68497
|
lastPromptStartIndex;
|
|
68498
|
+
attemptUsageStartIndex;
|
|
68499
|
+
discardedAttemptUsage = {
|
|
68500
|
+
input: 0,
|
|
68501
|
+
output: 0,
|
|
68502
|
+
cacheRead: 0,
|
|
68503
|
+
cacheWrite: 0,
|
|
68504
|
+
cost: 0,
|
|
68505
|
+
turns: 0
|
|
68506
|
+
};
|
|
68294
68507
|
terminatingToolCallIds = new Set;
|
|
68295
68508
|
latestStructuredOutputToolErrorValue;
|
|
68296
68509
|
unsubscribeTerminateWatcher;
|
|
@@ -68490,6 +68703,7 @@ class StageSessionController {
|
|
|
68490
68703
|
this.activeCandidateIndex = index;
|
|
68491
68704
|
this.selectedModel = candidate.id;
|
|
68492
68705
|
this.notifyModelFallbackMetaChange();
|
|
68706
|
+
this.beginAttemptUsage(activeSession);
|
|
68493
68707
|
const { terminalScanStartIndex } = await this.promptWithThrownErrorRetry(activeSession, promptText, sdkOptions);
|
|
68494
68708
|
const terminalFailure = latestTerminalAssistantFailureSince(activeSession.messages, terminalScanStartIndex);
|
|
68495
68709
|
if (terminalFailure !== undefined) {
|
|
@@ -68628,9 +68842,38 @@ class StageSessionController {
|
|
|
68628
68842
|
}
|
|
68629
68843
|
return;
|
|
68630
68844
|
}
|
|
68845
|
+
beginAttemptUsage(session) {
|
|
68846
|
+
this.attemptUsageStartIndex = session.messages.length;
|
|
68847
|
+
this.discardedAttemptUsage = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: 0, turns: 0 };
|
|
68848
|
+
}
|
|
68849
|
+
takeAttemptUsage(session) {
|
|
68850
|
+
const start = this.attemptUsageStartIndex;
|
|
68851
|
+
const usage = session === undefined || start === undefined ? undefined : usageForAttempt(session.messages, start, this.discardedAttemptUsage);
|
|
68852
|
+
this.clearAttemptUsage();
|
|
68853
|
+
return usage;
|
|
68854
|
+
}
|
|
68855
|
+
clearAttemptUsage() {
|
|
68856
|
+
this.attemptUsageStartIndex = undefined;
|
|
68857
|
+
this.discardedAttemptUsage = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: 0, turns: 0 };
|
|
68858
|
+
}
|
|
68859
|
+
accrueDiscardedAttemptUsage(message) {
|
|
68860
|
+
if (!hasMeaningfulUsage(message.usage))
|
|
68861
|
+
return;
|
|
68862
|
+
this.discardedAttemptUsage.input += message.usage.input;
|
|
68863
|
+
this.discardedAttemptUsage.output += message.usage.output;
|
|
68864
|
+
this.discardedAttemptUsage.cacheRead += message.usage.cacheRead;
|
|
68865
|
+
this.discardedAttemptUsage.cacheWrite += message.usage.cacheWrite;
|
|
68866
|
+
this.discardedAttemptUsage.cost += message.usage.cost.total;
|
|
68867
|
+
this.discardedAttemptUsage.turns += 1;
|
|
68868
|
+
}
|
|
68631
68869
|
restoreSessionMessages(session, snapshot, promptText, keepPrompt) {
|
|
68632
68870
|
const snapshotMessages = new Set(snapshot);
|
|
68633
68871
|
const admitted = session.messages.filter((message) => !snapshotMessages.has(message));
|
|
68872
|
+
for (const message of admitted) {
|
|
68873
|
+
if (message.role !== "assistant" || message.stopReason !== "error")
|
|
68874
|
+
continue;
|
|
68875
|
+
this.accrueDiscardedAttemptUsage(message);
|
|
68876
|
+
}
|
|
68634
68877
|
const failedAssistantIndex = admitted.findLastIndex((message) => message.role === "assistant" && message.stopReason === "error");
|
|
68635
68878
|
const promptUser = admitted.slice(0, failedAssistantIndex < 0 ? admitted.length : failedAssistantIndex).findLast((message) => message.role === "user" && stageUserMessageText(message) === promptText);
|
|
68636
68879
|
const retainedMessages = admitted.filter((message) => {
|
|
@@ -68979,7 +69222,11 @@ class StageSessionController {
|
|
|
68979
69222
|
throw new Error(`atomic-workflows: stage "${this.opts.stageName}" session has been disposed`);
|
|
68980
69223
|
throw this.staleCreationReason(startGeneration);
|
|
68981
69224
|
}
|
|
68982
|
-
|
|
69225
|
+
const session = attachCreatedStageSession(created, this.disposed, this.opts.stageName, (result) => this.attachSession(result));
|
|
69226
|
+
if (session instanceof Promise)
|
|
69227
|
+
return await session;
|
|
69228
|
+
await this.opts.onSessionReady?.();
|
|
69229
|
+
return session;
|
|
68983
69230
|
}
|
|
68984
69231
|
attachSession(created) {
|
|
68985
69232
|
const result = normalizeSessionCreateResult(created);
|
|
@@ -69087,11 +69334,17 @@ class StageSessionController {
|
|
|
69087
69334
|
const resumedSession = this.session;
|
|
69088
69335
|
const resumedLabel = this.selectedModel ?? workflowModelId(resumedSession.model) ?? candidates[0].id;
|
|
69089
69336
|
this.notifyModelFallbackMetaChange();
|
|
69337
|
+
this.beginAttemptUsage(resumedSession);
|
|
69090
69338
|
try {
|
|
69091
69339
|
const { terminalScanStartIndex } = await this.promptWithThrownErrorRetry(resumedSession, text, sdkOptions);
|
|
69092
69340
|
const terminalFailure = latestTerminalAssistantFailureSince(resumedSession.messages, terminalScanStartIndex);
|
|
69093
69341
|
if (terminalFailure === undefined || this.capturedStructuredOutputForAttempt()) {
|
|
69094
|
-
this.
|
|
69342
|
+
const usage = this.takeAttemptUsage(resumedSession);
|
|
69343
|
+
this.modelAttempts.push({
|
|
69344
|
+
model: resumedLabel,
|
|
69345
|
+
success: true,
|
|
69346
|
+
...usage === undefined ? {} : { usage }
|
|
69347
|
+
});
|
|
69095
69348
|
this.pendingFallbackWarnings.length = 0;
|
|
69096
69349
|
this.resumeCurrentSession = true;
|
|
69097
69350
|
return true;
|
|
@@ -69099,13 +69352,24 @@ class StageSessionController {
|
|
|
69099
69352
|
throw new WorkflowPromptModelFailure(terminalFailure);
|
|
69100
69353
|
} catch (err) {
|
|
69101
69354
|
if (this.capturedStructuredOutputForAttempt() && isRetryableModelFailure(err)) {
|
|
69102
|
-
this.
|
|
69355
|
+
const usage2 = this.takeAttemptUsage(resumedSession);
|
|
69356
|
+
this.modelAttempts.push({
|
|
69357
|
+
model: resumedLabel,
|
|
69358
|
+
success: true,
|
|
69359
|
+
...usage2 === undefined ? {} : { usage: usage2 }
|
|
69360
|
+
});
|
|
69103
69361
|
this.pendingFallbackWarnings.length = 0;
|
|
69104
69362
|
this.resumeCurrentSession = true;
|
|
69105
69363
|
return true;
|
|
69106
69364
|
}
|
|
69107
69365
|
const message = errorMessage3(err);
|
|
69108
|
-
this.
|
|
69366
|
+
const usage = this.takeAttemptUsage(resumedSession);
|
|
69367
|
+
this.modelAttempts.push({
|
|
69368
|
+
model: resumedLabel,
|
|
69369
|
+
success: false,
|
|
69370
|
+
...usage === undefined ? {} : { usage },
|
|
69371
|
+
error: message
|
|
69372
|
+
});
|
|
69109
69373
|
if (this.opts.signal?.aborted || !isRetryableModelFailure(err)) {
|
|
69110
69374
|
this.modelWarnings.push(...this.pendingFallbackWarnings);
|
|
69111
69375
|
this.pendingFallbackWarnings.length = 0;
|
|
@@ -69131,10 +69395,12 @@ class StageSessionController {
|
|
|
69131
69395
|
this.recordSuccessfulAttempt(candidate);
|
|
69132
69396
|
return "handled";
|
|
69133
69397
|
}
|
|
69398
|
+
const usage = this.takeAttemptUsage(this.session);
|
|
69134
69399
|
this.modelAttempts.push({
|
|
69135
69400
|
model: candidate.id,
|
|
69136
69401
|
success: false,
|
|
69137
69402
|
...modelAttemptReasoning(candidate, this.effectiveStageOptions?.thinkingLevel),
|
|
69403
|
+
...usage === undefined ? {} : { usage },
|
|
69138
69404
|
error: message
|
|
69139
69405
|
});
|
|
69140
69406
|
if (this.opts.signal?.aborted || !isRetryableModelFailure(err) || index === candidates.length - 1) {
|
|
@@ -69152,10 +69418,12 @@ class StageSessionController {
|
|
|
69152
69418
|
return this.structuredOutputCapture?.called === true && this.opts.signal?.aborted !== true;
|
|
69153
69419
|
}
|
|
69154
69420
|
recordSuccessfulAttempt(candidate) {
|
|
69421
|
+
const usage = this.takeAttemptUsage(this.session);
|
|
69155
69422
|
this.modelAttempts.push({
|
|
69156
69423
|
model: candidate.id,
|
|
69157
69424
|
success: true,
|
|
69158
|
-
...modelAttemptReasoning(candidate, this.effectiveStageOptions?.thinkingLevel)
|
|
69425
|
+
...modelAttemptReasoning(candidate, this.effectiveStageOptions?.thinkingLevel),
|
|
69426
|
+
...usage === undefined ? {} : { usage }
|
|
69159
69427
|
});
|
|
69160
69428
|
this.pendingFallbackWarnings.length = 0;
|
|
69161
69429
|
this.resumeCurrentSession = true;
|
|
@@ -69592,6 +69860,81 @@ function createStageContext2(opts) {
|
|
|
69592
69860
|
}
|
|
69593
69861
|
};
|
|
69594
69862
|
}
|
|
69863
|
+
// dist/builtin/workflows/src/runs/foreground/stage-session-heartbeat.ts
|
|
69864
|
+
var STAGE_SESSION_HEARTBEAT_INTERVAL_MS = 30000;
|
|
69865
|
+
function createStageSessionHeartbeat(checkpoint, intervalMs = STAGE_SESSION_HEARTBEAT_INTERVAL_MS) {
|
|
69866
|
+
let active2 = false;
|
|
69867
|
+
let timer;
|
|
69868
|
+
let generation = 0;
|
|
69869
|
+
let nextDeadline = 0;
|
|
69870
|
+
let failure3;
|
|
69871
|
+
let inFlight;
|
|
69872
|
+
let rejectFailure;
|
|
69873
|
+
const failureSignal = new Promise((_resolve, reject) => {
|
|
69874
|
+
rejectFailure = reject;
|
|
69875
|
+
});
|
|
69876
|
+
failureSignal.catch(() => {
|
|
69877
|
+
return;
|
|
69878
|
+
});
|
|
69879
|
+
const stopScheduling = () => {
|
|
69880
|
+
active2 = false;
|
|
69881
|
+
generation += 1;
|
|
69882
|
+
if (timer !== undefined)
|
|
69883
|
+
clearTimeout(timer);
|
|
69884
|
+
timer = undefined;
|
|
69885
|
+
};
|
|
69886
|
+
const fail = (error) => {
|
|
69887
|
+
if (failure3 !== undefined)
|
|
69888
|
+
return;
|
|
69889
|
+
failure3 = error;
|
|
69890
|
+
stopScheduling();
|
|
69891
|
+
rejectFailure(error);
|
|
69892
|
+
};
|
|
69893
|
+
const schedule = (scheduledGeneration) => {
|
|
69894
|
+
if (!active2 || failure3 !== undefined || scheduledGeneration !== generation)
|
|
69895
|
+
return;
|
|
69896
|
+
const delayMs = Math.max(0, nextDeadline - Date.now());
|
|
69897
|
+
timer = setTimeout(() => {
|
|
69898
|
+
timer = undefined;
|
|
69899
|
+
const startedAt = Date.now();
|
|
69900
|
+
do
|
|
69901
|
+
nextDeadline += intervalMs;
|
|
69902
|
+
while (nextDeadline <= startedAt);
|
|
69903
|
+
const running = checkpoint().catch(fail).finally(() => {
|
|
69904
|
+
if (inFlight === running)
|
|
69905
|
+
inFlight = undefined;
|
|
69906
|
+
schedule(scheduledGeneration);
|
|
69907
|
+
});
|
|
69908
|
+
inFlight = running;
|
|
69909
|
+
}, delayMs);
|
|
69910
|
+
timer.unref?.();
|
|
69911
|
+
};
|
|
69912
|
+
const drain = async () => {
|
|
69913
|
+
stopScheduling();
|
|
69914
|
+
await inFlight;
|
|
69915
|
+
if (failure3 !== undefined)
|
|
69916
|
+
throw failure3;
|
|
69917
|
+
};
|
|
69918
|
+
return {
|
|
69919
|
+
start() {
|
|
69920
|
+
if (active2 || failure3 !== undefined)
|
|
69921
|
+
return;
|
|
69922
|
+
active2 = true;
|
|
69923
|
+
generation += 1;
|
|
69924
|
+
nextDeadline = Date.now() + intervalMs;
|
|
69925
|
+
schedule(generation);
|
|
69926
|
+
},
|
|
69927
|
+
stop: stopScheduling,
|
|
69928
|
+
drain,
|
|
69929
|
+
fail,
|
|
69930
|
+
race(work) {
|
|
69931
|
+
if (failure3 !== undefined)
|
|
69932
|
+
return Promise.reject(failure3);
|
|
69933
|
+
return Promise.race([work, failureSignal]);
|
|
69934
|
+
}
|
|
69935
|
+
};
|
|
69936
|
+
}
|
|
69937
|
+
|
|
69595
69938
|
// dist/builtin/workflows/src/runs/foreground/executor-stage-factory.ts
|
|
69596
69939
|
function createWorkflowStageFactory(input) {
|
|
69597
69940
|
return (name, options, stageFailFastScope) => {
|
|
@@ -69672,6 +70015,15 @@ function createWorkflowStageFactory(input) {
|
|
|
69672
70015
|
if (meta2.modelAttempts !== undefined)
|
|
69673
70016
|
stageSnapshot.modelAttempts = meta2.modelAttempts;
|
|
69674
70017
|
};
|
|
70018
|
+
let runtime;
|
|
70019
|
+
const stageSessionHeartbeat = createStageSessionHeartbeat(async () => {
|
|
70020
|
+
try {
|
|
70021
|
+
await runtime.captureStageSessionMeta({ awaitDurable: true });
|
|
70022
|
+
} catch (error) {
|
|
70023
|
+
await runtime.innerCtx.abort().catch(() => {});
|
|
70024
|
+
throw error;
|
|
70025
|
+
}
|
|
70026
|
+
});
|
|
69675
70027
|
const innerCtx = createStageContext2({
|
|
69676
70028
|
stageId,
|
|
69677
70029
|
stageName: name,
|
|
@@ -69687,6 +70039,12 @@ function createWorkflowStageFactory(input) {
|
|
|
69687
70039
|
applyModelFallbackMeta(meta2);
|
|
69688
70040
|
if (stageSnapshot.status === "running")
|
|
69689
70041
|
input.activeStore.recordStageStart(input.runId, stageSnapshot);
|
|
70042
|
+
},
|
|
70043
|
+
async onSessionReady() {
|
|
70044
|
+
if (stageSnapshot.status !== "running")
|
|
70045
|
+
return;
|
|
70046
|
+
await runtime.captureStageSessionMeta({ awaitDurable: true });
|
|
70047
|
+
runtime.startStageSessionHeartbeat();
|
|
69690
70048
|
}
|
|
69691
70049
|
});
|
|
69692
70050
|
const state2 = {
|
|
@@ -69749,8 +70107,7 @@ function createWorkflowStageFactory(input) {
|
|
|
69749
70107
|
stageUiBroker.clearStagePrompt(input.runId, stageId);
|
|
69750
70108
|
await innerCtx.__dispose();
|
|
69751
70109
|
};
|
|
69752
|
-
|
|
69753
|
-
const captureStageSessionMeta = (checkpointOptions) => {
|
|
70110
|
+
const captureStageSessionMeta = async (checkpointOptions) => {
|
|
69754
70111
|
const meta2 = innerCtx.__sessionMeta();
|
|
69755
70112
|
if (meta2.sessionId !== undefined)
|
|
69756
70113
|
stageSnapshot.sessionId = meta2.sessionId;
|
|
@@ -69759,15 +70116,17 @@ function createWorkflowStageFactory(input) {
|
|
|
69759
70116
|
if (meta2.sessionId !== undefined || meta2.sessionFile !== undefined)
|
|
69760
70117
|
input.activeStore.recordStageSession(input.runId, stageId, meta2);
|
|
69761
70118
|
const pending = input.opts.onStageSession?.(input.runId, stageSnapshot, checkpointOptions);
|
|
69762
|
-
if (checkpointOptions?.forceDurable === true)
|
|
69763
|
-
|
|
70119
|
+
if (checkpointOptions?.forceDurable === true || checkpointOptions?.awaitDurable === true) {
|
|
70120
|
+
await pending;
|
|
70121
|
+
return;
|
|
70122
|
+
}
|
|
69764
70123
|
Promise.resolve(pending).catch(() => {});
|
|
69765
|
-
return;
|
|
69766
70124
|
};
|
|
69767
70125
|
const releaseLiveHandle = async () => {
|
|
69768
70126
|
if (state2.liveHandleReleased)
|
|
69769
70127
|
return;
|
|
69770
70128
|
state2.liveHandleReleased = true;
|
|
70129
|
+
stageSessionHeartbeat.stop();
|
|
69771
70130
|
runtime.dropStageControlHandle();
|
|
69772
70131
|
runtime.unregisterStageHandle();
|
|
69773
70132
|
await disposeInnerContext();
|
|
@@ -69800,6 +70159,7 @@ function createWorkflowStageFactory(input) {
|
|
|
69800
70159
|
});
|
|
69801
70160
|
};
|
|
69802
70161
|
const finalizeStageSnapshot = async () => {
|
|
70162
|
+
stageSessionHeartbeat.stop();
|
|
69803
70163
|
if (state2.stageFinalized)
|
|
69804
70164
|
return false;
|
|
69805
70165
|
if (stageSnapshot.endedAt !== undefined && isTerminalStage(stageSnapshot)) {
|
|
@@ -69872,6 +70232,9 @@ function createWorkflowStageFactory(input) {
|
|
|
69872
70232
|
dropStageControlHandle: () => {},
|
|
69873
70233
|
unregisterWorkflowExitCleanup: () => {},
|
|
69874
70234
|
captureStageSessionMeta,
|
|
70235
|
+
startStageSessionHeartbeat: stageSessionHeartbeat.start,
|
|
70236
|
+
drainStageSessionHeartbeat: stageSessionHeartbeat.drain,
|
|
70237
|
+
raceStageSessionHeartbeat: stageSessionHeartbeat.race,
|
|
69875
70238
|
applyModelFallbackMeta,
|
|
69876
70239
|
appendStageStartOnce,
|
|
69877
70240
|
finalizeStageSnapshot,
|
|
@@ -70024,9 +70387,22 @@ class EngineRuntime {
|
|
|
70024
70387
|
apply: () => {
|
|
70025
70388
|
if (!this.childRunOptions.mcp || !hasScope)
|
|
70026
70389
|
return;
|
|
70027
|
-
if (depth
|
|
70390
|
+
if (depth > 0) {
|
|
70391
|
+
depth += 1;
|
|
70392
|
+
return;
|
|
70393
|
+
}
|
|
70394
|
+
depth = 1;
|
|
70395
|
+
try {
|
|
70028
70396
|
this.childRunOptions.mcp.setScope(stageId, allow, deny);
|
|
70029
|
-
|
|
70397
|
+
} catch (error) {
|
|
70398
|
+
depth = 0;
|
|
70399
|
+
try {
|
|
70400
|
+
this.childRunOptions.mcp.clearScope(stageId);
|
|
70401
|
+
} catch (cleanupError) {
|
|
70402
|
+
throw new AggregateError([error, cleanupError], "MCP scope setup failed and compensating cleanup failed");
|
|
70403
|
+
}
|
|
70404
|
+
throw error;
|
|
70405
|
+
}
|
|
70030
70406
|
},
|
|
70031
70407
|
clear: () => {
|
|
70032
70408
|
if (!this.childRunOptions.mcp || !hasScope)
|
|
@@ -71369,6 +71745,72 @@ function disposeCompletedChatHandle(handle) {
|
|
|
71369
71745
|
});
|
|
71370
71746
|
}
|
|
71371
71747
|
|
|
71748
|
+
// dist/builtin/workflows/src/durable/targeted-inspection.ts
|
|
71749
|
+
async function inspectTargetedDurableWorkflow(backend, workflowId, now = Date.now()) {
|
|
71750
|
+
const hydrated = backend.hydrateWorkflowForInspection ? await backend.hydrateWorkflowForInspection(workflowId) : await hydrateWithoutClassification(backend, workflowId);
|
|
71751
|
+
if (hydrated.kind !== "current")
|
|
71752
|
+
return hydrationFailure(workflowId, hydrated.kind);
|
|
71753
|
+
const handle = hydrated.handle;
|
|
71754
|
+
if (handle.rootWorkflowId !== undefined && handle.rootWorkflowId !== handle.workflowId) {
|
|
71755
|
+
return malformed(workflowId, "the requested id belongs to a nested workflow rather than a durable root");
|
|
71756
|
+
}
|
|
71757
|
+
const reconstructed = durableWorkflowRunSnapshots(backend, handle);
|
|
71758
|
+
if (reconstructed.length === 0)
|
|
71759
|
+
return malformed(workflowId, "durable checkpoint topology is malformed or incomplete");
|
|
71760
|
+
const runs = structuredClone(reconstructed);
|
|
71761
|
+
const inspectionStore = createStore();
|
|
71762
|
+
for (const run2 of runs)
|
|
71763
|
+
inspectionStore.recordRunStart(structuredClone(run2));
|
|
71764
|
+
const inspected = inspectRun(workflowId, { store: inspectionStore });
|
|
71765
|
+
if (!inspected.ok)
|
|
71766
|
+
return malformed(workflowId, "the durable checkpoint graph has no reciprocal root");
|
|
71767
|
+
const foreignLive = isForeignLiveWorkflow(handle, getAtomicExecutorId(), now);
|
|
71768
|
+
const live = isLiveRunningWorkflow(handle, now);
|
|
71769
|
+
const crashed = handle.status === "running" && !live;
|
|
71770
|
+
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);
|
|
71771
|
+
return {
|
|
71772
|
+
kind: "found",
|
|
71773
|
+
runs,
|
|
71774
|
+
store: inspectionStore,
|
|
71775
|
+
detail: {
|
|
71776
|
+
...inspected.detail,
|
|
71777
|
+
...crashed ? { status: "crashed" } : {},
|
|
71778
|
+
...live ? { resumable: false } : {},
|
|
71779
|
+
...foreignLive ? { ownerActiveElsewhere: true } : {},
|
|
71780
|
+
resumeGuidance
|
|
71781
|
+
}
|
|
71782
|
+
};
|
|
71783
|
+
}
|
|
71784
|
+
function terminalGuidance(status, workflowId, resumable) {
|
|
71785
|
+
if (resumable)
|
|
71786
|
+
return `This retained workflow is ${status} and resumable. Resume it explicitly with /workflow resume ${workflowId}.`;
|
|
71787
|
+
return `This retained workflow is ${status} and available for read-only inspection.`;
|
|
71788
|
+
}
|
|
71789
|
+
async function hydrateWithoutClassification(backend, workflowId) {
|
|
71790
|
+
await backend.hydrateWorkflow(workflowId);
|
|
71791
|
+
const handle = backend.getLoadableWorkflow(workflowId);
|
|
71792
|
+
return handle === undefined ? { kind: "absent" } : { kind: "current", handle };
|
|
71793
|
+
}
|
|
71794
|
+
function hydrationFailure(workflowId, kind) {
|
|
71795
|
+
switch (kind) {
|
|
71796
|
+
case "absent":
|
|
71797
|
+
return {
|
|
71798
|
+
kind,
|
|
71799
|
+
message: `Run not found: ${workflowId} (not present in the current session or durable store).`
|
|
71800
|
+
};
|
|
71801
|
+
case "deleted":
|
|
71802
|
+
return { kind, message: `Durable workflow was deleted: ${workflowId}` };
|
|
71803
|
+
case "malformed":
|
|
71804
|
+
return malformed(workflowId, "current DBOS metadata or checkpoints are malformed");
|
|
71805
|
+
}
|
|
71806
|
+
}
|
|
71807
|
+
function malformed(workflowId, reason) {
|
|
71808
|
+
return {
|
|
71809
|
+
kind: "malformed",
|
|
71810
|
+
message: `Durable workflow ${workflowId} cannot be inspected safely: ${reason}.`
|
|
71811
|
+
};
|
|
71812
|
+
}
|
|
71813
|
+
|
|
71372
71814
|
// dist/builtin/workflows/src/extension/runtime-durable-resume.ts
|
|
71373
71815
|
function createDurableResumeRuntime(deps) {
|
|
71374
71816
|
const hydrateStoredWorkflowCandidates = async (backend, target) => {
|
|
@@ -71378,6 +71820,10 @@ function createDurableResumeRuntime(deps) {
|
|
|
71378
71820
|
};
|
|
71379
71821
|
let preparedCatalog = [];
|
|
71380
71822
|
return {
|
|
71823
|
+
async inspectDurableWorkflow(workflowId) {
|
|
71824
|
+
await deps.ensureReady();
|
|
71825
|
+
return await inspectTargetedDurableWorkflow(getDurableBackend(), workflowId);
|
|
71826
|
+
},
|
|
71381
71827
|
async resumeDurableWorkflow(workflowId, options) {
|
|
71382
71828
|
await deps.ensureReady();
|
|
71383
71829
|
const backend = getDurableBackend();
|
|
@@ -72052,6 +72498,9 @@ function createWorkflowExtensionRuntimeState(pi, adapters, resolveCwd = () => pi
|
|
|
72052
72498
|
resumeDurableWorkflow(workflowId, options) {
|
|
72053
72499
|
return runtimeRef.current.resumeDurableWorkflow(workflowId, options);
|
|
72054
72500
|
},
|
|
72501
|
+
inspectDurableWorkflow(workflowId) {
|
|
72502
|
+
return runtimeRef.current.inspectDurableWorkflow(workflowId);
|
|
72503
|
+
},
|
|
72055
72504
|
listDurableResumable() {
|
|
72056
72505
|
return runtimeRef.current.listDurableResumable();
|
|
72057
72506
|
},
|
|
@@ -73721,6 +74170,7 @@ function toPickerRow(session) {
|
|
|
73721
74170
|
modifiedAt: session.modified.getTime(),
|
|
73722
74171
|
messageCount: session.messageCount,
|
|
73723
74172
|
firstMessage: session.firstMessage,
|
|
74173
|
+
...session.summary !== undefined ? { summary: session.summary } : {},
|
|
73724
74174
|
allMessagesText: session.allMessagesText,
|
|
73725
74175
|
...session.name !== undefined ? { name: session.name } : {},
|
|
73726
74176
|
...session.messageColor !== undefined ? { messageColor: session.messageColor } : {}
|
|
@@ -74570,8 +75020,13 @@ Available: ${formatAvailableWorkflowNames(deps.runtimeProxy.registry.names())}`)
|
|
|
74570
75020
|
const resolved = resolveRunId(target);
|
|
74571
75021
|
if (resolved.kind === "malformed")
|
|
74572
75022
|
return fail(resolved.message);
|
|
74573
|
-
if (resolved.kind === "not_found")
|
|
74574
|
-
|
|
75023
|
+
if (resolved.kind === "not_found") {
|
|
75024
|
+
const durable = await deps.runtimeForContext(ctx).inspectDurableWorkflow(target);
|
|
75025
|
+
if (durable.kind !== "found")
|
|
75026
|
+
return fail(durable.message);
|
|
75027
|
+
emitChatSurface(pi, { kind: "detail", detail: durable.detail });
|
|
75028
|
+
return;
|
|
75029
|
+
}
|
|
74575
75030
|
const inspected = inspectRun(resolved.runId);
|
|
74576
75031
|
if (!inspected.ok)
|
|
74577
75032
|
return fail(`Run not found: ${target}`);
|
|
@@ -75645,8 +76100,9 @@ function snapshotTranscriptEntryCount(snapshot) {
|
|
|
75645
76100
|
}
|
|
75646
76101
|
|
|
75647
76102
|
// dist/builtin/workflows/src/extension/workflow-tool-inspection.ts
|
|
75648
|
-
function workflowStagesResult(args) {
|
|
75649
|
-
const
|
|
76103
|
+
function workflowStagesResult(args, source) {
|
|
76104
|
+
const activeStore = source?.store ?? store;
|
|
76105
|
+
const target = resolveToolRunTarget(args, "No active run to inspect.", activeStore);
|
|
75650
76106
|
const filter = args.statusFilter ?? "all";
|
|
75651
76107
|
if (target.kind === "all") {
|
|
75652
76108
|
return {
|
|
@@ -75666,19 +76122,20 @@ function workflowStagesResult(args) {
|
|
|
75666
76122
|
error: target.message
|
|
75667
76123
|
};
|
|
75668
76124
|
}
|
|
75669
|
-
const
|
|
75670
|
-
const stages =
|
|
76125
|
+
const stageSnapshots = source?.store === undefined ? activeStore.runs().find((run2) => run2.id === target.runId)?.stages ?? [] : expandWorkflowGraph(readGraphStoreSnapshot(activeStore), target.runId).stages;
|
|
76126
|
+
const stages = stageSnapshots.filter((stage) => filter === "all" || stage.status === filter).map(summarizeStage);
|
|
75671
76127
|
return { action: "stages", runId: target.runId, filter, stages };
|
|
75672
76128
|
}
|
|
75673
|
-
function workflowStageResult(args) {
|
|
75674
|
-
const
|
|
76129
|
+
function workflowStageResult(args, source) {
|
|
76130
|
+
const activeStore = source?.store ?? store;
|
|
76131
|
+
const target = resolveToolRunTarget(args, "No active run to inspect.", activeStore);
|
|
75675
76132
|
if (target.kind === "all") {
|
|
75676
76133
|
return { action: "stage", runId: "--all", error: "Stage inspection requires a single run." };
|
|
75677
76134
|
}
|
|
75678
76135
|
if (target.kind === "malformed" || target.kind === "not_found") {
|
|
75679
76136
|
return { action: "stage", runId: target.target, error: target.message };
|
|
75680
76137
|
}
|
|
75681
|
-
const stage = resolveToolStageTarget(target.runId, args.stageId);
|
|
76138
|
+
const stage = resolveToolStageTarget(target.runId, args.stageId, activeStore);
|
|
75682
76139
|
if (!stage.ok || stage.stageId === undefined) {
|
|
75683
76140
|
return {
|
|
75684
76141
|
action: "stage",
|
|
@@ -75687,7 +76144,7 @@ function workflowStageResult(args) {
|
|
|
75687
76144
|
};
|
|
75688
76145
|
}
|
|
75689
76146
|
const stageRunId = stage.runId ?? target.runId;
|
|
75690
|
-
const run2 =
|
|
76147
|
+
const run2 = activeStore.runs().find((r) => r.id === stageRunId);
|
|
75691
76148
|
const snapshot = run2?.stages.find((s) => s.id === stage.stageId);
|
|
75692
76149
|
return snapshot ? { action: "stage", runId: stageRunId, stage: cloneStage(snapshot) } : {
|
|
75693
76150
|
action: "stage",
|
|
@@ -75695,8 +76152,9 @@ function workflowStageResult(args) {
|
|
|
75695
76152
|
error: `Stage not found in run ${stageRunId}: ${stage.stageId}`
|
|
75696
76153
|
};
|
|
75697
76154
|
}
|
|
75698
|
-
function workflowTranscriptResult(args) {
|
|
75699
|
-
const
|
|
76155
|
+
function workflowTranscriptResult(args, source) {
|
|
76156
|
+
const activeStore = source?.store ?? store;
|
|
76157
|
+
const target = resolveToolRunTarget(args, "No active run to inspect.", activeStore);
|
|
75700
76158
|
if (target.kind === "all") {
|
|
75701
76159
|
return {
|
|
75702
76160
|
action: "transcript",
|
|
@@ -75717,7 +76175,7 @@ function workflowTranscriptResult(args) {
|
|
|
75717
76175
|
truncated: false
|
|
75718
76176
|
};
|
|
75719
76177
|
}
|
|
75720
|
-
const stage = resolveToolStageTarget(target.runId, args.stageId);
|
|
76178
|
+
const stage = resolveToolStageTarget(target.runId, args.stageId, activeStore);
|
|
75721
76179
|
if (!stage.ok || stage.stageId === undefined) {
|
|
75722
76180
|
return {
|
|
75723
76181
|
action: "transcript",
|
|
@@ -75729,9 +76187,9 @@ function workflowTranscriptResult(args) {
|
|
|
75729
76187
|
};
|
|
75730
76188
|
}
|
|
75731
76189
|
const stageRunId = stage.runId ?? target.runId;
|
|
75732
|
-
const run2 =
|
|
76190
|
+
const run2 = activeStore.runs().find((r) => r.id === stageRunId);
|
|
75733
76191
|
const snapshot = run2?.stages.find((s) => s.id === stage.stageId);
|
|
75734
|
-
const liveHandle2 = stageControlRegistry.get(stageRunId, stage.stageId);
|
|
76192
|
+
const liveHandle2 = source?.allowLiveHandles === false ? undefined : stageControlRegistry.get(stageRunId, stage.stageId);
|
|
75735
76193
|
if (liveHandle2 !== undefined) {
|
|
75736
76194
|
const sessionFile = liveHandle2.sessionFile ?? snapshot?.sessionFile;
|
|
75737
76195
|
const sessionId = liveHandle2.sessionId ?? snapshot?.sessionId;
|
|
@@ -75791,6 +76249,41 @@ function brokerAnswerFromArgs(args) {
|
|
|
75791
76249
|
const text = textPayloadFromArgs(args);
|
|
75792
76250
|
return text !== undefined ? { text } : {};
|
|
75793
76251
|
}
|
|
76252
|
+
function answersPendingPrompt(delivery, promptId) {
|
|
76253
|
+
return delivery === "answer" || delivery === "auto" || promptId !== undefined;
|
|
76254
|
+
}
|
|
76255
|
+
function answerablePromptIds(stage) {
|
|
76256
|
+
const target = stage.workflowGraphTarget;
|
|
76257
|
+
const ids = [];
|
|
76258
|
+
const brokered = stageUiBroker.peekStagePrompt(target.runId, target.stageId);
|
|
76259
|
+
if (brokered !== undefined)
|
|
76260
|
+
ids.push(brokered.id);
|
|
76261
|
+
if (stage.pendingPrompt !== undefined)
|
|
76262
|
+
ids.push(stage.pendingPrompt.id);
|
|
76263
|
+
if (stage.status === "awaiting_input" && stage.promptFootprint?.kind === "custom") {
|
|
76264
|
+
ids.push(stage.promptFootprint.id);
|
|
76265
|
+
}
|
|
76266
|
+
return ids;
|
|
76267
|
+
}
|
|
76268
|
+
function inferPromptStageTarget(runId, delivery, promptId) {
|
|
76269
|
+
if (!answersPendingPrompt(delivery, promptId))
|
|
76270
|
+
return { ok: true, runId };
|
|
76271
|
+
const pending = expandWorkflowGraph(readGraphStoreSnapshot(store), runId).stages.filter((stage) => {
|
|
76272
|
+
const ids = answerablePromptIds(stage);
|
|
76273
|
+
return promptId === undefined ? ids.length > 0 : ids.includes(promptId);
|
|
76274
|
+
});
|
|
76275
|
+
const only = pending[0];
|
|
76276
|
+
if (pending.length === 1 && only !== undefined) {
|
|
76277
|
+
return { ok: true, runId: only.workflowGraphTarget.runId, stageId: only.workflowGraphTarget.stageId };
|
|
76278
|
+
}
|
|
76279
|
+
if (pending.length === 0) {
|
|
76280
|
+
return promptId === undefined ? { ok: true, runId } : { ok: false, message: `No pending prompt ${promptId} in run ${runId}.` };
|
|
76281
|
+
}
|
|
76282
|
+
return {
|
|
76283
|
+
ok: false,
|
|
76284
|
+
message: `${pending.length} prompts pending; pass stageId: ${pending.map(expandedStageLabel).join(", ")}`
|
|
76285
|
+
};
|
|
76286
|
+
}
|
|
75794
76287
|
function workflowSendResult(runId, stageId, delivery, status, message) {
|
|
75795
76288
|
return { action: "send", runId, stageId, delivery, status, message };
|
|
75796
76289
|
}
|
|
@@ -75851,7 +76344,8 @@ async function workflowSendAction(args, deps = {}) {
|
|
|
75851
76344
|
if (rootRun !== undefined && isTerminalRunStatus(rootRun.status)) {
|
|
75852
76345
|
return terminalWorkflowSendResult(rootRun.id, args.stageId?.trim() ?? "", rootRun.status);
|
|
75853
76346
|
}
|
|
75854
|
-
const
|
|
76347
|
+
const requested = resolveToolStageTarget(target.runId, args.stageId);
|
|
76348
|
+
const stage = requested.ok && requested.stageId === undefined ? inferPromptStageTarget(target.runId, requestedDelivery, args.promptId) : requested;
|
|
75855
76349
|
if (!stage.ok || stage.stageId === undefined) {
|
|
75856
76350
|
return workflowSendResult(target.runId, "", requestedDelivery, "noop", stage.ok ? "Stage id or name is required." : stage.message);
|
|
75857
76351
|
}
|
|
@@ -75992,6 +76486,32 @@ async function workflowSendAction(args, deps = {}) {
|
|
|
75992
76486
|
}
|
|
75993
76487
|
|
|
75994
76488
|
// dist/builtin/workflows/src/extension/workflow-tool.ts
|
|
76489
|
+
async function resolveDurableInspectionSource(args, runtime) {
|
|
76490
|
+
const target = args.runId?.trim();
|
|
76491
|
+
if (args.all === true || target === undefined || target.length === 0 || target === "--all")
|
|
76492
|
+
return { kind: "local" };
|
|
76493
|
+
const local = resolveRunId(target);
|
|
76494
|
+
if (local.kind !== "not_found")
|
|
76495
|
+
return { kind: "local" };
|
|
76496
|
+
const durable = await runtime.inspectDurableWorkflow(target);
|
|
76497
|
+
if (durable.kind !== "found")
|
|
76498
|
+
return { kind: "error", message: durable.message };
|
|
76499
|
+
return { kind: "durable", source: { store: durable.store, allowLiveHandles: false } };
|
|
76500
|
+
}
|
|
76501
|
+
function durableInspectionError(action, runId, message) {
|
|
76502
|
+
if (action === "stages")
|
|
76503
|
+
return { action, runId, filter: "all", stages: [], error: message };
|
|
76504
|
+
if (action === "stage")
|
|
76505
|
+
return { action, runId, error: message };
|
|
76506
|
+
return {
|
|
76507
|
+
action,
|
|
76508
|
+
runId,
|
|
76509
|
+
stageId: "",
|
|
76510
|
+
source: "error",
|
|
76511
|
+
entries: [{ role: "notice", text: message }],
|
|
76512
|
+
truncated: false
|
|
76513
|
+
};
|
|
76514
|
+
}
|
|
75995
76515
|
function makeExecuteWorkflowTool(runtime, reloadWorkflowResources, ensureWorkflowResourcesLoaded = () => {}, sendDeps = {}) {
|
|
75996
76516
|
return async function executeWorkflowTool(args, ctx) {
|
|
75997
76517
|
const action = args.action ?? "run";
|
|
@@ -76047,7 +76567,8 @@ function makeExecuteWorkflowTool(runtime, reloadWorkflowResources, ensureWorkflo
|
|
|
76047
76567
|
return { action: "statusDetail", runId: target, error: resolved.message };
|
|
76048
76568
|
}
|
|
76049
76569
|
if (resolved.kind === "not_found") {
|
|
76050
|
-
|
|
76570
|
+
const durable = await getRuntime().inspectDurableWorkflow(target);
|
|
76571
|
+
return durable.kind === "found" ? { action: "statusDetail", runId: target, detail: durable.detail } : { action: "statusDetail", runId: target, error: durable.message };
|
|
76051
76572
|
}
|
|
76052
76573
|
const result2 = inspectRun(resolved.runId);
|
|
76053
76574
|
return result2.ok ? { action: "statusDetail", runId: result2.runId, detail: result2.detail } : { action: "statusDetail", runId: target, error: `run not found: ${target}` };
|
|
@@ -76063,11 +76584,18 @@ function makeExecuteWorkflowTool(runtime, reloadWorkflowResources, ensureWorkflo
|
|
|
76063
76584
|
return result;
|
|
76064
76585
|
}
|
|
76065
76586
|
case "stages":
|
|
76066
|
-
return workflowStagesResult(args);
|
|
76067
76587
|
case "stage":
|
|
76068
|
-
|
|
76069
|
-
|
|
76070
|
-
|
|
76588
|
+
case "transcript": {
|
|
76589
|
+
const resolved = await resolveDurableInspectionSource(args, getRuntime());
|
|
76590
|
+
if (resolved.kind === "error")
|
|
76591
|
+
return durableInspectionError(action, args.runId ?? "", resolved.message);
|
|
76592
|
+
const source = resolved.kind === "durable" ? resolved.source : undefined;
|
|
76593
|
+
if (action === "stages")
|
|
76594
|
+
return workflowStagesResult(args, source);
|
|
76595
|
+
if (action === "stage")
|
|
76596
|
+
return workflowStageResult(args, source);
|
|
76597
|
+
return workflowTranscriptResult(args, source);
|
|
76598
|
+
}
|
|
76071
76599
|
case "send":
|
|
76072
76600
|
return workflowSendAction(args, sendDeps);
|
|
76073
76601
|
case "pause":
|