@bastani/atomic 0.9.12 → 0.9.13-alpha.1
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 +20 -0
- package/dist/builtin/intercom/CHANGELOG.md +6 -0
- package/dist/builtin/intercom/README.md +5 -12
- package/dist/builtin/intercom/broker/client.ts +11 -2
- package/dist/builtin/intercom/contact-supervisor-tool.ts +13 -3
- package/dist/builtin/intercom/index-heavy.ts +13 -3
- package/dist/builtin/intercom/index.ts +43 -19
- package/dist/builtin/intercom/intercom-utils.ts +15 -29
- package/dist/builtin/intercom/package.json +1 -1
- package/dist/builtin/intercom/source-ownership.ts +9 -12
- package/dist/builtin/mcp/CHANGELOG.md +6 -0
- package/dist/builtin/mcp/README.md +3 -1
- package/dist/builtin/mcp/index.ts +10 -16
- package/dist/builtin/mcp/package.json +1 -1
- package/dist/builtin/mcp/startup-warmup.ts +20 -8
- package/dist/builtin/subagents/CHANGELOG.md +30 -0
- package/dist/builtin/subagents/README.md +22 -30
- package/dist/builtin/subagents/package.json +1 -1
- package/dist/builtin/subagents/src/extension/doctor.ts +1 -1
- package/dist/builtin/subagents/src/extension/fanout-child.ts +76 -56
- package/dist/builtin/subagents/src/extension/index.ts +23 -32
- package/dist/builtin/subagents/src/extension/startup-maintenance.ts +25 -44
- package/dist/builtin/subagents/src/intercom/result-intercom.ts +7 -7
- package/dist/builtin/subagents/src/runs/background/async-job-tracker.ts +166 -434
- package/dist/builtin/subagents/src/runs/background/notify.ts +29 -8
- package/dist/builtin/subagents/src/runs/foreground/chain-execution-dynamic-step.ts +2 -2
- package/dist/builtin/subagents/src/runs/foreground/chain-execution-parallel-runner.ts +4 -4
- package/dist/builtin/subagents/src/runs/foreground/chain-execution-parallel-step.ts +2 -2
- package/dist/builtin/subagents/src/runs/foreground/chain-execution-sequential-step.ts +2 -2
- package/dist/builtin/subagents/src/runs/foreground/execution-run-sync.ts +1 -281
- package/dist/builtin/subagents/src/runs/foreground/execution-structured-retries.ts +11 -75
- package/dist/builtin/subagents/src/runs/foreground/inprocess-run-sync.ts +457 -0
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-async.ts +119 -246
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-chain.ts +1 -1
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-context.ts +18 -9
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-parallel-task.ts +1 -1
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-parallel.ts +4 -4
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-resume.ts +1 -646
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-runtime.ts +2 -7
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-single.ts +5 -5
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-status.ts +7 -8
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-types.ts +14 -5
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor.ts +158 -93
- package/dist/builtin/subagents/src/runs/inprocess/background-single.ts +179 -0
- package/dist/builtin/subagents/src/runs/inprocess/background.ts +89 -0
- package/dist/builtin/subagents/src/runs/inprocess/child-policy.ts +27 -0
- package/dist/builtin/subagents/src/runs/inprocess/control-registry.ts +55 -0
- package/dist/builtin/subagents/src/runs/inprocess/control-status.ts +106 -0
- package/dist/builtin/subagents/src/runs/inprocess/index.ts +50 -0
- package/dist/builtin/subagents/src/runs/inprocess/nested-routing.ts +218 -0
- package/dist/builtin/subagents/src/runs/{shared/subagent-prompt-runtime.ts → inprocess/prompt-behavior.ts} +37 -75
- package/dist/builtin/subagents/src/runs/inprocess/runner.ts +1138 -0
- package/dist/builtin/subagents/src/runs/{shared/nested-events.ts → inprocess/runtime-support/nested-api.ts} +13 -7
- package/dist/builtin/subagents/src/runs/{shared/nested-events-control.ts → inprocess/runtime-support/nested-control.ts} +18 -17
- package/dist/builtin/subagents/src/runs/{shared/nested-events-core.ts → inprocess/runtime-support/nested-core.ts} +14 -61
- package/dist/builtin/subagents/src/runs/{shared/nested-events-projection.ts → inprocess/runtime-support/nested-projection.ts} +4 -10
- package/dist/builtin/subagents/src/runs/{shared/nested-events-registry.ts → inprocess/runtime-support/nested-registry.ts} +19 -4
- package/dist/builtin/subagents/src/runs/{shared/nested-render.ts → inprocess/runtime-support/nested-rendering.ts} +3 -3
- package/dist/builtin/subagents/src/runs/{shared/nested-events-sanitize.ts → inprocess/runtime-support/nested-sanitize.ts} +3 -3
- package/dist/builtin/subagents/src/runs/inprocess.ts +1 -0
- package/dist/builtin/subagents/src/runs/shared/dynamic-fanout.ts +10 -4
- package/dist/builtin/subagents/src/runs/shared/model-candidate-filter.ts +0 -1
- package/dist/builtin/subagents/src/runs/shared/model-fallback.ts +15 -492
- package/dist/builtin/subagents/src/runs/shared/parallel-utils.ts +13 -11
- package/dist/builtin/subagents/src/runs/shared/run-history.ts +3 -5
- package/dist/builtin/subagents/src/runs/shared/single-output.ts +4 -4
- package/dist/builtin/subagents/src/runs/shared/workflow-graph.ts +5 -5
- package/dist/builtin/subagents/src/shared/types-async.ts +0 -1
- package/dist/builtin/subagents/src/shared/types-config.ts +18 -0
- package/dist/builtin/subagents/src/shared/types-results.ts +9 -2
- package/dist/builtin/subagents/src/slash/prompt-template-bridge.ts +2 -3
- package/dist/builtin/subagents/src/slash/slash-live-state.ts +2 -2
- package/dist/builtin/subagents/src/tui/render-chain-graph.ts +10 -4
- package/dist/builtin/subagents/src/tui/render-event-formatting.ts +12 -11
- package/dist/builtin/subagents/src/tui/render-result-compact.ts +49 -12
- package/dist/builtin/subagents/src/tui/render-result.ts +46 -17
- package/dist/builtin/subagents/src/tui/render-stable-output.ts +1 -1
- package/dist/builtin/subagents/src/tui/render-status-progress.ts +8 -5
- package/dist/builtin/subagents/src/tui/render-widget-graph.ts +0 -8
- package/dist/builtin/subagents/src/tui/render-widget.ts +0 -24
- package/dist/builtin/web-access/package.json +1 -1
- package/dist/builtin/workflows/CHANGELOG.md +25 -0
- package/dist/builtin/workflows/README.md +13 -3
- package/dist/builtin/workflows/package.json +1 -1
- package/dist/builtin/workflows/src/durable/backend.ts +7 -0
- package/dist/builtin/workflows/src/durable/dbos-metadata.ts +11 -1
- package/dist/builtin/workflows/src/durable/resume-runtime.ts +1 -0
- package/dist/builtin/workflows/src/durable/tool-primitive.ts +4 -28
- package/dist/builtin/workflows/src/durable/types.ts +5 -0
- package/dist/builtin/workflows/src/engine/run.ts +17 -1
- package/dist/builtin/workflows/src/extension/atomic-stage-session.ts +12 -39
- package/dist/builtin/workflows/src/extension/config-file-loader.ts +10 -1
- package/dist/builtin/workflows/src/extension/config-loader.ts +1 -1
- package/dist/builtin/workflows/src/extension/dispatcher.ts +4 -0
- package/dist/builtin/workflows/src/extension/index.bundle.mjs +1151 -737
- package/dist/builtin/workflows/src/extension/lifecycle-notifications.ts +303 -38
- package/dist/builtin/workflows/src/extension/render-result.ts +4 -0
- package/dist/builtin/workflows/src/extension/runtime-durable-resume.ts +6 -3
- package/dist/builtin/workflows/src/extension/runtime.ts +7 -1
- package/dist/builtin/workflows/src/extension/wiring.ts +53 -11
- package/dist/builtin/workflows/src/extension/workflow-command-registration.ts +12 -3
- package/dist/builtin/workflows/src/extension/workflow-durable-resume-command.ts +5 -2
- package/dist/builtin/workflows/src/extension/workflow-run-control-command.ts +9 -7
- package/dist/builtin/workflows/src/extension/workflow-status-summary.ts +11 -0
- package/dist/builtin/workflows/src/extension/workflow-tool-content.ts +18 -1
- package/dist/builtin/workflows/src/extension/workflow-tool-control.ts +10 -8
- package/dist/builtin/workflows/src/extension/workflow-tool.ts +9 -4
- package/dist/builtin/workflows/src/runs/background/quit.ts +28 -4
- package/dist/builtin/workflows/src/runs/background/resume-acknowledgements.ts +2 -1
- package/dist/builtin/workflows/src/runs/background/status.ts +55 -8
- package/dist/builtin/workflows/src/runs/foreground/executor-direct-helpers.ts +4 -0
- package/dist/builtin/workflows/src/runs/foreground/executor-prompt-nodes.ts +3 -1
- package/dist/builtin/workflows/src/runs/foreground/executor-stage-control.ts +1 -1
- package/dist/builtin/workflows/src/runs/foreground/stage-runner-context.ts +1 -1
- package/dist/builtin/workflows/src/runs/foreground/stage-runner-controller.ts +688 -38
- package/dist/builtin/workflows/src/runs/foreground/stage-runner-types.ts +3 -1
- package/dist/builtin/workflows/src/runs/shared/model-fallback-failures.ts +19 -514
- package/dist/builtin/workflows/src/runs/shared/retry.ts +44 -0
- package/dist/builtin/workflows/src/shared/authoring-contract-stage.d.ts +5 -0
- package/dist/builtin/workflows/src/shared/authoring-contract-stage.ts +6 -0
- package/dist/builtin/workflows/src/shared/authoring-contract-ui.d.ts +5 -1
- package/dist/builtin/workflows/src/shared/authoring-contract-ui.ts +5 -0
- package/dist/builtin/workflows/src/shared/persistence-restore-helpers.ts +5 -0
- package/dist/builtin/workflows/src/shared/persistence-restore.ts +3 -0
- package/dist/builtin/workflows/src/shared/persistence-session-entries.ts +4 -0
- package/dist/builtin/workflows/src/shared/run-indicator-status.ts +75 -0
- package/dist/builtin/workflows/src/shared/store-public-types.ts +43 -7
- package/dist/builtin/workflows/src/shared/store-run-methods.ts +42 -8
- package/dist/builtin/workflows/src/shared/store-stage-methods.ts +31 -8
- package/dist/builtin/workflows/src/shared/store-types.ts +34 -0
- package/dist/builtin/workflows/src/shared/timing.ts +10 -0
- package/dist/builtin/workflows/src/tui/chat-surface-message.ts +22 -2
- package/dist/builtin/workflows/src/tui/session-list.ts +1 -1
- package/dist/builtin/workflows/src/tui/session-overlays.ts +14 -10
- package/dist/builtin/workflows/src/tui/session-picker.ts +20 -4
- package/dist/builtin/workflows/src/tui/status-list.ts +31 -47
- package/dist/builtin/workflows/src/tui/store-widget-installer.ts +9 -1
- package/dist/builtin/workflows/src/tui/widget.ts +16 -46
- package/dist/core/agent-session-auto-compaction.d.ts.map +1 -1
- package/dist/core/agent-session-auto-compaction.js +54 -11
- package/dist/core/agent-session-auto-compaction.js.map +1 -1
- package/dist/core/agent-session-events.d.ts.map +1 -1
- package/dist/core/agent-session-events.js +49 -14
- package/dist/core/agent-session-events.js.map +1 -1
- package/dist/core/agent-session-methods.d.ts +13 -0
- 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-models.d.ts.map +1 -1
- package/dist/core/agent-session-models.js +12 -1
- package/dist/core/agent-session-models.js.map +1 -1
- package/dist/core/agent-session-prompt.d.ts.map +1 -1
- package/dist/core/agent-session-prompt.js +4 -0
- package/dist/core/agent-session-prompt.js.map +1 -1
- package/dist/core/agent-session-retry.d.ts +21 -4
- package/dist/core/agent-session-retry.d.ts.map +1 -1
- package/dist/core/agent-session-retry.js +232 -106
- package/dist/core/agent-session-retry.js.map +1 -1
- package/dist/core/agent-session-state.d.ts.map +1 -1
- package/dist/core/agent-session-state.js +2 -1
- package/dist/core/agent-session-state.js.map +1 -1
- package/dist/core/agent-session-tool-hooks.d.ts.map +1 -1
- package/dist/core/agent-session-tool-hooks.js +12 -0
- package/dist/core/agent-session-tool-hooks.js.map +1 -1
- package/dist/core/agent-session-tool-registry.d.ts.map +1 -1
- package/dist/core/agent-session-tool-registry.js +1 -1
- package/dist/core/agent-session-tool-registry.js.map +1 -1
- package/dist/core/agent-session-types.d.ts +3 -1
- package/dist/core/agent-session-types.d.ts.map +1 -1
- package/dist/core/agent-session-types.js.map +1 -1
- package/dist/core/agent-session.d.ts +12 -1
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +7 -0
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/extensions/context-types.d.ts +25 -0
- package/dist/core/extensions/context-types.d.ts.map +1 -1
- package/dist/core/extensions/context-types.js.map +1 -1
- package/dist/core/extensions/index.d.ts +1 -1
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/runner-context.d.ts +2 -1
- package/dist/core/extensions/runner-context.d.ts.map +1 -1
- package/dist/core/extensions/runner-context.js +4 -0
- package/dist/core/extensions/runner-context.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +3 -2
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +3 -1
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/model-fallback-failures.d.ts +30 -0
- package/dist/core/model-fallback-failures.d.ts.map +1 -0
- package/dist/core/model-fallback-failures.js +610 -0
- package/dist/core/model-fallback-failures.js.map +1 -0
- package/dist/core/retry-policy.d.ts +30 -0
- package/dist/core/retry-policy.d.ts.map +1 -0
- package/dist/core/retry-policy.js +25 -0
- package/dist/core/retry-policy.js.map +1 -0
- package/dist/core/sdk-types.d.ts +8 -2
- package/dist/core/sdk-types.d.ts.map +1 -1
- package/dist/core/sdk-types.js.map +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +6 -1
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager-core.d.ts +2 -0
- package/dist/core/session-manager-core.d.ts.map +1 -1
- package/dist/core/session-manager-core.js +7 -0
- package/dist/core/session-manager-core.js.map +1 -1
- package/dist/index-extensions.d.ts +1 -1
- package/dist/index-extensions.d.ts.map +1 -1
- package/dist/index-extensions.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/docs/intercom.md +5 -10
- package/docs/settings.md +7 -1
- package/docs/subagents.md +19 -19
- package/docs/workflows.md +21 -5
- package/examples/extensions/gondolin/package-lock.json +3 -3
- package/npm-shrinkwrap.json +29 -29
- package/package.json +2 -2
- package/dist/builtin/subagents/src/runs/background/async-event-journal.ts +0 -112
- package/dist/builtin/subagents/src/runs/background/async-execution-chain.ts +0 -543
- package/dist/builtin/subagents/src/runs/background/async-execution-common.ts +0 -140
- package/dist/builtin/subagents/src/runs/background/async-execution-single.ts +0 -279
- package/dist/builtin/subagents/src/runs/background/async-execution-types.ts +0 -99
- package/dist/builtin/subagents/src/runs/background/async-execution.ts +0 -17
- package/dist/builtin/subagents/src/runs/background/async-resume.ts +0 -402
- package/dist/builtin/subagents/src/runs/background/async-status.ts +0 -411
- package/dist/builtin/subagents/src/runs/background/completion-claims.ts +0 -196
- package/dist/builtin/subagents/src/runs/background/completion-dedupe.ts +0 -102
- package/dist/builtin/subagents/src/runs/background/parallel-groups.ts +0 -59
- package/dist/builtin/subagents/src/runs/background/result-delivery-processor.ts +0 -300
- package/dist/builtin/subagents/src/runs/background/result-file-claims.ts +0 -166
- package/dist/builtin/subagents/src/runs/background/result-quarantine.ts +0 -77
- package/dist/builtin/subagents/src/runs/background/result-retry-scheduler.ts +0 -48
- package/dist/builtin/subagents/src/runs/background/result-status.ts +0 -87
- package/dist/builtin/subagents/src/runs/background/result-watcher-data.ts +0 -72
- package/dist/builtin/subagents/src/runs/background/result-watcher.ts +0 -320
- package/dist/builtin/subagents/src/runs/background/run-id-resolver.ts +0 -105
- package/dist/builtin/subagents/src/runs/background/run-status.ts +0 -358
- package/dist/builtin/subagents/src/runs/background/stale-run-reconciler.ts +0 -457
- package/dist/builtin/subagents/src/runs/background/subagent-runner-dynamic.ts +0 -376
- package/dist/builtin/subagents/src/runs/background/subagent-runner-finalize.ts +0 -150
- package/dist/builtin/subagents/src/runs/background/subagent-runner-output.ts +0 -109
- package/dist/builtin/subagents/src/runs/background/subagent-runner-parallel-helpers.ts +0 -128
- package/dist/builtin/subagents/src/runs/background/subagent-runner-parallel.ts +0 -309
- package/dist/builtin/subagents/src/runs/background/subagent-runner-sequential.ts +0 -173
- package/dist/builtin/subagents/src/runs/background/subagent-runner-state.ts +0 -578
- package/dist/builtin/subagents/src/runs/background/subagent-runner-step.ts +0 -330
- package/dist/builtin/subagents/src/runs/background/subagent-runner-streaming.ts +0 -330
- package/dist/builtin/subagents/src/runs/background/subagent-runner-types.ts +0 -210
- package/dist/builtin/subagents/src/runs/background/subagent-runner-utils.ts +0 -69
- package/dist/builtin/subagents/src/runs/background/subagent-runner.ts +0 -90
- package/dist/builtin/subagents/src/runs/background/top-level-async.ts +0 -12
- package/dist/builtin/subagents/src/runs/foreground/execution-attempt-control.ts +0 -140
- package/dist/builtin/subagents/src/runs/foreground/execution-attempt-finalize.ts +0 -108
- package/dist/builtin/subagents/src/runs/foreground/execution-attempt-types.ts +0 -17
- package/dist/builtin/subagents/src/runs/foreground/execution-attempt.ts +0 -558
- package/dist/builtin/subagents/src/runs/shared/attempt-watchdog.ts +0 -126
- package/dist/builtin/subagents/src/runs/shared/final-drain.ts +0 -39
- package/dist/builtin/subagents/src/runs/shared/pi-args.ts +0 -339
- package/dist/builtin/subagents/src/runs/shared/pi-spawn.ts +0 -165
- package/dist/builtin/subagents/src/runs/shared/spawn-env.ts +0 -21
- package/dist/builtin/subagents/src/shared/post-exit-stdio-guard.ts +0 -86
- /package/dist/builtin/subagents/src/runs/{shared/nested-path.ts → inprocess/runtime-support/nested-paths.ts} +0 -0
|
@@ -129,7 +129,7 @@ export async function handleRunControlCommand(
|
|
|
129
129
|
return true;
|
|
130
130
|
}
|
|
131
131
|
}
|
|
132
|
-
const results = action === "quit" ? await quitAllRuns() : await interruptAllRuns();
|
|
132
|
+
const results = action === "quit" ? await quitAllRuns({ actor: "user" }) : await interruptAllRuns();
|
|
133
133
|
const successes = results.filter((result) => result.ok);
|
|
134
134
|
const changed = successes.length;
|
|
135
135
|
const failures = results.filter((result) => !result.ok);
|
|
@@ -171,7 +171,7 @@ export async function handleRunControlCommand(
|
|
|
171
171
|
return true;
|
|
172
172
|
}
|
|
173
173
|
try {
|
|
174
|
-
const result = await quitRun(resolved.runId);
|
|
174
|
+
const result = await quitRun(resolved.runId, { actor: "user" });
|
|
175
175
|
if (result.ok) print(`Run ${result.runId} quit and can be resumed with /workflow resume.`);
|
|
176
176
|
else if (result.reason === "already_ended") print(`Run ${result.runId} already ended.`);
|
|
177
177
|
else if (result.reason === "no_active_stages") {
|
|
@@ -284,11 +284,11 @@ export async function handleRunControlCommand(
|
|
|
284
284
|
await ensureWorkflowResourcesVisible();
|
|
285
285
|
const continuation = await deps
|
|
286
286
|
.runtimeForContext(ctx)
|
|
287
|
-
.resumeFailedRun(resolved.runId, undefined, { policy });
|
|
287
|
+
.resumeFailedRun(resolved.runId, undefined, { policy, actor: "user" });
|
|
288
288
|
continuation.ok ? print(continuation.message) : fail(continuation.message);
|
|
289
289
|
} else {
|
|
290
290
|
try {
|
|
291
|
-
const result = await resumeRun(resolved.runId, {});
|
|
291
|
+
const result = await resumeRun(resolved.runId, { actor: "user" });
|
|
292
292
|
if (result.ok && !isPaused && result.mode === "snapshot" && run?.exitReason === "quit") {
|
|
293
293
|
return await handleDurableResume(resolved.runId, ctx, reporter, deps);
|
|
294
294
|
}
|
|
@@ -443,7 +443,7 @@ export async function handleRunControlCommand(
|
|
|
443
443
|
const stageRunId = resolvedStage.runId ?? runId;
|
|
444
444
|
if (action === "pause") {
|
|
445
445
|
try {
|
|
446
|
-
const result = await pauseRun(stageRunId, { stageId });
|
|
446
|
+
const result = await pauseRun(stageRunId, { stageId, actor: "user" });
|
|
447
447
|
if (!result.ok) {
|
|
448
448
|
fail(
|
|
449
449
|
result.reason === "not_found"
|
|
@@ -495,7 +495,9 @@ export async function handleRunControlCommand(
|
|
|
495
495
|
}
|
|
496
496
|
if (isResumableContinuation) {
|
|
497
497
|
await ensureWorkflowResourcesVisible();
|
|
498
|
-
const continuation = await deps
|
|
498
|
+
const continuation = await deps
|
|
499
|
+
.runtimeForContext(ctx)
|
|
500
|
+
.resumeFailedRun(stageRunId, stageId, { policy, actor: "user" });
|
|
499
501
|
continuation.ok ? print(continuation.message) : fail(continuation.message);
|
|
500
502
|
return true;
|
|
501
503
|
}
|
|
@@ -507,7 +509,7 @@ export async function handleRunControlCommand(
|
|
|
507
509
|
}
|
|
508
510
|
let result: Awaited<ReturnType<typeof resumeRun>>;
|
|
509
511
|
try {
|
|
510
|
-
result = await resumeRun(stageRunId, { stageId, message });
|
|
512
|
+
result = await resumeRun(stageRunId, { stageId, message, actor: "user" });
|
|
511
513
|
} catch (error) {
|
|
512
514
|
fail(`Failed to resume run ${stageRunId}: ${error instanceof Error ? error.message : String(error)}`);
|
|
513
515
|
return true;
|
|
@@ -102,6 +102,17 @@ export interface WorkflowStatusListing {
|
|
|
102
102
|
readonly snapshots: RunSnapshot[];
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
+
const workflowStatusRenderRuns = new WeakMap<object, readonly RunSnapshot[]>();
|
|
106
|
+
|
|
107
|
+
/** Keep the full point-in-time run collection out of agent-facing result JSON. */
|
|
108
|
+
export function setWorkflowStatusRenderRuns(result: object, runs: readonly RunSnapshot[]): void {
|
|
109
|
+
workflowStatusRenderRuns.set(result, runs);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export function getWorkflowStatusRenderRuns(result: object): readonly RunSnapshot[] | undefined {
|
|
113
|
+
return workflowStatusRenderRuns.get(result);
|
|
114
|
+
}
|
|
115
|
+
|
|
105
116
|
function stageIsActive(stage: StageSnapshot): boolean {
|
|
106
117
|
return stage.status === "running" || stage.status === "awaiting_input";
|
|
107
118
|
}
|
|
@@ -1,10 +1,13 @@
|
|
|
1
|
+
import { runIndicatorStatus } from "../shared/run-indicator-status.js";
|
|
1
2
|
import { deriveInputFields } from "../shared/schema-introspection.js";
|
|
3
|
+
import type { RunSnapshot } from "../shared/store-types.js";
|
|
2
4
|
import type { WorkflowSerializableValue } from "../shared/types.js";
|
|
3
|
-
import { fmtDuration } from "../tui/status-helpers.js";
|
|
5
|
+
import { fmtDuration, statusIcon } from "../tui/status-helpers.js";
|
|
4
6
|
import type { WorkflowToolArgs } from "./public-types.js";
|
|
5
7
|
import type { WorkflowToolResult } from "./render-result.js";
|
|
6
8
|
import type { ExtensionRuntime } from "./runtime.js";
|
|
7
9
|
import type { WorkflowRunStatusSummary, WorkflowStatusAwaitingInput } from "./workflow-status-summary.js";
|
|
10
|
+
import { getWorkflowStatusRenderRuns } from "./workflow-status-summary.js";
|
|
8
11
|
|
|
9
12
|
function stringifyWorkflowToolResult(result: WorkflowToolResult): string {
|
|
10
13
|
return JSON.stringify(result, null, 2);
|
|
@@ -69,7 +72,20 @@ function statusAwaitingInputLine(entry: WorkflowStatusAwaitingInput): string {
|
|
|
69
72
|
return ` awaiting input: ${target}${prompt}${message}`;
|
|
70
73
|
}
|
|
71
74
|
|
|
75
|
+
function statusRunIcon(
|
|
76
|
+
run: WorkflowRunStatusSummary,
|
|
77
|
+
snapshot: RunSnapshot | undefined,
|
|
78
|
+
allRuns: readonly RunSnapshot[],
|
|
79
|
+
): string {
|
|
80
|
+
if (snapshot === undefined) return statusIcon(run.status);
|
|
81
|
+
const indicatorStatus = runIndicatorStatus(snapshot, allRuns);
|
|
82
|
+
if (snapshot.endedAt === undefined && snapshot.status === "paused" && snapshot.exitReason === "quit") {
|
|
83
|
+
return statusIcon("pending");
|
|
84
|
+
}
|
|
85
|
+
return statusIcon(indicatorStatus);
|
|
86
|
+
}
|
|
72
87
|
function renderStatusToolContent(result: Extract<WorkflowToolResult, { action: "status" }>): string {
|
|
88
|
+
const allRuns = getWorkflowStatusRenderRuns(result) ?? result.snapshots;
|
|
73
89
|
const lines = ["action: status", `filter: ${result.filter}`];
|
|
74
90
|
if (result.runs.length === 0) {
|
|
75
91
|
lines.push(result.filter === "all" ? "runs: none" : `runs: none (statusFilter: ${result.filter})`);
|
|
@@ -81,6 +97,7 @@ function renderStatusToolContent(result: Extract<WorkflowToolResult, { action: "
|
|
|
81
97
|
const hint = statusRunHint(run);
|
|
82
98
|
const summaryLine = [
|
|
83
99
|
`[${index + 1}]`,
|
|
100
|
+
statusRunIcon(run, result.snapshots[index], allRuns),
|
|
84
101
|
run.runId,
|
|
85
102
|
run.name,
|
|
86
103
|
run.status,
|
|
@@ -70,7 +70,7 @@ export async function workflowPauseAction(args: WorkflowToolArgs): Promise<Workf
|
|
|
70
70
|
return { action, runId: "--all", status: "noop", message: allStageConflictMessage("pause") };
|
|
71
71
|
}
|
|
72
72
|
try {
|
|
73
|
-
const results = await pauseAllRuns();
|
|
73
|
+
const results = await pauseAllRuns({ actor: "agent" });
|
|
74
74
|
const paused = results.filter((result) => result.ok).length;
|
|
75
75
|
return {
|
|
76
76
|
action,
|
|
@@ -100,7 +100,7 @@ export async function workflowPauseAction(args: WorkflowToolArgs): Promise<Workf
|
|
|
100
100
|
if (!stage.ok) return { action, runId: target.runId, status: "noop", message: stage.message };
|
|
101
101
|
const stageRunId = stage.runId ?? target.runId;
|
|
102
102
|
try {
|
|
103
|
-
const result = await pauseRun(stageRunId, { stageId: stage.stageId });
|
|
103
|
+
const result = await pauseRun(stageRunId, { stageId: stage.stageId, actor: "agent" });
|
|
104
104
|
return result.ok
|
|
105
105
|
? {
|
|
106
106
|
action,
|
|
@@ -241,7 +241,7 @@ export async function workflowQuitAction(args: WorkflowToolArgs): Promise<Workfl
|
|
|
241
241
|
if (args.stageId !== undefined && args.stageId.length > 0) {
|
|
242
242
|
return { action, runId: "--all", status: "noop", message: allStageConflictMessage("quit") };
|
|
243
243
|
}
|
|
244
|
-
const results = await quitAllRuns();
|
|
244
|
+
const results = await quitAllRuns({ actor: "agent" });
|
|
245
245
|
const successes = results.filter((result) => result.ok);
|
|
246
246
|
const quitCount = successes.length;
|
|
247
247
|
const failures = results.filter((result) => !result.ok);
|
|
@@ -264,7 +264,7 @@ export async function workflowQuitAction(args: WorkflowToolArgs): Promise<Workfl
|
|
|
264
264
|
if (!controlNode.ok) return { action, runId: target.runId, status: "noop", message: controlNode.message };
|
|
265
265
|
if (controlNode.kind === "tool") return quitToolNodeAction(controlNode.runId, controlNode.nodeId, action);
|
|
266
266
|
try {
|
|
267
|
-
const result = await quitRun(target.runId);
|
|
267
|
+
const result = await quitRun(target.runId, { actor: "agent" });
|
|
268
268
|
if (result.ok) {
|
|
269
269
|
return {
|
|
270
270
|
action,
|
|
@@ -354,7 +354,7 @@ async function resumeDurableShadow(
|
|
|
354
354
|
} catch (error) {
|
|
355
355
|
warning = formatWorkflowResourceLoadWarning(error);
|
|
356
356
|
}
|
|
357
|
-
const resumed = await runtime.resumeDurableWorkflow(runId, { policy: deps.policy });
|
|
357
|
+
const resumed = await runtime.resumeDurableWorkflow(runId, { policy: deps.policy, actor: "agent" });
|
|
358
358
|
const message = warning === undefined ? resumed.message : `${warning}\n\n${resumed.message}`;
|
|
359
359
|
return {
|
|
360
360
|
action: "resume",
|
|
@@ -369,7 +369,7 @@ async function resumePreparedDurableTarget(
|
|
|
369
369
|
deps: Pick<WorkflowControlActionDeps, "getRuntime" | "policy">,
|
|
370
370
|
): Promise<WorkflowToolResult> {
|
|
371
371
|
try {
|
|
372
|
-
const resumed = await deps.getRuntime().resumeDurableWorkflow(runId, { policy: deps.policy });
|
|
372
|
+
const resumed = await deps.getRuntime().resumeDurableWorkflow(runId, { policy: deps.policy, actor: "agent" });
|
|
373
373
|
return {
|
|
374
374
|
action: "resume",
|
|
375
375
|
runId: resumed.ok ? resumed.runId : runId,
|
|
@@ -493,7 +493,9 @@ export async function workflowResumeAction(
|
|
|
493
493
|
} catch (error) {
|
|
494
494
|
warning = formatWorkflowResourceLoadWarning(error);
|
|
495
495
|
}
|
|
496
|
-
const continuation = await deps
|
|
496
|
+
const continuation = await deps
|
|
497
|
+
.getRuntime()
|
|
498
|
+
.resumeFailedRun(stageRunId, stage.stageId, { policy: deps.policy, actor: "agent" });
|
|
497
499
|
const message = warning === undefined ? continuation.message : `${warning}\n\n${continuation.message}`;
|
|
498
500
|
return {
|
|
499
501
|
action: "resume",
|
|
@@ -503,7 +505,7 @@ export async function workflowResumeAction(
|
|
|
503
505
|
};
|
|
504
506
|
}
|
|
505
507
|
try {
|
|
506
|
-
const result = await resumeRun(stageRunId, { stageId: stage.stageId, message: args.message });
|
|
508
|
+
const result = await resumeRun(stageRunId, { stageId: stage.stageId, message: args.message, actor: "agent" });
|
|
507
509
|
if (result.ok) {
|
|
508
510
|
const runLevelResumed =
|
|
509
511
|
hadPausedRunState &&
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { getSupportedThinkingLevels } from "@earendil-works/pi-ai/compat";
|
|
2
2
|
import { inspectRun } from "../runs/background/status.js";
|
|
3
|
+
import { store } from "../shared/store.js";
|
|
3
4
|
import type { WorkflowExecutionPolicy } from "../shared/types.js";
|
|
4
5
|
import type { PiExecuteContext, WorkflowToolArgs } from "./public-types.js";
|
|
5
6
|
import type { WorkflowToolResult } from "./render-result.js";
|
|
@@ -7,7 +8,7 @@ import type { ExtensionRuntime } from "./runtime.js";
|
|
|
7
8
|
import { formatWorkflowResourceLoadWarning } from "./workflow-command-surfaces.js";
|
|
8
9
|
import { workflowPolicyFromContext } from "./workflow-policy.js";
|
|
9
10
|
import type { WorkflowReloadReport } from "./workflow-reload-report.js";
|
|
10
|
-
import { buildWorkflowStatusListing } from "./workflow-status-summary.js";
|
|
11
|
+
import { buildWorkflowStatusListing, setWorkflowStatusRenderRuns } from "./workflow-status-summary.js";
|
|
11
12
|
import { isWorkflowStageToolContext, resolveRunId, topLevelExpandedSnapshots } from "./workflow-targets.js";
|
|
12
13
|
import { workflowGetResult } from "./workflow-tool-content.js";
|
|
13
14
|
import {
|
|
@@ -74,7 +75,9 @@ export function makeExecuteWorkflowTool(
|
|
|
74
75
|
}
|
|
75
76
|
case "run": {
|
|
76
77
|
await ensureWorkflowResourcesVisible();
|
|
77
|
-
|
|
78
|
+
// A tool launch is the agent's own action: it is attributed as such and
|
|
79
|
+
// the tool result already reports the run, so it raises no chat notice.
|
|
80
|
+
return getRuntime().dispatch(args, { policy, origin: "agent" });
|
|
78
81
|
}
|
|
79
82
|
case "status": {
|
|
80
83
|
const target = args.runId;
|
|
@@ -92,12 +95,14 @@ export function makeExecuteWorkflowTool(
|
|
|
92
95
|
: { action: "statusDetail", runId: target, error: `run not found: ${target}` };
|
|
93
96
|
}
|
|
94
97
|
const listing = buildWorkflowStatusListing(topLevelExpandedSnapshots(), args.statusFilter ?? "all");
|
|
95
|
-
|
|
96
|
-
action: "status",
|
|
98
|
+
const result = {
|
|
99
|
+
action: "status" as const,
|
|
97
100
|
filter: listing.filter,
|
|
98
101
|
runs: listing.runs,
|
|
99
102
|
snapshots: listing.snapshots,
|
|
100
103
|
};
|
|
104
|
+
setWorkflowStatusRenderRuns(result, store.graphSnapshot().runs);
|
|
105
|
+
return result;
|
|
101
106
|
}
|
|
102
107
|
case "stages":
|
|
103
108
|
return workflowStagesResult(args);
|
|
@@ -20,7 +20,7 @@ import { topLevelWorkflowRuns } from "../../shared/run-visibility.js";
|
|
|
20
20
|
import { store as defaultStore } from "../../shared/store.js";
|
|
21
21
|
import { readGraphStoreSnapshot } from "../../shared/store-observation.js";
|
|
22
22
|
import type { Store } from "../../shared/store-public-types.js";
|
|
23
|
-
import type { RunSnapshot, StageSnapshot } from "../../shared/store-types.js";
|
|
23
|
+
import type { RunSnapshot, StageSnapshot, WorkflowActor } from "../../shared/store-types.js";
|
|
24
24
|
import type { WorkflowCancelledToolNode, WorkflowToolNodeIdentity } from "../../shared/types.js";
|
|
25
25
|
import {
|
|
26
26
|
stageControlRegistry as defaultStageControlRegistry,
|
|
@@ -83,6 +83,12 @@ type QuitAllRunResult =
|
|
|
83
83
|
* It deliberately does NOT abort through the cancellation registry or append a
|
|
84
84
|
* terminal `workflow.run.end` entry. Destructive cancellation remains an
|
|
85
85
|
* internal lifecycle mechanism.
|
|
86
|
+
*
|
|
87
|
+
* A quit publishes its stage pauses in step 1, long before step 5 can record the
|
|
88
|
+
* quit itself, so the run passes through an ordinary paused state on the way.
|
|
89
|
+
* Only step 5 carries the caller's `actor`, so an observer that reports deliberate
|
|
90
|
+
* control actions sees one quit rather than a pause followed by a quit — and
|
|
91
|
+
* still sees nothing at all when a quit never publishes.
|
|
86
92
|
*/
|
|
87
93
|
export async function quitRun(
|
|
88
94
|
runId: string,
|
|
@@ -91,6 +97,8 @@ export async function quitRun(
|
|
|
91
97
|
stageControlRegistry?: StageControlRegistry;
|
|
92
98
|
toolControlRegistry?: ToolControlRegistry;
|
|
93
99
|
jobs?: JobTracker;
|
|
100
|
+
/** Who requested this quit. Omitted for internal callers. */
|
|
101
|
+
actor?: WorkflowActor;
|
|
94
102
|
},
|
|
95
103
|
): Promise<QuitRunResult> {
|
|
96
104
|
const activeStore = opts?.store ?? defaultStore;
|
|
@@ -170,7 +178,7 @@ export async function quitRun(
|
|
|
170
178
|
// record, and only the publication below can report that the run stopped.
|
|
171
179
|
const suspendedByAbort = toolHandles.length > 0;
|
|
172
180
|
const publish = (resumable: boolean): void => {
|
|
173
|
-
publishLocalQuit(activeStore, runId, pausedRunIds, resumable);
|
|
181
|
+
publishLocalQuit(activeStore, runId, pausedRunIds, resumable, opts?.actor);
|
|
174
182
|
// An abandoned callback keeps its executor alive, but that executor is no
|
|
175
183
|
// longer authoritative for this run id: detach it so `/workflow resume`
|
|
176
184
|
// relaunches a fresh executor instead of adopting the stale job and
|
|
@@ -202,15 +210,28 @@ export async function quitRun(
|
|
|
202
210
|
* process could resume from it, so it is not advertised as resumable. Recording
|
|
203
211
|
* it keeps the run controllable, so a later `/workflow quit` re-attempts the
|
|
204
212
|
* transition and upgrades the record.
|
|
213
|
+
*
|
|
214
|
+
* The boundary run is deliberately excluded from the descendant loop: a bare
|
|
215
|
+
* `recordRunPaused(runId)` first would publish a plain paused state, and a
|
|
216
|
+
* lifecycle observer would report this quit as a pause followed by a quit. The
|
|
217
|
+
* single metadata-carrying call below records the same end state in one step.
|
|
205
218
|
*/
|
|
206
219
|
function publishLocalQuit(
|
|
207
220
|
activeStore: Store,
|
|
208
221
|
runId: string,
|
|
209
222
|
pausedRunIds: ReadonlySet<string>,
|
|
210
223
|
resumable: boolean,
|
|
224
|
+
actor?: WorkflowActor,
|
|
211
225
|
): void {
|
|
212
|
-
for (const pausedRunId of pausedRunIds)
|
|
213
|
-
|
|
226
|
+
for (const pausedRunId of pausedRunIds) {
|
|
227
|
+
if (pausedRunId === runId) continue;
|
|
228
|
+
activeStore.recordRunPaused(pausedRunId);
|
|
229
|
+
}
|
|
230
|
+
activeStore.recordRunPaused(runId, undefined, {
|
|
231
|
+
exitReason: "quit",
|
|
232
|
+
resumable,
|
|
233
|
+
...(actor === undefined ? {} : { actor }),
|
|
234
|
+
});
|
|
214
235
|
}
|
|
215
236
|
|
|
216
237
|
/**
|
|
@@ -368,6 +389,8 @@ export async function quitAllRuns(opts?: {
|
|
|
368
389
|
stageControlRegistry?: StageControlRegistry;
|
|
369
390
|
toolControlRegistry?: ToolControlRegistry;
|
|
370
391
|
jobs?: JobTracker;
|
|
392
|
+
/** Who requested these quits. Omitted for internal callers. */
|
|
393
|
+
actor?: WorkflowActor;
|
|
371
394
|
}): Promise<QuitAllRunResult[]> {
|
|
372
395
|
const activeStore = opts?.store ?? defaultStore;
|
|
373
396
|
const inFlight = topLevelWorkflowRuns(activeStore.runs()).filter((run) => run.endedAt === undefined);
|
|
@@ -377,6 +400,7 @@ export async function quitAllRuns(opts?: {
|
|
|
377
400
|
stageControlRegistry: opts?.stageControlRegistry,
|
|
378
401
|
toolControlRegistry: opts?.toolControlRegistry,
|
|
379
402
|
jobs: opts?.jobs,
|
|
403
|
+
...(opts?.actor === undefined ? {} : { actor: opts.actor }),
|
|
380
404
|
}),
|
|
381
405
|
);
|
|
382
406
|
const settled = await Promise.allSettled(attempts);
|
|
@@ -75,7 +75,8 @@ export async function settleResumeAcknowledgements(
|
|
|
75
75
|
if (visiblyRunning) lateFailures.push(qualified);
|
|
76
76
|
else if (controlRun?.endedAt === undefined && targetIsActuallyPaused(store, target)) failures.push(qualified);
|
|
77
77
|
});
|
|
78
|
-
for (const controlRunId of resumedRunIds)
|
|
78
|
+
for (const controlRunId of resumedRunIds)
|
|
79
|
+
store.recordRunResumed(controlRunId, undefined, { source: "acknowledgement" });
|
|
79
80
|
return { resumed, acknowledged, failures, lateFailures };
|
|
80
81
|
}
|
|
81
82
|
|
|
@@ -16,7 +16,7 @@ import { topLevelWorkflowRuns } from "../../shared/run-visibility.js";
|
|
|
16
16
|
import type { Store } from "../../shared/store.js";
|
|
17
17
|
import { store as defaultStore } from "../../shared/store.js";
|
|
18
18
|
import { readGraphStoreSnapshot } from "../../shared/store-observation.js";
|
|
19
|
-
import type { RunSnapshot, RunStatus, StageSnapshot } from "../../shared/store-types.js";
|
|
19
|
+
import type { RunSnapshot, RunStatus, StageSnapshot, WorkflowActor } from "../../shared/store-types.js";
|
|
20
20
|
import type { WorkflowPersistencePort } from "../../shared/types.js";
|
|
21
21
|
import type { StageControlRegistry } from "../foreground/stage-control-registry.js";
|
|
22
22
|
import { stageControlRegistry as defaultStageControlRegistry } from "../foreground/stage-control-registry.js";
|
|
@@ -204,6 +204,8 @@ export async function resumeRun(
|
|
|
204
204
|
stageId?: string;
|
|
205
205
|
/** Optional resume message forwarded to each resumed stage. */
|
|
206
206
|
message?: string;
|
|
207
|
+
/** Who requested this resume. Omitted for internal callers. */
|
|
208
|
+
actor?: WorkflowActor;
|
|
207
209
|
},
|
|
208
210
|
): Promise<ResumeResult> {
|
|
209
211
|
const activeStore = opts?.store ?? defaultStore;
|
|
@@ -250,8 +252,29 @@ export async function resumeRun(
|
|
|
250
252
|
!hasPausedDescendant &&
|
|
251
253
|
currentRun?.status === "paused")
|
|
252
254
|
) {
|
|
253
|
-
|
|
254
|
-
|
|
255
|
+
// One scope carries the actor, mirroring pauseRun: the stage when a
|
|
256
|
+
// stage-scoped resume leaves siblings paused, the run otherwise. The
|
|
257
|
+
// aggregate root is reconciled without attribution so one request never
|
|
258
|
+
// reports twice.
|
|
259
|
+
//
|
|
260
|
+
// A run only carries the actor when it has a resume transition to attach
|
|
261
|
+
// it to. A stage-scoped resume of a run that never paused — because a
|
|
262
|
+
// sibling stage kept it running — leaves `resumedAt` unset, and
|
|
263
|
+
// `recordRunResumed` refuses an attribution-only claim against a run that
|
|
264
|
+
// never resumed. Attributing the run there would report nothing at all,
|
|
265
|
+
// so the stage carries it instead.
|
|
266
|
+
const attributeStage =
|
|
267
|
+
opts?.stageId !== undefined && (hasPausedDescendant || currentRun?.resumedAt === undefined);
|
|
268
|
+
activeStore.recordRunResumed(runId, undefined, {
|
|
269
|
+
source: "run_control",
|
|
270
|
+
...(opts?.actor === undefined || attributeStage ? {} : { actor: opts.actor }),
|
|
271
|
+
});
|
|
272
|
+
if (aggregateRootRunId !== runId) {
|
|
273
|
+
activeStore.recordRunResumed(aggregateRootRunId, undefined, { source: "run_control" });
|
|
274
|
+
}
|
|
275
|
+
if (attributeStage && opts?.actor !== undefined && opts.stageId !== undefined) {
|
|
276
|
+
activeStore.recordStageResumed(runId, opts.stageId, undefined, { actor: opts.actor });
|
|
277
|
+
}
|
|
255
278
|
}
|
|
256
279
|
const reconciledRoot = activeStore.runs().find((candidate) => candidate.id === runId);
|
|
257
280
|
if (acknowledgements.failures.length > 0) {
|
|
@@ -346,7 +369,15 @@ export async function resumeRun(
|
|
|
346
369
|
}
|
|
347
370
|
|
|
348
371
|
// pauseRun
|
|
349
|
-
/**
|
|
372
|
+
/**
|
|
373
|
+
* Pause a run only after its live stage controls acknowledge the request.
|
|
374
|
+
*
|
|
375
|
+
* `actor` attributes the pause to whoever asked for it. Exactly one scope carries
|
|
376
|
+
* it: a whole-run pause attributes the run, and a stage-scoped pause attributes
|
|
377
|
+
* the run when it stops the last active stage and the stage otherwise. An
|
|
378
|
+
* observer therefore reports one event per request, never a stage and a run
|
|
379
|
+
* event for the same one.
|
|
380
|
+
*/
|
|
350
381
|
export async function pauseRun(
|
|
351
382
|
runId: string,
|
|
352
383
|
opts?: {
|
|
@@ -354,11 +385,14 @@ export async function pauseRun(
|
|
|
354
385
|
stageControlRegistry?: StageControlRegistry;
|
|
355
386
|
/** Pause only this stage. */
|
|
356
387
|
stageId?: string;
|
|
388
|
+
/** Who requested this pause. Omitted for internal callers. */
|
|
389
|
+
actor?: WorkflowActor;
|
|
357
390
|
},
|
|
358
391
|
): Promise<PauseResult> {
|
|
359
392
|
const activeStore = opts?.store ?? defaultStore;
|
|
360
393
|
const registry = opts?.stageControlRegistry ?? defaultStageControlRegistry;
|
|
361
394
|
const run = activeStore.runs().find((candidate) => candidate.id === runId);
|
|
395
|
+
const actorMetadata = opts?.actor === undefined ? undefined : { actor: opts.actor };
|
|
362
396
|
|
|
363
397
|
if (!run) return { ok: false, runId, reason: "not_found" };
|
|
364
398
|
if (run.endedAt !== undefined) return { ok: false, runId, reason: "already_ended" };
|
|
@@ -379,7 +413,9 @@ export async function pauseRun(
|
|
|
379
413
|
(candidate) =>
|
|
380
414
|
candidate.id !== opts.stageId && (candidate.status === "running" || candidate.status === "pending"),
|
|
381
415
|
) ?? false;
|
|
382
|
-
if (!stillActive) activeStore.recordRunPaused(runId);
|
|
416
|
+
if (!stillActive) activeStore.recordRunPaused(runId, undefined, actorMetadata);
|
|
417
|
+
else if (actorMetadata !== undefined)
|
|
418
|
+
activeStore.recordStagePaused(runId, opts.stageId, undefined, actorMetadata);
|
|
383
419
|
return { ok: true, runId, paused };
|
|
384
420
|
}
|
|
385
421
|
|
|
@@ -403,19 +439,30 @@ export async function pauseRun(
|
|
|
403
439
|
const stage = controlRun?.stages.find((candidate) => candidate.id === handle.stageId);
|
|
404
440
|
if (stage !== undefined) paused.push(structuredClone(stage));
|
|
405
441
|
}
|
|
406
|
-
for (const pausedRunId of pausedRunIds)
|
|
407
|
-
|
|
442
|
+
for (const pausedRunId of pausedRunIds) {
|
|
443
|
+
if (pausedRunId === runId) continue;
|
|
444
|
+
activeStore.recordRunPaused(pausedRunId);
|
|
445
|
+
}
|
|
446
|
+
activeStore.recordRunPaused(runId, undefined, actorMetadata);
|
|
408
447
|
return { ok: true, runId, paused };
|
|
409
448
|
}
|
|
410
449
|
|
|
411
450
|
export async function pauseAllRuns(opts?: {
|
|
412
451
|
store?: Store;
|
|
413
452
|
stageControlRegistry?: StageControlRegistry;
|
|
453
|
+
/** Who requested these pauses. Omitted for internal callers. */
|
|
454
|
+
actor?: WorkflowActor;
|
|
414
455
|
}): Promise<PauseResult[]> {
|
|
415
456
|
const activeStore = opts?.store ?? defaultStore;
|
|
416
457
|
const inFlight = topLevelWorkflowRuns(activeStore.runs()).filter((run) => run.endedAt === undefined);
|
|
417
458
|
return Promise.all(
|
|
418
|
-
inFlight.map((run) =>
|
|
459
|
+
inFlight.map((run) =>
|
|
460
|
+
pauseRun(run.id, {
|
|
461
|
+
store: activeStore,
|
|
462
|
+
stageControlRegistry: opts?.stageControlRegistry,
|
|
463
|
+
...(opts?.actor === undefined ? {} : { actor: opts.actor }),
|
|
464
|
+
}),
|
|
465
|
+
),
|
|
419
466
|
);
|
|
420
467
|
}
|
|
421
468
|
// ---------------------------------------------------------------------------
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { isAbsolute, join, resolve } from "node:path";
|
|
2
2
|
import { CONFIG_DIR_NAME, isCodexFastModeCandidateModelId } from "@bastani/atomic";
|
|
3
|
+
import type { WorkflowActor } from "../../shared/store-types.js";
|
|
3
4
|
import type { StageOptions, WorkflowArtifact, WorkflowTaskOptions, WorkflowTaskStep } from "../../shared/types.js";
|
|
4
5
|
import { workflowArtifactRunPath } from "../../shared/workflow-artifacts.js";
|
|
5
6
|
import { buildModelCandidatesFromCatalog, workflowModelId } from "../shared/model-fallback.js";
|
|
@@ -178,11 +179,13 @@ export function workflowInvocationMetadata(
|
|
|
178
179
|
inputDefaults: Partial<StageOptions>,
|
|
179
180
|
workflowInvocationCwd: string,
|
|
180
181
|
cache?: GitWorktreeSetupCache,
|
|
182
|
+
origin?: WorkflowActor,
|
|
181
183
|
): {
|
|
182
184
|
readonly invocationCwd: string;
|
|
183
185
|
readonly workflowCwd?: string;
|
|
184
186
|
readonly repositoryRoot?: string;
|
|
185
187
|
readonly gitWorktreeRoot?: string;
|
|
188
|
+
readonly origin?: WorkflowActor;
|
|
186
189
|
} {
|
|
187
190
|
const setup = setupWorkflowInputGitWorktree(inputDefaults, workflowInvocationCwd, cache);
|
|
188
191
|
return {
|
|
@@ -190,6 +193,7 @@ export function workflowInvocationMetadata(
|
|
|
190
193
|
...(setup !== undefined
|
|
191
194
|
? { workflowCwd: setup.cwd, repositoryRoot: setup.repositoryRoot, gitWorktreeRoot: setup.worktreeRoot }
|
|
192
195
|
: {}),
|
|
196
|
+
...(origin !== undefined ? { origin } : {}),
|
|
193
197
|
};
|
|
194
198
|
}
|
|
195
199
|
|
|
@@ -182,7 +182,9 @@ export function buildPromptNodeUiAdapter(input: {
|
|
|
182
182
|
},
|
|
183
183
|
async resume() {
|
|
184
184
|
input.activeStore.recordStageResumed(input.runId, stageId);
|
|
185
|
-
|
|
185
|
+
// Answering a human-in-the-loop prompt continues work already in flight.
|
|
186
|
+
// It is not a control action and must never reach the main chat.
|
|
187
|
+
input.activeStore.recordRunResumed(input.runId, undefined, { source: "prompt_answer" });
|
|
186
188
|
const currentPauseGate = pauseGate;
|
|
187
189
|
pauseGate = undefined;
|
|
188
190
|
currentPauseGate?.resolve();
|
|
@@ -193,7 +193,7 @@ export function createStageControlHandle(runtime: LiveStageRuntime): StageContro
|
|
|
193
193
|
await runtime.scheduler.cascadeResumeFrom(runtime.stageId);
|
|
194
194
|
// Preserve manual per-stage semantics: once this acknowledged
|
|
195
195
|
// resume succeeds, the run is active even if sibling stages remain paused.
|
|
196
|
-
runtime.activeStore.recordRunResumed(runtime.runId);
|
|
196
|
+
runtime.activeStore.recordRunResumed(runtime.runId, undefined, { source: "stage_control" });
|
|
197
197
|
}
|
|
198
198
|
if (wakeReleasedIdleStageChat) runtime.state.wakeWaitingForStageChatTurn?.();
|
|
199
199
|
if (resumesIdleStageChat && hasMessage) {
|