@bastani/atomic 0.9.8 → 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 +28 -0
- package/dist/builtin/cursor/CHANGELOG.md +6 -0
- package/dist/builtin/cursor/package.json +2 -2
- package/dist/builtin/intercom/CHANGELOG.md +6 -0
- package/dist/builtin/intercom/package.json +1 -1
- package/dist/builtin/mcp/CHANGELOG.md +6 -0
- package/dist/builtin/mcp/package.json +1 -1
- package/dist/builtin/subagents/CHANGELOG.md +6 -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 +6 -0
- package/dist/builtin/web-access/package.json +1 -1
- package/dist/builtin/workflows/CHANGELOG.md +22 -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
|
@@ -1,210 +1,156 @@
|
|
|
1
1
|
import { formatNoModelSelectedMessage } from "./auth-guidance.js";
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
import { getKeptTailTokenEstimate, prepareCompactionBoundary, runVerbatimCompaction, VERBATIM_COMPACTION_PROMPT_VERSION, VERBATIM_COMPACTION_STRATEGY, } from "./compaction/index.js";
|
|
3
|
+
function frozenCollectionMutation() {
|
|
4
|
+
throw new TypeError("Cannot mutate frozen compaction preparation");
|
|
5
|
+
}
|
|
5
6
|
function deepFreeze(value) {
|
|
6
|
-
if (value
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
if (!value || typeof value !== "object" || Object.isFrozen(value))
|
|
8
|
+
return value;
|
|
9
|
+
if (value instanceof Map) {
|
|
10
|
+
for (const [key, nested] of value) {
|
|
11
|
+
deepFreeze(key);
|
|
9
12
|
deepFreeze(nested);
|
|
10
13
|
}
|
|
14
|
+
Object.defineProperties(value, {
|
|
15
|
+
set: { value: frozenCollectionMutation },
|
|
16
|
+
delete: { value: frozenCollectionMutation },
|
|
17
|
+
clear: { value: frozenCollectionMutation },
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
else if (value instanceof Set) {
|
|
21
|
+
for (const nested of value)
|
|
22
|
+
deepFreeze(nested);
|
|
23
|
+
Object.defineProperties(value, {
|
|
24
|
+
add: { value: frozenCollectionMutation },
|
|
25
|
+
delete: { value: frozenCollectionMutation },
|
|
26
|
+
clear: { value: frozenCollectionMutation },
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
for (const nested of Object.values(value))
|
|
31
|
+
deepFreeze(nested);
|
|
11
32
|
}
|
|
12
|
-
return value;
|
|
33
|
+
return Object.freeze(value);
|
|
13
34
|
}
|
|
14
|
-
|
|
15
|
-
|
|
35
|
+
function extensionStats(preparation, compactedText) {
|
|
36
|
+
const linesBefore = preparation.region.lines.length;
|
|
37
|
+
const linesKept = compactedText.split("\n").length;
|
|
38
|
+
const tokensAfter = Math.ceil(compactedText.length / 4) + getKeptTailTokenEstimate(preparation);
|
|
39
|
+
return {
|
|
40
|
+
linesBefore,
|
|
41
|
+
linesDeleted: Math.max(0, linesBefore - linesKept),
|
|
42
|
+
linesKept,
|
|
43
|
+
rangeCount: 0,
|
|
44
|
+
tokensBefore: preparation.tokensBefore,
|
|
45
|
+
tokensAfter,
|
|
46
|
+
percentReduction: preparation.tokensBefore === 0 ? 0 : Math.round((1 - tokensAfter / preparation.tokensBefore) * 1000) / 10,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
export async function _applyVerbatimCompaction(options) {
|
|
50
|
+
if (!this.model)
|
|
16
51
|
throw new Error(formatNoModelSelectedMessage());
|
|
17
|
-
}
|
|
18
|
-
// Capture the narrowed model now (control-flow narrowing holds immediately after the
|
|
19
|
-
// guard) so the lazy planner-fallback closure below can use a non-undefined model.
|
|
20
52
|
const model = this.model;
|
|
21
|
-
const compactionThinkingLevel = this.thinkingLevel;
|
|
22
53
|
const pathEntries = this.sessionManager.getBranch();
|
|
23
54
|
const settings = this.settingsManager.getCompactionSettings();
|
|
24
|
-
const preparation =
|
|
55
|
+
const preparation = prepareCompactionBoundary(pathEntries, settings, {
|
|
25
56
|
...(options.compression_ratio === undefined ? {} : { compression_ratio: options.compression_ratio }),
|
|
26
57
|
...(options.preserve_recent === undefined ? {} : { preserve_recent: options.preserve_recent }),
|
|
27
58
|
...(options.query === undefined ? {} : { query: options.query }),
|
|
28
59
|
});
|
|
29
60
|
if (!preparation) {
|
|
30
|
-
|
|
31
|
-
// a silent no-op would leave the session overflowing without proving safe deletion is exhausted.
|
|
32
|
-
if (options.reason === "overflow") {
|
|
61
|
+
if (options.reason === "overflow")
|
|
33
62
|
throw new Error("Context compaction found no compactable transcript entries; nothing more was safely deletable");
|
|
34
|
-
}
|
|
35
63
|
return undefined;
|
|
36
64
|
}
|
|
37
|
-
const
|
|
38
|
-
const effectiveBudget = getEffectiveInputBudget(model);
|
|
39
|
-
const ladderOptions = options.reason === "overflow"
|
|
40
|
-
? { acceptanceTokenBudget: effectiveBudget, criticalEvictionTokenBudget: effectiveBudget }
|
|
41
|
-
: options.reason === "threshold"
|
|
42
|
-
// Match the shouldCompact trigger boundary in transcript-estimate space:
|
|
43
|
-
// tokensAfter <= effectiveBudget - reserveTokens is equivalent to
|
|
44
|
-
// !shouldCompact(tokensAfter, effectiveBudget, settings). The live post-retry
|
|
45
|
-
// trigger uses provider usage (system/tools included), so this is a best-effort
|
|
46
|
-
// boundary; a negative boundary correctly means no estimated result fits.
|
|
47
|
-
? { acceptanceTokenBudget: effectiveBudget - settings.reserveTokens }
|
|
48
|
-
: undefined;
|
|
49
|
-
// Planner fallback used when no extension supplies a deletionRequest. Auth is resolved
|
|
50
|
-
// lazily here so extension-provided deletion requests keep working offline. Overflow with
|
|
51
|
-
// missing auth uses deterministic eviction directly instead of silently no-oping.
|
|
52
|
-
const runPlanner = async () => {
|
|
53
|
-
const auth = await options.resolvePlannerAuth();
|
|
54
|
-
if (!auth) {
|
|
55
|
-
if (options.reason === "overflow")
|
|
56
|
-
return runDeterministicContextEviction(preparation.transcript, effectiveBudget);
|
|
57
|
-
return undefined;
|
|
58
|
-
}
|
|
59
|
-
return runContextCompact(preparation, model, auth.apiKey, auth.headers, options.abortController.signal, compactionThinkingLevel, ladderOptions);
|
|
60
|
-
};
|
|
61
|
-
// Emit session_before_compact to allow extensions to cancel or provide a deletion request.
|
|
62
|
-
// This happens BEFORE any auth resolution so local extension deletion requests work
|
|
63
|
-
// without configured API credentials.
|
|
65
|
+
const plan = { streamFn: this.agent.streamFn };
|
|
64
66
|
let fromExtension = false;
|
|
65
|
-
let
|
|
67
|
+
let compacted;
|
|
66
68
|
if (this._extensionRunner.hasHandlers("session_before_compact")) {
|
|
67
|
-
|
|
68
|
-
// receive an isolated, frozen snapshot so they cannot mutate protection metadata
|
|
69
|
-
// (protectedEntryIds, entry .protected flags, etc.) on the internal preparation used for
|
|
70
|
-
// validation. Building it lazily avoids deep-cloning the transcript — largest exactly when
|
|
71
|
-
// compaction fires — on the common no-extension path.
|
|
72
|
-
let extensionPreparation;
|
|
69
|
+
let snapshot;
|
|
73
70
|
try {
|
|
74
|
-
|
|
71
|
+
snapshot = deepFreeze(structuredClone(preparation));
|
|
75
72
|
}
|
|
76
73
|
catch (error) {
|
|
77
|
-
// structuredClone only throws if an entry carries a non-cloneable value (a function or a
|
|
78
|
-
// class instance). Transcript entries are plain data today, so this guards a latent
|
|
79
|
-
// invariant: surface a clear error instead of letting a raw DataCloneError abort an
|
|
80
|
-
// otherwise-viable compaction.
|
|
81
74
|
throw new Error(`Failed to snapshot transcript for compaction extensions: ${error instanceof Error ? error.message : String(error)}`);
|
|
82
75
|
}
|
|
83
76
|
const hookResult = (await this._extensionRunner.emit({
|
|
84
77
|
type: "session_before_compact",
|
|
85
78
|
reason: options.reason,
|
|
86
|
-
parameters,
|
|
87
|
-
preparation:
|
|
79
|
+
parameters: preparation.parameters,
|
|
80
|
+
preparation: snapshot,
|
|
88
81
|
branchEntries: pathEntries,
|
|
89
82
|
signal: options.abortController.signal,
|
|
90
83
|
}));
|
|
91
|
-
if (hookResult?.cancel)
|
|
84
|
+
if (hookResult?.cancel)
|
|
92
85
|
throw new Error("Compaction cancelled");
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
if (!Array.isArray(extensionDeletionRequest.deletions) || extensionDeletionRequest.deletions.length === 0) {
|
|
98
|
-
throw new Error("No safe context deletions proposed by extension");
|
|
99
|
-
}
|
|
100
|
-
// Validate against the internal transcript snapshot, not the extension-facing clone.
|
|
101
|
-
// Auth is NOT resolved here — local extension deletion requests work offline.
|
|
102
|
-
validated = validateContextDeletionRequest(extensionDeletionRequest, preparation.transcript);
|
|
103
|
-
// Reject if reconciliation reduced deletions to zero.
|
|
104
|
-
if (validated.deletedTargets.length === 0) {
|
|
105
|
-
throw new Error("No safe context deletions proposed by extension");
|
|
106
|
-
}
|
|
86
|
+
if (hookResult?.compactedText !== undefined) {
|
|
87
|
+
if (hookResult.compactedText.trim().length === 0)
|
|
88
|
+
throw new Error("No compacted text provided by extension");
|
|
89
|
+
compacted = { text: hookResult.compactedText, stats: extensionStats(preparation, hookResult.compactedText), rung: "extension" };
|
|
107
90
|
fromExtension = true;
|
|
108
91
|
}
|
|
109
92
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
if (!plannerResult) {
|
|
116
|
-
return undefined;
|
|
117
|
-
}
|
|
118
|
-
validated = plannerResult;
|
|
93
|
+
if (!compacted) {
|
|
94
|
+
const auth = await options.resolvePlannerAuth();
|
|
95
|
+
if (!auth)
|
|
96
|
+
throw new Error("Compaction provider authentication is unavailable");
|
|
97
|
+
compacted = await runVerbatimCompaction(preparation, model, auth.apiKey, auth.headers, options.abortController.signal, this.thinkingLevel, plan);
|
|
119
98
|
}
|
|
120
|
-
if (options.abortController.signal.aborted)
|
|
99
|
+
if (options.abortController.signal.aborted)
|
|
121
100
|
throw new Error("Compaction cancelled");
|
|
122
|
-
}
|
|
123
101
|
const backupPath = this.sessionManager.writeBackupSnapshot(options.backupLabel);
|
|
124
|
-
const
|
|
125
|
-
|
|
126
|
-
|
|
102
|
+
const details = {
|
|
103
|
+
strategy: VERBATIM_COMPACTION_STRATEGY,
|
|
104
|
+
promptVersion: VERBATIM_COMPACTION_PROMPT_VERSION,
|
|
105
|
+
parameters: preparation.parameters,
|
|
106
|
+
stats: compacted.stats,
|
|
107
|
+
rung: compacted.rung,
|
|
108
|
+
...(backupPath ? { backupPath } : {}),
|
|
109
|
+
};
|
|
110
|
+
const entryId = this.sessionManager.appendCompaction(compacted.text, preparation.firstKeptEntryId, preparation.tokensBefore, details);
|
|
111
|
+
this.agent.state.messages = this.sessionManager.buildSessionContext().messages;
|
|
127
112
|
const result = {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
113
|
+
compactedText: compacted.text,
|
|
114
|
+
firstKeptEntryId: preparation.firstKeptEntryId,
|
|
115
|
+
tokensBefore: preparation.tokensBefore,
|
|
116
|
+
stats: compacted.stats,
|
|
117
|
+
parameters: preparation.parameters,
|
|
118
|
+
promptVersion: VERBATIM_COMPACTION_PROMPT_VERSION,
|
|
119
|
+
rung: compacted.rung,
|
|
131
120
|
...(backupPath ? { backupPath } : {}),
|
|
132
121
|
};
|
|
133
|
-
|
|
134
|
-
// observation hook fired AFTER the compaction has been committed (backup written,
|
|
135
|
-
// context_compaction entry persisted, active context rebuilt). A misbehaving observer must
|
|
136
|
-
// never turn a successful, already-persisted compaction into a reported failure, so any
|
|
137
|
-
// throw is routed to the non-fatal extension-error channel and compaction still reports
|
|
138
|
-
// success.
|
|
139
|
-
const contextCompactionEntry = this.sessionManager.getEntry(compactionEntryId);
|
|
122
|
+
const compactionEntry = this.sessionManager.getEntry(entryId);
|
|
140
123
|
try {
|
|
141
|
-
await this._extensionRunner.emit({
|
|
142
|
-
type: "session_compact",
|
|
143
|
-
reason: options.reason,
|
|
144
|
-
parameters,
|
|
145
|
-
result,
|
|
146
|
-
contextCompactionEntry,
|
|
147
|
-
fromExtension,
|
|
148
|
-
});
|
|
124
|
+
await this._extensionRunner.emit({ type: "session_compact", reason: options.reason, parameters: preparation.parameters, result, compactionEntry, fromExtension });
|
|
149
125
|
}
|
|
150
126
|
catch (error) {
|
|
151
|
-
this._extensionRunner.emitError({
|
|
152
|
-
extensionPath: "<session_compact>",
|
|
153
|
-
event: "session_compact",
|
|
154
|
-
error: error instanceof Error ? error.message : String(error),
|
|
155
|
-
stack: error instanceof Error ? error.stack : undefined,
|
|
156
|
-
});
|
|
127
|
+
this._extensionRunner.emitError({ extensionPath: "<session_compact>", event: "session_compact", error: error instanceof Error ? error.message : String(error), stack: error instanceof Error ? error.stack : undefined });
|
|
157
128
|
}
|
|
158
129
|
return result;
|
|
159
130
|
}
|
|
160
|
-
/**
|
|
161
|
-
* Manually compact the session context using deletion-only verbatim context compaction.
|
|
162
|
-
* Aborts current agent operation first.
|
|
163
|
-
*/
|
|
131
|
+
/** Persist one verbatim line-subset compaction boundary. */
|
|
164
132
|
export async function compact(options = {}) {
|
|
165
133
|
this._disconnectFromAgent();
|
|
166
134
|
await this.abort();
|
|
167
135
|
this._compactionAbortController = new AbortController();
|
|
168
136
|
this._emit({ type: "compaction_start", reason: "manual" });
|
|
169
137
|
try {
|
|
170
|
-
if (!this.model)
|
|
138
|
+
if (!this.model)
|
|
171
139
|
throw new Error(formatNoModelSelectedMessage());
|
|
172
|
-
}
|
|
173
|
-
// Auth is resolved lazily: only called when the planner fallback is needed.
|
|
174
|
-
// Extensions that provide a deletionRequest work without configured credentials.
|
|
175
140
|
const model = this.model;
|
|
176
|
-
const result = await this.
|
|
177
|
-
resolvePlannerAuth: () => this._getRequiredRequestAuth(model),
|
|
178
|
-
|
|
179
|
-
backupLabel: "compact",
|
|
180
|
-
reason: "manual",
|
|
181
|
-
...(options.compression_ratio === undefined ? {} : { compression_ratio: options.compression_ratio }),
|
|
182
|
-
...(options.preserve_recent === undefined ? {} : { preserve_recent: options.preserve_recent }),
|
|
183
|
-
...(options.query === undefined ? {} : { query: options.query }),
|
|
141
|
+
const result = await this._applyVerbatimCompaction({
|
|
142
|
+
resolvePlannerAuth: () => this._getRequiredRequestAuth(model), abortController: this._compactionAbortController,
|
|
143
|
+
backupLabel: "compact", reason: "manual", ...options,
|
|
184
144
|
});
|
|
185
|
-
if (!result)
|
|
145
|
+
if (!result)
|
|
186
146
|
throw new Error("Nothing to compact (session too small)");
|
|
187
|
-
}
|
|
188
|
-
this._emit({
|
|
189
|
-
type: "compaction_end",
|
|
190
|
-
reason: "manual",
|
|
191
|
-
result,
|
|
192
|
-
aborted: false,
|
|
193
|
-
willRetry: false,
|
|
194
|
-
});
|
|
147
|
+
this._emit({ type: "compaction_end", reason: "manual", result, aborted: false, willRetry: false });
|
|
195
148
|
return result;
|
|
196
149
|
}
|
|
197
150
|
catch (error) {
|
|
198
151
|
const message = error instanceof Error ? error.message : String(error);
|
|
199
152
|
const aborted = message === "Compaction cancelled" || (error instanceof Error && error.name === "AbortError");
|
|
200
|
-
this._emit({
|
|
201
|
-
type: "compaction_end",
|
|
202
|
-
reason: "manual",
|
|
203
|
-
result: undefined,
|
|
204
|
-
aborted,
|
|
205
|
-
willRetry: false,
|
|
206
|
-
errorMessage: aborted ? undefined : `Compaction failed: ${message}`,
|
|
207
|
-
});
|
|
153
|
+
this._emit({ type: "compaction_end", reason: "manual", result: undefined, aborted, willRetry: false, errorMessage: aborted ? undefined : `Compaction failed: ${message}` });
|
|
208
154
|
throw error;
|
|
209
155
|
}
|
|
210
156
|
finally {
|
|
@@ -212,92 +158,8 @@ export async function compact(options = {}) {
|
|
|
212
158
|
this._reconnectToAgent();
|
|
213
159
|
}
|
|
214
160
|
}
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
export async function contextCompact() {
|
|
220
|
-
this._disconnectFromAgent();
|
|
221
|
-
await this.abort();
|
|
222
|
-
this._compactionAbortController = new AbortController();
|
|
223
|
-
this._emit({ type: "context_compaction_start", reason: "manual" });
|
|
224
|
-
try {
|
|
225
|
-
if (!this.model) {
|
|
226
|
-
throw new Error(formatNoModelSelectedMessage());
|
|
227
|
-
}
|
|
228
|
-
// Auth is resolved lazily: only called when the planner fallback is needed.
|
|
229
|
-
// Extensions that provide a deletionRequest work without configured credentials.
|
|
230
|
-
const model = this.model;
|
|
231
|
-
const result = await this._applyContextVerbatimCompaction({
|
|
232
|
-
resolvePlannerAuth: () => this._getRequiredRequestAuth(model),
|
|
233
|
-
abortController: this._compactionAbortController,
|
|
234
|
-
backupLabel: "context-compact",
|
|
235
|
-
reason: "manual",
|
|
236
|
-
});
|
|
237
|
-
if (!result) {
|
|
238
|
-
throw new Error("Nothing to context-compact (session too small)");
|
|
239
|
-
}
|
|
240
|
-
this._emit({
|
|
241
|
-
type: "context_compaction_end",
|
|
242
|
-
reason: "manual",
|
|
243
|
-
result,
|
|
244
|
-
aborted: false,
|
|
245
|
-
willRetry: false,
|
|
246
|
-
});
|
|
247
|
-
return result;
|
|
248
|
-
}
|
|
249
|
-
catch (error) {
|
|
250
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
251
|
-
const aborted = message === "Compaction cancelled" || (error instanceof Error && error.name === "AbortError");
|
|
252
|
-
this._emit({
|
|
253
|
-
type: "context_compaction_end",
|
|
254
|
-
reason: "manual",
|
|
255
|
-
result: undefined,
|
|
256
|
-
aborted,
|
|
257
|
-
willRetry: false,
|
|
258
|
-
errorMessage: aborted ? undefined : `Context compaction failed: ${message}`,
|
|
259
|
-
});
|
|
260
|
-
throw error;
|
|
261
|
-
}
|
|
262
|
-
finally {
|
|
263
|
-
this._compactionAbortController = undefined;
|
|
264
|
-
this._reconnectToAgent();
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
/**
|
|
268
|
-
* Cancel in-progress compaction (manual or auto).
|
|
269
|
-
*/
|
|
270
|
-
export function abortCompaction() {
|
|
271
|
-
this._compactionAbortController?.abort();
|
|
272
|
-
this._autoCompactionAbortController?.abort();
|
|
273
|
-
}
|
|
274
|
-
/**
|
|
275
|
-
* Cancel in-progress branch summarization.
|
|
276
|
-
*/
|
|
277
|
-
export function abortBranchSummary() {
|
|
278
|
-
this._branchSummaryAbortController?.abort();
|
|
279
|
-
}
|
|
280
|
-
/**
|
|
281
|
-
* Check if compaction is needed and run it.
|
|
282
|
-
* Called after agent_end and before prompt submission.
|
|
283
|
-
*
|
|
284
|
-
* Two cases:
|
|
285
|
-
* 1. Overflow: LLM returned context overflow error, remove error message from agent state, compact, auto-retry
|
|
286
|
-
* 2. Threshold: Context over threshold, compact, resume queued active-turn work if present; otherwise wait for user
|
|
287
|
-
*
|
|
288
|
-
* @param assistantMessage The assistant message to check
|
|
289
|
-
* @param skipAbortedCheck If false, include aborted messages (for pre-prompt check). Default: true
|
|
290
|
-
*/
|
|
291
|
-
export function setAutoCompactionEnabled(enabled) {
|
|
292
|
-
this.settingsManager.setCompactionEnabled(enabled);
|
|
293
|
-
}
|
|
294
|
-
/** Whether auto-compaction is enabled */
|
|
295
|
-
export const agentSessionCompactionMethods = {
|
|
296
|
-
_applyContextVerbatimCompaction,
|
|
297
|
-
compact,
|
|
298
|
-
contextCompact,
|
|
299
|
-
abortCompaction,
|
|
300
|
-
abortBranchSummary,
|
|
301
|
-
setAutoCompactionEnabled,
|
|
302
|
-
};
|
|
161
|
+
export function abortCompaction() { this._compactionAbortController?.abort(); this._autoCompactionAbortController?.abort(); }
|
|
162
|
+
export function abortBranchSummary() { this._branchSummaryAbortController?.abort(); }
|
|
163
|
+
export function setAutoCompactionEnabled(enabled) { this.settingsManager.setCompactionEnabled(enabled); }
|
|
164
|
+
export const agentSessionCompactionMethods = { _applyVerbatimCompaction, compact, abortCompaction, abortBranchSummary, setAutoCompactionEnabled };
|
|
303
165
|
//# sourceMappingURL=agent-session-compaction.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-session-compaction.js","sourceRoot":"","sources":["../../src/core/agent-session-compaction.ts"],"names":[],"mappings":"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","sourcesContent":["import { formatNoModelSelectedMessage } from \"./auth-guidance.ts\";\nimport type { AgentSessionInternalSurface as AgentSession } from \"./agent-session-methods.ts\";\nimport type { ContextCompactionApplyOptions } from \"./agent-session-methods.ts\";\nimport { getEffectiveInputBudget } from \"./context-window.ts\";\nimport { type ContextCompactionParameters, type ContextCompactionPreparation, type ContextCompactionResult, type ContextDeletionRequest, type ValidatedContextDeletionResult, contextCompact as runContextCompact, prepareContextCompaction, validateContextDeletionRequest } from \"./compaction/index.ts\";\nimport { runDeterministicContextEviction } from \"./compaction/context-compaction-eviction.ts\";\n// Type-only import: erased at runtime so module mocks of the compaction barrel stay authoritative.\nimport type { ContextCompactionLadderOptions } from \"./compaction/context-compaction-runner.ts\";\nimport type { SessionBeforeCompactEvent, SessionBeforeCompactResult, SessionCompactEvent } from \"./extensions/index.ts\";\nimport type { ContextCompactionEntry } from \"./session-manager.ts\";\n\nfunction deepFreeze<T>(value: T): T {\n\tif (value && typeof value === \"object\") {\n\t\tObject.freeze(value);\n\t\tfor (const nested of Object.values(value)) {\n\t\t\tdeepFreeze(nested);\n\t\t}\n\t}\n\treturn value;\n}\n\nexport async function _applyContextVerbatimCompaction(\n\tthis: AgentSession,\n\toptions: ContextCompactionApplyOptions,\n): Promise<ContextCompactionResult | undefined> {\n\tif (!this.model) {\n\t\tthrow new Error(formatNoModelSelectedMessage());\n\t}\n\t// Capture the narrowed model now (control-flow narrowing holds immediately after the\n\t// guard) so the lazy planner-fallback closure below can use a non-undefined model.\n\tconst model = this.model;\n\tconst compactionThinkingLevel = this.thinkingLevel;\n\n\tconst pathEntries = this.sessionManager.getBranch();\n\tconst settings = this.settingsManager.getCompactionSettings();\n\tconst preparation = prepareContextCompaction(pathEntries, settings, {\n\t\t...(options.compression_ratio === undefined ? {} : { compression_ratio: options.compression_ratio }),\n\t\t...(options.preserve_recent === undefined ? {} : { preserve_recent: options.preserve_recent }),\n\t\t...(options.query === undefined ? {} : { query: options.query }),\n\t});\n\tif (!preparation) {\n\t\t// Overflow recovery must be loud when there is no transcript the ladder can compact:\n\t\t// a silent no-op would leave the session overflowing without proving safe deletion is exhausted.\n\t\tif (options.reason === \"overflow\") {\n\t\t\tthrow new Error(\"Context compaction found no compactable transcript entries; nothing more was safely deletable\");\n\t\t}\n\t\treturn undefined;\n\t}\n\tconst parameters: ContextCompactionParameters = preparation.parameters;\n\tconst effectiveBudget = getEffectiveInputBudget(model);\n\tconst ladderOptions: ContextCompactionLadderOptions | undefined =\n\t\toptions.reason === \"overflow\"\n\t\t\t? { acceptanceTokenBudget: effectiveBudget, criticalEvictionTokenBudget: effectiveBudget }\n\t\t\t: options.reason === \"threshold\"\n\t\t\t\t// Match the shouldCompact trigger boundary in transcript-estimate space:\n\t\t\t\t// tokensAfter <= effectiveBudget - reserveTokens is equivalent to\n\t\t\t\t// !shouldCompact(tokensAfter, effectiveBudget, settings). The live post-retry\n\t\t\t\t// trigger uses provider usage (system/tools included), so this is a best-effort\n\t\t\t\t// boundary; a negative boundary correctly means no estimated result fits.\n\t\t\t\t? { acceptanceTokenBudget: effectiveBudget - settings.reserveTokens }\n\t\t\t\t: undefined;\n\n\t// Planner fallback used when no extension supplies a deletionRequest. Auth is resolved\n\t// lazily here so extension-provided deletion requests keep working offline. Overflow with\n\t// missing auth uses deterministic eviction directly instead of silently no-oping.\n\tconst runPlanner = async (): Promise<ValidatedContextDeletionResult | undefined> => {\n\t\tconst auth = await options.resolvePlannerAuth();\n\t\tif (!auth) {\n\t\t\tif (options.reason === \"overflow\") return runDeterministicContextEviction(preparation.transcript, effectiveBudget);\n\t\t\treturn undefined;\n\t\t}\n\t\treturn runContextCompact(\n\t\t\tpreparation,\n\t\t\tmodel,\n\t\t\tauth.apiKey,\n\t\t\tauth.headers,\n\t\t\toptions.abortController.signal,\n\t\t\tcompactionThinkingLevel,\n\t\t\tladderOptions,\n\t\t);\n\t};\n\n\t// Emit session_before_compact to allow extensions to cancel or provide a deletion request.\n\t// This happens BEFORE any auth resolution so local extension deletion requests work\n\t// without configured API credentials.\n\tlet fromExtension = false;\n\tlet validated: ValidatedContextDeletionResult | undefined;\n\n\tif (this._extensionRunner.hasHandlers(\"session_before_compact\")) {\n\t\t// Deep-clone the preparation only when a before-compact handler actually exists. Extensions\n\t\t// receive an isolated, frozen snapshot so they cannot mutate protection metadata\n\t\t// (protectedEntryIds, entry .protected flags, etc.) on the internal preparation used for\n\t\t// validation. Building it lazily avoids deep-cloning the transcript — largest exactly when\n\t\t// compaction fires — on the common no-extension path.\n\t\tlet extensionPreparation: ContextCompactionPreparation;\n\t\ttry {\n\t\t\textensionPreparation = deepFreeze(structuredClone(preparation));\n\t\t} catch (error) {\n\t\t\t// structuredClone only throws if an entry carries a non-cloneable value (a function or a\n\t\t\t// class instance). Transcript entries are plain data today, so this guards a latent\n\t\t\t// invariant: surface a clear error instead of letting a raw DataCloneError abort an\n\t\t\t// otherwise-viable compaction.\n\t\t\tthrow new Error(\n\t\t\t\t`Failed to snapshot transcript for compaction extensions: ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t);\n\t\t}\n\n\t\tconst hookResult = (await this._extensionRunner.emit({\n\t\t\ttype: \"session_before_compact\",\n\t\t\treason: options.reason,\n\t\t\tparameters,\n\t\t\tpreparation: extensionPreparation,\n\t\t\tbranchEntries: pathEntries,\n\t\t\tsignal: options.abortController.signal,\n\t\t} satisfies SessionBeforeCompactEvent)) as SessionBeforeCompactResult | undefined;\n\n\t\tif (hookResult?.cancel) {\n\t\t\tthrow new Error(\"Compaction cancelled\");\n\t\t}\n\n\t\tif (hookResult?.deletionRequest) {\n\t\t\tconst extensionDeletionRequest = hookResult.deletionRequest as ContextDeletionRequest;\n\t\t\t// Reject empty deletion requests before any side effects (backup, append, rebuild).\n\t\t\tif (!Array.isArray(extensionDeletionRequest.deletions) || extensionDeletionRequest.deletions.length === 0) {\n\t\t\t\tthrow new Error(\"No safe context deletions proposed by extension\");\n\t\t\t}\n\t\t\t// Validate against the internal transcript snapshot, not the extension-facing clone.\n\t\t\t// Auth is NOT resolved here — local extension deletion requests work offline.\n\t\t\tvalidated = validateContextDeletionRequest(extensionDeletionRequest, preparation.transcript);\n\t\t\t// Reject if reconciliation reduced deletions to zero.\n\t\t\tif (validated.deletedTargets.length === 0) {\n\t\t\t\tthrow new Error(\"No safe context deletions proposed by extension\");\n\t\t\t}\n\t\t\tfromExtension = true;\n\t\t}\n\t}\n\n\t// Planner fallback shared by both paths: no before-compact handler at all, or a handler that\n\t// observed without supplying a deletionRequest. Resolves auth lazily; undefined means auth is\n\t// unavailable (auto-mode resolvers), so compaction is a no-op.\n\tif (!validated) {\n\t\tconst plannerResult = await runPlanner();\n\t\tif (!plannerResult) {\n\t\t\treturn undefined;\n\t\t}\n\t\tvalidated = plannerResult;\n\t}\n\n\tif (options.abortController.signal.aborted) {\n\t\tthrow new Error(\"Compaction cancelled\");\n\t}\n\n\tconst backupPath = this.sessionManager.writeBackupSnapshot(options.backupLabel);\n\tconst compactionEntryId = this.sessionManager.appendContextCompaction(\n\t\tvalidated.deletedTargets,\n\t\tvalidated.protectedEntryIds,\n\t\tvalidated.stats,\n\t\tbackupPath,\n\t);\n\tconst sessionContext = this.sessionManager.buildSessionContext();\n\tthis.agent.state.messages = sessionContext.messages;\n\n\tconst result: ContextCompactionResult = {\n\t\t...validated,\n\t\tpromptVersion: 1,\n\t\tparameters,\n\t\t...(backupPath ? { backupPath } : {}),\n\t};\n\n\t// Emit session_compact so extensions can observe the validated result. This is a pure\n\t// observation hook fired AFTER the compaction has been committed (backup written,\n\t// context_compaction entry persisted, active context rebuilt). A misbehaving observer must\n\t// never turn a successful, already-persisted compaction into a reported failure, so any\n\t// throw is routed to the non-fatal extension-error channel and compaction still reports\n\t// success.\n\tconst contextCompactionEntry = this.sessionManager.getEntry(compactionEntryId) as ContextCompactionEntry;\n\ttry {\n\t\tawait this._extensionRunner.emit({\n\t\t\ttype: \"session_compact\",\n\t\t\treason: options.reason,\n\t\t\tparameters,\n\t\t\tresult,\n\t\t\tcontextCompactionEntry,\n\t\t\tfromExtension,\n\t\t} satisfies SessionCompactEvent);\n\t} catch (error) {\n\t\tthis._extensionRunner.emitError({\n\t\t\textensionPath: \"<session_compact>\",\n\t\t\tevent: \"session_compact\",\n\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\tstack: error instanceof Error ? error.stack : undefined,\n\t\t});\n\t}\n\n\treturn result;\n}\n\n/**\n * Manually compact the session context using deletion-only verbatim context compaction.\n * Aborts current agent operation first.\n */\n\nexport async function compact(this: AgentSession, options: Partial<ContextCompactionParameters> = {}): Promise<ContextCompactionResult> {\n\tthis._disconnectFromAgent();\n\tawait this.abort();\n\tthis._compactionAbortController = new AbortController();\n\tthis._emit({ type: \"compaction_start\", reason: \"manual\" });\n\n\ttry {\n\t\tif (!this.model) {\n\t\t\tthrow new Error(formatNoModelSelectedMessage());\n\t\t}\n\n\t\t// Auth is resolved lazily: only called when the planner fallback is needed.\n\t\t// Extensions that provide a deletionRequest work without configured credentials.\n\t\tconst model = this.model;\n\t\tconst result = await this._applyContextVerbatimCompaction({\n\t\t\tresolvePlannerAuth: () => this._getRequiredRequestAuth(model),\n\t\t\tabortController: this._compactionAbortController,\n\t\t\tbackupLabel: \"compact\",\n\t\t\treason: \"manual\",\n\t\t\t...(options.compression_ratio === undefined ? {} : { compression_ratio: options.compression_ratio }),\n\t\t\t...(options.preserve_recent === undefined ? {} : { preserve_recent: options.preserve_recent }),\n\t\t\t...(options.query === undefined ? {} : { query: options.query }),\n\t\t});\n\t\tif (!result) {\n\t\t\tthrow new Error(\"Nothing to compact (session too small)\");\n\t\t}\n\n\t\tthis._emit({\n\t\t\ttype: \"compaction_end\",\n\t\t\treason: \"manual\",\n\t\t\tresult,\n\t\t\taborted: false,\n\t\t\twillRetry: false,\n\t\t});\n\t\treturn result;\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tconst aborted = message === \"Compaction cancelled\" || (error instanceof Error && error.name === \"AbortError\");\n\t\tthis._emit({\n\t\t\ttype: \"compaction_end\",\n\t\t\treason: \"manual\",\n\t\t\tresult: undefined,\n\t\t\taborted,\n\t\t\twillRetry: false,\n\t\t\terrorMessage: aborted ? undefined : `Compaction failed: ${message}`,\n\t\t});\n\t\tthrow error;\n\t} finally {\n\t\tthis._compactionAbortController = undefined;\n\t\tthis._reconnectToAgent();\n\t}\n}\n\n/**\n * Manually compact the session context by applying validated logical deletions.\n * Retained transcript entries/content blocks stay verbatim; no user prompt text is accepted.\n */\n\nexport async function contextCompact(this: AgentSession): Promise<ContextCompactionResult> {\n\tthis._disconnectFromAgent();\n\tawait this.abort();\n\tthis._compactionAbortController = new AbortController();\n\tthis._emit({ type: \"context_compaction_start\", reason: \"manual\" });\n\n\ttry {\n\t\tif (!this.model) {\n\t\t\tthrow new Error(formatNoModelSelectedMessage());\n\t\t}\n\n\t\t// Auth is resolved lazily: only called when the planner fallback is needed.\n\t\t// Extensions that provide a deletionRequest work without configured credentials.\n\t\tconst model = this.model;\n\t\tconst result = await this._applyContextVerbatimCompaction({\n\t\t\tresolvePlannerAuth: () => this._getRequiredRequestAuth(model),\n\t\t\tabortController: this._compactionAbortController,\n\t\t\tbackupLabel: \"context-compact\",\n\t\t\treason: \"manual\",\n\t\t});\n\t\tif (!result) {\n\t\t\tthrow new Error(\"Nothing to context-compact (session too small)\");\n\t\t}\n\n\t\tthis._emit({\n\t\t\ttype: \"context_compaction_end\",\n\t\t\treason: \"manual\",\n\t\t\tresult,\n\t\t\taborted: false,\n\t\t\twillRetry: false,\n\t\t});\n\t\treturn result;\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tconst aborted = message === \"Compaction cancelled\" || (error instanceof Error && error.name === \"AbortError\");\n\t\tthis._emit({\n\t\t\ttype: \"context_compaction_end\",\n\t\t\treason: \"manual\",\n\t\t\tresult: undefined,\n\t\t\taborted,\n\t\t\twillRetry: false,\n\t\t\terrorMessage: aborted ? undefined : `Context compaction failed: ${message}`,\n\t\t});\n\t\tthrow error;\n\t} finally {\n\t\tthis._compactionAbortController = undefined;\n\t\tthis._reconnectToAgent();\n\t}\n}\n\n/**\n * Cancel in-progress compaction (manual or auto).\n */\n\nexport function abortCompaction(this: AgentSession): void {\n\tthis._compactionAbortController?.abort();\n\tthis._autoCompactionAbortController?.abort();\n}\n\n/**\n * Cancel in-progress branch summarization.\n */\n\nexport function abortBranchSummary(this: AgentSession): void {\n\tthis._branchSummaryAbortController?.abort();\n}\n\n/**\n * Check if compaction is needed and run it.\n * Called after agent_end and before prompt submission.\n *\n * Two cases:\n * 1. Overflow: LLM returned context overflow error, remove error message from agent state, compact, auto-retry\n * 2. Threshold: Context over threshold, compact, resume queued active-turn work if present; otherwise wait for user\n *\n * @param assistantMessage The assistant message to check\n * @param skipAbortedCheck If false, include aborted messages (for pre-prompt check). Default: true\n */\n\nexport function setAutoCompactionEnabled(this: AgentSession, enabled: boolean): void {\n\tthis.settingsManager.setCompactionEnabled(enabled);\n}\n\n/** Whether auto-compaction is enabled */\n\nexport const agentSessionCompactionMethods = {\n\t_applyContextVerbatimCompaction,\n\tcompact,\n\tcontextCompact,\n\tabortCompaction,\n\tabortBranchSummary,\n\tsetAutoCompactionEnabled,\n};\n"]}
|
|
1
|
+
{"version":3,"file":"agent-session-compaction.js","sourceRoot":"","sources":["../../src/core/agent-session-compaction.ts"],"names":[],"mappings":"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","sourcesContent":["import { formatNoModelSelectedMessage } from \"./auth-guidance.ts\";\nimport type { AgentSessionInternalSurface as AgentSession, VerbatimCompactionApplyOptions } from \"./agent-session-methods.ts\";\nimport {\n\tgetKeptTailTokenEstimate,\n\tprepareCompactionBoundary,\n\trunVerbatimCompaction,\n\tVERBATIM_COMPACTION_PROMPT_VERSION,\n\tVERBATIM_COMPACTION_STRATEGY,\n\ttype CompactionPlanOptions,\n\ttype VerbatimCompactionDetails,\n\ttype VerbatimCompactionParameters,\n\ttype VerbatimCompactionPreparation,\n\ttype VerbatimCompactionResult,\n\ttype VerbatimCompactionStats,\n} from \"./compaction/index.ts\";\nimport type { SessionBeforeCompactEvent, SessionBeforeCompactResult, SessionCompactEvent } from \"./extensions/index.ts\";\nimport type { CompactionEntry } from \"./session-manager.ts\";\n\nfunction frozenCollectionMutation(): never {\n\tthrow new TypeError(\"Cannot mutate frozen compaction preparation\");\n}\n\nfunction deepFreeze<T>(value: T): T {\n\tif (!value || typeof value !== \"object\" || Object.isFrozen(value)) return value;\n\tif (value instanceof Map) {\n\t\tfor (const [key, nested] of value) { deepFreeze(key); deepFreeze(nested); }\n\t\tObject.defineProperties(value, {\n\t\t\tset: { value: frozenCollectionMutation },\n\t\t\tdelete: { value: frozenCollectionMutation },\n\t\t\tclear: { value: frozenCollectionMutation },\n\t\t});\n\t} else if (value instanceof Set) {\n\t\tfor (const nested of value) deepFreeze(nested);\n\t\tObject.defineProperties(value, {\n\t\t\tadd: { value: frozenCollectionMutation },\n\t\t\tdelete: { value: frozenCollectionMutation },\n\t\t\tclear: { value: frozenCollectionMutation },\n\t\t});\n\t} else {\n\t\tfor (const nested of Object.values(value)) deepFreeze(nested);\n\t}\n\treturn Object.freeze(value);\n}\n\nfunction extensionStats(preparation: VerbatimCompactionPreparation, compactedText: string): VerbatimCompactionStats {\n\tconst linesBefore = preparation.region.lines.length;\n\tconst linesKept = compactedText.split(\"\\n\").length;\n\tconst tokensAfter = Math.ceil(compactedText.length / 4) + getKeptTailTokenEstimate(preparation);\n\treturn {\n\t\tlinesBefore,\n\t\tlinesDeleted: Math.max(0, linesBefore - linesKept),\n\t\tlinesKept,\n\t\trangeCount: 0,\n\t\ttokensBefore: preparation.tokensBefore,\n\t\ttokensAfter,\n\t\tpercentReduction: preparation.tokensBefore === 0 ? 0 : Math.round((1 - tokensAfter / preparation.tokensBefore) * 1000) / 10,\n\t};\n}\n\nexport async function _applyVerbatimCompaction(\n\tthis: AgentSession,\n\toptions: VerbatimCompactionApplyOptions,\n): Promise<VerbatimCompactionResult | undefined> {\n\tif (!this.model) throw new Error(formatNoModelSelectedMessage());\n\tconst model = this.model;\n\tconst pathEntries = this.sessionManager.getBranch();\n\tconst settings = this.settingsManager.getCompactionSettings();\n\tconst preparation = prepareCompactionBoundary(pathEntries, settings, {\n\t\t...(options.compression_ratio === undefined ? {} : { compression_ratio: options.compression_ratio }),\n\t\t...(options.preserve_recent === undefined ? {} : { preserve_recent: options.preserve_recent }),\n\t\t...(options.query === undefined ? {} : { query: options.query }),\n\t});\n\tif (!preparation) {\n\t\tif (options.reason === \"overflow\") throw new Error(\"Context compaction found no compactable transcript entries; nothing more was safely deletable\");\n\t\treturn undefined;\n\t}\n\n\tconst plan: CompactionPlanOptions = { streamFn: this.agent.streamFn };\n\tlet fromExtension = false;\n\tlet compacted: { text: string; stats: VerbatimCompactionStats; rung: VerbatimCompactionResult[\"rung\"] } | undefined;\n\n\tif (this._extensionRunner.hasHandlers(\"session_before_compact\")) {\n\t\tlet snapshot: VerbatimCompactionPreparation;\n\t\ttry {\n\t\t\tsnapshot = deepFreeze(structuredClone(preparation));\n\t\t} catch (error) {\n\t\t\tthrow new Error(`Failed to snapshot transcript for compaction extensions: ${error instanceof Error ? error.message : String(error)}`);\n\t\t}\n\t\tconst hookResult = (await this._extensionRunner.emit({\n\t\t\ttype: \"session_before_compact\",\n\t\t\treason: options.reason,\n\t\t\tparameters: preparation.parameters,\n\t\t\tpreparation: snapshot,\n\t\t\tbranchEntries: pathEntries,\n\t\t\tsignal: options.abortController.signal,\n\t\t} satisfies SessionBeforeCompactEvent)) as SessionBeforeCompactResult | undefined;\n\t\tif (hookResult?.cancel) throw new Error(\"Compaction cancelled\");\n\t\tif (hookResult?.compactedText !== undefined) {\n\t\t\tif (hookResult.compactedText.trim().length === 0) throw new Error(\"No compacted text provided by extension\");\n\t\t\tcompacted = { text: hookResult.compactedText, stats: extensionStats(preparation, hookResult.compactedText), rung: \"extension\" };\n\t\t\tfromExtension = true;\n\t\t}\n\t}\n\n\tif (!compacted) {\n\t\tconst auth = await options.resolvePlannerAuth();\n\t\tif (!auth) throw new Error(\"Compaction provider authentication is unavailable\");\n\t\tcompacted = await runVerbatimCompaction(\n\t\t\tpreparation,\n\t\t\tmodel,\n\t\t\tauth.apiKey,\n\t\t\tauth.headers,\n\t\t\toptions.abortController.signal,\n\t\t\tthis.thinkingLevel,\n\t\t\tplan,\n\t\t);\n\t}\n\tif (options.abortController.signal.aborted) throw new Error(\"Compaction cancelled\");\n\n\tconst backupPath = this.sessionManager.writeBackupSnapshot(options.backupLabel);\n\tconst details: VerbatimCompactionDetails = {\n\t\tstrategy: VERBATIM_COMPACTION_STRATEGY,\n\t\tpromptVersion: VERBATIM_COMPACTION_PROMPT_VERSION,\n\t\tparameters: preparation.parameters,\n\t\tstats: compacted.stats,\n\t\trung: compacted.rung,\n\t\t...(backupPath ? { backupPath } : {}),\n\t};\n\tconst entryId = this.sessionManager.appendCompaction(compacted.text, preparation.firstKeptEntryId, preparation.tokensBefore, details);\n\tthis.agent.state.messages = this.sessionManager.buildSessionContext().messages;\n\tconst result: VerbatimCompactionResult = {\n\t\tcompactedText: compacted.text,\n\t\tfirstKeptEntryId: preparation.firstKeptEntryId,\n\t\ttokensBefore: preparation.tokensBefore,\n\t\tstats: compacted.stats,\n\t\tparameters: preparation.parameters,\n\t\tpromptVersion: VERBATIM_COMPACTION_PROMPT_VERSION,\n\t\trung: compacted.rung,\n\t\t...(backupPath ? { backupPath } : {}),\n\t};\n\tconst compactionEntry = this.sessionManager.getEntry(entryId) as CompactionEntry<VerbatimCompactionDetails>;\n\ttry {\n\t\tawait this._extensionRunner.emit({ type: \"session_compact\", reason: options.reason, parameters: preparation.parameters, result, compactionEntry, fromExtension } satisfies SessionCompactEvent);\n\t} catch (error) {\n\t\tthis._extensionRunner.emitError({ extensionPath: \"<session_compact>\", event: \"session_compact\", error: error instanceof Error ? error.message : String(error), stack: error instanceof Error ? error.stack : undefined });\n\t}\n\treturn result;\n}\n\n/** Persist one verbatim line-subset compaction boundary. */\nexport async function compact(this: AgentSession, options: Partial<VerbatimCompactionParameters> = {}): Promise<VerbatimCompactionResult> {\n\tthis._disconnectFromAgent();\n\tawait this.abort();\n\tthis._compactionAbortController = new AbortController();\n\tthis._emit({ type: \"compaction_start\", reason: \"manual\" });\n\ttry {\n\t\tif (!this.model) throw new Error(formatNoModelSelectedMessage());\n\t\tconst model = this.model;\n\t\tconst result = await this._applyVerbatimCompaction({\n\t\t\tresolvePlannerAuth: () => this._getRequiredRequestAuth(model), abortController: this._compactionAbortController,\n\t\t\tbackupLabel: \"compact\", reason: \"manual\", ...options,\n\t\t});\n\t\tif (!result) throw new Error(\"Nothing to compact (session too small)\");\n\t\tthis._emit({ type: \"compaction_end\", reason: \"manual\", result, aborted: false, willRetry: false });\n\t\treturn result;\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tconst aborted = message === \"Compaction cancelled\" || (error instanceof Error && error.name === \"AbortError\");\n\t\tthis._emit({ type: \"compaction_end\", reason: \"manual\", result: undefined, aborted, willRetry: false, errorMessage: aborted ? undefined : `Compaction failed: ${message}` });\n\t\tthrow error;\n\t} finally {\n\t\tthis._compactionAbortController = undefined;\n\t\tthis._reconnectToAgent();\n\t}\n}\n\nexport function abortCompaction(this: AgentSession): void { this._compactionAbortController?.abort(); this._autoCompactionAbortController?.abort(); }\nexport function abortBranchSummary(this: AgentSession): void { this._branchSummaryAbortController?.abort(); }\nexport function setAutoCompactionEnabled(this: AgentSession, enabled: boolean): void { this.settingsManager.setCompactionEnabled(enabled); }\n\nexport const agentSessionCompactionMethods = { _applyVerbatimCompaction, compact, abortCompaction, abortBranchSummary, setAutoCompactionEnabled };\n"]}
|
|
@@ -58,10 +58,6 @@ export declare function setSteeringMode(this: AgentSession, mode: "all" | "one-a
|
|
|
58
58
|
* Saves to settings.
|
|
59
59
|
*/
|
|
60
60
|
export declare function setFollowUpMode(this: AgentSession, mode: "all" | "one-at-a-time"): void;
|
|
61
|
-
/**
|
|
62
|
-
* Apply validated logical deletions and rebuild active agent context.
|
|
63
|
-
* Retained transcript entries/content blocks stay verbatim.
|
|
64
|
-
*/
|
|
65
61
|
export declare const agentSessionMessageQueueMethods: {
|
|
66
62
|
_queueSteer: typeof _queueSteer;
|
|
67
63
|
_queueFollowUp: typeof _queueFollowUp;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-session-message-queue.d.ts","sourceRoot":"","sources":["../../src/core/agent-session-message-queue.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentMessage } from \"@earendil-works/pi-agent-core\";\nimport type { ImageContent, TextContent } from \"@earendil-works/pi-ai/compat\";\nimport type { CustomMessage } from \"./messages.ts\";\nimport type { SendMessageOptions } from \"./extensions/index.ts\";\nimport type { AgentSessionInternalSurface as AgentSession } from \"./agent-session-methods.ts\";\nimport { customMessageExcludesContext, drainAgentMessageQueue, normalizeInterruptAbortMessage, type AgentQueueAccess, type DrainedAgentQueues, type InterruptQueueHold } from \"./agent-session-types.ts\";\n\nexport async function _queueSteer(this: AgentSession, text: string, images?: ImageContent[]): Promise<void> {\n\tthis._steeringMessages.push(text);\n\tthis._emitQueueUpdate();\n\tconst content: (TextContent | ImageContent)[] = [{ type: \"text\", text }];\n\tif (images) {\n\t\tcontent.push(...images);\n\t}\n\tthis._queueAgentMessage(\n\t\t{\n\t\t\trole: \"user\",\n\t\t\tcontent,\n\t\t\ttimestamp: Date.now(),\n\t\t},\n\t\t\"steer\",\n\t);\n}\n\n/**\n * Internal: Queue a follow-up message (already expanded, no extension command check).\n */\n\nexport async function _queueFollowUp(this: AgentSession, text: string, images?: ImageContent[]): Promise<void> {\n\tthis._followUpMessages.push(text);\n\tthis._emitQueueUpdate();\n\tconst content: (TextContent | ImageContent)[] = [{ type: \"text\", text }];\n\tif (images) {\n\t\tcontent.push(...images);\n\t}\n\tthis._queueAgentMessage(\n\t\t{\n\t\t\trole: \"user\",\n\t\t\tcontent,\n\t\t\ttimestamp: Date.now(),\n\t\t},\n\t\t\"followUp\",\n\t);\n}\n\n/**\n * Throw an error if the text is an extension command.\n */\n\nexport function _throwIfExtensionCommand(this: AgentSession, text: string): void {\n\tconst spaceIndex = text.indexOf(\" \");\n\tconst commandName = spaceIndex === -1 ? text.slice(1) : text.slice(1, spaceIndex);\n\tconst command = this._extensionRunner.getCommand(commandName);\n\n\tif (command) {\n\t\tthrow new Error(\n\t\t\t`Extension command \"/${commandName}\" cannot be queued. Use prompt() or execute the command when not streaming.`,\n\t\t);\n\t}\n}\n\n/**\n * Send a custom message to the session. Creates a CustomMessageEntry.\n *\n * Handles five cases:\n * - Streaming + interrupt trigger: aborts the active run and starts an immediate custom-message turn\n * - Streaming + explicit display-only context exclusion: appends to state/session, no turn and no queue\n * - Streaming otherwise: queues message, processed when loop pulls from queue\n * - Not streaming + triggerTurn: appends to state/session, starts new turn\n * - Not streaming + no trigger: appends to state/session, no turn\n *\n * @param message Custom message with customType, content, display, details\n * @param options.triggerTurn If true and not streaming, triggers a new LLM turn\n * @param options.deliverAs Delivery mode: \"steer\", \"followUp\", \"nextTurn\", or \"interrupt\"\n */\n\nexport async function sendCustomMessage<T = unknown>(this: AgentSession, \n\tmessage: Pick<CustomMessage<T>, \"customType\" | \"content\" | \"display\" | \"details\">,\n\toptions?: SendMessageOptions,\n): Promise<void> {\n\tconst appMessage = {\n\t\trole: \"custom\" as const,\n\t\tcustomType: message.customType,\n\t\tcontent: message.content ?? [],\n\t\tdisplay: message.display,\n\t\tdetails: message.details,\n\t\ttimestamp: Date.now(),\n\t\t...(options?.excludeFromContext === true ? { excludeFromContext: true } : {}),\n\t} satisfies CustomMessage<T>;\n\tif (options?.deliverAs === \"nextTurn\") {\n\t\tthis._pendingNextTurnMessages.push(appMessage);\n\t} else if (options?.deliverAs === \"interrupt\" && options.triggerTurn) {\n\t\tawait this._enqueueInterruptCustomMessage(appMessage, options);\n\t} else if (this.isStreaming && options?.excludeFromContext === true && options.triggerTurn !== true && options.deliverAs === undefined) {\n\t\tthis._appendCustomMessage(appMessage);\n\t} else if (this.isStreaming) {\n\t\tthis._queueAgentMessage(appMessage, options?.deliverAs === \"followUp\" ? \"followUp\" : \"steer\");\n\t} else if (options?.triggerTurn) {\n\t\tawait this._runAgentPrompt(appMessage);\n\t} else {\n\t\tthis._appendCustomMessage(appMessage);\n\t}\n}\n\n\nexport function _appendCustomMessage<T>(this: AgentSession, message: CustomMessage<T>): void {\n\tthis.agent.state.messages.push(message);\n\tthis.sessionManager.appendCustomMessageEntry(\n\t\tmessage.customType,\n\t\tmessage.content,\n\t\tmessage.display,\n\t\tmessage.details,\n\t\tcustomMessageExcludesContext(message),\n\t);\n\tthis._emit({ type: \"message_start\", message });\n\tthis._emit({ type: \"message_end\", message });\n}\n\n\nexport function _enqueueInterruptCustomMessage<T>(this: AgentSession, message: CustomMessage<T>, options?: SendMessageOptions): Promise<void> {\n\tthis._pendingInterruptDeliveries += 1;\n\t// Establish the hold synchronously when the interrupt is enqueued, not when\n\t// the serialized delivery callback later starts. Callers commonly fire and\n\t// forget sendCustomMessage(), then queue additional steer/follow-up messages\n\t// before the promise chain gets a microtask; those messages must be captured\n\t// in the active interrupt hold instead of pi-agent-core's live queues.\n\tthis._ensureActiveInterruptQueueHold();\n\tconst delivery = this._interruptDeliveryQueue.then(async () => {\n\t\ttry {\n\t\t\tawait this._sendInterruptCustomMessageNow(message, options);\n\t\t} finally {\n\t\t\tthis._pendingInterruptDeliveries -= 1;\n\t\t\tif (this._pendingInterruptDeliveries === 0) {\n\t\t\t\tthis._restoreAndClearActiveInterruptQueueHold();\n\t\t\t}\n\t\t}\n\t});\n\tthis._interruptDeliveryQueue = delivery.catch(() => undefined);\n\treturn delivery;\n}\n\n\nexport async function _sendInterruptCustomMessageNow<T>(this: AgentSession, \n\tmessage: CustomMessage<T>,\n\toptions?: SendMessageOptions,\n): Promise<void> {\n\tthis.abortRetry();\n\tthis._ensureActiveInterruptQueueHold();\n\tif (this.isStreaming) {\n\t\tconst previousAbortMessage = this._activeInterruptAbortMessage;\n\t\tthis._activeInterruptAbortMessage = normalizeInterruptAbortMessage(options?.interruptAbortMessage);\n\t\ttry {\n\t\t\tthis.agent.abort();\n\t\t\tawait this.agent.waitForIdle();\n\t\t\tawait this._agentEventQueue;\n\t\t} finally {\n\t\t\tthis._activeInterruptAbortMessage = previousAbortMessage;\n\t\t}\n\t}\n\tawait this.agent.prompt(message);\n}\n\n\nexport function _ensureActiveInterruptQueueHold(this: AgentSession): InterruptQueueHold {\n\tif (this._activeInterruptQueueHold !== undefined) {\n\t\treturn this._activeInterruptQueueHold;\n\t}\n\tconst drained = this._drainQueuedAgentMessages();\n\tthis._activeInterruptQueueHold = {\n\t\tsteering: [...drained.steering],\n\t\tfollowUp: [...drained.followUp],\n\t};\n\treturn this._activeInterruptQueueHold;\n}\n\n\nexport function _restoreAndClearActiveInterruptQueueHold(this: AgentSession): void {\n\tconst hold = this._activeInterruptQueueHold;\n\tif (hold === undefined) {\n\t\treturn;\n\t}\n\tconst currentCoreQueues = this._drainQueuedAgentMessages();\n\tthis._restoreQueuedAgentMessages({\n\t\tsteering: [...hold.steering, ...currentCoreQueues.steering],\n\t\tfollowUp: [...hold.followUp, ...currentCoreQueues.followUp],\n\t});\n\tthis._activeInterruptQueueHold = undefined;\n}\n\n\nexport function _queueAgentMessage(this: AgentSession, message: AgentMessage, delivery: \"steer\" | \"followUp\"): void {\n\tconst hold = this._activeInterruptQueueHold;\n\tif (hold !== undefined) {\n\t\tif (delivery === \"followUp\") {\n\t\t\thold.followUp.push(message);\n\t\t} else {\n\t\t\thold.steering.push(message);\n\t\t}\n\t\treturn;\n\t}\n\tif (delivery === \"followUp\") {\n\t\tthis.agent.followUp(message);\n\t} else {\n\t\tthis.agent.steer(message);\n\t}\n}\n\n\nexport function _drainQueuedAgentMessages(this: AgentSession): DrainedAgentQueues {\n\t// pi-agent-core exposes public clear methods but no public drain/restore pair.\n\t// Interrupts need to prevent the aborting run from consuming queued steer/follow-up\n\t// messages while still preserving those queues for a later turn.\n\tconst agentWithQueues = this.agent as unknown as AgentQueueAccess;\n\treturn {\n\t\tsteering: drainAgentMessageQueue(agentWithQueues.steeringQueue),\n\t\tfollowUp: drainAgentMessageQueue(agentWithQueues.followUpQueue),\n\t};\n}\n\n\nexport function _restoreQueuedAgentMessages(this: AgentSession, queues: DrainedAgentQueues): void {\n\tfor (const message of queues.steering) {\n\t\tthis.agent.steer(message);\n\t}\n\tfor (const message of queues.followUp) {\n\t\tthis.agent.followUp(message);\n\t}\n}\n\n/**\n * Send a user message to the agent. Always triggers a turn.\n * When the agent is streaming, use deliverAs to specify how to queue the message.\n *\n * @param content User message content (string or content array)\n * @param options.deliverAs Delivery mode when streaming: \"steer\" or \"followUp\"\n */\n\nexport function clearQueue(this: AgentSession): { steering: string[]; followUp: string[] } {\n\tconst steering = [...this._steeringMessages];\n\tconst followUp = [...this._followUpMessages];\n\tthis._steeringMessages = [];\n\tthis._followUpMessages = [];\n\tthis.agent.clearAllQueues();\n\tif (this._activeInterruptQueueHold !== undefined) {\n\t\tthis._activeInterruptQueueHold.steering.length = 0;\n\t\tthis._activeInterruptQueueHold.followUp.length = 0;\n\t}\n\tthis._emitQueueUpdate();\n\treturn { steering, followUp };\n}\n\n/** Number of pending messages (includes both steering and follow-up) */\n\nexport function getSteeringMessages(this: AgentSession): readonly string[] {\n\treturn this._steeringMessages;\n}\n\n/** Get pending follow-up messages (read-only) */\n\nexport function getFollowUpMessages(this: AgentSession): readonly string[] {\n\treturn this._followUpMessages;\n}\n\n\nexport async function abort(this: AgentSession): Promise<void> {\n\tthis.abortRetry();\n\tthis.agent.abort();\n\tawait this.agent.waitForIdle();\n}\n\n// =========================================================================\n// Model Management\n// =========================================================================\n\n\nexport function setSteeringMode(this: AgentSession, mode: \"all\" | \"one-at-a-time\"): void {\n\tthis.agent.steeringMode = mode;\n\tthis.settingsManager.setSteeringMode(mode);\n}\n\n/**\n * Set follow-up message mode.\n * Saves to settings.\n */\n\nexport function setFollowUpMode(this: AgentSession, mode: \"all\" | \"one-at-a-time\"): void {\n\tthis.agent.followUpMode = mode;\n\tthis.settingsManager.setFollowUpMode(mode);\n}\n\n// =========================================================================\n// Compaction\n// =========================================================================\n\n/**\n * Apply validated logical deletions and rebuild active agent context.\n * Retained transcript entries/content blocks stay verbatim.\n */\n\nexport const agentSessionMessageQueueMethods = {\n\t_queueSteer,\n\t_queueFollowUp,\n\t_throwIfExtensionCommand,\n\tsendCustomMessage,\n\t_appendCustomMessage,\n\t_enqueueInterruptCustomMessage,\n\t_sendInterruptCustomMessageNow,\n\t_ensureActiveInterruptQueueHold,\n\t_restoreAndClearActiveInterruptQueueHold,\n\t_queueAgentMessage,\n\t_drainQueuedAgentMessages,\n\t_restoreQueuedAgentMessages,\n\tclearQueue,\n\tgetSteeringMessages,\n\tgetFollowUpMessages,\n\tabort,\n\tsetSteeringMode,\n\tsetFollowUpMode,\n};\n"]}
|
|
1
|
+
{"version":3,"file":"agent-session-message-queue.d.ts","sourceRoot":"","sources":["../../src/core/agent-session-message-queue.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentMessage } from \"@earendil-works/pi-agent-core\";\nimport type { ImageContent, TextContent } from \"@earendil-works/pi-ai/compat\";\nimport type { CustomMessage } from \"./messages.ts\";\nimport type { SendMessageOptions } from \"./extensions/index.ts\";\nimport type { AgentSessionInternalSurface as AgentSession } from \"./agent-session-methods.ts\";\nimport { customMessageExcludesContext, drainAgentMessageQueue, normalizeInterruptAbortMessage, type AgentQueueAccess, type DrainedAgentQueues, type InterruptQueueHold } from \"./agent-session-types.ts\";\n\nexport async function _queueSteer(this: AgentSession, text: string, images?: ImageContent[]): Promise<void> {\n\tthis._steeringMessages.push(text);\n\tthis._emitQueueUpdate();\n\tconst content: (TextContent | ImageContent)[] = [{ type: \"text\", text }];\n\tif (images) {\n\t\tcontent.push(...images);\n\t}\n\tthis._queueAgentMessage(\n\t\t{\n\t\t\trole: \"user\",\n\t\t\tcontent,\n\t\t\ttimestamp: Date.now(),\n\t\t},\n\t\t\"steer\",\n\t);\n}\n\n/**\n * Internal: Queue a follow-up message (already expanded, no extension command check).\n */\n\nexport async function _queueFollowUp(this: AgentSession, text: string, images?: ImageContent[]): Promise<void> {\n\tthis._followUpMessages.push(text);\n\tthis._emitQueueUpdate();\n\tconst content: (TextContent | ImageContent)[] = [{ type: \"text\", text }];\n\tif (images) {\n\t\tcontent.push(...images);\n\t}\n\tthis._queueAgentMessage(\n\t\t{\n\t\t\trole: \"user\",\n\t\t\tcontent,\n\t\t\ttimestamp: Date.now(),\n\t\t},\n\t\t\"followUp\",\n\t);\n}\n\n/**\n * Throw an error if the text is an extension command.\n */\n\nexport function _throwIfExtensionCommand(this: AgentSession, text: string): void {\n\tconst spaceIndex = text.indexOf(\" \");\n\tconst commandName = spaceIndex === -1 ? text.slice(1) : text.slice(1, spaceIndex);\n\tconst command = this._extensionRunner.getCommand(commandName);\n\n\tif (command) {\n\t\tthrow new Error(\n\t\t\t`Extension command \"/${commandName}\" cannot be queued. Use prompt() or execute the command when not streaming.`,\n\t\t);\n\t}\n}\n\n/**\n * Send a custom message to the session. Creates a CustomMessageEntry.\n *\n * Handles five cases:\n * - Streaming + interrupt trigger: aborts the active run and starts an immediate custom-message turn\n * - Streaming + explicit display-only context exclusion: appends to state/session, no turn and no queue\n * - Streaming otherwise: queues message, processed when loop pulls from queue\n * - Not streaming + triggerTurn: appends to state/session, starts new turn\n * - Not streaming + no trigger: appends to state/session, no turn\n *\n * @param message Custom message with customType, content, display, details\n * @param options.triggerTurn If true and not streaming, triggers a new LLM turn\n * @param options.deliverAs Delivery mode: \"steer\", \"followUp\", \"nextTurn\", or \"interrupt\"\n */\n\nexport async function sendCustomMessage<T = unknown>(this: AgentSession, \n\tmessage: Pick<CustomMessage<T>, \"customType\" | \"content\" | \"display\" | \"details\">,\n\toptions?: SendMessageOptions,\n): Promise<void> {\n\tconst appMessage = {\n\t\trole: \"custom\" as const,\n\t\tcustomType: message.customType,\n\t\tcontent: message.content ?? [],\n\t\tdisplay: message.display,\n\t\tdetails: message.details,\n\t\ttimestamp: Date.now(),\n\t\t...(options?.excludeFromContext === true ? { excludeFromContext: true } : {}),\n\t} satisfies CustomMessage<T>;\n\tif (options?.deliverAs === \"nextTurn\") {\n\t\tthis._pendingNextTurnMessages.push(appMessage);\n\t} else if (options?.deliverAs === \"interrupt\" && options.triggerTurn) {\n\t\tawait this._enqueueInterruptCustomMessage(appMessage, options);\n\t} else if (this.isStreaming && options?.excludeFromContext === true && options.triggerTurn !== true && options.deliverAs === undefined) {\n\t\tthis._appendCustomMessage(appMessage);\n\t} else if (this.isStreaming) {\n\t\tthis._queueAgentMessage(appMessage, options?.deliverAs === \"followUp\" ? \"followUp\" : \"steer\");\n\t} else if (options?.triggerTurn) {\n\t\tawait this._runAgentPrompt(appMessage);\n\t} else {\n\t\tthis._appendCustomMessage(appMessage);\n\t}\n}\n\n\nexport function _appendCustomMessage<T>(this: AgentSession, message: CustomMessage<T>): void {\n\tthis.agent.state.messages.push(message);\n\tthis.sessionManager.appendCustomMessageEntry(\n\t\tmessage.customType,\n\t\tmessage.content,\n\t\tmessage.display,\n\t\tmessage.details,\n\t\tcustomMessageExcludesContext(message),\n\t);\n\tthis._emit({ type: \"message_start\", message });\n\tthis._emit({ type: \"message_end\", message });\n}\n\n\nexport function _enqueueInterruptCustomMessage<T>(this: AgentSession, message: CustomMessage<T>, options?: SendMessageOptions): Promise<void> {\n\tthis._pendingInterruptDeliveries += 1;\n\t// Establish the hold synchronously when the interrupt is enqueued, not when\n\t// the serialized delivery callback later starts. Callers commonly fire and\n\t// forget sendCustomMessage(), then queue additional steer/follow-up messages\n\t// before the promise chain gets a microtask; those messages must be captured\n\t// in the active interrupt hold instead of pi-agent-core's live queues.\n\tthis._ensureActiveInterruptQueueHold();\n\tconst delivery = this._interruptDeliveryQueue.then(async () => {\n\t\ttry {\n\t\t\tawait this._sendInterruptCustomMessageNow(message, options);\n\t\t} finally {\n\t\t\tthis._pendingInterruptDeliveries -= 1;\n\t\t\tif (this._pendingInterruptDeliveries === 0) {\n\t\t\t\tthis._restoreAndClearActiveInterruptQueueHold();\n\t\t\t}\n\t\t}\n\t});\n\tthis._interruptDeliveryQueue = delivery.catch(() => undefined);\n\treturn delivery;\n}\n\n\nexport async function _sendInterruptCustomMessageNow<T>(this: AgentSession, \n\tmessage: CustomMessage<T>,\n\toptions?: SendMessageOptions,\n): Promise<void> {\n\tthis.abortRetry();\n\tthis._ensureActiveInterruptQueueHold();\n\tif (this.isStreaming) {\n\t\tconst previousAbortMessage = this._activeInterruptAbortMessage;\n\t\tthis._activeInterruptAbortMessage = normalizeInterruptAbortMessage(options?.interruptAbortMessage);\n\t\ttry {\n\t\t\tthis.agent.abort();\n\t\t\tawait this.agent.waitForIdle();\n\t\t\tawait this._agentEventQueue;\n\t\t} finally {\n\t\t\tthis._activeInterruptAbortMessage = previousAbortMessage;\n\t\t}\n\t}\n\tawait this.agent.prompt(message);\n}\n\n\nexport function _ensureActiveInterruptQueueHold(this: AgentSession): InterruptQueueHold {\n\tif (this._activeInterruptQueueHold !== undefined) {\n\t\treturn this._activeInterruptQueueHold;\n\t}\n\tconst drained = this._drainQueuedAgentMessages();\n\tthis._activeInterruptQueueHold = {\n\t\tsteering: [...drained.steering],\n\t\tfollowUp: [...drained.followUp],\n\t};\n\treturn this._activeInterruptQueueHold;\n}\n\n\nexport function _restoreAndClearActiveInterruptQueueHold(this: AgentSession): void {\n\tconst hold = this._activeInterruptQueueHold;\n\tif (hold === undefined) {\n\t\treturn;\n\t}\n\tconst currentCoreQueues = this._drainQueuedAgentMessages();\n\tthis._restoreQueuedAgentMessages({\n\t\tsteering: [...hold.steering, ...currentCoreQueues.steering],\n\t\tfollowUp: [...hold.followUp, ...currentCoreQueues.followUp],\n\t});\n\tthis._activeInterruptQueueHold = undefined;\n}\n\n\nexport function _queueAgentMessage(this: AgentSession, message: AgentMessage, delivery: \"steer\" | \"followUp\"): void {\n\tconst hold = this._activeInterruptQueueHold;\n\tif (hold !== undefined) {\n\t\tif (delivery === \"followUp\") {\n\t\t\thold.followUp.push(message);\n\t\t} else {\n\t\t\thold.steering.push(message);\n\t\t}\n\t\treturn;\n\t}\n\tif (delivery === \"followUp\") {\n\t\tthis.agent.followUp(message);\n\t} else {\n\t\tthis.agent.steer(message);\n\t}\n}\n\n\nexport function _drainQueuedAgentMessages(this: AgentSession): DrainedAgentQueues {\n\t// pi-agent-core exposes public clear methods but no public drain/restore pair.\n\t// Interrupts need to prevent the aborting run from consuming queued steer/follow-up\n\t// messages while still preserving those queues for a later turn.\n\tconst agentWithQueues = this.agent as unknown as AgentQueueAccess;\n\treturn {\n\t\tsteering: drainAgentMessageQueue(agentWithQueues.steeringQueue),\n\t\tfollowUp: drainAgentMessageQueue(agentWithQueues.followUpQueue),\n\t};\n}\n\n\nexport function _restoreQueuedAgentMessages(this: AgentSession, queues: DrainedAgentQueues): void {\n\tfor (const message of queues.steering) {\n\t\tthis.agent.steer(message);\n\t}\n\tfor (const message of queues.followUp) {\n\t\tthis.agent.followUp(message);\n\t}\n}\n\n/**\n * Send a user message to the agent. Always triggers a turn.\n * When the agent is streaming, use deliverAs to specify how to queue the message.\n *\n * @param content User message content (string or content array)\n * @param options.deliverAs Delivery mode when streaming: \"steer\" or \"followUp\"\n */\n\nexport function clearQueue(this: AgentSession): { steering: string[]; followUp: string[] } {\n\tconst steering = [...this._steeringMessages];\n\tconst followUp = [...this._followUpMessages];\n\tthis._steeringMessages = [];\n\tthis._followUpMessages = [];\n\tthis.agent.clearAllQueues();\n\tif (this._activeInterruptQueueHold !== undefined) {\n\t\tthis._activeInterruptQueueHold.steering.length = 0;\n\t\tthis._activeInterruptQueueHold.followUp.length = 0;\n\t}\n\tthis._emitQueueUpdate();\n\treturn { steering, followUp };\n}\n\n/** Number of pending messages (includes both steering and follow-up) */\n\nexport function getSteeringMessages(this: AgentSession): readonly string[] {\n\treturn this._steeringMessages;\n}\n\n/** Get pending follow-up messages (read-only) */\n\nexport function getFollowUpMessages(this: AgentSession): readonly string[] {\n\treturn this._followUpMessages;\n}\n\n\nexport async function abort(this: AgentSession): Promise<void> {\n\tthis.abortRetry();\n\tthis.agent.abort();\n\tawait this.agent.waitForIdle();\n}\n\n// =========================================================================\n// Model Management\n// =========================================================================\n\n\nexport function setSteeringMode(this: AgentSession, mode: \"all\" | \"one-at-a-time\"): void {\n\tthis.agent.steeringMode = mode;\n\tthis.settingsManager.setSteeringMode(mode);\n}\n\n/**\n * Set follow-up message mode.\n * Saves to settings.\n */\n\nexport function setFollowUpMode(this: AgentSession, mode: \"all\" | \"one-at-a-time\"): void {\n\tthis.agent.followUpMode = mode;\n\tthis.settingsManager.setFollowUpMode(mode);\n}\n\n// =========================================================================\n// Queue and delivery settings\n// =========================================================================\nexport const agentSessionMessageQueueMethods = {\n\t_queueSteer,\n\t_queueFollowUp,\n\t_throwIfExtensionCommand,\n\tsendCustomMessage,\n\t_appendCustomMessage,\n\t_enqueueInterruptCustomMessage,\n\t_sendInterruptCustomMessageNow,\n\t_ensureActiveInterruptQueueHold,\n\t_restoreAndClearActiveInterruptQueueHold,\n\t_queueAgentMessage,\n\t_drainQueuedAgentMessages,\n\t_restoreQueuedAgentMessages,\n\tclearQueue,\n\tgetSteeringMessages,\n\tgetFollowUpMessages,\n\tabort,\n\tsetSteeringMode,\n\tsetFollowUpMode,\n};\n"]}
|
|
@@ -235,12 +235,8 @@ export function setFollowUpMode(mode) {
|
|
|
235
235
|
this.settingsManager.setFollowUpMode(mode);
|
|
236
236
|
}
|
|
237
237
|
// =========================================================================
|
|
238
|
-
//
|
|
238
|
+
// Queue and delivery settings
|
|
239
239
|
// =========================================================================
|
|
240
|
-
/**
|
|
241
|
-
* Apply validated logical deletions and rebuild active agent context.
|
|
242
|
-
* Retained transcript entries/content blocks stay verbatim.
|
|
243
|
-
*/
|
|
244
240
|
export const agentSessionMessageQueueMethods = {
|
|
245
241
|
_queueSteer,
|
|
246
242
|
_queueFollowUp,
|