@bastani/atomic 0.9.8-alpha.1 → 0.9.9-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 +42 -0
- package/dist/builtin/cursor/CHANGELOG.md +12 -0
- package/dist/builtin/cursor/package.json +2 -2
- package/dist/builtin/intercom/CHANGELOG.md +12 -0
- package/dist/builtin/intercom/package.json +1 -1
- package/dist/builtin/mcp/CHANGELOG.md +12 -0
- package/dist/builtin/mcp/package.json +1 -1
- package/dist/builtin/subagents/CHANGELOG.md +13 -0
- package/dist/builtin/subagents/package.json +1 -1
- package/dist/builtin/subagents/src/runs/background/async-execution-chain.ts +2 -0
- package/dist/builtin/subagents/src/runs/background/async-execution-common.ts +7 -1
- package/dist/builtin/subagents/src/runs/background/async-execution-single.ts +2 -0
- package/dist/builtin/subagents/src/runs/background/async-execution-types.ts +8 -2
- package/dist/builtin/subagents/src/runs/foreground/chain-execution-parallel-runner.ts +2 -0
- package/dist/builtin/subagents/src/runs/foreground/chain-execution-sequential-step.ts +2 -0
- package/dist/builtin/subagents/src/runs/foreground/execution-attempt.ts +2 -1
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-async.ts +2 -0
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-parallel-task.ts +2 -0
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-resume.ts +2 -0
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-single.ts +2 -0
- package/dist/builtin/subagents/src/runs/shared/pi-args.ts +6 -0
- package/dist/builtin/subagents/src/shared/types-config.ts +4 -0
- package/dist/builtin/subagents/src/shared/types-depth.ts +29 -2
- package/dist/builtin/web-access/CHANGELOG.md +12 -0
- package/dist/builtin/web-access/package.json +1 -1
- package/dist/builtin/workflows/CHANGELOG.md +34 -0
- package/dist/builtin/workflows/README.md +17 -8
- package/dist/builtin/workflows/builtin/goal-prompts.ts +8 -2
- package/dist/builtin/workflows/builtin/open-claude-design-utils.ts +26 -9
- package/dist/builtin/workflows/builtin/ralph-forked-prompts.ts +1 -1
- package/dist/builtin/workflows/builtin/ralph-reviewer-prompt.ts +8 -3
- package/dist/builtin/workflows/builtin/ralph-runner.ts +2 -0
- package/dist/builtin/workflows/builtin/shared-prompts.ts +24 -1
- package/dist/builtin/workflows/package.json +1 -1
- package/dist/builtin/workflows/src/durable/backend.ts +53 -15
- package/dist/builtin/workflows/src/durable/completed-catalog.ts +245 -0
- package/dist/builtin/workflows/src/durable/completed-inspection.ts +213 -0
- package/dist/builtin/workflows/src/durable/dbos-backend.ts +120 -170
- package/dist/builtin/workflows/src/durable/dbos-envelope.ts +84 -8
- package/dist/builtin/workflows/src/durable/dbos-metadata.ts +98 -0
- package/dist/builtin/workflows/src/durable/dbos-tombstone.ts +27 -0
- package/dist/builtin/workflows/src/durable/factory.ts +1 -1
- package/dist/builtin/workflows/src/durable/file-backend.ts +247 -241
- package/dist/builtin/workflows/src/durable/file-lock.ts +153 -0
- package/dist/builtin/workflows/src/durable/file-state.ts +104 -0
- package/dist/builtin/workflows/src/durable/format-version.ts +12 -0
- package/dist/builtin/workflows/src/durable/index.ts +12 -0
- package/dist/builtin/workflows/src/durable/resume-catalog.ts +16 -27
- package/dist/builtin/workflows/src/durable/resume-eligibility.ts +20 -0
- package/dist/builtin/workflows/src/durable/resume-runtime.ts +29 -29
- package/dist/builtin/workflows/src/durable/scoped-backend.ts +20 -3
- package/dist/builtin/workflows/src/durable/stage-primitive.ts +29 -8
- package/dist/builtin/workflows/src/durable/types.ts +3 -0
- package/dist/builtin/workflows/src/engine/primitives/task.ts +1 -0
- package/dist/builtin/workflows/src/engine/run.ts +14 -14
- package/dist/builtin/workflows/src/extension/extension-lifecycle.ts +39 -9
- package/dist/builtin/workflows/src/extension/extension-runtime-state.ts +10 -0
- package/dist/builtin/workflows/src/extension/runtime-durable-resume.ts +133 -0
- package/dist/builtin/workflows/src/extension/runtime.ts +15 -40
- package/dist/builtin/workflows/src/extension/wiring.ts +9 -6
- package/dist/builtin/workflows/src/extension/workflow-durable-resume-command.ts +226 -0
- package/dist/builtin/workflows/src/extension/workflow-prompts.ts +1 -0
- package/dist/builtin/workflows/src/extension/workflow-run-control-command.ts +66 -112
- package/dist/builtin/workflows/src/extension/workflow-schema.ts +5 -5
- package/dist/builtin/workflows/src/extension/workflow-tool-control.ts +16 -1
- package/dist/builtin/workflows/src/runs/foreground/executor-direct-helpers.ts +50 -43
- package/dist/builtin/workflows/src/runs/foreground/executor-direct-output.ts +91 -0
- package/dist/builtin/workflows/src/runs/foreground/executor-direct.ts +95 -46
- package/dist/builtin/workflows/src/runs/foreground/executor-stage-call.ts +3 -1
- package/dist/builtin/workflows/src/runs/foreground/executor-task-prompts.ts +1 -1
- package/dist/builtin/workflows/src/runs/foreground/executor-types.ts +3 -0
- package/dist/builtin/workflows/src/runs/foreground/stage-runner-controller.ts +1 -1
- package/dist/builtin/workflows/src/runs/foreground/stage-runner-options.ts +36 -7
- package/dist/builtin/workflows/src/runs/shared/worktree-cache-lifecycle.ts +25 -0
- package/dist/builtin/workflows/src/runs/shared/worktree-cwd.ts +103 -0
- package/dist/builtin/workflows/src/runs/shared/worktree-generation.ts +57 -0
- package/dist/builtin/workflows/src/runs/shared/worktree-git.ts +134 -8
- package/dist/builtin/workflows/src/runs/shared/worktree.ts +2 -0
- package/dist/builtin/workflows/src/shared/resumable-workflow-notices.ts +43 -0
- package/dist/builtin/workflows/src/shared/timing.ts +4 -0
- package/dist/builtin/workflows/src/shared/types.ts +5 -3
- package/dist/builtin/workflows/src/tui/graph-view-constants.ts +1 -0
- package/dist/builtin/workflows/src/tui/graph-view-input.ts +24 -14
- package/dist/builtin/workflows/src/tui/workflow-resume-selector.ts +43 -13
- package/dist/core/agent-session-auto-compaction.d.ts.map +1 -1
- package/dist/core/agent-session-auto-compaction.js +5 -7
- package/dist/core/agent-session-auto-compaction.js.map +1 -1
- package/dist/core/agent-session-compaction.d.ts +6 -34
- package/dist/core/agent-session-compaction.d.ts.map +1 -1
- package/dist/core/agent-session-compaction.js +95 -233
- package/dist/core/agent-session-compaction.js.map +1 -1
- package/dist/core/agent-session-message-queue.d.ts +0 -4
- package/dist/core/agent-session-message-queue.d.ts.map +1 -1
- package/dist/core/agent-session-message-queue.js +1 -5
- package/dist/core/agent-session-message-queue.js.map +1 -1
- package/dist/core/agent-session-methods.d.ts +5 -6
- 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-types.d.ts +2 -12
- package/dist/core/agent-session-types.d.ts.map +1 -1
- package/dist/core/agent-session-types.js.map +1 -1
- package/dist/core/compaction/branch-summarization.d.ts +1 -1
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js +1 -2
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/compaction/compaction-boundary.d.ts +9 -0
- package/dist/core/compaction/compaction-boundary.d.ts.map +1 -0
- package/dist/core/compaction/compaction-boundary.js +115 -0
- package/dist/core/compaction/compaction-boundary.js.map +1 -0
- package/dist/core/compaction/compaction-parameters.d.ts +5 -0
- package/dist/core/compaction/compaction-parameters.d.ts.map +1 -0
- package/dist/core/compaction/compaction-parameters.js +27 -0
- package/dist/core/compaction/compaction-parameters.js.map +1 -0
- package/dist/core/compaction/compaction-runner.d.ts +14 -0
- package/dist/core/compaction/compaction-runner.d.ts.map +1 -0
- package/dist/core/compaction/compaction-runner.js +29 -0
- package/dist/core/compaction/compaction-runner.js.map +1 -0
- package/dist/core/compaction/compaction-types.d.ts +79 -0
- package/dist/core/compaction/compaction-types.d.ts.map +1 -0
- package/dist/core/compaction/compaction-types.js +6 -0
- package/dist/core/compaction/compaction-types.js.map +1 -0
- package/dist/core/compaction/deleted-ranges.d.ts +6 -0
- package/dist/core/compaction/deleted-ranges.d.ts.map +1 -0
- package/dist/core/compaction/deleted-ranges.js +134 -0
- package/dist/core/compaction/deleted-ranges.js.map +1 -0
- package/dist/core/compaction/index.d.ts +7 -1
- package/dist/core/compaction/index.d.ts.map +1 -1
- package/dist/core/compaction/index.js +7 -1
- package/dist/core/compaction/index.js.map +1 -1
- package/dist/core/compaction/range-planner.d.ts +21 -0
- package/dist/core/compaction/range-planner.d.ts.map +1 -0
- package/dist/core/compaction/range-planner.js +145 -0
- package/dist/core/compaction/range-planner.js.map +1 -0
- package/dist/core/compaction/transcript-serialization.d.ts +11 -0
- package/dist/core/compaction/transcript-serialization.d.ts.map +1 -0
- package/dist/core/compaction/transcript-serialization.js +104 -0
- package/dist/core/compaction/transcript-serialization.js.map +1 -0
- package/dist/core/extensions/context-types.d.ts +2 -2
- package/dist/core/extensions/context-types.d.ts.map +1 -1
- package/dist/core/extensions/context-types.js.map +1 -1
- package/dist/core/extensions/event-results.d.ts +2 -2
- package/dist/core/extensions/event-results.d.ts.map +1 -1
- package/dist/core/extensions/event-results.js.map +1 -1
- package/dist/core/extensions/session-events.d.ts +7 -7
- package/dist/core/extensions/session-events.d.ts.map +1 -1
- package/dist/core/extensions/session-events.js.map +1 -1
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/messages.d.ts +4 -0
- package/dist/core/messages.d.ts.map +1 -1
- package/dist/core/messages.js +11 -0
- package/dist/core/messages.js.map +1 -1
- package/dist/core/provider-context-usage.d.ts.map +1 -1
- package/dist/core/provider-context-usage.js +1 -2
- package/dist/core/provider-context-usage.js.map +1 -1
- package/dist/core/session-manager-archive.d.ts +2 -1
- package/dist/core/session-manager-archive.d.ts.map +1 -1
- package/dist/core/session-manager-archive.js +2 -2
- package/dist/core/session-manager-archive.js.map +1 -1
- package/dist/core/session-manager-classification.d.ts +9 -0
- package/dist/core/session-manager-classification.d.ts.map +1 -0
- package/dist/core/session-manager-classification.js +37 -0
- package/dist/core/session-manager-classification.js.map +1 -0
- package/dist/core/session-manager-core.d.ts +4 -4
- package/dist/core/session-manager-core.d.ts.map +1 -1
- package/dist/core/session-manager-core.js +13 -8
- package/dist/core/session-manager-core.js.map +1 -1
- package/dist/core/session-manager-entries.d.ts +4 -3
- package/dist/core/session-manager-entries.d.ts.map +1 -1
- package/dist/core/session-manager-entries.js +12 -10
- package/dist/core/session-manager-entries.js.map +1 -1
- package/dist/core/session-manager-history.d.ts +6 -23
- package/dist/core/session-manager-history.d.ts.map +1 -1
- package/dist/core/session-manager-history.js +23 -256
- package/dist/core/session-manager-history.js.map +1 -1
- package/dist/core/session-manager-list.d.ts.map +1 -1
- package/dist/core/session-manager-list.js +3 -3
- package/dist/core/session-manager-list.js.map +1 -1
- package/dist/core/session-manager-storage.d.ts +1 -1
- package/dist/core/session-manager-storage.d.ts.map +1 -1
- package/dist/core/session-manager-storage.js +3 -2
- package/dist/core/session-manager-storage.js.map +1 -1
- package/dist/core/session-manager-types.d.ts +14 -15
- package/dist/core/session-manager-types.d.ts.map +1 -1
- package/dist/core/session-manager-types.js.map +1 -1
- package/dist/core/session-manager.d.ts +3 -2
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +1 -1
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +1 -1
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/main-session.d.ts +1 -0
- package/dist/main-session.d.ts.map +1 -1
- package/dist/main-session.js +7 -0
- package/dist/main-session.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +2 -2
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/chat-message-renderer.d.ts +4 -1
- package/dist/modes/interactive/components/chat-message-renderer.d.ts.map +1 -1
- package/dist/modes/interactive/components/chat-message-renderer.js +12 -22
- package/dist/modes/interactive/components/chat-message-renderer.js.map +1 -1
- package/dist/modes/interactive/components/chat-session-host-events.d.ts.map +1 -1
- package/dist/modes/interactive/components/chat-session-host-events.js +5 -11
- package/dist/modes/interactive/components/chat-session-host-events.js.map +1 -1
- package/dist/modes/interactive/components/chat-session-host-rendering.d.ts.map +1 -1
- package/dist/modes/interactive/components/chat-session-host-rendering.js +3 -0
- package/dist/modes/interactive/components/chat-session-host-rendering.js.map +1 -1
- package/dist/modes/interactive/components/chat-session-host-state.d.ts +1 -0
- package/dist/modes/interactive/components/chat-session-host-state.d.ts.map +1 -1
- package/dist/modes/interactive/components/chat-session-host-state.js +1 -0
- package/dist/modes/interactive/components/chat-session-host-state.js.map +1 -1
- package/dist/modes/interactive/components/chat-session-host-utils.d.ts.map +1 -1
- package/dist/modes/interactive/components/chat-session-host-utils.js +1 -1
- package/dist/modes/interactive/components/chat-session-host-utils.js.map +1 -1
- package/dist/modes/interactive/components/chat-session-host.d.ts.map +1 -1
- package/dist/modes/interactive/components/chat-session-host.js +1 -0
- package/dist/modes/interactive/components/chat-session-host.js.map +1 -1
- package/dist/modes/interactive/components/compaction-boundary-message.d.ts +20 -0
- package/dist/modes/interactive/components/compaction-boundary-message.d.ts.map +1 -0
- package/dist/modes/interactive/components/compaction-boundary-message.js +48 -0
- package/dist/modes/interactive/components/compaction-boundary-message.js.map +1 -0
- package/dist/modes/interactive/components/index.d.ts +1 -1
- package/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/dist/modes/interactive/components/index.js +1 -1
- package/dist/modes/interactive/components/index.js.map +1 -1
- package/dist/modes/interactive/components/session-selector-list.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector-list.js +3 -0
- package/dist/modes/interactive/components/session-selector-list.js.map +1 -1
- package/dist/modes/interactive/interactive-agent-events.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-agent-events.js +3 -47
- package/dist/modes/interactive/interactive-agent-events.js.map +1 -1
- package/dist/modes/interactive/interactive-mode-deps.d.ts +2 -2
- package/dist/modes/interactive/interactive-mode-deps.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode-deps.js +1 -1
- package/dist/modes/interactive/interactive-mode-deps.js.map +1 -1
- package/dist/modes/interactive/interactive-mode-surface.d.ts +5 -3
- package/dist/modes/interactive/interactive-mode-surface.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode-surface.js.map +1 -1
- package/dist/modes/interactive/interactive-render-chat.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-render-chat.js +21 -12
- package/dist/modes/interactive/interactive-render-chat.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts +3 -5
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +1 -6
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-command-handler.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-command-handler.js +0 -4
- package/dist/modes/rpc/rpc-command-handler.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +2 -11
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/docs/compaction.md +97 -772
- package/docs/extensions.md +25 -29
- package/docs/json.md +2 -2
- package/docs/rpc.md +32 -24
- package/docs/sdk.md +3 -3
- package/docs/session-format.md +49 -30
- package/docs/sessions.md +5 -3
- package/docs/settings.md +14 -4
- package/docs/usage.md +1 -1
- package/docs/workflows.md +30 -15
- package/examples/extensions/custom-compaction.ts +14 -58
- package/examples/extensions/handoff.ts +2 -3
- package/npm-shrinkwrap.json +23 -23
- package/package.json +2 -2
- package/dist/core/compaction/context-assistant-turns.d.ts +0 -42
- package/dist/core/compaction/context-assistant-turns.d.ts.map +0 -1
- package/dist/core/compaction/context-assistant-turns.js +0 -87
- package/dist/core/compaction/context-assistant-turns.js.map +0 -1
- package/dist/core/compaction/context-compaction-critical.d.ts +0 -15
- package/dist/core/compaction/context-compaction-critical.d.ts.map +0 -1
- package/dist/core/compaction/context-compaction-critical.js +0 -57
- package/dist/core/compaction/context-compaction-critical.js.map +0 -1
- package/dist/core/compaction/context-compaction-eviction-alternates.d.ts +0 -18
- package/dist/core/compaction/context-compaction-eviction-alternates.d.ts.map +0 -1
- package/dist/core/compaction/context-compaction-eviction-alternates.js +0 -186
- package/dist/core/compaction/context-compaction-eviction-alternates.js.map +0 -1
- package/dist/core/compaction/context-compaction-eviction.d.ts +0 -12
- package/dist/core/compaction/context-compaction-eviction.d.ts.map +0 -1
- package/dist/core/compaction/context-compaction-eviction.js +0 -222
- package/dist/core/compaction/context-compaction-eviction.js.map +0 -1
- package/dist/core/compaction/context-compaction-metrics.d.ts +0 -28
- package/dist/core/compaction/context-compaction-metrics.d.ts.map +0 -1
- package/dist/core/compaction/context-compaction-metrics.js +0 -107
- package/dist/core/compaction/context-compaction-metrics.js.map +0 -1
- package/dist/core/compaction/context-compaction-prompt.d.ts +0 -9
- package/dist/core/compaction/context-compaction-prompt.d.ts.map +0 -1
- package/dist/core/compaction/context-compaction-prompt.js +0 -163
- package/dist/core/compaction/context-compaction-prompt.js.map +0 -1
- package/dist/core/compaction/context-compaction-runner.d.ts +0 -11
- package/dist/core/compaction/context-compaction-runner.d.ts.map +0 -1
- package/dist/core/compaction/context-compaction-runner.js +0 -273
- package/dist/core/compaction/context-compaction-runner.js.map +0 -1
- package/dist/core/compaction/context-compaction-strategy.d.ts +0 -5
- package/dist/core/compaction/context-compaction-strategy.d.ts.map +0 -1
- package/dist/core/compaction/context-compaction-strategy.js +0 -27
- package/dist/core/compaction/context-compaction-strategy.js.map +0 -1
- package/dist/core/compaction/context-compaction-types.d.ts +0 -75
- package/dist/core/compaction/context-compaction-types.d.ts.map +0 -1
- package/dist/core/compaction/context-compaction-types.js +0 -6
- package/dist/core/compaction/context-compaction-types.js.map +0 -1
- package/dist/core/compaction/context-compaction.d.ts +0 -10
- package/dist/core/compaction/context-compaction.d.ts.map +0 -1
- package/dist/core/compaction/context-compaction.js +0 -8
- package/dist/core/compaction/context-compaction.js.map +0 -1
- package/dist/core/compaction/context-deletion-application.d.ts +0 -14
- package/dist/core/compaction/context-deletion-application.d.ts.map +0 -1
- package/dist/core/compaction/context-deletion-application.js +0 -261
- package/dist/core/compaction/context-deletion-application.js.map +0 -1
- package/dist/core/compaction/context-deletion-store.d.ts +0 -78
- package/dist/core/compaction/context-deletion-store.d.ts.map +0 -1
- package/dist/core/compaction/context-deletion-store.js +0 -162
- package/dist/core/compaction/context-deletion-store.js.map +0 -1
- package/dist/core/compaction/context-deletion-targets.d.ts +0 -43
- package/dist/core/compaction/context-deletion-targets.d.ts.map +0 -1
- package/dist/core/compaction/context-deletion-targets.js +0 -292
- package/dist/core/compaction/context-deletion-targets.js.map +0 -1
- package/dist/core/compaction/context-deletion-tool-definitions.d.ts +0 -193
- package/dist/core/compaction/context-deletion-tool-definitions.d.ts.map +0 -1
- package/dist/core/compaction/context-deletion-tool-definitions.js +0 -98
- package/dist/core/compaction/context-deletion-tool-definitions.js.map +0 -1
- package/dist/core/compaction/context-deletion-tool-helpers.d.ts +0 -19
- package/dist/core/compaction/context-deletion-tool-helpers.d.ts.map +0 -1
- package/dist/core/compaction/context-deletion-tool-helpers.js +0 -210
- package/dist/core/compaction/context-deletion-tool-helpers.js.map +0 -1
- package/dist/core/compaction/context-deletion-tools.d.ts +0 -4
- package/dist/core/compaction/context-deletion-tools.d.ts.map +0 -1
- package/dist/core/compaction/context-deletion-tools.js +0 -403
- package/dist/core/compaction/context-deletion-tools.js.map +0 -1
- package/dist/core/compaction/context-transcript-analysis.d.ts +0 -11
- package/dist/core/compaction/context-transcript-analysis.d.ts.map +0 -1
- package/dist/core/compaction/context-transcript-analysis.js +0 -228
- package/dist/core/compaction/context-transcript-analysis.js.map +0 -1
- package/dist/core/session-manager-tool-dependencies.d.ts +0 -10
- package/dist/core/session-manager-tool-dependencies.d.ts.map +0 -1
- package/dist/core/session-manager-tool-dependencies.js +0 -133
- package/dist/core/session-manager-tool-dependencies.js.map +0 -1
- package/dist/modes/interactive/components/context-compaction-summary-message.d.ts +0 -17
- package/dist/modes/interactive/components/context-compaction-summary-message.d.ts.map +0 -1
- package/dist/modes/interactive/components/context-compaction-summary-message.js +0 -83
- package/dist/modes/interactive/components/context-compaction-summary-message.js.map +0 -1
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
import { readFileSync, statSync } from "node:fs";
|
|
2
|
+
import type { RunSnapshot, StageSnapshot } from "../shared/store-types.js";
|
|
3
|
+
import type { WorkflowInputValues } from "../shared/types.js";
|
|
4
|
+
import type { DurableWorkflowBackend } from "./backend.js";
|
|
5
|
+
import type {
|
|
6
|
+
DurableCheckpoint,
|
|
7
|
+
DurableStageCheckpoint,
|
|
8
|
+
ResumableWorkflowEntry,
|
|
9
|
+
} from "./types.js";
|
|
10
|
+
import { resolveDurableEntry } from "./resume-runtime.js";
|
|
11
|
+
|
|
12
|
+
export type CompletedWorkflowResolution =
|
|
13
|
+
| { readonly kind: "found"; readonly entry: ResumableWorkflowEntry; readonly snapshot: RunSnapshot }
|
|
14
|
+
| { readonly kind: "ambiguous"; readonly matches: readonly ResumableWorkflowEntry[] }
|
|
15
|
+
| { readonly kind: "not_found" }
|
|
16
|
+
| { readonly kind: "stale"; readonly entry: ResumableWorkflowEntry };
|
|
17
|
+
|
|
18
|
+
interface SessionTranscriptEntry {
|
|
19
|
+
readonly type?: string;
|
|
20
|
+
readonly id?: string;
|
|
21
|
+
readonly timestamp?: string;
|
|
22
|
+
readonly message?: {
|
|
23
|
+
readonly role?: string;
|
|
24
|
+
readonly content?: string | object;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
interface StageDraft {
|
|
29
|
+
readonly replayKey: string;
|
|
30
|
+
readonly name: string;
|
|
31
|
+
readonly firstCompletedAt: number;
|
|
32
|
+
readonly output?: DurableStageCheckpoint["output"];
|
|
33
|
+
readonly result?: string;
|
|
34
|
+
readonly sessionId?: string;
|
|
35
|
+
readonly sessionFile?: string;
|
|
36
|
+
readonly startedAt?: number;
|
|
37
|
+
readonly endedAt?: number;
|
|
38
|
+
readonly durationMs?: number;
|
|
39
|
+
readonly model?: string;
|
|
40
|
+
readonly fastMode?: boolean;
|
|
41
|
+
readonly attemptedModels?: readonly string[];
|
|
42
|
+
readonly modelAttempts?: DurableStageCheckpoint["modelAttempts"];
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** Authoritative completed rows. This path is deliberately separate from resumability. */
|
|
46
|
+
export function listCompletedFromBackend(
|
|
47
|
+
backend: DurableWorkflowBackend,
|
|
48
|
+
): readonly ResumableWorkflowEntry[] {
|
|
49
|
+
return backend.listCompletedWorkflows();
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** Completed rows whose authoritative checkpoints and referenced transcripts still exist. */
|
|
53
|
+
export function listOpenableCompletedWorkflows(
|
|
54
|
+
backend: DurableWorkflowBackend,
|
|
55
|
+
): readonly ResumableWorkflowEntry[] {
|
|
56
|
+
return listCompletedFromBackend(backend)
|
|
57
|
+
.filter((entry) => completedWorkflowSnapshot(backend, entry) !== undefined)
|
|
58
|
+
.sort((a, b) => b.updatedAt - a.updatedAt);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function resolveCompletedWorkflow(
|
|
62
|
+
workflowIdOrPrefix: string,
|
|
63
|
+
backend: DurableWorkflowBackend,
|
|
64
|
+
openableCatalog: readonly ResumableWorkflowEntry[] = listOpenableCompletedWorkflows(backend),
|
|
65
|
+
): CompletedWorkflowResolution {
|
|
66
|
+
const resolved = resolveDurableEntry(workflowIdOrPrefix, openableCatalog);
|
|
67
|
+
if (resolved !== undefined) {
|
|
68
|
+
if ("kind" in resolved) return { kind: "ambiguous", matches: resolved.matches };
|
|
69
|
+
const snapshot = completedWorkflowSnapshot(backend, resolved);
|
|
70
|
+
return snapshot === undefined
|
|
71
|
+
? { kind: "stale", entry: resolved }
|
|
72
|
+
: { kind: "found", entry: resolved, snapshot };
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const authoritative = resolveDurableEntry(workflowIdOrPrefix, listCompletedFromBackend(backend));
|
|
76
|
+
if (authoritative === undefined) return { kind: "not_found" };
|
|
77
|
+
if ("kind" in authoritative) return { kind: "ambiguous", matches: authoritative.matches };
|
|
78
|
+
return { kind: "stale", entry: authoritative };
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export function completedWorkflowSnapshot(
|
|
82
|
+
backend: DurableWorkflowBackend,
|
|
83
|
+
entry: ResumableWorkflowEntry,
|
|
84
|
+
): RunSnapshot | undefined {
|
|
85
|
+
const handle = backend.getWorkflow(entry.workflowId);
|
|
86
|
+
if (handle === undefined || handle.status !== "completed") return undefined;
|
|
87
|
+
const checkpoints = backend.listCheckpoints(entry.workflowId);
|
|
88
|
+
if (checkpoints.length === 0) return undefined;
|
|
89
|
+
const stages = stageSnapshotsFromCheckpoints(checkpoints, handle.updatedAt).map(validatedStageTranscript);
|
|
90
|
+
if (!stages.some((stage) => stage.sessionFile !== undefined)) return undefined;
|
|
91
|
+
|
|
92
|
+
return {
|
|
93
|
+
id: handle.workflowId,
|
|
94
|
+
name: handle.name,
|
|
95
|
+
inputs: { ...handle.inputs } as WorkflowInputValues,
|
|
96
|
+
status: "completed",
|
|
97
|
+
stages,
|
|
98
|
+
startedAt: handle.createdAt,
|
|
99
|
+
endedAt: handle.updatedAt,
|
|
100
|
+
durationMs: Math.max(0, handle.updatedAt - handle.createdAt),
|
|
101
|
+
resumable: false,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function validatedStageTranscript(stage: StageSnapshot): StageSnapshot {
|
|
106
|
+
if (stage.sessionFile === undefined || isReopenableSessionTranscript(stage.sessionFile)) return stage;
|
|
107
|
+
const { sessionFile, ...withoutSessionFile } = stage;
|
|
108
|
+
void sessionFile;
|
|
109
|
+
return withoutSessionFile;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function isReopenableSessionTranscript(path: string): boolean {
|
|
113
|
+
try {
|
|
114
|
+
const stats = statSync(path);
|
|
115
|
+
if (!stats.isFile() || stats.size === 0) return false;
|
|
116
|
+
const lines = readFileSync(path, "utf8").split("\n").filter((line) => line.trim().length > 0);
|
|
117
|
+
if (lines.length < 2) return false;
|
|
118
|
+
const entries: SessionTranscriptEntry[] = [];
|
|
119
|
+
for (const line of lines) {
|
|
120
|
+
const parsed = JSON.parse(line) as object;
|
|
121
|
+
if (typeof parsed !== "object" || parsed === null) return false;
|
|
122
|
+
entries.push(parsed as SessionTranscriptEntry);
|
|
123
|
+
}
|
|
124
|
+
const header = entries[0];
|
|
125
|
+
return header?.type === "session" && typeof header.id === "string" && entries.some(isUsableContextMessage);
|
|
126
|
+
} catch {
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function isUsableContextMessage(entry: SessionTranscriptEntry): boolean {
|
|
132
|
+
return entry.type === "message"
|
|
133
|
+
&& typeof entry.id === "string"
|
|
134
|
+
&& typeof entry.timestamp === "string"
|
|
135
|
+
&& typeof entry.message?.role === "string"
|
|
136
|
+
&& hasUsableMessageContent(entry.message.content);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function hasUsableMessageContent(content: string | object | undefined): boolean {
|
|
140
|
+
if (typeof content === "string") return content.trim().length > 0;
|
|
141
|
+
return Array.isArray(content) && content.some(hasUsableContentBlock);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function hasUsableContentBlock(block: object): boolean {
|
|
145
|
+
if (typeof block !== "object" || block === null) return false;
|
|
146
|
+
const contentBlock = block as {
|
|
147
|
+
readonly text?: string;
|
|
148
|
+
readonly thinking?: string;
|
|
149
|
+
readonly data?: string;
|
|
150
|
+
readonly name?: string;
|
|
151
|
+
};
|
|
152
|
+
return [contentBlock.text, contentBlock.thinking, contentBlock.data, contentBlock.name]
|
|
153
|
+
.some((value) => typeof value === "string" && value.trim().length > 0);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function stageSnapshotsFromCheckpoints(
|
|
157
|
+
checkpoints: readonly DurableCheckpoint[],
|
|
158
|
+
fallbackCompletedAt: number,
|
|
159
|
+
): StageSnapshot[] {
|
|
160
|
+
const drafts = new Map<string, StageDraft>();
|
|
161
|
+
for (const checkpoint of checkpoints) {
|
|
162
|
+
if (checkpoint.kind !== "stage") continue;
|
|
163
|
+
const existing = drafts.get(checkpoint.replayKey);
|
|
164
|
+
drafts.set(checkpoint.replayKey, mergeStageDraft(existing, checkpoint));
|
|
165
|
+
}
|
|
166
|
+
const ordered = [...drafts.values()].sort((a, b) => a.firstCompletedAt - b.firstCompletedAt);
|
|
167
|
+
if (ordered.length === 0) return [syntheticCheckpointStage(checkpoints.length, fallbackCompletedAt)];
|
|
168
|
+
return ordered.map(stageSnapshotFromDraft);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function mergeStageDraft(
|
|
172
|
+
existing: StageDraft | undefined,
|
|
173
|
+
checkpoint: DurableStageCheckpoint,
|
|
174
|
+
): StageDraft {
|
|
175
|
+
return {
|
|
176
|
+
replayKey: checkpoint.replayKey,
|
|
177
|
+
name: existing?.name ?? checkpoint.name,
|
|
178
|
+
firstCompletedAt: Math.min(existing?.firstCompletedAt ?? checkpoint.completedAt, checkpoint.completedAt),
|
|
179
|
+
...valueOrExisting("output", checkpoint, existing),
|
|
180
|
+
...valueOrExisting("result", checkpoint, existing),
|
|
181
|
+
...valueOrExisting("sessionId", checkpoint, existing),
|
|
182
|
+
...valueOrExisting("sessionFile", checkpoint, existing),
|
|
183
|
+
...valueOrExisting("startedAt", checkpoint, existing),
|
|
184
|
+
...valueOrExisting("endedAt", checkpoint, existing),
|
|
185
|
+
...valueOrExisting("durationMs", checkpoint, existing),
|
|
186
|
+
...valueOrExisting("model", checkpoint, existing),
|
|
187
|
+
...valueOrExisting("fastMode", checkpoint, existing),
|
|
188
|
+
...valueOrExisting("attemptedModels", checkpoint, existing),
|
|
189
|
+
...valueOrExisting("modelAttempts", checkpoint, existing),
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function valueOrExisting<
|
|
194
|
+
K extends keyof Omit<StageDraft, "replayKey" | "name" | "firstCompletedAt">
|
|
195
|
+
>(key: K, checkpoint: DurableStageCheckpoint, existing: StageDraft | undefined): Pick<StageDraft, K> | object {
|
|
196
|
+
const checkpointValue = checkpoint[key];
|
|
197
|
+
if (checkpointValue !== undefined) return { [key]: checkpointValue } as Pick<StageDraft, K>;
|
|
198
|
+
const existingValue = existing?.[key];
|
|
199
|
+
return existingValue === undefined ? {} : { [key]: existingValue } as Pick<StageDraft, K>;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
function stageSnapshotFromDraft(draft: StageDraft, index: number): StageSnapshot {
|
|
203
|
+
const startedAt = draft.startedAt ?? draft.firstCompletedAt;
|
|
204
|
+
const endedAt = draft.endedAt ?? draft.firstCompletedAt;
|
|
205
|
+
return {
|
|
206
|
+
id: `completed-stage-${index + 1}`,
|
|
207
|
+
name: draft.name,
|
|
208
|
+
status: "completed",
|
|
209
|
+
parentIds: [],
|
|
210
|
+
startedAt,
|
|
211
|
+
endedAt,
|
|
212
|
+
durationMs: draft.durationMs ?? Math.max(0, endedAt - startedAt),
|
|
213
|
+
...(stageResult(draft) !== undefined ? { result: stageResult(draft) } : {}),
|
|
214
|
+
replayKey: draft.replayKey,
|
|
215
|
+
toolEvents: [],
|
|
216
|
+
attachable: false,
|
|
217
|
+
...(draft.sessionId !== undefined ? { sessionId: draft.sessionId } : {}),
|
|
218
|
+
...(draft.sessionFile !== undefined ? { sessionFile: draft.sessionFile } : {}),
|
|
219
|
+
...(draft.model !== undefined ? { model: draft.model } : {}),
|
|
220
|
+
...(draft.fastMode !== undefined ? { fastMode: draft.fastMode } : {}),
|
|
221
|
+
...(draft.attemptedModels !== undefined ? { attemptedModels: draft.attemptedModels } : {}),
|
|
222
|
+
...(draft.modelAttempts !== undefined ? { modelAttempts: draft.modelAttempts } : {}),
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
function stageResult(draft: StageDraft): string | undefined {
|
|
227
|
+
if (draft.result !== undefined) return draft.result;
|
|
228
|
+
if (draft.output === undefined) return undefined;
|
|
229
|
+
return typeof draft.output === "string" ? draft.output : JSON.stringify(draft.output);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
function syntheticCheckpointStage(checkpointCount: number, completedAt: number): StageSnapshot {
|
|
233
|
+
return {
|
|
234
|
+
id: "completed-checkpoints",
|
|
235
|
+
name: "durable checkpoints",
|
|
236
|
+
status: "completed",
|
|
237
|
+
parentIds: [],
|
|
238
|
+
startedAt: completedAt,
|
|
239
|
+
endedAt: completedAt,
|
|
240
|
+
durationMs: 0,
|
|
241
|
+
result: `${checkpointCount} durable checkpoint${checkpointCount === 1 ? "" : "s"}`,
|
|
242
|
+
toolEvents: [],
|
|
243
|
+
attachable: false,
|
|
244
|
+
};
|
|
245
|
+
}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import type { Store } from "../shared/store.js";
|
|
2
|
+
import type { RunSnapshot, StageSnapshot } from "../shared/store-types.js";
|
|
3
|
+
import { createStageContext, type StageAdapters } from "../runs/foreground/stage-runner.js";
|
|
4
|
+
import {
|
|
5
|
+
stageControlRegistry as defaultStageControlRegistry,
|
|
6
|
+
type AgentSessionEventListener,
|
|
7
|
+
type StageControlHandle,
|
|
8
|
+
type StageControlRegistry,
|
|
9
|
+
} from "../runs/foreground/stage-control-registry.js";
|
|
10
|
+
import type { DurableWorkflowBackend } from "./backend.js";
|
|
11
|
+
import {
|
|
12
|
+
listOpenableCompletedWorkflows,
|
|
13
|
+
resolveCompletedWorkflow,
|
|
14
|
+
} from "./completed-catalog.js";
|
|
15
|
+
import type { ResumableWorkflowEntry } from "./types.js";
|
|
16
|
+
|
|
17
|
+
export type OpenCompletedDurableResult =
|
|
18
|
+
| { readonly ok: true; readonly runId: string; readonly workflowId: string; readonly name: string; readonly message: string }
|
|
19
|
+
| { readonly ok: false; readonly reason: "not_found" | "ambiguous" | "stale" | "active"; readonly message: string };
|
|
20
|
+
|
|
21
|
+
export interface OpenCompletedDurableDeps {
|
|
22
|
+
readonly durableBackend: DurableWorkflowBackend;
|
|
23
|
+
readonly store: Store;
|
|
24
|
+
readonly adapters?: StageAdapters;
|
|
25
|
+
readonly stageControlRegistry?: StageControlRegistry;
|
|
26
|
+
readonly cwd?: string;
|
|
27
|
+
readonly defaultSessionDir?: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
interface CompletedChatRegistration {
|
|
31
|
+
readonly handle: StageControlHandle;
|
|
32
|
+
readonly unregister: () => void;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const completedChatRegistrations = new WeakMap<
|
|
36
|
+
StageControlRegistry,
|
|
37
|
+
Map<string, CompletedChatRegistration>
|
|
38
|
+
>();
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Open a completed durable workflow as an immutable run snapshot. The only
|
|
42
|
+
* mutable surface is a lazily reopened stage chat, which appends follow-up
|
|
43
|
+
* conversation to its retained Atomic session without dispatching the workflow.
|
|
44
|
+
*/
|
|
45
|
+
export function openCompletedDurableWorkflow(
|
|
46
|
+
workflowIdOrPrefix: string,
|
|
47
|
+
deps: OpenCompletedDurableDeps,
|
|
48
|
+
catalog: readonly ResumableWorkflowEntry[] = listOpenableCompletedWorkflows(deps.durableBackend),
|
|
49
|
+
): OpenCompletedDurableResult {
|
|
50
|
+
const resolved = resolveCompletedWorkflow(workflowIdOrPrefix, deps.durableBackend, catalog);
|
|
51
|
+
if (resolved.kind === "not_found") {
|
|
52
|
+
return failure("not_found", `No completed durable workflow found for id/prefix: ${workflowIdOrPrefix}`);
|
|
53
|
+
}
|
|
54
|
+
if (resolved.kind === "ambiguous") {
|
|
55
|
+
const matches = resolved.matches.map((entry) => `${entry.name} (${entry.workflowId.slice(0, 8)})`).join(", ");
|
|
56
|
+
return failure("ambiguous", `Ambiguous completed workflow prefix "${workflowIdOrPrefix}" matches: ${matches}`);
|
|
57
|
+
}
|
|
58
|
+
if (resolved.kind === "stale") {
|
|
59
|
+
return failure(
|
|
60
|
+
"stale",
|
|
61
|
+
`Completed workflow ${resolved.entry.workflowId.slice(0, 8)} is stale or missing durable checkpoint/session data and cannot be opened.`,
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const existing = deps.store.runs().find((run) => run.id === resolved.snapshot.id);
|
|
66
|
+
if (existing !== undefined && existing.status !== "completed") {
|
|
67
|
+
return failure(
|
|
68
|
+
"active",
|
|
69
|
+
`Workflow ${resolved.snapshot.id.slice(0, 8)} is already active in this session; attach with /workflow connect ${resolved.snapshot.id.slice(0, 8)} instead.`,
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
const snapshot = resolved.snapshot;
|
|
73
|
+
if (existing !== undefined) deps.store.removeRun(existing.id);
|
|
74
|
+
deps.store.recordRunStart(snapshot);
|
|
75
|
+
registerCompletedChatHandles(snapshot, deps);
|
|
76
|
+
return {
|
|
77
|
+
ok: true,
|
|
78
|
+
runId: snapshot.id,
|
|
79
|
+
workflowId: snapshot.id,
|
|
80
|
+
name: snapshot.name,
|
|
81
|
+
message: `Opened completed durable workflow "${snapshot.name}" (${snapshot.id.slice(0, 8)}) for read-only inspection and follow-up chat.`,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function failure(
|
|
86
|
+
reason: "not_found" | "ambiguous" | "stale" | "active",
|
|
87
|
+
message: string,
|
|
88
|
+
): OpenCompletedDurableResult {
|
|
89
|
+
return { ok: false, reason, message };
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function registerCompletedChatHandles(
|
|
93
|
+
snapshot: RunSnapshot,
|
|
94
|
+
deps: OpenCompletedDurableDeps,
|
|
95
|
+
): void {
|
|
96
|
+
if (deps.adapters?.agentSession === undefined) return;
|
|
97
|
+
const registry = deps.stageControlRegistry ?? defaultStageControlRegistry;
|
|
98
|
+
const registrations = completedChatRegistrations.get(registry) ?? new Map();
|
|
99
|
+
completedChatRegistrations.set(registry, registrations);
|
|
100
|
+
const desiredKeys = new Set(
|
|
101
|
+
snapshot.stages
|
|
102
|
+
.filter((stage) => stage.sessionFile !== undefined)
|
|
103
|
+
.map((stage) => completedChatKey(snapshot.id, stage.id)),
|
|
104
|
+
);
|
|
105
|
+
for (const [key, registration] of registrations) {
|
|
106
|
+
if (!key.startsWith(`${snapshot.id}:`) || desiredKeys.has(key)) continue;
|
|
107
|
+
removeCompletedChatRegistration(registrations, key, registration);
|
|
108
|
+
}
|
|
109
|
+
for (const stage of snapshot.stages) {
|
|
110
|
+
if (stage.sessionFile === undefined) continue;
|
|
111
|
+
const key = completedChatKey(snapshot.id, stage.id);
|
|
112
|
+
const registration = registrations.get(key);
|
|
113
|
+
const existing = registry.get(snapshot.id, stage.id);
|
|
114
|
+
if (existing?.sessionFile === stage.sessionFile && !existing.isDisposed) continue;
|
|
115
|
+
if (registration !== undefined) {
|
|
116
|
+
removeCompletedChatRegistration(registrations, key, registration);
|
|
117
|
+
} else if (existing !== undefined) {
|
|
118
|
+
disposeCompletedChatHandle(existing);
|
|
119
|
+
}
|
|
120
|
+
const handle = createCompletedChatHandle(snapshot, stage, stage.sessionFile, deps.adapters, deps.cwd, deps.defaultSessionDir);
|
|
121
|
+
const unregister = registry.register(handle);
|
|
122
|
+
registrations.set(key, { handle, unregister });
|
|
123
|
+
registry.detachControl(snapshot.id, stage.id, handle);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function completedChatKey(runId: string, stageId: string): string {
|
|
128
|
+
return `${runId}:${stageId}`;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function removeCompletedChatRegistration(
|
|
132
|
+
registrations: Map<string, CompletedChatRegistration>,
|
|
133
|
+
key: string,
|
|
134
|
+
registration: CompletedChatRegistration,
|
|
135
|
+
): void {
|
|
136
|
+
registration.unregister();
|
|
137
|
+
registrations.delete(key);
|
|
138
|
+
disposeCompletedChatHandle(registration.handle);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function disposeCompletedChatHandle(handle: StageControlHandle): void {
|
|
142
|
+
void Promise.resolve(handle.dispose?.()).catch((error: Error) => {
|
|
143
|
+
console.warn("atomic-workflows: completed chat handle dispose failed", error);
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function createCompletedChatHandle(
|
|
148
|
+
run: RunSnapshot,
|
|
149
|
+
stage: StageSnapshot,
|
|
150
|
+
sessionFile: string,
|
|
151
|
+
adapters: StageAdapters,
|
|
152
|
+
cwd: string | undefined,
|
|
153
|
+
defaultSessionDir: string | undefined,
|
|
154
|
+
): StageControlHandle {
|
|
155
|
+
const context = createStageContext({
|
|
156
|
+
runId: run.id,
|
|
157
|
+
stageId: stage.id,
|
|
158
|
+
stageName: stage.name,
|
|
159
|
+
adapters,
|
|
160
|
+
stageOptions: {
|
|
161
|
+
resumeFromSessionFile: sessionFile,
|
|
162
|
+
...(cwd !== undefined ? { cwd } : {}),
|
|
163
|
+
},
|
|
164
|
+
...(defaultSessionDir !== undefined ? { defaultSessionDir } : {}),
|
|
165
|
+
});
|
|
166
|
+
let disposed = false;
|
|
167
|
+
const ensureAttached = async (): Promise<void> => {
|
|
168
|
+
if (disposed) throw new Error(`Completed stage chat "${stage.name}" is closed.`);
|
|
169
|
+
if (context.__sessionMeta().sessionFile === undefined) {
|
|
170
|
+
await context.__ensureSessionFromFile(sessionFile);
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
return {
|
|
174
|
+
runId: run.id,
|
|
175
|
+
stageId: stage.id,
|
|
176
|
+
stageName: stage.name,
|
|
177
|
+
status: "completed",
|
|
178
|
+
get sessionId() { return context.__sessionMeta().sessionId ?? stage.sessionId; },
|
|
179
|
+
get sessionFile() { return context.__sessionMeta().sessionFile ?? sessionFile; },
|
|
180
|
+
get isStreaming() { return context.isStreaming; },
|
|
181
|
+
get isDisposed() { return disposed; },
|
|
182
|
+
get messages() { return context.messages; },
|
|
183
|
+
get agentSession() { return context.__agentSession(); },
|
|
184
|
+
async ensureAttached() { await ensureAttached(); },
|
|
185
|
+
async prompt(text: string) {
|
|
186
|
+
await ensureAttached();
|
|
187
|
+
await context.prompt(text);
|
|
188
|
+
},
|
|
189
|
+
async steer(text: string) {
|
|
190
|
+
await ensureAttached();
|
|
191
|
+
await context.steer(text);
|
|
192
|
+
},
|
|
193
|
+
async followUp(text: string) {
|
|
194
|
+
await ensureAttached();
|
|
195
|
+
await context.followUp(text);
|
|
196
|
+
},
|
|
197
|
+
async pause() {
|
|
198
|
+
throw new Error("Completed workflow snapshots cannot be paused or resumed.");
|
|
199
|
+
},
|
|
200
|
+
async resume(message?: string) {
|
|
201
|
+
if (message !== undefined && message.trim().length > 0) {
|
|
202
|
+
await ensureAttached();
|
|
203
|
+
await context.prompt(message);
|
|
204
|
+
}
|
|
205
|
+
},
|
|
206
|
+
subscribe(listener: AgentSessionEventListener) { return context.subscribe(listener); },
|
|
207
|
+
async dispose() {
|
|
208
|
+
if (disposed) return;
|
|
209
|
+
disposed = true;
|
|
210
|
+
await context.__dispose();
|
|
211
|
+
},
|
|
212
|
+
};
|
|
213
|
+
}
|