@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
|
@@ -60,6 +60,8 @@ export interface RunSyncOptions {
|
|
|
60
60
|
signal?: AbortSignal;
|
|
61
61
|
interruptSignal?: AbortSignal;
|
|
62
62
|
allowIntercomDetach?: boolean;
|
|
63
|
+
/** Start the admitted child and settle this call with a continued result immediately. */
|
|
64
|
+
backgroundContinuation?: boolean;
|
|
63
65
|
intercomEvents?: IntercomEventBus;
|
|
64
66
|
onDetachedExit?: (result: SingleResult) => void;
|
|
65
67
|
/** Shared foreground-group signal used to release sibling supervision after one exact child commits Intercom detach. */
|
|
@@ -71,6 +73,12 @@ export interface RunSyncOptions {
|
|
|
71
73
|
controlConfig?: ResolvedControlConfig;
|
|
72
74
|
intercomSessionName?: string;
|
|
73
75
|
orchestratorIntercomTarget?: string;
|
|
76
|
+
/** Typed supervisor capability issued for this child; never read from environment. */
|
|
77
|
+
supervisorAuthorization?: {
|
|
78
|
+
capability: string;
|
|
79
|
+
supervisorSessionId: string;
|
|
80
|
+
childName: string;
|
|
81
|
+
};
|
|
74
82
|
/** Resolved intercom home group for the spawned child (explicit subagent group or inherited stage group). */
|
|
75
83
|
intercomGroup?: string;
|
|
76
84
|
maxOutput?: MaxOutputConfig;
|
|
@@ -106,6 +114,16 @@ export interface RunSyncOptions {
|
|
|
106
114
|
schemaPath: string;
|
|
107
115
|
outputPath: string;
|
|
108
116
|
};
|
|
117
|
+
/** Test-only in-process session stub configuration; production runs create a real AgentSession. */
|
|
118
|
+
testSession?: {
|
|
119
|
+
output?: string;
|
|
120
|
+
structuredOutputAfterPrompt?: number;
|
|
121
|
+
promptLogPath?: string;
|
|
122
|
+
/** Hold a test prompt open until the caller releases the supplied promise. */
|
|
123
|
+
promptGate?: Promise<void>;
|
|
124
|
+
/** Match AgentSession.abort() settling an active prompt without throwing. */
|
|
125
|
+
abortResolvesPrompt?: boolean;
|
|
126
|
+
};
|
|
109
127
|
}
|
|
110
128
|
|
|
111
129
|
export type IntercomBridgeMode = "off" | "fork-only" | "always";
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* Result, progress, and core subagent public types.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
+
import type { SessionStats } from "@bastani/atomic";
|
|
5
6
|
import type { AgentToolResult } from "@earendil-works/pi-agent-core";
|
|
6
7
|
import type { Message } from "@earendil-works/pi-ai/compat";
|
|
7
8
|
import type { NestedRunAddress, NestedRunSummary, NestedStepSummary } from "./types-async.ts";
|
|
@@ -271,15 +272,21 @@ export interface ModelAttempt {
|
|
|
271
272
|
model: string;
|
|
272
273
|
reasoningLevel?: string;
|
|
273
274
|
success: boolean;
|
|
274
|
-
exitCode?: number | null;
|
|
275
275
|
error?: string;
|
|
276
276
|
usage?: Usage;
|
|
277
277
|
}
|
|
278
278
|
|
|
279
|
+
export type SubagentAttemptStatus = "ok" | "error" | "skipped" | "interrupted" | "continued";
|
|
280
|
+
|
|
279
281
|
export interface SingleResult {
|
|
280
282
|
agent: string;
|
|
281
283
|
task: string;
|
|
282
|
-
|
|
284
|
+
/** Typed terminal outcome; this is the only result discriminator. */
|
|
285
|
+
status: SubagentAttemptStatus;
|
|
286
|
+
cause?: string;
|
|
287
|
+
stats?: SessionStats;
|
|
288
|
+
path?: string;
|
|
289
|
+
envelope?: string;
|
|
283
290
|
detached?: boolean;
|
|
284
291
|
detachedReason?: string;
|
|
285
292
|
interrupted?: boolean;
|
|
@@ -77,9 +77,9 @@ interface PromptTemplateBridgeResult {
|
|
|
77
77
|
details?: {
|
|
78
78
|
results?: Array<{
|
|
79
79
|
agent?: string;
|
|
80
|
+
status?: "ok" | "error" | "skipped" | "interrupted" | "continued";
|
|
80
81
|
messages?: unknown[];
|
|
81
82
|
finalOutput?: string;
|
|
82
|
-
exitCode?: number;
|
|
83
83
|
error?: string;
|
|
84
84
|
model?: string;
|
|
85
85
|
toolCalls?: Array<{ text?: string; expandedText?: string }>;
|
|
@@ -367,12 +367,11 @@ export function registerPromptTemplateDelegationBridge<Ctx extends { cwd?: strin
|
|
|
367
367
|
errorText: "Missing result for delegated parallel task.",
|
|
368
368
|
};
|
|
369
369
|
}
|
|
370
|
-
const exitCode = typeof step.exitCode === "number" ? step.exitCode : undefined;
|
|
371
370
|
const errorText = step.error;
|
|
372
371
|
return {
|
|
373
372
|
agent: step.agent ?? task.agent,
|
|
374
373
|
messages: buildDelegationMessages(step),
|
|
375
|
-
isError:
|
|
374
|
+
isError: step.status === "error" || !!errorText,
|
|
376
375
|
errorText: errorText || undefined,
|
|
377
376
|
};
|
|
378
377
|
})
|
|
@@ -79,7 +79,7 @@ function createPlaceholderResult(
|
|
|
79
79
|
return {
|
|
80
80
|
agent,
|
|
81
81
|
task,
|
|
82
|
-
|
|
82
|
+
status: "continued",
|
|
83
83
|
messages: EMPTY_MESSAGES,
|
|
84
84
|
usage: cloneUsage(),
|
|
85
85
|
progress: {
|
|
@@ -292,7 +292,7 @@ export function failSlashResult(
|
|
|
292
292
|
const initial = buildSlashInitialResult(requestId, params, owner).result;
|
|
293
293
|
const failedResults = initial.details.results.map((result) => ({
|
|
294
294
|
...result,
|
|
295
|
-
|
|
295
|
+
status: "error" as const,
|
|
296
296
|
error: message,
|
|
297
297
|
progress: result.progress ? { ...result.progress, status: "failed" as const } : result.progress,
|
|
298
298
|
}));
|
|
@@ -105,8 +105,8 @@ export function isDoneResult(result: Details["results"][number]): boolean {
|
|
|
105
105
|
const status = result.progress?.status;
|
|
106
106
|
if (status === "completed") return true;
|
|
107
107
|
if (status === "running" || status === "pending") return false;
|
|
108
|
-
if (result.interrupted || result.detached) return false;
|
|
109
|
-
return
|
|
108
|
+
if (result.interrupted || result.detached || result.status !== "ok") return false;
|
|
109
|
+
return true;
|
|
110
110
|
}
|
|
111
111
|
|
|
112
112
|
export function workflowGraphHasStatus(
|
|
@@ -188,7 +188,7 @@ export function buildMultiProgressLabel(
|
|
|
188
188
|
if (details.mode === "parallel") {
|
|
189
189
|
const totalCount = details.totalSteps ?? details.results.length;
|
|
190
190
|
const statuses = new Array(totalCount).fill("pending") as Array<
|
|
191
|
-
"pending" | "running" | "completed" | "failed" | "detached"
|
|
191
|
+
"pending" | "running" | "completed" | "failed" | "paused" | "detached"
|
|
192
192
|
>;
|
|
193
193
|
for (const progress of details.progress ?? []) {
|
|
194
194
|
if (progress.index >= 0 && progress.index < totalCount) statuses[progress.index] = progress.status;
|
|
@@ -202,7 +202,13 @@ export function buildMultiProgressLabel(
|
|
|
202
202
|
if (index < 0 || index >= totalCount) continue;
|
|
203
203
|
const status =
|
|
204
204
|
result.progress?.status ??
|
|
205
|
-
(result.interrupted || result.
|
|
205
|
+
(result.interrupted || result.status === "interrupted"
|
|
206
|
+
? "paused"
|
|
207
|
+
: result.detached || result.status === "continued"
|
|
208
|
+
? "detached"
|
|
209
|
+
: result.status === "ok"
|
|
210
|
+
? "completed"
|
|
211
|
+
: "failed");
|
|
206
212
|
statuses[index] = status;
|
|
207
213
|
}
|
|
208
214
|
const running = statuses.filter((status) => status === "running").length;
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { flatToLogicalStepIndex } from "../runs/background/parallel-groups.ts";
|
|
3
|
-
import { formatNestedAggregate } from "../runs/shared/nested-render.ts";
|
|
1
|
+
import { formatNestedAggregate } from "../runs/inprocess/runtime-support/nested-rendering.ts";
|
|
4
2
|
import { formatDuration, formatModelThinking, shortenPath } from "../shared/formatters.ts";
|
|
5
3
|
import { formatAgentRunningLabel } from "../shared/status-format.ts";
|
|
6
4
|
import {
|
|
@@ -19,6 +17,17 @@ import {
|
|
|
19
17
|
statJoin,
|
|
20
18
|
} from "./render-status-progress.ts";
|
|
21
19
|
|
|
20
|
+
function flatToLogicalStepIndex(
|
|
21
|
+
currentStep: number,
|
|
22
|
+
_total: number,
|
|
23
|
+
groups: Array<{ start: number; count: number; stepIndex?: number }>,
|
|
24
|
+
): number {
|
|
25
|
+
return (
|
|
26
|
+
groups.find((group) => currentStep >= group.start && currentStep < group.start + group.count)?.stepIndex ??
|
|
27
|
+
currentStep
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
|
|
22
31
|
export function formatWidgetAgents(agents: string[]): string {
|
|
23
32
|
const distinct = [...new Set(agents)];
|
|
24
33
|
if (distinct.length === 1 && agents.length > 1) return `${distinct[0]} ×${agents.length}`;
|
|
@@ -167,14 +176,6 @@ export function widgetStepActivityLine(
|
|
|
167
176
|
return "";
|
|
168
177
|
}
|
|
169
178
|
|
|
170
|
-
export function widgetOutputPath(
|
|
171
|
-
job: AsyncJobState,
|
|
172
|
-
step: NonNullable<AsyncJobState["steps"]>[number],
|
|
173
|
-
): string | undefined {
|
|
174
|
-
if (typeof step.index !== "number") return undefined;
|
|
175
|
-
return path.join(job.asyncDir, `output-${step.index}.log`);
|
|
176
|
-
}
|
|
177
|
-
|
|
178
179
|
export function nestedRunName(run: NestedRunSummary): string {
|
|
179
180
|
if (run.agent) return run.agent;
|
|
180
181
|
if (run.agents?.length) return formatWidgetAgents(run.agents);
|
|
@@ -73,7 +73,7 @@ export function renderSingleCompact(
|
|
|
73
73
|
|
|
74
74
|
c.addChild(new Text(truncLine(theme.fg("dim", ` ⎿ ${resultStatusLine(r, output)}`), width), 0, 0));
|
|
75
75
|
const preview = firstOutputLine(output);
|
|
76
|
-
if (preview && r.
|
|
76
|
+
if (preview && r.status === "ok" && !hasEmptyTextOutputWithoutOutputTarget(r.task, output)) {
|
|
77
77
|
c.addChild(new Text(truncLine(theme.fg("dim", ` ${preview}`), width), 0, 0));
|
|
78
78
|
}
|
|
79
79
|
if (r.sessionFile)
|
|
@@ -95,11 +95,18 @@ export function renderMultiCompact(d: Details, theme: Theme, now?: number, pulse
|
|
|
95
95
|
d.results.some((r) => r.progress?.status === "running") ||
|
|
96
96
|
workflowGraphHasStatus(d, ["running"]);
|
|
97
97
|
const failed =
|
|
98
|
-
d.results.some((r) => r.
|
|
98
|
+
d.results.some((r) => r.status === "error" && r.progress?.status !== "running") ||
|
|
99
99
|
workflowGraphHasStatus(d, ["failed"]);
|
|
100
100
|
const paused =
|
|
101
|
-
d.results.some(
|
|
102
|
-
|
|
101
|
+
d.results.some(
|
|
102
|
+
(r) =>
|
|
103
|
+
(r.interrupted ||
|
|
104
|
+
r.detached ||
|
|
105
|
+
r.status === "interrupted" ||
|
|
106
|
+
r.status === "continued" ||
|
|
107
|
+
r.status === "skipped") &&
|
|
108
|
+
r.progress?.status !== "running",
|
|
109
|
+
) || workflowGraphHasStatus(d, ["paused", "detached"]);
|
|
103
110
|
let totalSummary = d.progressSummary;
|
|
104
111
|
if (!totalSummary) {
|
|
105
112
|
let sawProgress = false;
|
|
@@ -140,11 +147,13 @@ export function renderMultiCompact(d: Details, theme: Theme, now?: number, pulse
|
|
|
140
147
|
);
|
|
141
148
|
|
|
142
149
|
const useResultsDirectly = multiLabel.hasParallelInChain || !d.chainAgents?.length;
|
|
150
|
+
const progressSpan = d.progress?.length ? Math.max(...d.progress.map((p) => p.index + 1)) : 0;
|
|
151
|
+
const resultsSpan = Math.max(d.results.length, progressSpan, d.mode === "parallel" ? (d.totalSteps ?? 0) : 0);
|
|
143
152
|
const displayStart = multiLabel.showActiveGroupOnly ? multiLabel.groupStartIndex : 0;
|
|
144
153
|
const displayEnd = multiLabel.showActiveGroupOnly
|
|
145
154
|
? multiLabel.groupEndIndex
|
|
146
155
|
: useResultsDirectly
|
|
147
|
-
?
|
|
156
|
+
? resultsSpan
|
|
148
157
|
: d.chainAgents!.length;
|
|
149
158
|
const chainEntries = buildChainRenderEntries(d, multiLabel);
|
|
150
159
|
const renderEntries =
|
|
@@ -152,6 +161,7 @@ export function renderMultiCompact(d: Details, theme: Theme, now?: number, pulse
|
|
|
152
161
|
Array.from({ length: displayEnd - displayStart }, (_, offset): ChainRenderEntry => {
|
|
153
162
|
const i = displayStart + offset;
|
|
154
163
|
const r = d.results[i];
|
|
164
|
+
const progressAgent = d.progress?.find((p) => p.index === i)?.agent;
|
|
155
165
|
const fallbackLabel = itemTitle.toLowerCase();
|
|
156
166
|
const rowNumber = multiLabel.showActiveGroupOnly ? i - multiLabel.groupStartIndex + 1 : i + 1;
|
|
157
167
|
return {
|
|
@@ -159,10 +169,11 @@ export function renderMultiCompact(d: Details, theme: Theme, now?: number, pulse
|
|
|
159
169
|
resultIndex: i,
|
|
160
170
|
rowNumber,
|
|
161
171
|
agentName: useResultsDirectly
|
|
162
|
-
? r?.agent || `${fallbackLabel}-${rowNumber}`
|
|
163
|
-
: d.chainAgents![i] || r?.agent || `${fallbackLabel}-${rowNumber}`,
|
|
172
|
+
? r?.agent || progressAgent || `${fallbackLabel}-${rowNumber}`
|
|
173
|
+
: d.chainAgents![i] || r?.agent || progressAgent || `${fallbackLabel}-${rowNumber}`,
|
|
164
174
|
};
|
|
165
175
|
});
|
|
176
|
+
let liveDetailHintShown = false;
|
|
166
177
|
for (const entry of renderEntries) {
|
|
167
178
|
if (entry.kind === "placeholder") {
|
|
168
179
|
const glyph = widgetStepGlyph(entry.status as AsyncJobStep["status"], theme);
|
|
@@ -186,8 +197,24 @@ export function renderMultiCompact(d: Details, theme: Theme, now?: number, pulse
|
|
|
186
197
|
const rowNumber = entry.rowNumber;
|
|
187
198
|
const agentName = entry.agentName;
|
|
188
199
|
if (!r) {
|
|
189
|
-
const
|
|
190
|
-
|
|
200
|
+
const rowLabel = resultRowLabel(d, multiLabel, i, rowNumber);
|
|
201
|
+
const runningProg = d.progress?.find((p) => p.index === i && p.status === "running") as
|
|
202
|
+
| AgentProgress
|
|
203
|
+
| undefined;
|
|
204
|
+
if (runningProg) {
|
|
205
|
+
const runningStats = formatProgressStats(theme, runningProg, true, now);
|
|
206
|
+
const runningLine = `${theme.fg("accent", pulseGlyph(pulseFrame))} ${rowLabel}: ${themeBold(theme, agentName)}${runningStats ? ` ${theme.fg("dim", "·")} ${runningStats}` : ""}`;
|
|
207
|
+
c.addChild(new Text(truncLine(` ${runningLine}`, width), 0, 0));
|
|
208
|
+
const activity = compactCurrentActivity(runningProg, now);
|
|
209
|
+
c.addChild(new Text(truncLine(theme.fg("dim", ` ⎿ ${activity}`), width), 0, 0));
|
|
210
|
+
const expandHint = keyHintIfBound("app.tools.expand", "for live detail");
|
|
211
|
+
if (expandHint) {
|
|
212
|
+
c.addChild(new Text(truncLine(theme.fg("accent", ` Press ${expandHint}`), width), 0, 0));
|
|
213
|
+
liveDetailHintShown = true;
|
|
214
|
+
}
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
c.addChild(new Text(truncLine(theme.fg("dim", ` ◦ ${rowLabel}: ${agentName} · pending`), width), 0, 0));
|
|
191
218
|
continue;
|
|
192
219
|
}
|
|
193
220
|
const output = getSingleResultOutput(r);
|
|
@@ -213,14 +240,20 @@ export function renderMultiCompact(d: Details, theme: Theme, now?: number, pulse
|
|
|
213
240
|
const activity = compactCurrentActivity(rProg, now);
|
|
214
241
|
c.addChild(new Text(truncLine(theme.fg("dim", ` ⎿ ${activity}`), width), 0, 0));
|
|
215
242
|
const expandHint = keyHintIfBound("app.tools.expand", "for live detail");
|
|
216
|
-
if (expandHint)
|
|
243
|
+
if (expandHint) {
|
|
244
|
+
c.addChild(new Text(truncLine(theme.fg("accent", ` Press ${expandHint}`), width), 0, 0));
|
|
245
|
+
liveDetailHintShown = true;
|
|
246
|
+
}
|
|
217
247
|
} else if (
|
|
218
248
|
!rPending &&
|
|
219
|
-
(r.
|
|
249
|
+
(r.status !== "ok" || r.interrupted || r.detached || hasEmptyTextOutputWithoutOutputTarget(r.task, output))
|
|
220
250
|
) {
|
|
221
251
|
c.addChild(
|
|
222
252
|
new Text(
|
|
223
|
-
truncLine(
|
|
253
|
+
truncLine(
|
|
254
|
+
theme.fg(r.status === "error" ? "error" : "dim", ` ⎿ ${resultStatusLine(r, output)}`),
|
|
255
|
+
width,
|
|
256
|
+
),
|
|
224
257
|
0,
|
|
225
258
|
0,
|
|
226
259
|
),
|
|
@@ -233,6 +266,10 @@ export function renderMultiCompact(d: Details, theme: Theme, now?: number, pulse
|
|
|
233
266
|
new Text(truncLine(theme.fg("dim", ` output: ${shortenPath(r.artifactPaths.outputPath)}`), width), 0, 0),
|
|
234
267
|
);
|
|
235
268
|
}
|
|
269
|
+
if (hasRunning && !liveDetailHintShown) {
|
|
270
|
+
const groupHint = keyHintIfBound("app.tools.expand", "for live detail");
|
|
271
|
+
if (groupHint) c.addChild(new Text(truncLine(theme.fg("accent", ` Press ${groupHint}`), width), 0, 0));
|
|
272
|
+
}
|
|
236
273
|
if (d.artifacts)
|
|
237
274
|
c.addChild(new Text(truncLine(theme.fg("dim", ` artifacts: ${shortenPath(d.artifacts.dir)}`), width), 0, 0));
|
|
238
275
|
return c;
|
|
@@ -84,7 +84,8 @@ export function renderSubagentResult(
|
|
|
84
84
|
);
|
|
85
85
|
return container;
|
|
86
86
|
}
|
|
87
|
-
|
|
87
|
+
const liveMultiProgress = (d?.mode === "parallel" || d?.mode === "chain") && (d?.progress?.length ?? 0) > 0;
|
|
88
|
+
if (!d?.results.length && !liveMultiProgress) {
|
|
88
89
|
const t = result.content[0];
|
|
89
90
|
const text = t?.type === "text" ? t.text : "(no output)";
|
|
90
91
|
const contextPrefix = d?.context === "fork" ? `${theme.fg("warning", "[fork]")} ` : "";
|
|
@@ -100,9 +101,9 @@ export function renderSubagentResult(
|
|
|
100
101
|
const isRunning = r.progress?.status === "running";
|
|
101
102
|
const icon = isRunning
|
|
102
103
|
? theme.fg("warning", "running")
|
|
103
|
-
: r.detached
|
|
104
|
+
: r.detached || r.status === "continued"
|
|
104
105
|
? theme.fg("warning", "detached")
|
|
105
|
-
: r.
|
|
106
|
+
: r.status === "ok"
|
|
106
107
|
? theme.fg("success", "ok")
|
|
107
108
|
: theme.fg("error", "failed");
|
|
108
109
|
const contextBadge = d.context === "fork" ? theme.fg("warning", " [fork]") : "";
|
|
@@ -202,11 +203,11 @@ export function renderSubagentResult(
|
|
|
202
203
|
d.results.some((r) => r.progress?.status === "running") ||
|
|
203
204
|
workflowGraphHasStatus(d, ["running"]);
|
|
204
205
|
const ok = d.results.filter(
|
|
205
|
-
(r) => r.progress?.status === "completed" || (r.
|
|
206
|
+
(r) => r.progress?.status === "completed" || (r.status === "ok" && r.progress?.status !== "running"),
|
|
206
207
|
).length;
|
|
207
208
|
const hasEmptyWithoutTarget = d.results.some(
|
|
208
209
|
(r) =>
|
|
209
|
-
r.
|
|
210
|
+
r.status === "ok" &&
|
|
210
211
|
r.progress?.status !== "running" &&
|
|
211
212
|
hasEmptyTextOutputWithoutOutputTarget(r.task, getSingleResultOutput(r)),
|
|
212
213
|
);
|
|
@@ -248,15 +249,14 @@ export function renderSubagentResult(
|
|
|
248
249
|
const modeLabel = d.mode;
|
|
249
250
|
const contextBadge = d.context === "fork" ? theme.fg("warning", " [fork]") : "";
|
|
250
251
|
const multiLabel = buildMultiProgressLabel(d, hasRunning);
|
|
251
|
-
const itemTitle = multiLabel.itemTitle;
|
|
252
252
|
|
|
253
253
|
const chainVis =
|
|
254
254
|
d.chainAgents?.length && !multiLabel.hasParallelInChain
|
|
255
255
|
? d.chainAgents
|
|
256
256
|
.map((agent, i) => {
|
|
257
257
|
const result = d.results[i];
|
|
258
|
-
const isFailed = result && result.
|
|
259
|
-
const isComplete = result && result.
|
|
258
|
+
const isFailed = result && result.status === "error" && result.progress?.status !== "running";
|
|
259
|
+
const isComplete = result && result.status === "ok" && result.progress?.status !== "running";
|
|
260
260
|
const isEmptyWithoutTarget =
|
|
261
261
|
Boolean(result) &&
|
|
262
262
|
Boolean(isComplete) &&
|
|
@@ -293,11 +293,13 @@ export function renderSubagentResult(
|
|
|
293
293
|
}
|
|
294
294
|
|
|
295
295
|
const useResultsDirectly = multiLabel.hasParallelInChain || !d.chainAgents?.length;
|
|
296
|
+
const progressSpan = d.progress?.length ? Math.max(...d.progress.map((p) => p.index + 1)) : 0;
|
|
297
|
+
const resultsSpan = Math.max(d.results.length, progressSpan, d.mode === "parallel" ? (d.totalSteps ?? 0) : 0);
|
|
296
298
|
const displayStart = multiLabel.showActiveGroupOnly ? multiLabel.groupStartIndex : 0;
|
|
297
299
|
const displayEnd = multiLabel.showActiveGroupOnly
|
|
298
300
|
? multiLabel.groupEndIndex
|
|
299
301
|
: useResultsDirectly
|
|
300
|
-
?
|
|
302
|
+
? resultsSpan
|
|
301
303
|
: d.chainAgents!.length;
|
|
302
304
|
const chainEntries = buildChainRenderEntries(d, multiLabel);
|
|
303
305
|
const renderEntries =
|
|
@@ -305,14 +307,15 @@ export function renderSubagentResult(
|
|
|
305
307
|
Array.from({ length: displayEnd - displayStart }, (_, offset): ChainRenderEntry => {
|
|
306
308
|
const i = displayStart + offset;
|
|
307
309
|
const r = d.results[i];
|
|
310
|
+
const progressAgent = d.progress?.find((p) => p.index === i)?.agent;
|
|
308
311
|
const rowNumber = multiLabel.showActiveGroupOnly ? i - multiLabel.groupStartIndex + 1 : i + 1;
|
|
309
312
|
return {
|
|
310
313
|
kind: "result",
|
|
311
314
|
resultIndex: i,
|
|
312
315
|
rowNumber,
|
|
313
316
|
agentName: useResultsDirectly
|
|
314
|
-
? r?.agent || `step-${rowNumber}`
|
|
315
|
-
: d.chainAgents![i] || r?.agent || `step-${rowNumber}`,
|
|
317
|
+
? r?.agent || progressAgent || `step-${rowNumber}`
|
|
318
|
+
: d.chainAgents![i] || r?.agent || progressAgent || `step-${rowNumber}`,
|
|
316
319
|
};
|
|
317
320
|
});
|
|
318
321
|
|
|
@@ -335,8 +338,32 @@ export function renderSubagentResult(
|
|
|
335
338
|
const agentName = entry.agentName;
|
|
336
339
|
|
|
337
340
|
if (!r) {
|
|
338
|
-
const
|
|
339
|
-
|
|
341
|
+
const rowLabel = resultRowLabel(d, multiLabel, i, rowNumber);
|
|
342
|
+
const runningProg = d.progress?.find((p) => p.index === i && p.status === "running") as
|
|
343
|
+
| AgentProgress
|
|
344
|
+
| undefined;
|
|
345
|
+
if (runningProg) {
|
|
346
|
+
const runningStats = ` | ${runningProg.toolCount} tools, ${formatDuration(displayProgressDurationMs(runningProg, options.now))}`;
|
|
347
|
+
c.addChild(
|
|
348
|
+
new Text(
|
|
349
|
+
fit(
|
|
350
|
+
`${theme.fg("warning", "running")} ${rowLabel}: ${theme.bold(theme.fg("warning", agentName))}${runningStats}`,
|
|
351
|
+
),
|
|
352
|
+
0,
|
|
353
|
+
0,
|
|
354
|
+
),
|
|
355
|
+
);
|
|
356
|
+
const progressSnapshotNow = snapshotNowForProgress(runningProg, options.now);
|
|
357
|
+
const liveStatusLine = buildLiveStatusLine(runningProg, progressSnapshotNow);
|
|
358
|
+
if (liveStatusLine) {
|
|
359
|
+
c.addChild(new Text(fit(theme.fg("accent", ` ${liveStatusLine}`)), 0, 0));
|
|
360
|
+
}
|
|
361
|
+
const expandHint = keyHintIfBound("app.tools.expand", "for live detail");
|
|
362
|
+
if (expandHint) c.addChild(new Text(fit(theme.fg("accent", ` Press ${expandHint}`)), 0, 0));
|
|
363
|
+
c.addChild(new Spacer(1));
|
|
364
|
+
continue;
|
|
365
|
+
}
|
|
366
|
+
c.addChild(new Text(fit(theme.fg("dim", ` ${rowLabel}: ${agentName}`)), 0, 0));
|
|
340
367
|
c.addChild(new Text(theme.fg("dim", ` status: pending`), 0, 0));
|
|
341
368
|
c.addChild(new Spacer(1));
|
|
342
369
|
continue;
|
|
@@ -352,11 +379,13 @@ export function renderSubagentResult(
|
|
|
352
379
|
const resultOutput = getSingleResultOutput(r);
|
|
353
380
|
const statusIcon = rRunning
|
|
354
381
|
? theme.fg("warning", "running")
|
|
355
|
-
: r.
|
|
382
|
+
: r.status === "error"
|
|
356
383
|
? theme.fg("error", "failed")
|
|
357
|
-
:
|
|
358
|
-
? theme.fg("warning",
|
|
359
|
-
:
|
|
384
|
+
: r.status === "skipped" || r.status === "interrupted" || r.status === "continued"
|
|
385
|
+
? theme.fg("warning", r.status)
|
|
386
|
+
: hasEmptyTextOutputWithoutOutputTarget(r.task, resultOutput)
|
|
387
|
+
? theme.fg("warning", "warning")
|
|
388
|
+
: theme.fg("success", "done");
|
|
360
389
|
const stats = rProg
|
|
361
390
|
? ` | ${rProg.toolCount} tools, ${formatDuration(displayProgressDurationMs(rProg, options.now))}`
|
|
362
391
|
: "";
|
|
@@ -65,7 +65,7 @@ export function subagentResultRenderKey(
|
|
|
65
65
|
...details.results.map((entry) =>
|
|
66
66
|
[
|
|
67
67
|
entry.agent,
|
|
68
|
-
entry.
|
|
68
|
+
entry.status,
|
|
69
69
|
entry.interrupted === true ? "interrupted" : "",
|
|
70
70
|
entry.detached === true ? "detached" : "",
|
|
71
71
|
progressRenderKey(entry.progress),
|
|
@@ -134,8 +134,10 @@ export function firstOutputLine(text: string): string {
|
|
|
134
134
|
|
|
135
135
|
export function resultStatusLine(result: Details["results"][number], output: string): string {
|
|
136
136
|
if (result.detached) return result.detachedReason ? `Detached: ${result.detachedReason}` : "Detached";
|
|
137
|
-
if (result.
|
|
138
|
-
if (result.
|
|
137
|
+
if (result.status === "continued") return "Continued";
|
|
138
|
+
if (result.interrupted || result.status === "interrupted") return "Paused";
|
|
139
|
+
if (result.status === "skipped") return result.error ? `Skipped: ${result.error}` : "Skipped";
|
|
140
|
+
if (result.status === "error") return `Error: ${result.error ?? (firstOutputLine(output) || "failed")}`;
|
|
139
141
|
if (hasEmptyTextOutputWithoutOutputTarget(result.task, output)) return "Done (no text output)";
|
|
140
142
|
return "Done";
|
|
141
143
|
}
|
|
@@ -148,9 +150,10 @@ export function resultGlyph(
|
|
|
148
150
|
pulseFrame?: number,
|
|
149
151
|
): string {
|
|
150
152
|
if (running) return theme.fg("accent", pulseGlyph(pulseFrame));
|
|
151
|
-
if (result.detached) return theme.fg("warning", "■");
|
|
152
|
-
if (result.interrupted
|
|
153
|
-
|
|
153
|
+
if (result.detached || result.status === "continued") return theme.fg("warning", "■");
|
|
154
|
+
if (result.interrupted || result.status === "interrupted" || result.status === "skipped")
|
|
155
|
+
return theme.fg("warning", "■");
|
|
156
|
+
if (result.status === "error") return theme.fg("error", "✗");
|
|
154
157
|
if (hasEmptyTextOutputWithoutOutputTarget(result.task, output)) return theme.fg("warning", "✓");
|
|
155
158
|
return theme.fg("success", "✓");
|
|
156
159
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { keyHintIfBound } from "@bastani/atomic";
|
|
2
|
-
import { shortenPath } from "../shared/formatters.ts";
|
|
3
2
|
import { aggregateStepStatus, formatParallelOutcome } from "../shared/status-format.ts";
|
|
4
3
|
import type { AsyncJobState } from "../shared/types.ts";
|
|
5
4
|
import { buildAsyncChainStepSpans } from "./render-chain-graph.ts";
|
|
@@ -8,7 +7,6 @@ import {
|
|
|
8
7
|
modelThinkingBadge,
|
|
9
8
|
widgetActivity,
|
|
10
9
|
widgetJobName,
|
|
11
|
-
widgetOutputPath,
|
|
12
10
|
widgetStats,
|
|
13
11
|
widgetStatusGlyph,
|
|
14
12
|
widgetStepActivity,
|
|
@@ -130,8 +128,6 @@ export function foregroundStyleWidgetStepLines(
|
|
|
130
128
|
if (step.status === "running") {
|
|
131
129
|
const expandHint = keyHintIfBound("app.tools.expand", "for live detail");
|
|
132
130
|
if (!expanded && expandHint) lines.push(` ${theme.fg("accent", `Press ${expandHint}`)}`);
|
|
133
|
-
const output = widgetOutputPath(job, step);
|
|
134
|
-
if (output) lines.push(` ${theme.fg("dim", `output: ${shortenPath(output)}`)}`);
|
|
135
131
|
if (expanded) {
|
|
136
132
|
const liveStatus = buildLiveStatusLine(step, job.updatedAt);
|
|
137
133
|
if (liveStatus && liveStatus !== activity) lines.push(` ${theme.fg("accent", liveStatus)}`);
|
|
@@ -247,10 +243,6 @@ export function compactSingleWidgetLines(
|
|
|
247
243
|
pulseFrame,
|
|
248
244
|
))
|
|
249
245
|
lines.push(` ${nestedLine}`);
|
|
250
|
-
if (step.status === "running") {
|
|
251
|
-
const output = widgetOutputPath(job, step);
|
|
252
|
-
if (output) lines.push(` ${theme.fg("dim", `output: ${shortenPath(output)}`)}`);
|
|
253
|
-
}
|
|
254
246
|
}
|
|
255
247
|
const expandHint = keyHintIfBound("app.tools.expand", "for live detail");
|
|
256
248
|
if (expandHint && job.steps.some((step) => step.status === "running"))
|
|
@@ -170,28 +170,6 @@ function getWidgetOwnerKey(ctx: ExtensionContext): string {
|
|
|
170
170
|
return `${sessionOwner}|cwd:${cwdOwner}`;
|
|
171
171
|
}
|
|
172
172
|
|
|
173
|
-
function widgetStatusText(jobs: AsyncJobState[]): string | undefined {
|
|
174
|
-
if (jobs.length === 0) return undefined;
|
|
175
|
-
const counts = new Map<string, number>();
|
|
176
|
-
for (const job of jobs) counts.set(job.status, (counts.get(job.status) ?? 0) + 1);
|
|
177
|
-
const ordered = ["running", "queued", "complete", "failed", "paused"];
|
|
178
|
-
const parts = ordered
|
|
179
|
-
.map((status) => {
|
|
180
|
-
const count = counts.get(status) ?? 0;
|
|
181
|
-
return count > 0 ? `${count} ${status}` : undefined;
|
|
182
|
-
})
|
|
183
|
-
.filter((part): part is string => part !== undefined);
|
|
184
|
-
return `Async agents: ${parts.join(", ")}`;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
function setWidgetStatus(ctx: ExtensionContext, jobs: AsyncJobState[]): void {
|
|
188
|
-
try {
|
|
189
|
-
ctx.ui.setStatus?.(WIDGET_KEY, widgetStatusText(jobs));
|
|
190
|
-
} catch {
|
|
191
|
-
// Status mirroring must never prevent the primary widget render path.
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
|
|
195
173
|
function requestWidgetRender(ctx: ExtensionContext): void {
|
|
196
174
|
(ctx as RenderRequestingContext).ui.requestRender?.();
|
|
197
175
|
}
|
|
@@ -343,7 +321,6 @@ export function renderWidget(ctx: ExtensionContext, jobs: AsyncJobState[], owner
|
|
|
343
321
|
if (requestedSurface.activeOwner && requestedSurface.activeOwner !== owner) return;
|
|
344
322
|
if (state.surfaceKey && getSurfaceState(state.surfaceKey).activeOwner !== owner) return;
|
|
345
323
|
if (state.mounted && state.mountedOwnerKey !== ownerKey) return;
|
|
346
|
-
if (ctx.hasUI) setWidgetStatus(ctx, []);
|
|
347
324
|
stopWidgetAnimation(ctx, owner);
|
|
348
325
|
return;
|
|
349
326
|
}
|
|
@@ -363,7 +340,6 @@ export function renderWidget(ctx: ExtensionContext, jobs: AsyncJobState[], owner
|
|
|
363
340
|
state.latestJobs = [...jobs];
|
|
364
341
|
refreshWidgetSnapshot(state, jobs);
|
|
365
342
|
}
|
|
366
|
-
setWidgetStatus(ctx, jobs);
|
|
367
343
|
if (!state.mounted) {
|
|
368
344
|
const surface = getSurfaceState(requestedSurfaceKey);
|
|
369
345
|
if (surface.activeOwner && surface.activeOwner !== owner) return;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bastani/web-access",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.13-alpha.1",
|
|
4
4
|
"private": true,
|
|
5
5
|
"description": "Atomic extension for web search, URL fetching, GitHub repo cloning, PDF/video extraction. Fork of: https://github.com/nicobailon/pi-web-access",
|
|
6
6
|
"contributors": [
|
|
@@ -6,6 +6,31 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.9.13-alpha.1] - 2026-08-05
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- Added four user-initiated workflow lifecycle notices — `started`, `paused`, `quit`, and `resumed` — so the main chat learns when a top-level background run begins, stops, or picks back up. Each travels the same steer delivery, capped-backoff retry, and notice-card path the failure notice already uses, so an agent waiting on a background run no longer mistakes a deliberate stop for work still in progress. `WORKFLOW STARTED` (`▶`), `WORKFLOW PAUSED` (`⏸`, warning tone), `WORKFLOW QUIT` (`⏹`, warning tone, also reporting whether the run stayed resumable), and `WORKFLOW RESUMED` (`▶`) render as cards; the paused and quit text states that the stop was deliberate and user-requested and tells the model not to resume the run or take over the work unless asked, hinting `/workflow resume <run-id>`, while the resumed text does not, because the run is progressing again ([#2177](https://github.com/bastani-inc/atomic/issues/2177)).
|
|
14
|
+
- Only user actions raise those notices. `/workflow <name>`, `/workflow pause`, `/workflow quit`, and `/workflow resume` notify; the matching `workflow({ action: "run" | "pause" | "quit" | "resume" })` tool calls stay silent because the tool result already reports them, and `/workflow interrupt` raises nothing. Engine-internal transitions stay silent as well: a notice exists only where a control path recorded an actor, which is what keeps answering a human-in-the-loop prompt, per-stage control, and the resume-acknowledgement pass out of the chat ([#2177](https://github.com/bastani-inc/atomic/issues/2177)).
|
|
15
|
+
- Lifecycle notices now carry two attributions. *Origin* — who launched the run — renders on every kind as "which you started" or "which the user started", is recorded once at dispatch, survives session restore and durable resume, and is inherited by a continuation from the run it continues rather than recomputed. *Actor* — who performed this one event — renders as "The user paused". A run with no recorded origin, including a legacy or restored snapshot, omits the clause entirely instead of guessing ([#2177](https://github.com/bastani-inc/atomic/issues/2177)).
|
|
16
|
+
- One request now produces exactly one notice. A whole-run pause or resume reports at run scope; a stage-scoped pause or resume that leaves siblings paused reports at stage scope, and one that stops or restarts the whole run reports the run instead, never both. A quit reports the quit alone rather than the pause it publishes on the way. Because control actions are reversible, they are deduplicated by run id together with the occurrence timestamp, so pause → resume → pause → resume notifies four times while repeated snapshot invalidations at one unchanged state notify once. Resuming reports a resume and never a start, whoever requested it: resuming a failed or blocked run launches a continuation under a fresh id whose notice names both run ids, while resuming a quit run reuses the original workflow id so durable checkpoints replay and its notice names the one id. A run already started, paused, or quit when notifications install (restore, replay, `/reload`, session-preserving reinstall) stays silent, and nested child runs never notify at top level. The default `workflowNotifications.notifyOn` becomes `["started", "completed", "failed", "blocked", "awaiting_input", "paused", "quit", "resumed"]`; a config that pins `notifyOn` explicitly keeps exactly the kinds it lists ([#2177](https://github.com/bastani-inc/atomic/issues/2177)).
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
- Workflow stage resource loading now carries typed subagent policy in session options and no longer mutates process-global child environment flags during reload. Concurrent stage creation preserves tool allowlists and orchestration limits without the process-era isolation race ([#2188](https://github.com/bastani-inc/atomic/issues/2188)).
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
|
|
24
|
+
- Fixed thrown transient stage failures — rate limits, provider outages, network timeouts, transport errors — to retry the current model with bounded exponential backoff from `settings.retry` before advancing through `fallbackModels`; disabling retry keeps immediate candidate advancement. Failures another request to the same model cannot repair — a rejected credential, an unavailable model, an incompatible request — skip the same-model retry and advance to the next candidate immediately, for prompt delivery and session creation alike ([#2170](https://github.com/bastani-inc/atomic/issues/2170)).
|
|
25
|
+
- Fixed a same-candidate stage retry losing the stage prompt. The retry resumed the existing session turn with a transcript that no longer ended in the prompt it was resuming, which the agent rejects; the prompt is now retained for that path and still re-sent on the re-prompt path ([#2170](https://github.com/bastani-inc/atomic/issues/2170)).
|
|
26
|
+
- Fixed a same-candidate stage retry stopping outright when the failed attempt had already streamed a completed assistant message. Resuming the existing turn is now attempted only when the transcript, as converted for the provider, still ends in a message the agent can continue from; otherwise the retry re-sends the prompt, which recovers instead of failing. Messages that convert away — a note excluded from context, an empty branch summary — no longer look like a valid tail ([#2170](https://github.com/bastani-inc/atomic/issues/2170)).
|
|
27
|
+
- Fixed an eagerly created stage session never reaching its `fallbackModels`. A session created before any prompt — by an eager stage call, a control attach, or `ctx.__ensureSession()` — retried only its first candidate and then failed the stage. It now walks the configured chain, and a failure that exhausts the chain is no longer cached and replayed to every later caller ([#2170](https://github.com/bastani-inc/atomic/issues/2170)).
|
|
28
|
+
- Fixed a paused eager session creation dropping its replacement objective when the stage had explicit model candidates. The resumed text is now authoritative for the next prompt and is sent exactly once ([#2170](https://github.com/bastani-inc/atomic/issues/2170)).
|
|
29
|
+
- Fixed a context overflow that compaction had already failed to resolve being retried on the same candidate for the whole `settings.retry` budget. Re-sending an identical request cannot fit a context compaction could not shrink, so the chain now advances immediately while still treating the failure as fallbackable ([#2170](https://github.com/bastani-inc/atomic/issues/2170)).
|
|
30
|
+
- Fixed a stage running two candidate walks at once. Advancing a candidate released the shared creation gate while the walk was still creating the next session, so a concurrent `ctx.__ensureSession()` or a first `ctx.prompt()` could start a second walk, duplicate provider work, and leave the losing session live and undisposed. Concurrent callers now join the creation already in flight ([#2170](https://github.com/bastani-inc/atomic/issues/2170)).
|
|
31
|
+
- Fixed a controlled pause that both started and finished while a stage session was still being created losing its replacement objective, so the stale objective was prompted instead ([#2170](https://github.com/bastani-inc/atomic/issues/2170)).
|
|
32
|
+
- Fixed a controlled pause during a same-candidate continuation aborting the stage unrecoverably. The abort a pause causes is no longer classified as a terminal model failure: the pause settles, and resuming with a replacement objective re-prompts on the same candidate instead of spending a fallback ([#2170](https://github.com/bastani-inc/atomic/issues/2170)).
|
|
33
|
+
|
|
9
34
|
## [0.9.12] - 2026-08-04
|
|
10
35
|
|
|
11
36
|
Cumulative release of the `0.9.12-alpha.1` prerelease. The summary below covers the user-visible outcome of that work; the per-change detail remains in the prerelease section below.
|