@bastani/atomic 0.9.5-alpha.9 → 0.9.5
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 +106 -0
- package/README.md +2 -2
- package/dist/builtin/cursor/CHANGELOG.md +12 -0
- package/dist/builtin/cursor/package.json +3 -3
- package/dist/builtin/cursor/src/model-mapper.ts +6 -3
- package/dist/builtin/intercom/CHANGELOG.md +37 -0
- package/dist/builtin/intercom/README.md +4 -2
- package/dist/builtin/intercom/broker/broker.ts +6 -114
- package/dist/builtin/intercom/broker/client.ts +29 -54
- package/dist/builtin/intercom/broker/delivered-message-cache.ts +44 -0
- package/dist/builtin/intercom/broker/pending-send-registry.ts +142 -0
- package/dist/builtin/intercom/broker/send-handler.ts +106 -0
- package/dist/builtin/intercom/broker/send-signature.ts +37 -0
- package/dist/builtin/intercom/foreground-detach-handoff.ts +136 -0
- package/dist/builtin/intercom/index-heavy.ts +49 -53
- package/dist/builtin/intercom/index.ts +278 -262
- package/dist/builtin/intercom/lazy-heavy-proxy.ts +114 -0
- package/dist/builtin/intercom/lazy-subagent-ack.ts +20 -0
- package/dist/builtin/intercom/lazy-tool-execution.ts +39 -0
- package/dist/builtin/intercom/lifecycle-lease.ts +51 -0
- package/dist/builtin/intercom/lifecycle.ts +37 -20
- package/dist/builtin/intercom/package.json +3 -6
- package/dist/builtin/intercom/reply-routing.ts +17 -0
- package/dist/builtin/intercom/subagent-relay.ts +58 -12
- package/dist/builtin/intercom/types.ts +3 -3
- package/dist/builtin/mcp/CHANGELOG.md +27 -0
- package/dist/builtin/mcp/OAUTH.md +1 -0
- package/dist/builtin/mcp/README.md +4 -0
- package/dist/builtin/mcp/apps-cancellation.ts +32 -0
- package/dist/builtin/mcp/call-tool-result.ts +9 -0
- package/dist/builtin/mcp/caller-wait.ts +50 -0
- package/dist/builtin/mcp/command-registration.ts +82 -0
- package/dist/builtin/mcp/direct-tool-executor.ts +279 -0
- package/dist/builtin/mcp/direct-tools.ts +6 -239
- package/dist/builtin/mcp/host-html-template.ts +4 -2
- package/dist/builtin/mcp/index.ts +258 -250
- package/dist/builtin/mcp/init.ts +96 -87
- package/dist/builtin/mcp/mcp-auth-flow.ts +247 -237
- package/dist/builtin/mcp/mcp-callback-server.ts +89 -68
- package/dist/builtin/mcp/mcp-oauth-provider.ts +23 -1
- package/dist/builtin/mcp/metadata-hydration.ts +21 -6
- package/dist/builtin/mcp/package.json +3 -3
- package/dist/builtin/mcp/proxy-auth.ts +4 -4
- package/dist/builtin/mcp/proxy-call.ts +111 -40
- package/dist/builtin/mcp/proxy-connect.ts +35 -15
- package/dist/builtin/mcp/proxy-info-modes.ts +49 -19
- package/dist/builtin/mcp/proxy-modes.ts +3 -3
- package/dist/builtin/mcp/session-cleanup-barrier.ts +43 -0
- package/dist/builtin/mcp/state-lease.ts +12 -0
- package/dist/builtin/mcp/ui-server.ts +8 -8
- package/dist/builtin/mcp/ui-session.ts +9 -18
- package/dist/builtin/subagents/CHANGELOG.md +66 -0
- package/dist/builtin/subagents/README.md +30 -29
- package/dist/builtin/subagents/agents/code-simplifier.md +2 -2
- package/dist/builtin/subagents/agents/codebase-analyzer.md +2 -2
- package/dist/builtin/subagents/agents/codebase-locator.md +2 -2
- package/dist/builtin/subagents/agents/codebase-online-researcher.md +2 -2
- package/dist/builtin/subagents/agents/codebase-pattern-finder.md +2 -2
- package/dist/builtin/subagents/agents/codebase-research-analyzer.md +2 -2
- package/dist/builtin/subagents/agents/codebase-research-locator.md +2 -2
- package/dist/builtin/subagents/agents/debugger.md +2 -2
- package/dist/builtin/subagents/agents/worker.md +2 -2
- package/dist/builtin/subagents/package.json +5 -5
- package/dist/builtin/subagents/prompts/review-loop.md +1 -1
- package/dist/builtin/subagents/skills/subagent/SKILL.md +37 -36
- package/dist/builtin/subagents/src/extension/api-lifecycle.ts +64 -0
- package/dist/builtin/subagents/src/extension/fanout-child.ts +44 -51
- package/dist/builtin/subagents/src/extension/index.ts +287 -307
- package/dist/builtin/subagents/src/extension/prompt-guidance.ts +7 -10
- package/dist/builtin/subagents/src/extension/schemas.ts +22 -5
- package/dist/builtin/subagents/src/extension/tool-description.ts +29 -0
- package/dist/builtin/subagents/src/intercom/intercom-bridge.ts +13 -2
- package/dist/builtin/subagents/src/intercom/result-intercom.ts +4 -4
- package/dist/builtin/subagents/src/runs/background/async-event-journal.ts +106 -0
- package/dist/builtin/subagents/src/runs/background/async-execution-common.ts +3 -2
- package/dist/builtin/subagents/src/runs/background/async-execution-single.ts +13 -2
- package/dist/builtin/subagents/src/runs/background/async-execution-types.ts +3 -0
- package/dist/builtin/subagents/src/runs/background/async-job-tracker.ts +1 -1
- package/dist/builtin/subagents/src/runs/background/completion-claims.ts +189 -0
- package/dist/builtin/subagents/src/runs/background/completion-dedupe.ts +44 -7
- package/dist/builtin/subagents/src/runs/background/completion-notification.ts +34 -0
- package/dist/builtin/subagents/src/runs/background/notify.ts +72 -22
- package/dist/builtin/subagents/src/runs/background/result-delivery-processor.ts +232 -0
- package/dist/builtin/subagents/src/runs/background/result-file-claims.ts +151 -0
- package/dist/builtin/subagents/src/runs/background/result-quarantine.ts +72 -0
- package/dist/builtin/subagents/src/runs/background/result-retry-scheduler.ts +48 -0
- package/dist/builtin/subagents/src/runs/background/result-status.ts +81 -0
- package/dist/builtin/subagents/src/runs/background/result-watcher-data.ts +59 -0
- package/dist/builtin/subagents/src/runs/background/result-watcher.ts +172 -238
- package/dist/builtin/subagents/src/runs/background/run-id-resolver.ts +3 -2
- package/dist/builtin/subagents/src/runs/background/stale-run-reconciler.ts +73 -14
- package/dist/builtin/subagents/src/runs/background/subagent-runner-streaming.ts +17 -13
- package/dist/builtin/subagents/src/runs/background/top-level-async.ts +1 -2
- package/dist/builtin/subagents/src/runs/foreground/chain-execution-dynamic-step.ts +1 -0
- package/dist/builtin/subagents/src/runs/foreground/chain-execution-parallel-runner.ts +1 -0
- package/dist/builtin/subagents/src/runs/foreground/chain-execution-parallel-step.ts +1 -0
- package/dist/builtin/subagents/src/runs/foreground/chain-execution-sequential-step.ts +7 -9
- package/dist/builtin/subagents/src/runs/foreground/chain-execution-types.ts +3 -13
- package/dist/builtin/subagents/src/runs/foreground/chain-execution.ts +2 -15
- package/dist/builtin/subagents/src/runs/foreground/execution-attempt-finalize.ts +2 -2
- package/dist/builtin/subagents/src/runs/foreground/execution-attempt.ts +53 -44
- package/dist/builtin/subagents/src/runs/foreground/execution-detach-reservations.ts +48 -0
- package/dist/builtin/subagents/src/runs/foreground/execution-detach-route.ts +17 -0
- package/dist/builtin/subagents/src/runs/foreground/execution-run-sync.ts +39 -26
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-async.ts +3 -1
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-chain.ts +3 -51
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-context.ts +6 -11
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-input.ts +11 -2
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-parallel-task.ts +2 -0
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-parallel.ts +5 -112
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-resume.ts +2 -0
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-single.ts +68 -118
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-status.ts +79 -7
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor-types.ts +2 -2
- package/dist/builtin/subagents/src/runs/foreground/subagent-executor.ts +3 -0
- package/dist/builtin/subagents/src/runs/shared/pi-args.ts +2 -2
- package/dist/builtin/subagents/src/runs/shared/pi-spawn.ts +27 -11
- package/dist/builtin/subagents/src/shared/artifacts.ts +22 -11
- package/dist/builtin/subagents/src/shared/event-jsonl-writer.ts +294 -0
- package/dist/builtin/subagents/src/shared/exclusive-file-publication.ts +44 -0
- package/dist/builtin/subagents/src/shared/jsonl-writer.ts +1 -0
- package/dist/builtin/subagents/src/shared/model-info.ts +2 -2
- package/dist/builtin/subagents/src/shared/settings.ts +20 -10
- package/dist/builtin/subagents/src/shared/types-async.ts +3 -1
- package/dist/builtin/subagents/src/shared/types-config.ts +2 -0
- package/dist/builtin/subagents/src/shared/types-runtime.ts +3 -2
- package/dist/builtin/subagents/src/slash/slash-commands.ts +9 -12
- package/dist/builtin/subagents/src/slash/slash-live-state.ts +63 -32
- package/dist/builtin/subagents/src/tui/render-result.ts +7 -0
- package/dist/builtin/subagents/src/tui/render-stable-output.ts +1 -0
- package/dist/builtin/subagents/src/tui/render-widget.ts +128 -89
- package/dist/builtin/web-access/CHANGELOG.md +28 -0
- package/dist/builtin/web-access/README.md +4 -0
- package/dist/builtin/web-access/content-tools.ts +8 -3
- package/dist/builtin/web-access/index-heavy.ts +1 -1
- package/dist/builtin/web-access/index.ts +190 -46
- package/dist/builtin/web-access/lifecycle-lease.ts +38 -0
- package/dist/builtin/web-access/package.json +2 -2
- package/dist/builtin/web-access/result-renderers.ts +1 -1
- package/dist/builtin/web-access/summary-review.ts +1 -1
- package/dist/builtin/web-access/web-search-activity.ts +1 -1
- package/dist/builtin/web-access/web-search-return.ts +7 -0
- package/dist/builtin/web-access/web-search-summary.ts +1 -1
- package/dist/builtin/web-access/web-search-tool.ts +4 -2
- package/dist/builtin/workflows/CHANGELOG.md +68 -0
- package/dist/builtin/workflows/README.md +4 -4
- package/dist/builtin/workflows/builtin/deep-research-codebase-utils.ts +27 -4
- package/dist/builtin/workflows/builtin/goal-runner.ts +47 -26
- package/dist/builtin/workflows/builtin/open-claude-design-runner.ts +10 -0
- package/dist/builtin/workflows/builtin/ralph-core.ts +9 -9
- package/dist/builtin/workflows/builtin/ralph-models.ts +71 -36
- package/dist/builtin/workflows/builtin/ralph-runner.ts +20 -31
- package/dist/builtin/workflows/package.json +2 -2
- package/dist/builtin/workflows/src/durable/stage-primitive.ts +2 -1
- package/dist/builtin/workflows/src/engine/primitives/task.ts +2 -1
- package/dist/builtin/workflows/src/extension/workflow-prompts.ts +17 -22
- package/dist/builtin/workflows/src/extension/workflow-schema.ts +15 -2
- package/dist/builtin/workflows/src/runs/foreground/executor-hil.ts +1 -2
- package/dist/builtin/workflows/src/runs/shared/model-fallback-candidates.ts +1 -1
- package/dist/builtin/workflows/src/shared/authoring-contract-stage.d.ts +2 -2
- package/dist/builtin/workflows/src/shared/authoring-contract-stage.ts +2 -2
- package/dist/builtin/workflows/src/shared/resume-continuation.ts +2 -0
- package/dist/builtin/workflows/src/tui/stage-chat-view-archive-history.ts +1 -23
- package/dist/builtin/workflows/src/tui/stage-chat-view-footer-status.ts +54 -9
- package/dist/builtin/workflows/src/tui/stage-chat-view.ts +5 -2
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +2 -2
- package/dist/cli/args.js.map +1 -1
- package/dist/core/agent-session-events.d.ts.map +1 -1
- package/dist/core/agent-session-events.js +2 -1
- package/dist/core/agent-session-events.js.map +1 -1
- package/dist/core/agent-session-message-queue.d.ts.map +1 -1
- package/dist/core/agent-session-message-queue.js +1 -1
- package/dist/core/agent-session-message-queue.js.map +1 -1
- package/dist/core/agent-session-prompt.d.ts.map +1 -1
- package/dist/core/agent-session-prompt.js +1 -1
- package/dist/core/agent-session-prompt.js.map +1 -1
- package/dist/core/agent-session-retry.d.ts.map +1 -1
- package/dist/core/agent-session-retry.js +1 -1
- package/dist/core/agent-session-retry.js.map +1 -1
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js +3 -2
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session-types.d.ts.map +1 -1
- package/dist/core/agent-session-types.js +1 -1
- package/dist/core/agent-session-types.js.map +1 -1
- package/dist/core/anthropic-thinking-guard.d.ts +5 -5
- package/dist/core/anthropic-thinking-guard.d.ts.map +1 -1
- package/dist/core/anthropic-thinking-guard.js +42 -32
- package/dist/core/anthropic-thinking-guard.js.map +1 -1
- package/dist/core/atomic-guide-command.d.ts.map +1 -1
- package/dist/core/atomic-guide-command.js +15 -15
- package/dist/core/atomic-guide-command.js.map +1 -1
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +14 -9
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +2 -0
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +79 -46
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/compaction/context-assistant-turns.d.ts +42 -0
- package/dist/core/compaction/context-assistant-turns.d.ts.map +1 -0
- package/dist/core/compaction/context-assistant-turns.js +87 -0
- package/dist/core/compaction/context-assistant-turns.js.map +1 -0
- package/dist/core/compaction/context-compaction-critical.d.ts +1 -1
- package/dist/core/compaction/context-compaction-critical.d.ts.map +1 -1
- package/dist/core/compaction/context-compaction-critical.js +2 -2
- package/dist/core/compaction/context-compaction-critical.js.map +1 -1
- package/dist/core/compaction/context-compaction-eviction-alternates.d.ts +18 -0
- package/dist/core/compaction/context-compaction-eviction-alternates.d.ts.map +1 -0
- package/dist/core/compaction/context-compaction-eviction-alternates.js +186 -0
- package/dist/core/compaction/context-compaction-eviction-alternates.js.map +1 -0
- package/dist/core/compaction/context-compaction-eviction.d.ts +10 -2
- package/dist/core/compaction/context-compaction-eviction.d.ts.map +1 -1
- package/dist/core/compaction/context-compaction-eviction.js +196 -146
- package/dist/core/compaction/context-compaction-eviction.js.map +1 -1
- package/dist/core/compaction/context-compaction-prompt.d.ts.map +1 -1
- package/dist/core/compaction/context-compaction-prompt.js +1 -1
- package/dist/core/compaction/context-compaction-prompt.js.map +1 -1
- package/dist/core/compaction/context-compaction-types.d.ts +2 -0
- package/dist/core/compaction/context-compaction-types.d.ts.map +1 -1
- package/dist/core/compaction/context-compaction-types.js.map +1 -1
- package/dist/core/compaction/context-deletion-application.d.ts +5 -4
- package/dist/core/compaction/context-deletion-application.d.ts.map +1 -1
- package/dist/core/compaction/context-deletion-application.js +17 -15
- package/dist/core/compaction/context-deletion-application.js.map +1 -1
- package/dist/core/compaction/context-deletion-store.d.ts.map +1 -1
- package/dist/core/compaction/context-deletion-store.js +1 -1
- package/dist/core/compaction/context-deletion-store.js.map +1 -1
- package/dist/core/compaction/context-deletion-targets.d.ts +2 -1
- package/dist/core/compaction/context-deletion-targets.d.ts.map +1 -1
- package/dist/core/compaction/context-deletion-targets.js +36 -31
- package/dist/core/compaction/context-deletion-targets.js.map +1 -1
- package/dist/core/compaction/context-deletion-tool-helpers.d.ts.map +1 -1
- package/dist/core/compaction/context-deletion-tool-helpers.js +116 -43
- package/dist/core/compaction/context-deletion-tool-helpers.js.map +1 -1
- package/dist/core/compaction/context-transcript-analysis.d.ts +1 -2
- package/dist/core/compaction/context-transcript-analysis.d.ts.map +1 -1
- package/dist/core/compaction/context-transcript-analysis.js +33 -37
- package/dist/core/compaction/context-transcript-analysis.js.map +1 -1
- package/dist/core/copilot-model-synthesis.d.ts.map +1 -1
- package/dist/core/copilot-model-synthesis.js +3 -1
- package/dist/core/copilot-model-synthesis.js.map +1 -1
- package/dist/core/extensions/provider-types.d.ts +2 -7
- package/dist/core/extensions/provider-types.d.ts.map +1 -1
- package/dist/core/extensions/provider-types.js.map +1 -1
- package/dist/core/messages.d.ts +9 -0
- package/dist/core/messages.d.ts.map +1 -1
- package/dist/core/messages.js +100 -18
- package/dist/core/messages.js.map +1 -1
- package/dist/core/model-registry-builtins.d.ts.map +1 -1
- package/dist/core/model-registry-builtins.js +5 -0
- package/dist/core/model-registry-builtins.js.map +1 -1
- package/dist/core/model-registry-custom-loader.d.ts.map +1 -1
- package/dist/core/model-registry-custom-loader.js +49 -8
- package/dist/core/model-registry-custom-loader.js.map +1 -1
- package/dist/core/model-registry-dynamic.d.ts.map +1 -1
- package/dist/core/model-registry-dynamic.js +11 -5
- package/dist/core/model-registry-dynamic.js.map +1 -1
- package/dist/core/model-registry-loader.d.ts.map +1 -1
- package/dist/core/model-registry-loader.js +8 -0
- package/dist/core/model-registry-loader.js.map +1 -1
- package/dist/core/model-registry-schemas.d.ts +93 -8
- package/dist/core/model-registry-schemas.d.ts.map +1 -1
- package/dist/core/model-registry-schemas.js +24 -12
- package/dist/core/model-registry-schemas.js.map +1 -1
- package/dist/core/model-registry-types.d.ts +7 -6
- package/dist/core/model-registry-types.d.ts.map +1 -1
- package/dist/core/model-registry-types.js.map +1 -1
- package/dist/core/model-registry.d.ts +5 -0
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +23 -0
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-resolver-cli.d.ts.map +1 -1
- package/dist/core/model-resolver-cli.js +33 -5
- package/dist/core/model-resolver-cli.js.map +1 -1
- package/dist/core/model-resolver-initial.d.ts +6 -1
- package/dist/core/model-resolver-initial.d.ts.map +1 -1
- package/dist/core/model-resolver-initial.js +12 -7
- package/dist/core/model-resolver-initial.js.map +1 -1
- package/dist/core/model-resolver.d.ts +1 -1
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +1 -1
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/resource-loader-context-files.d.ts +1 -0
- package/dist/core/resource-loader-context-files.d.ts.map +1 -1
- package/dist/core/resource-loader-context-files.js +13 -10
- package/dist/core/resource-loader-context-files.js.map +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +2 -2
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-entry-normalization.d.ts +7 -0
- package/dist/core/session-entry-normalization.d.ts.map +1 -0
- package/dist/core/session-entry-normalization.js +14 -0
- package/dist/core/session-entry-normalization.js.map +1 -0
- package/dist/core/session-manager-core.d.ts.map +1 -1
- package/dist/core/session-manager-core.js +1 -0
- package/dist/core/session-manager-core.js.map +1 -1
- package/dist/core/session-manager-history.d.ts +2 -2
- package/dist/core/session-manager-history.d.ts.map +1 -1
- package/dist/core/session-manager-history.js +127 -108
- package/dist/core/session-manager-history.js.map +1 -1
- package/dist/core/settings-manager-basic-accessors.d.ts +2 -2
- package/dist/core/settings-manager-basic-accessors.d.ts.map +1 -1
- package/dist/core/settings-manager-basic-accessors.js.map +1 -1
- package/dist/core/settings-types.d.ts +1 -1
- package/dist/core/settings-types.d.ts.map +1 -1
- package/dist/core/settings-types.js.map +1 -1
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +11 -8
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/main-session.d.ts.map +1 -1
- package/dist/main-session.js +1 -0
- package/dist/main-session.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector-options.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector-options.js +3 -1
- package/dist/modes/interactive/components/settings-selector-options.js.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.js +2 -1
- package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
- package/dist/modes/interactive/interactive-agent-events.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-agent-events.js +2 -1
- package/dist/modes/interactive/interactive-agent-events.js.map +1 -1
- package/dist/modes/interactive/interactive-child-ordering.d.ts +7 -0
- package/dist/modes/interactive/interactive-child-ordering.d.ts.map +1 -0
- package/dist/modes/interactive/interactive-child-ordering.js +26 -0
- package/dist/modes/interactive/interactive-child-ordering.js.map +1 -0
- package/dist/modes/interactive/interactive-deferred-startup.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-deferred-startup.js +2 -2
- package/dist/modes/interactive/interactive-deferred-startup.js.map +1 -1
- package/dist/modes/interactive/interactive-mode-deps.d.ts +1 -1
- 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-model-routing.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-model-routing.js +8 -3
- package/dist/modes/interactive/interactive-model-routing.js.map +1 -1
- package/dist/modes/interactive/theme/theme-class.d.ts +1 -1
- package/dist/modes/interactive/theme/theme-class.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme-class.js +2 -0
- package/dist/modes/interactive/theme/theme-class.js.map +1 -1
- package/dist/utils/clipboard-image.d.ts.map +1 -1
- package/dist/utils/clipboard-image.js +3 -0
- package/dist/utils/clipboard-image.js.map +1 -1
- package/docs/changelog.mdx +19 -0
- package/docs/compaction.md +55 -48
- package/docs/custom-provider.md +18 -5
- package/docs/extensions.md +7 -3
- package/docs/models.md +69 -10
- package/docs/providers.md +1 -1
- package/docs/quickstart.md +11 -7
- package/docs/rpc.md +2 -2
- package/docs/sdk.md +1 -1
- package/docs/settings.md +3 -3
- package/docs/subagents.md +36 -5
- package/docs/tools.md +1 -1
- package/docs/usage.md +4 -2
- package/docs/workflows.md +26 -43
- package/examples/extensions/preset.ts +2 -2
- package/examples/extensions/subagent/README.md +2 -2
- package/examples/extensions/subagent/index.ts +1 -2
- package/examples/extensions/subagent/schemas.ts +4 -1
- package/examples/sdk/12-full-control.ts +1 -1
- package/npm-shrinkwrap.json +48 -51
- package/package.json +7 -7
- package/dist/builtin/subagents/src/runs/foreground/chain-clarify-behavior.ts +0 -75
- package/dist/builtin/subagents/src/runs/foreground/chain-clarify-component.ts +0 -202
- package/dist/builtin/subagents/src/runs/foreground/chain-clarify-edit.ts +0 -97
- package/dist/builtin/subagents/src/runs/foreground/chain-clarify-editor.ts +0 -160
- package/dist/builtin/subagents/src/runs/foreground/chain-clarify-frame.ts +0 -72
- package/dist/builtin/subagents/src/runs/foreground/chain-clarify-render-modes.ts +0 -161
- package/dist/builtin/subagents/src/runs/foreground/chain-clarify-render-selectors.ts +0 -203
- package/dist/builtin/subagents/src/runs/foreground/chain-clarify-selectors.ts +0 -234
- package/dist/builtin/subagents/src/runs/foreground/chain-clarify-state.ts +0 -103
- package/dist/builtin/subagents/src/runs/foreground/chain-clarify-types.ts +0 -29
- package/dist/builtin/subagents/src/runs/foreground/chain-clarify.ts +0 -9
- package/dist/builtin/subagents/src/runs/foreground/chain-execution-clarify.ts +0 -117
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
import { getTranscriptCompactionParameters } from "./context-compaction-strategy.js";
|
|
2
|
-
import { assistantEntryHasThinkingContentBlock } from "./context-
|
|
2
|
+
import { analyzeCompactableAssistantTurns, assistantEntryHasThinkingContentBlock, compactableContentBlockIsLlmVisible, transcriptEntryStartsNewTurn, } from "./context-assistant-turns.js";
|
|
3
|
+
function findAssistantTurnDeletionViolation(transcript, targets) {
|
|
4
|
+
const { deletedEntryIds, turns } = analyzeCompactableAssistantTurns(transcript, targets);
|
|
5
|
+
for (const turn of turns) {
|
|
6
|
+
if (turn.signedThinkingEntryIds.length === 0)
|
|
7
|
+
continue;
|
|
8
|
+
const deleted = turn.signedThinkingEntryIds.filter((entryId) => deletedEntryIds.has(entryId));
|
|
9
|
+
if (turn.active && deleted.length > 0)
|
|
10
|
+
return { entryId: deleted[0], active: true };
|
|
11
|
+
if (!turn.active && deleted.length > 0 && deleted.length < turn.signedThinkingEntryIds.length) {
|
|
12
|
+
return { entryId: deleted[0], active: false };
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
3
17
|
export function targetKey(target) {
|
|
4
18
|
return target.kind === "entry" ? `entry:${target.entryId}` : `content_block:${target.entryId}:${target.blockIndex}`;
|
|
5
19
|
}
|
|
@@ -96,10 +110,12 @@ export function formatProtectedToolDependencyError(transcript, blockedTarget, co
|
|
|
96
110
|
const protectedMessage = formatProtectedDeletionError(transcript, blockedTarget);
|
|
97
111
|
return `${context} ${protectedMessage}`;
|
|
98
112
|
}
|
|
113
|
+
// Keep legacy protection phrases recognizable for callers handling errors
|
|
114
|
+
// produced by older compaction plans and extension versions.
|
|
99
115
|
export function isProtectedContextDeletionErrorMessage(message) {
|
|
100
116
|
return (/\bprotected\b/i.test(message) ||
|
|
101
117
|
/Cannot delete (?:recent context entry|content block .* because entry .* is one of the last)/u.test(message) ||
|
|
102
|
-
/latest assistant message|thinking\/redacted_thinking block in (?:the latest|a retained) assistant message/u.test(message));
|
|
118
|
+
/latest assistant message|active assistant tool-use turn|completed assistant tool-use turn|thinking\/redacted_thinking block in (?:the latest|a retained) assistant message/u.test(message));
|
|
103
119
|
}
|
|
104
120
|
export function assertNoRecentContextDeletionTargets(transcript, targets) {
|
|
105
121
|
const recentEntryIds = getRecentContextEntryIds(transcript);
|
|
@@ -131,26 +147,10 @@ export function findAssistantThinkingContentBlockDeletionViolation(transcript, t
|
|
|
131
147
|
return undefined;
|
|
132
148
|
}
|
|
133
149
|
export function findLatestAssistantThinkingDeletionViolation(transcript, targets) {
|
|
134
|
-
const
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
const entry = findTranscriptEntry(transcript, target.entryId);
|
|
139
|
-
if (!entry || !assistantEntryHasThinkingContentBlock(entry))
|
|
140
|
-
continue;
|
|
141
|
-
const deletedEntryIdsIfTargetWereKept = new Set(deletedEntryIds);
|
|
142
|
-
deletedEntryIdsIfTargetWereKept.delete(target.entryId);
|
|
143
|
-
if (latestAssistantEntry(transcript, deletedEntryIdsIfTargetWereKept)?.entryId === target.entryId) {
|
|
144
|
-
return target;
|
|
145
|
-
}
|
|
146
|
-
continue;
|
|
147
|
-
}
|
|
148
|
-
if (latestRetainedAssistant?.entryId === target.entryId &&
|
|
149
|
-
assistantEntryHasThinkingContentBlock(latestRetainedAssistant)) {
|
|
150
|
-
return target;
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
return undefined;
|
|
150
|
+
const violation = findAssistantTurnDeletionViolation(transcript, targets);
|
|
151
|
+
if (!violation)
|
|
152
|
+
return undefined;
|
|
153
|
+
return targets.find((target) => target.kind === "entry" && target.entryId === violation.entryId);
|
|
154
154
|
}
|
|
155
155
|
export function assertNoAssistantThinkingContentBlockDeletionTargets(transcript, targets) {
|
|
156
156
|
const violation = findAssistantThinkingContentBlockDeletionViolation(transcript, targets);
|
|
@@ -159,13 +159,13 @@ export function assertNoAssistantThinkingContentBlockDeletionTargets(transcript,
|
|
|
159
159
|
throw new Error(`Cannot delete content block ${violation.entryId}:${violation.blockIndex} because a thinking/redacted_thinking block in a retained assistant message must remain unmodified; retained assistant messages containing thinking/redacted_thinking content blocks are all-or-nothing`);
|
|
160
160
|
}
|
|
161
161
|
export function assertNoLatestAssistantThinkingDeletionTargets(transcript, targets) {
|
|
162
|
-
const violation =
|
|
162
|
+
const violation = findAssistantTurnDeletionViolation(transcript, targets);
|
|
163
163
|
if (!violation)
|
|
164
164
|
return;
|
|
165
|
-
if (violation.
|
|
166
|
-
throw new Error(`Cannot delete assistant entry ${violation.entryId} because
|
|
165
|
+
if (violation.active) {
|
|
166
|
+
throw new Error(`Cannot delete assistant entry ${violation.entryId} because the active assistant tool-use turn must retain every thinking/redacted_thinking-bearing assistant entry`);
|
|
167
167
|
}
|
|
168
|
-
throw new Error(`Cannot delete
|
|
168
|
+
throw new Error(`Cannot delete assistant entry ${violation.entryId} because a completed assistant tool-use turn must retain all or omit all thinking/redacted_thinking-bearing assistant entries`);
|
|
169
169
|
}
|
|
170
170
|
export function isToolCallBlockDeleted(entry, callId, deletedEntryIds, deletedContentBlocks) {
|
|
171
171
|
if (deletedEntryIds.has(entry.entryId))
|
|
@@ -239,11 +239,13 @@ export function addToolCallDeletion(transcript, targets, entry, callId) {
|
|
|
239
239
|
}
|
|
240
240
|
return canonicalizeEntryTargets(transcript, targets, entry) || changed;
|
|
241
241
|
}
|
|
242
|
-
|
|
243
|
-
|
|
242
|
+
/** Whether a task-bearing entry remains provider-visible after proposed block deletions. */
|
|
243
|
+
export function isTaskBearingEntry(entry, deletedContentBlocks = new Set()) {
|
|
244
|
+
const taskRole = entry.role === "user" ||
|
|
244
245
|
entry.role === "custom" ||
|
|
245
246
|
entry.role === "branchSummary" ||
|
|
246
|
-
entry.entryType === "branch_summary"
|
|
247
|
+
entry.entryType === "branch_summary";
|
|
248
|
+
return taskRole && transcriptEntryStartsNewTurn(entry, deletedContentBlocks);
|
|
247
249
|
}
|
|
248
250
|
export function isRecentTarget(transcript, target) {
|
|
249
251
|
const entry = transcript.entries.find((candidate) => candidate.entryId === target.entryId);
|
|
@@ -252,7 +254,8 @@ export function isRecentTarget(transcript, target) {
|
|
|
252
254
|
export function isStaleUserImageOnlyEntry(transcript, entry) {
|
|
253
255
|
if (entry.role !== "user" || isRecentContextEntry(entry, transcript))
|
|
254
256
|
return false;
|
|
255
|
-
|
|
257
|
+
const visibleBlocks = entry.contentBlocks.filter((block) => compactableContentBlockIsLlmVisible(entry, block));
|
|
258
|
+
if (visibleBlocks.length === 0 || !visibleBlocks.every((block) => block.type === "image"))
|
|
256
259
|
return false;
|
|
257
260
|
return transcript.entries.some((candidate) => candidate.entryId !== entry.entryId && isTaskBearingEntry(candidate));
|
|
258
261
|
}
|
|
@@ -265,7 +268,9 @@ export function canDeleteStaleUserImageContentBlock(transcript, target) {
|
|
|
265
268
|
const block = entry.contentBlocks.find((candidate) => candidate.blockIndex === target.blockIndex);
|
|
266
269
|
if (!block || block.type !== "image")
|
|
267
270
|
return false;
|
|
268
|
-
return entry.contentBlocks.some((candidate) => candidate.blockIndex !== target.blockIndex &&
|
|
271
|
+
return entry.contentBlocks.some((candidate) => candidate.blockIndex !== target.blockIndex &&
|
|
272
|
+
candidate.type !== "image" &&
|
|
273
|
+
compactableContentBlockIsLlmVisible(entry, candidate));
|
|
269
274
|
}
|
|
270
275
|
export function canDeleteTarget(transcript, target) {
|
|
271
276
|
const entry = transcript.entries.find((candidate) => candidate.entryId === target.entryId);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context-deletion-targets.js","sourceRoot":"","sources":["../../../src/core/compaction/context-deletion-targets.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ContextDeletionTarget } from \"../session-manager.ts\";\nimport type {\n\tCompactableContentBlock,\n\tCompactableTranscript,\n\tCompactableTranscriptEntry,\n\tContextDeletionRequest,\n} from \"./context-compaction-types.ts\";\nimport { getTranscriptCompactionParameters } from \"./context-compaction-strategy.ts\";\nimport { assistantEntryHasThinkingContentBlock } from \"./context-transcript-analysis.ts\";\n\nexport function targetKey(target: ContextDeletionTarget): string {\n\treturn target.kind === \"entry\" ? `entry:${target.entryId}` : `content_block:${target.entryId}:${target.blockIndex}`;\n}\n\nexport function rawTargetKey(target: ContextDeletionRequest[\"deletions\"][number]): string {\n\treturn target.kind === \"entry\" ? `entry:${target.entryId}` : `content_block:${target.entryId}:${target.blockIndex}`;\n}\n\nexport function normalizeRawTarget(target: ContextDeletionRequest[\"deletions\"][number]): ContextDeletionTarget {\n\tif (target.kind === \"entry\") return { kind: \"entry\", entryId: target.entryId };\n\treturn { kind: \"content_block\", entryId: target.entryId, blockIndex: target.blockIndex as number };\n}\n\nexport function assertIdOnlyDeletionTarget(target: Record<string, unknown>): void {\n\tconst allowedKeys = target.kind === \"content_block\" ? new Set([\"kind\", \"entryId\", \"blockIndex\"]) : new Set([\"kind\", \"entryId\"]);\n\tfor (const key of Object.keys(target)) {\n\t\tif (!allowedKeys.has(key)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Deletion target includes unsupported property ${JSON.stringify(key)}; context deletion targets are id-only and must contain only kind, entryId${target.kind === \"content_block\" ? \", and blockIndex\" : \"\"}`,\n\t\t\t);\n\t\t}\n\t}\n}\n\nexport function rawDeletionFromTarget(target: ContextDeletionTarget): ContextDeletionRequest[\"deletions\"][number] {\n\tif (target.kind === \"entry\") return { kind: \"entry\", entryId: target.entryId };\n\treturn { kind: \"content_block\", entryId: target.entryId, blockIndex: target.blockIndex };\n}\n\nexport function deletionRequestFromTargets(targets: readonly ContextDeletionTarget[]): ContextDeletionRequest {\n\treturn { deletions: targets.map(rawDeletionFromTarget) };\n}\n\nexport function getDeletedEntryIds(targets: readonly ContextDeletionTarget[]): Set<string> {\n\treturn new Set(targets.filter((target) => target.kind === \"entry\").map((target) => target.entryId));\n}\n\nexport function getDeletedContentBlocks(targets: readonly ContextDeletionTarget[]): Map<string, Set<number>> {\n\tconst blocksByEntry = new Map<string, Set<number>>();\n\tfor (const target of targets) {\n\t\tif (target.kind !== \"content_block\") continue;\n\t\tconst blocks = blocksByEntry.get(target.entryId) ?? new Set<number>();\n\t\tblocks.add(target.blockIndex);\n\t\tblocksByEntry.set(target.entryId, blocks);\n\t}\n\treturn blocksByEntry;\n}\n\nexport function recentContextEntryBoundary(transcript: CompactableTranscript): number {\n\tconst { preserve_recent } = getTranscriptCompactionParameters(transcript);\n\treturn preserve_recent > 0 ? Math.max(0, transcript.entries.length - preserve_recent) : transcript.entries.length;\n}\n\nexport function getRecentContextEntryIds(transcript: CompactableTranscript): Set<string> {\n\tconst { preserve_recent } = getTranscriptCompactionParameters(transcript);\n\tif (preserve_recent <= 0) return new Set();\n\treturn new Set(transcript.entries.slice(recentContextEntryBoundary(transcript)).map((entry) => entry.entryId));\n}\n\nexport function isRecentContextEntry(entry: CompactableTranscriptEntry, transcript: CompactableTranscript): boolean {\n\tconst { preserve_recent } = getTranscriptCompactionParameters(transcript);\n\tif (preserve_recent <= 0) return false;\n\tconst entryIndex = transcript.entries.findIndex((candidate) => candidate.entryId === entry.entryId);\n\treturn entryIndex >= 0 && entryIndex >= recentContextEntryBoundary(transcript);\n}\n\nexport function formatRecentContextDeletionError(transcript: CompactableTranscript, target: ContextDeletionTarget): string {\n\tconst { preserve_recent } = getTranscriptCompactionParameters(transcript);\n\tconst recentWindow = `last ${preserve_recent} context ${preserve_recent === 1 ? \"entry\" : \"entries\"}`;\n\tif (target.kind === \"entry\") {\n\t\treturn `Cannot delete recent context entry ${target.entryId} because the ${recentWindow} must remain available for active continuity. Choose an older entry.`;\n\t}\n\treturn `Cannot delete content block ${target.entryId}:${target.blockIndex} because entry ${target.entryId} is one of the ${recentWindow} that must remain available for active continuity. Choose an older entry or content block.`;\n}\n\nexport function deletionGuidance(): string {\n\treturn \"Choose another deletion candidate.\";\n}\n\nexport function findTranscriptEntry(transcript: CompactableTranscript, entryId: string): CompactableTranscriptEntry | undefined {\n\treturn transcript.entries.find((entry) => entry.entryId === entryId);\n}\n\nexport function findTranscriptContentBlock(\n\ttranscript: CompactableTranscript,\n\ttarget: ContextDeletionTarget,\n): CompactableContentBlock | undefined {\n\tif (target.kind !== \"content_block\") return undefined;\n\treturn findTranscriptEntry(transcript, target.entryId)?.contentBlocks.find((block) => block.blockIndex === target.blockIndex);\n}\n\nexport function firstToolCallBlockTarget(\n\tentry: CompactableTranscriptEntry,\n\tcallId: string,\n): ContextDeletionTarget | undefined {\n\tconst blockIndex = toolCallBlockIndexes(entry, callId)[0];\n\treturn blockIndex === undefined ? undefined : { kind: \"content_block\", entryId: entry.entryId, blockIndex };\n}\n\nexport function formatProtectedDeletionError(transcript: CompactableTranscript, target: ContextDeletionTarget): string {\n\tconst entry = findTranscriptEntry(transcript, target.entryId);\n\tif (target.kind === \"entry\") {\n\t\tconst toolResultSuffix = entry?.toolResultFor ? ` for tool call ${entry.toolResultFor}` : \"\";\n\t\tconst toolCallSuffix = entry && entry.toolCallIds.length > 0 ? ` containing tool call ${entry.toolCallIds.join(\", \")}` : \"\";\n\t\treturn `Deletion target ${target.entryId}${toolResultSuffix}${toolCallSuffix} is protected. ${deletionGuidance()}`;\n\t}\n\n\tconst block = findTranscriptContentBlock(transcript, target);\n\tconst toolBlockSuffix = block?.toolCallId ? ` It is a protected tool block for tool call ${block.toolCallId}.` : \"\";\n\treturn `Content block ${target.entryId}:${target.blockIndex} is protected.${toolBlockSuffix} ${deletionGuidance()}`;\n}\n\nexport function formatProtectedToolDependencyError(\n\ttranscript: CompactableTranscript,\n\tblockedTarget: ContextDeletionTarget,\n\tcontext: string,\n): string {\n\tconst protectedMessage = formatProtectedDeletionError(transcript, blockedTarget);\n\treturn `${context} ${protectedMessage}`;\n}\n\nexport function isProtectedContextDeletionErrorMessage(message: string): boolean {\n\treturn (\n\t\t/\\bprotected\\b/i.test(message) ||\n\t\t/Cannot delete (?:recent context entry|content block .* because entry .* is one of the last)/u.test(message) ||\n\t\t/latest assistant message|thinking\\/redacted_thinking block in (?:the latest|a retained) assistant message/u.test(message)\n\t);\n}\n\nexport function assertNoRecentContextDeletionTargets(\n\ttranscript: CompactableTranscript,\n\ttargets: readonly ContextDeletionTarget[],\n): void {\n\tconst recentEntryIds = getRecentContextEntryIds(transcript);\n\tfor (const target of targets) {\n\t\tif (recentEntryIds.has(target.entryId)) {\n\t\t\tthrow new Error(formatRecentContextDeletionError(transcript, target));\n\t\t}\n\t}\n}\n\nexport function latestAssistantEntry(\n\ttranscript: CompactableTranscript,\n\tdeletedEntryIds: ReadonlySet<string> = new Set<string>(),\n): CompactableTranscriptEntry | undefined {\n\tfor (let index = transcript.entries.length - 1; index >= 0; index--) {\n\t\tconst entry = transcript.entries[index];\n\t\tif (entry.role === \"assistant\" && !deletedEntryIds.has(entry.entryId)) return entry;\n\t}\n\treturn undefined;\n}\n\nexport function findAssistantThinkingContentBlockDeletionViolation(\n\ttranscript: CompactableTranscript,\n\ttargets: readonly ContextDeletionTarget[],\n): Extract<ContextDeletionTarget, { kind: \"content_block\" }> | undefined {\n\tconst deletedEntryIds = getDeletedEntryIds(targets);\n\tfor (const target of targets) {\n\t\tif (target.kind !== \"content_block\") continue;\n\t\tif (deletedEntryIds.has(target.entryId)) continue;\n\t\tconst entry = findTranscriptEntry(transcript, target.entryId);\n\t\tif (entry && assistantEntryHasThinkingContentBlock(entry)) return target;\n\t}\n\treturn undefined;\n}\n\nexport function findLatestAssistantThinkingDeletionViolation(\n\ttranscript: CompactableTranscript,\n\ttargets: readonly ContextDeletionTarget[],\n): ContextDeletionTarget | undefined {\n\tconst deletedEntryIds = getDeletedEntryIds(targets);\n\tconst latestRetainedAssistant = latestAssistantEntry(transcript, deletedEntryIds);\n\n\tfor (const target of targets) {\n\t\tif (target.kind === \"entry\") {\n\t\t\tconst entry = findTranscriptEntry(transcript, target.entryId);\n\t\t\tif (!entry || !assistantEntryHasThinkingContentBlock(entry)) continue;\n\t\t\tconst deletedEntryIdsIfTargetWereKept = new Set(deletedEntryIds);\n\t\t\tdeletedEntryIdsIfTargetWereKept.delete(target.entryId);\n\t\t\tif (latestAssistantEntry(transcript, deletedEntryIdsIfTargetWereKept)?.entryId === target.entryId) {\n\t\t\t\treturn target;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tif (\n\t\t\tlatestRetainedAssistant?.entryId === target.entryId &&\n\t\t\tassistantEntryHasThinkingContentBlock(latestRetainedAssistant)\n\t\t) {\n\t\t\treturn target;\n\t\t}\n\t}\n\treturn undefined;\n}\n\nexport function assertNoAssistantThinkingContentBlockDeletionTargets(\n\ttranscript: CompactableTranscript,\n\ttargets: readonly ContextDeletionTarget[],\n): void {\n\tconst violation = findAssistantThinkingContentBlockDeletionViolation(transcript, targets);\n\tif (!violation) return;\n\tthrow new Error(\n\t\t`Cannot delete content block ${violation.entryId}:${violation.blockIndex} because a thinking/redacted_thinking block in a retained assistant message must remain unmodified; retained assistant messages containing thinking/redacted_thinking content blocks are all-or-nothing`,\n\t);\n}\n\nexport function assertNoLatestAssistantThinkingDeletionTargets(\n\ttranscript: CompactableTranscript,\n\ttargets: readonly ContextDeletionTarget[],\n): void {\n\tconst violation = findLatestAssistantThinkingDeletionViolation(transcript, targets);\n\tif (!violation) return;\n\tif (violation.kind === \"entry\") {\n\t\tthrow new Error(\n\t\t\t`Cannot delete assistant entry ${violation.entryId} because it is the latest assistant message retained after other deletions and contains thinking/redacted_thinking content blocks`,\n\t\t);\n\t}\n\tthrow new Error(\n\t\t`Cannot delete content block ${violation.entryId}:${violation.blockIndex} because a thinking/redacted_thinking block in the latest assistant message must remain unmodified; the latest retained assistant message contains thinking/redacted_thinking content blocks`,\n\t);\n}\n\nexport function isToolCallBlockDeleted(\n\tentry: CompactableTranscriptEntry,\n\tcallId: string,\n\tdeletedEntryIds: ReadonlySet<string>,\n\tdeletedContentBlocks: ReadonlyMap<string, ReadonlySet<number>>,\n): boolean {\n\tif (deletedEntryIds.has(entry.entryId)) return true;\n\tconst deletedBlocks = deletedContentBlocks.get(entry.entryId);\n\tif (!deletedBlocks) return false;\n\treturn entry.contentBlocks.some((block) => block.toolCallId === callId && deletedBlocks.has(block.blockIndex));\n}\n\nexport function toolCallBlockIndexes(entry: CompactableTranscriptEntry, callId: string): number[] {\n\treturn entry.contentBlocks\n\t\t.filter((block) => block.toolCallId === callId)\n\t\t.map((block) => block.blockIndex);\n}\n\nexport function addTarget(targets: ContextDeletionTarget[], target: ContextDeletionTarget): boolean {\n\tif (targets.some((existing) => targetKey(existing) === targetKey(target))) return false;\n\ttargets.push(target);\n\treturn true;\n}\n\nexport function deleteEntryTarget(targets: ContextDeletionTarget[], entryId: string): boolean {\n\tlet changed = false;\n\tfor (let index = targets.length - 1; index >= 0; index--) {\n\t\tconst target = targets[index];\n\t\tif (target.kind === \"content_block\" && target.entryId === entryId) {\n\t\t\ttargets.splice(index, 1);\n\t\t\tchanged = true;\n\t\t}\n\t}\n\treturn addTarget(targets, { kind: \"entry\", entryId }) || changed;\n}\n\nexport function mergeContextDeletionTargets(\n\tbaseTargets: readonly ContextDeletionTarget[],\n\tadditionalTargets: readonly ContextDeletionTarget[],\n): ContextDeletionTarget[] {\n\tconst targets = [...baseTargets];\n\tfor (const target of additionalTargets) {\n\t\tif (target.kind === \"entry\") {\n\t\t\tdeleteEntryTarget(targets, target.entryId);\n\t\t\tcontinue;\n\t\t}\n\t\tif (!getDeletedEntryIds(targets).has(target.entryId)) {\n\t\t\taddTarget(targets, target);\n\t\t}\n\t}\n\treturn targets;\n}\n\nexport function canonicalizeEntryTargets(\n\ttranscript: CompactableTranscript,\n\ttargets: ContextDeletionTarget[],\n\tentry: CompactableTranscriptEntry,\n): boolean {\n\tif (!canDeleteTarget(transcript, { kind: \"entry\", entryId: entry.entryId })) return false;\n\tif (getDeletedEntryIds(targets).has(entry.entryId)) return false;\n\tconst deletedBlocks = getDeletedContentBlocks(targets).get(entry.entryId);\n\tif (!deletedBlocks || !entry.contentBlocks.every((block) => deletedBlocks.has(block.blockIndex))) return false;\n\t// Only repair/promote when dependency reconciliation reaches this entry. Non-tool entries that\n\t// request every block individually stay invalid so the assistant must choose explicit entry deletion.\n\treturn deleteEntryTarget(targets, entry.entryId);\n}\n\nexport function addToolCallDeletion(\n\ttranscript: CompactableTranscript,\n\ttargets: ContextDeletionTarget[],\n\tentry: CompactableTranscriptEntry,\n\tcallId: string,\n): boolean {\n\tif (assistantEntryHasThinkingContentBlock(entry)) {\n\t\tif (!canDeleteTarget(transcript, { kind: \"entry\", entryId: entry.entryId })) return false;\n\t\treturn deleteEntryTarget(targets, entry.entryId);\n\t}\n\n\tlet changed = false;\n\tfor (const blockIndex of toolCallBlockIndexes(entry, callId)) {\n\t\tconst target: ContextDeletionTarget = { kind: \"content_block\", entryId: entry.entryId, blockIndex };\n\t\tif (!canDeleteTarget(transcript, target)) continue;\n\t\tif (!getDeletedEntryIds(targets).has(entry.entryId)) {\n\t\t\tchanged = addTarget(targets, target) || changed;\n\t\t}\n\t}\n\treturn canonicalizeEntryTargets(transcript, targets, entry) || changed;\n}\n\nexport function isTaskBearingEntry(entry: CompactableTranscriptEntry): boolean {\n\treturn (\n\t\tentry.role === \"user\" ||\n\t\tentry.role === \"custom\" ||\n\t\tentry.role === \"branchSummary\" ||\n\t\tentry.entryType === \"branch_summary\"\n\t);\n}\n\nexport function isRecentTarget(transcript: CompactableTranscript, target: ContextDeletionTarget): boolean {\n\tconst entry = transcript.entries.find((candidate) => candidate.entryId === target.entryId);\n\treturn entry !== undefined && isRecentContextEntry(entry, transcript);\n}\n\nexport function isStaleUserImageOnlyEntry(transcript: CompactableTranscript, entry: CompactableTranscriptEntry): boolean {\n\tif (entry.role !== \"user\" || isRecentContextEntry(entry, transcript)) return false;\n\tif (entry.contentBlocks.length === 0 || !entry.contentBlocks.every((block) => block.type === \"image\")) return false;\n\treturn transcript.entries.some((candidate) => candidate.entryId !== entry.entryId && isTaskBearingEntry(candidate));\n}\n\nexport function canDeleteStaleUserImageContentBlock(\n\ttranscript: CompactableTranscript,\n\ttarget: ContextDeletionTarget,\n): boolean {\n\tif (target.kind !== \"content_block\") return false;\n\tconst entry = transcript.entries.find((candidate) => candidate.entryId === target.entryId);\n\tif (!entry || entry.role !== \"user\" || isRecentTarget(transcript, target)) return false;\n\tconst block = entry.contentBlocks.find((candidate) => candidate.blockIndex === target.blockIndex);\n\tif (!block || block.type !== \"image\") return false;\n\treturn entry.contentBlocks.some((candidate) => candidate.blockIndex !== target.blockIndex && candidate.type !== \"image\");\n}\n\nexport function canDeleteTarget(transcript: CompactableTranscript, target: ContextDeletionTarget): boolean {\n\tconst entry = transcript.entries.find((candidate) => candidate.entryId === target.entryId);\n\tif (!entry) return false;\n\tif (isRecentTarget(transcript, target)) return false;\n\tif (target.kind === \"entry\") return isStaleUserImageOnlyEntry(transcript, entry) || !entry.protected;\n\tconst block = entry.contentBlocks.find((candidate) => candidate.blockIndex === target.blockIndex);\n\tif (!block) return false;\n\tif (canDeleteStaleUserImageContentBlock(transcript, target)) return true;\n\tif (entry.protected) return false;\n\treturn !block.protected;\n}\n\n"]}
|
|
1
|
+
{"version":3,"file":"context-deletion-targets.js","sourceRoot":"","sources":["../../../src/core/compaction/context-deletion-targets.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,iCAAiC,EAAE,MAAM,kCAAkC,CAAC;AACrF,OAAO,EACN,gCAAgC,EAChC,qCAAqC,EACrC,mCAAmC,EACnC,4BAA4B,GAC5B,MAAM,8BAA8B,CAAC;AAOtC,SAAS,kCAAkC,CAC1C,UAAiC,EACjC,OAAyC;IAEzC,MAAM,EAAE,eAAe,EAAE,KAAK,EAAE,GAAG,gCAAgC,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IACzF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QAC1B,IAAI,IAAI,CAAC,sBAAsB,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QACvD,MAAM,OAAO,GAAG,IAAI,CAAC,sBAAsB,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;QAC9F,IAAI,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;QACrF,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,sBAAsB,CAAC,MAAM,EAAE,CAAC;YAC/F,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;QAChD,CAAC;IACF,CAAC;IACD,OAAO,SAAS,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,MAA6B;IACtD,OAAO,MAAM,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,SAAS,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,iBAAiB,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;AACrH,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,MAAmD;IAC/E,OAAO,MAAM,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,SAAS,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,iBAAiB,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;AACrH,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,MAAmD;IACrF,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO;QAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;IAC/E,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,UAAU,EAAE,MAAM,CAAC,UAAoB,EAAE,CAAC;AACpG,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,MAA+B;IACzE,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,KAAK,eAAe,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,SAAS,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;IAChI,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QACvC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CACd,iDAAiD,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,6EAA6E,MAAM,CAAC,IAAI,KAAK,eAAe,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,EAAE,CAC5M,CAAC;QACH,CAAC;IACF,CAAC;AACF,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,MAA6B;IAClE,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO;QAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;IAC/E,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE,CAAC;AAC1F,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,OAAyC;IACnF,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,EAAE,CAAC;AAC1D,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,OAAyC;IAC3E,OAAO,IAAI,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;AACrG,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,OAAyC;IAChF,MAAM,aAAa,GAAG,IAAI,GAAG,EAAuB,CAAC;IACrD,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC9B,IAAI,MAAM,CAAC,IAAI,KAAK,eAAe;YAAE,SAAS;QAC9C,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI,GAAG,EAAU,CAAC;QACtE,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAC9B,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC3C,CAAC;IACD,OAAO,aAAa,CAAC;AACtB,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,UAAiC;IAC3E,MAAM,EAAE,eAAe,EAAE,GAAG,iCAAiC,CAAC,UAAU,CAAC,CAAC;IAC1E,OAAO,eAAe,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,MAAM,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC;AACnH,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,UAAiC;IACzE,MAAM,EAAE,eAAe,EAAE,GAAG,iCAAiC,CAAC,UAAU,CAAC,CAAC;IAC1E,IAAI,eAAe,IAAI,CAAC;QAAE,OAAO,IAAI,GAAG,EAAE,CAAC;IAC3C,OAAO,IAAI,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,0BAA0B,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;AAChH,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,KAAiC,EAAE,UAAiC;IACxG,MAAM,EAAE,eAAe,EAAE,GAAG,iCAAiC,CAAC,UAAU,CAAC,CAAC;IAC1E,IAAI,eAAe,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IACvC,MAAM,UAAU,GAAG,UAAU,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,OAAO,KAAK,KAAK,CAAC,OAAO,CAAC,CAAC;IACpG,OAAO,UAAU,IAAI,CAAC,IAAI,UAAU,IAAI,0BAA0B,CAAC,UAAU,CAAC,CAAC;AAChF,CAAC;AAED,MAAM,UAAU,gCAAgC,CAAC,UAAiC,EAAE,MAA6B;IAChH,MAAM,EAAE,eAAe,EAAE,GAAG,iCAAiC,CAAC,UAAU,CAAC,CAAC;IAC1E,MAAM,YAAY,GAAG,QAAQ,eAAe,YAAY,eAAe,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC;IACtG,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAC7B,OAAO,sCAAsC,MAAM,CAAC,OAAO,gBAAgB,YAAY,sEAAsE,CAAC;IAC/J,CAAC;IACD,OAAO,+BAA+B,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,UAAU,kBAAkB,MAAM,CAAC,OAAO,kBAAkB,YAAY,4FAA4F,CAAC;AACrO,CAAC;AAED,MAAM,UAAU,gBAAgB;IAC/B,OAAO,oCAAoC,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,UAAiC,EAAE,OAAe;IACrF,OAAO,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,KAAK,OAAO,CAAC,CAAC;AACtE,CAAC;AAED,MAAM,UAAU,0BAA0B,CACzC,UAAiC,EACjC,MAA6B;IAE7B,IAAI,MAAM,CAAC,IAAI,KAAK,eAAe;QAAE,OAAO,SAAS,CAAC;IACtD,OAAO,mBAAmB,CAAC,UAAU,EAAE,MAAM,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,UAAU,KAAK,MAAM,CAAC,UAAU,CAAC,CAAC;AAC/H,CAAC;AAED,MAAM,UAAU,wBAAwB,CACvC,KAAiC,EACjC,MAAc;IAEd,MAAM,UAAU,GAAG,oBAAoB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1D,OAAO,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,UAAU,EAAE,CAAC;AAC7G,CAAC;AAED,MAAM,UAAU,4BAA4B,CAAC,UAAiC,EAAE,MAA6B;IAC5G,MAAM,KAAK,GAAG,mBAAmB,CAAC,UAAU,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAC9D,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAC7B,MAAM,gBAAgB,GAAG,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,kBAAkB,KAAK,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7F,MAAM,cAAc,GAAG,KAAK,IAAI,KAAK,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,yBAAyB,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5H,OAAO,mBAAmB,MAAM,CAAC,OAAO,GAAG,gBAAgB,GAAG,cAAc,kBAAkB,gBAAgB,EAAE,EAAE,CAAC;IACpH,CAAC;IAED,MAAM,KAAK,GAAG,0BAA0B,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IAC7D,MAAM,eAAe,GAAG,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,+CAA+C,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IACpH,OAAO,iBAAiB,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,UAAU,iBAAiB,eAAe,IAAI,gBAAgB,EAAE,EAAE,CAAC;AACrH,CAAC;AAED,MAAM,UAAU,kCAAkC,CACjD,UAAiC,EACjC,aAAoC,EACpC,OAAe;IAEf,MAAM,gBAAgB,GAAG,4BAA4B,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;IACjF,OAAO,GAAG,OAAO,IAAI,gBAAgB,EAAE,CAAC;AACzC,CAAC;AAED,0EAA0E;AAC1E,6DAA6D;AAC7D,MAAM,UAAU,sCAAsC,CAAC,OAAe;IACrE,OAAO,CACN,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC;QAC9B,8FAA8F,CAAC,IAAI,CAAC,OAAO,CAAC;QAC5G,6KAA6K,CAAC,IAAI,CAAC,OAAO,CAAC,CAC3L,CAAC;AACH,CAAC;AAED,MAAM,UAAU,oCAAoC,CACnD,UAAiC,EACjC,OAAyC;IAEzC,MAAM,cAAc,GAAG,wBAAwB,CAAC,UAAU,CAAC,CAAC;IAC5D,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC9B,IAAI,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;YACxC,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC;QACvE,CAAC;IACF,CAAC;AACF,CAAC;AAED,MAAM,UAAU,oBAAoB,CACnC,UAAiC,EACjC,eAAe,GAAwB,IAAI,GAAG,EAAU;IAExD,KAAK,IAAI,KAAK,GAAG,UAAU,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;QACrE,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACxC,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC;YAAE,OAAO,KAAK,CAAC;IACrF,CAAC;IACD,OAAO,SAAS,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,kDAAkD,CACjE,UAAiC,EACjC,OAAyC;IAEzC,MAAM,eAAe,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;IACpD,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC9B,IAAI,MAAM,CAAC,IAAI,KAAK,eAAe;YAAE,SAAS;QAC9C,IAAI,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC;YAAE,SAAS;QAClD,MAAM,KAAK,GAAG,mBAAmB,CAAC,UAAU,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;QAC9D,IAAI,KAAK,IAAI,qCAAqC,CAAC,KAAK,CAAC;YAAE,OAAO,MAAM,CAAC;IAC1E,CAAC;IACD,OAAO,SAAS,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,4CAA4C,CAC3D,UAAiC,EACjC,OAAyC;IAEzC,MAAM,SAAS,GAAG,kCAAkC,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IAC1E,IAAI,CAAC,SAAS;QAAE,OAAO,SAAS,CAAC;IACjC,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,OAAO,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS,CAAC,OAAO,CAAC,CAAC;AAClG,CAAC;AAED,MAAM,UAAU,oDAAoD,CACnE,UAAiC,EACjC,OAAyC;IAEzC,MAAM,SAAS,GAAG,kDAAkD,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IAC1F,IAAI,CAAC,SAAS;QAAE,OAAO;IACvB,MAAM,IAAI,KAAK,CACd,+BAA+B,SAAS,CAAC,OAAO,IAAI,SAAS,CAAC,UAAU,yMAAyM,CACjR,CAAC;AACH,CAAC;AAED,MAAM,UAAU,8CAA8C,CAC7D,UAAiC,EACjC,OAAyC;IAEzC,MAAM,SAAS,GAAG,kCAAkC,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IAC1E,IAAI,CAAC,SAAS;QAAE,OAAO;IACvB,IAAI,SAAS,CAAC,MAAM,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CACd,iCAAiC,SAAS,CAAC,OAAO,kHAAkH,CACpK,CAAC;IACH,CAAC;IACD,MAAM,IAAI,KAAK,CACd,iCAAiC,SAAS,CAAC,OAAO,+HAA+H,CACjL,CAAC;AACH,CAAC;AAED,MAAM,UAAU,sBAAsB,CACrC,KAAiC,EACjC,MAAc,EACd,eAAoC,EACpC,oBAA8D;IAE9D,IAAI,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IACpD,MAAM,aAAa,GAAG,oBAAoB,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC9D,IAAI,CAAC,aAAa;QAAE,OAAO,KAAK,CAAC;IACjC,OAAO,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,UAAU,KAAK,MAAM,IAAI,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC;AAChH,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,KAAiC,EAAE,MAAc;IACrF,OAAO,KAAK,CAAC,aAAa;SACxB,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,UAAU,KAAK,MAAM,CAAC;SAC9C,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,OAAgC,EAAE,MAA6B;IACxF,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,SAAS,CAAC,MAAM,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IACxF,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACrB,OAAO,IAAI,CAAC;AACb,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,OAAgC,EAAE,OAAe;IAClF,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,KAAK,IAAI,KAAK,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;QAC1D,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;QAC9B,IAAI,MAAM,CAAC,IAAI,KAAK,eAAe,IAAI,MAAM,CAAC,OAAO,KAAK,OAAO,EAAE,CAAC;YACnE,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;YACzB,OAAO,GAAG,IAAI,CAAC;QAChB,CAAC;IACF,CAAC;IACD,OAAO,SAAS,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,IAAI,OAAO,CAAC;AAClE,CAAC;AAED,MAAM,UAAU,2BAA2B,CAC1C,WAA6C,EAC7C,iBAAmD;IAEnD,MAAM,OAAO,GAAG,CAAC,GAAG,WAAW,CAAC,CAAC;IACjC,KAAK,MAAM,MAAM,IAAI,iBAAiB,EAAE,CAAC;QACxC,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YAC7B,iBAAiB,CAAC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;YAC3C,SAAS;QACV,CAAC;QACD,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;YACtD,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC5B,CAAC;IACF,CAAC;IACD,OAAO,OAAO,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,wBAAwB,CACvC,UAAiC,EACjC,OAAgC,EAChC,KAAiC;IAEjC,IAAI,CAAC,eAAe,CAAC,UAAU,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;QAAE,OAAO,KAAK,CAAC;IAC1F,IAAI,kBAAkB,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC;QAAE,OAAO,KAAK,CAAC;IACjE,MAAM,aAAa,GAAG,uBAAuB,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC1E,IAAI,CAAC,aAAa,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IAC/G,+FAA+F;IAC/F,sGAAsG;IACtG,OAAO,iBAAiB,CAAC,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,mBAAmB,CAClC,UAAiC,EACjC,OAAgC,EAChC,KAAiC,EACjC,MAAc;IAEd,IAAI,qCAAqC,CAAC,KAAK,CAAC,EAAE,CAAC;QAClD,IAAI,CAAC,eAAe,CAAC,UAAU,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;YAAE,OAAO,KAAK,CAAC;QAC1F,OAAO,iBAAiB,CAAC,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;IAClD,CAAC;IAED,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,KAAK,MAAM,UAAU,IAAI,oBAAoB,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC;QAC9D,MAAM,MAAM,GAA0B,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,UAAU,EAAE,CAAC;QACpG,IAAI,CAAC,eAAe,CAAC,UAAU,EAAE,MAAM,CAAC;YAAE,SAAS;QACnD,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;YACrD,OAAO,GAAG,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,OAAO,CAAC;QACjD,CAAC;IACF,CAAC;IACD,OAAO,wBAAwB,CAAC,UAAU,EAAE,OAAO,EAAE,KAAK,CAAC,IAAI,OAAO,CAAC;AACxE,CAAC;AAED,4FAA4F;AAC5F,MAAM,UAAU,kBAAkB,CACjC,KAAiC,EACjC,oBAAoB,GAAwB,IAAI,GAAG,EAAU;IAE7D,MAAM,QAAQ,GACb,KAAK,CAAC,IAAI,KAAK,MAAM;QACrB,KAAK,CAAC,IAAI,KAAK,QAAQ;QACvB,KAAK,CAAC,IAAI,KAAK,eAAe;QAC9B,KAAK,CAAC,SAAS,KAAK,gBAAgB,CAAC;IACtC,OAAO,QAAQ,IAAI,4BAA4B,CAAC,KAAK,EAAE,oBAAoB,CAAC,CAAC;AAC9E,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,UAAiC,EAAE,MAA6B;IAC9F,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,OAAO,KAAK,MAAM,CAAC,OAAO,CAAC,CAAC;IAC3F,OAAO,KAAK,KAAK,SAAS,IAAI,oBAAoB,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;AACvE,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,UAAiC,EAAE,KAAiC;IAC7G,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,oBAAoB,CAAC,KAAK,EAAE,UAAU,CAAC;QAAE,OAAO,KAAK,CAAC;IACnF,MAAM,aAAa,GAAG,KAAK,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,mCAAmC,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;IAC/G,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,OAAO,CAAC;QAAE,OAAO,KAAK,CAAC;IACxG,OAAO,UAAU,CAAC,OAAO,CAAC,IAAI,CAC7B,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,OAAO,KAAK,KAAK,CAAC,OAAO,IAAI,kBAAkB,CAAC,SAAS,CAAC,CACnF,CAAC;AACH,CAAC;AAED,MAAM,UAAU,mCAAmC,CAClD,UAAiC,EACjC,MAA6B;IAE7B,IAAI,MAAM,CAAC,IAAI,KAAK,eAAe;QAAE,OAAO,KAAK,CAAC;IAClD,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,OAAO,KAAK,MAAM,CAAC,OAAO,CAAC,CAAC;IAC3F,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,cAAc,CAAC,UAAU,EAAE,MAAM,CAAC;QAAE,OAAO,KAAK,CAAC;IACxF,MAAM,KAAK,GAAG,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,UAAU,KAAK,MAAM,CAAC,UAAU,CAAC,CAAC;IAClG,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO;QAAE,OAAO,KAAK,CAAC;IACnD,OAAO,KAAK,CAAC,aAAa,CAAC,IAAI,CAC9B,CAAC,SAAS,EAAE,EAAE,CACb,SAAS,CAAC,UAAU,KAAK,MAAM,CAAC,UAAU;QAC1C,SAAS,CAAC,IAAI,KAAK,OAAO;QAC1B,mCAAmC,CAAC,KAAK,EAAE,SAAS,CAAC,CACtD,CAAC;AACH,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,UAAiC,EAAE,MAA6B;IAC/F,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,OAAO,KAAK,MAAM,CAAC,OAAO,CAAC,CAAC;IAC3F,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IACzB,IAAI,cAAc,CAAC,UAAU,EAAE,MAAM,CAAC;QAAE,OAAO,KAAK,CAAC;IACrD,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO;QAAE,OAAO,yBAAyB,CAAC,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC;IACrG,MAAM,KAAK,GAAG,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,UAAU,KAAK,MAAM,CAAC,UAAU,CAAC,CAAC;IAClG,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IACzB,IAAI,mCAAmC,CAAC,UAAU,EAAE,MAAM,CAAC;QAAE,OAAO,IAAI,CAAC;IACzE,IAAI,KAAK,CAAC,SAAS;QAAE,OAAO,KAAK,CAAC;IAClC,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC;AACzB,CAAC","sourcesContent":["import type { ContextDeletionTarget } from \"../session-manager.ts\";\nimport type {\n\tCompactableContentBlock,\n\tCompactableTranscript,\n\tCompactableTranscriptEntry,\n\tContextDeletionRequest,\n} from \"./context-compaction-types.ts\";\nimport { getTranscriptCompactionParameters } from \"./context-compaction-strategy.ts\";\nimport {\n\tanalyzeCompactableAssistantTurns,\n\tassistantEntryHasThinkingContentBlock,\n\tcompactableContentBlockIsLlmVisible,\n\ttranscriptEntryStartsNewTurn,\n} from \"./context-assistant-turns.js\";\n\ninterface AssistantTurnDeletionViolation {\n\tentryId: string;\n\tactive: boolean;\n}\n\nfunction findAssistantTurnDeletionViolation(\n\ttranscript: CompactableTranscript,\n\ttargets: readonly ContextDeletionTarget[],\n): AssistantTurnDeletionViolation | undefined {\n\tconst { deletedEntryIds, turns } = analyzeCompactableAssistantTurns(transcript, targets);\n\tfor (const turn of turns) {\n\t\tif (turn.signedThinkingEntryIds.length === 0) continue;\n\t\tconst deleted = turn.signedThinkingEntryIds.filter((entryId) => deletedEntryIds.has(entryId));\n\t\tif (turn.active && deleted.length > 0) return { entryId: deleted[0]!, active: true };\n\t\tif (!turn.active && deleted.length > 0 && deleted.length < turn.signedThinkingEntryIds.length) {\n\t\t\treturn { entryId: deleted[0]!, active: false };\n\t\t}\n\t}\n\treturn undefined;\n}\n\nexport function targetKey(target: ContextDeletionTarget): string {\n\treturn target.kind === \"entry\" ? `entry:${target.entryId}` : `content_block:${target.entryId}:${target.blockIndex}`;\n}\n\nexport function rawTargetKey(target: ContextDeletionRequest[\"deletions\"][number]): string {\n\treturn target.kind === \"entry\" ? `entry:${target.entryId}` : `content_block:${target.entryId}:${target.blockIndex}`;\n}\n\nexport function normalizeRawTarget(target: ContextDeletionRequest[\"deletions\"][number]): ContextDeletionTarget {\n\tif (target.kind === \"entry\") return { kind: \"entry\", entryId: target.entryId };\n\treturn { kind: \"content_block\", entryId: target.entryId, blockIndex: target.blockIndex as number };\n}\n\nexport function assertIdOnlyDeletionTarget(target: Record<string, unknown>): void {\n\tconst allowedKeys = target.kind === \"content_block\" ? new Set([\"kind\", \"entryId\", \"blockIndex\"]) : new Set([\"kind\", \"entryId\"]);\n\tfor (const key of Object.keys(target)) {\n\t\tif (!allowedKeys.has(key)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Deletion target includes unsupported property ${JSON.stringify(key)}; context deletion targets are id-only and must contain only kind, entryId${target.kind === \"content_block\" ? \", and blockIndex\" : \"\"}`,\n\t\t\t);\n\t\t}\n\t}\n}\n\nexport function rawDeletionFromTarget(target: ContextDeletionTarget): ContextDeletionRequest[\"deletions\"][number] {\n\tif (target.kind === \"entry\") return { kind: \"entry\", entryId: target.entryId };\n\treturn { kind: \"content_block\", entryId: target.entryId, blockIndex: target.blockIndex };\n}\n\nexport function deletionRequestFromTargets(targets: readonly ContextDeletionTarget[]): ContextDeletionRequest {\n\treturn { deletions: targets.map(rawDeletionFromTarget) };\n}\n\nexport function getDeletedEntryIds(targets: readonly ContextDeletionTarget[]): Set<string> {\n\treturn new Set(targets.filter((target) => target.kind === \"entry\").map((target) => target.entryId));\n}\n\nexport function getDeletedContentBlocks(targets: readonly ContextDeletionTarget[]): Map<string, Set<number>> {\n\tconst blocksByEntry = new Map<string, Set<number>>();\n\tfor (const target of targets) {\n\t\tif (target.kind !== \"content_block\") continue;\n\t\tconst blocks = blocksByEntry.get(target.entryId) ?? new Set<number>();\n\t\tblocks.add(target.blockIndex);\n\t\tblocksByEntry.set(target.entryId, blocks);\n\t}\n\treturn blocksByEntry;\n}\n\nexport function recentContextEntryBoundary(transcript: CompactableTranscript): number {\n\tconst { preserve_recent } = getTranscriptCompactionParameters(transcript);\n\treturn preserve_recent > 0 ? Math.max(0, transcript.entries.length - preserve_recent) : transcript.entries.length;\n}\n\nexport function getRecentContextEntryIds(transcript: CompactableTranscript): Set<string> {\n\tconst { preserve_recent } = getTranscriptCompactionParameters(transcript);\n\tif (preserve_recent <= 0) return new Set();\n\treturn new Set(transcript.entries.slice(recentContextEntryBoundary(transcript)).map((entry) => entry.entryId));\n}\n\nexport function isRecentContextEntry(entry: CompactableTranscriptEntry, transcript: CompactableTranscript): boolean {\n\tconst { preserve_recent } = getTranscriptCompactionParameters(transcript);\n\tif (preserve_recent <= 0) return false;\n\tconst entryIndex = transcript.entries.findIndex((candidate) => candidate.entryId === entry.entryId);\n\treturn entryIndex >= 0 && entryIndex >= recentContextEntryBoundary(transcript);\n}\n\nexport function formatRecentContextDeletionError(transcript: CompactableTranscript, target: ContextDeletionTarget): string {\n\tconst { preserve_recent } = getTranscriptCompactionParameters(transcript);\n\tconst recentWindow = `last ${preserve_recent} context ${preserve_recent === 1 ? \"entry\" : \"entries\"}`;\n\tif (target.kind === \"entry\") {\n\t\treturn `Cannot delete recent context entry ${target.entryId} because the ${recentWindow} must remain available for active continuity. Choose an older entry.`;\n\t}\n\treturn `Cannot delete content block ${target.entryId}:${target.blockIndex} because entry ${target.entryId} is one of the ${recentWindow} that must remain available for active continuity. Choose an older entry or content block.`;\n}\n\nexport function deletionGuidance(): string {\n\treturn \"Choose another deletion candidate.\";\n}\n\nexport function findTranscriptEntry(transcript: CompactableTranscript, entryId: string): CompactableTranscriptEntry | undefined {\n\treturn transcript.entries.find((entry) => entry.entryId === entryId);\n}\n\nexport function findTranscriptContentBlock(\n\ttranscript: CompactableTranscript,\n\ttarget: ContextDeletionTarget,\n): CompactableContentBlock | undefined {\n\tif (target.kind !== \"content_block\") return undefined;\n\treturn findTranscriptEntry(transcript, target.entryId)?.contentBlocks.find((block) => block.blockIndex === target.blockIndex);\n}\n\nexport function firstToolCallBlockTarget(\n\tentry: CompactableTranscriptEntry,\n\tcallId: string,\n): ContextDeletionTarget | undefined {\n\tconst blockIndex = toolCallBlockIndexes(entry, callId)[0];\n\treturn blockIndex === undefined ? undefined : { kind: \"content_block\", entryId: entry.entryId, blockIndex };\n}\n\nexport function formatProtectedDeletionError(transcript: CompactableTranscript, target: ContextDeletionTarget): string {\n\tconst entry = findTranscriptEntry(transcript, target.entryId);\n\tif (target.kind === \"entry\") {\n\t\tconst toolResultSuffix = entry?.toolResultFor ? ` for tool call ${entry.toolResultFor}` : \"\";\n\t\tconst toolCallSuffix = entry && entry.toolCallIds.length > 0 ? ` containing tool call ${entry.toolCallIds.join(\", \")}` : \"\";\n\t\treturn `Deletion target ${target.entryId}${toolResultSuffix}${toolCallSuffix} is protected. ${deletionGuidance()}`;\n\t}\n\n\tconst block = findTranscriptContentBlock(transcript, target);\n\tconst toolBlockSuffix = block?.toolCallId ? ` It is a protected tool block for tool call ${block.toolCallId}.` : \"\";\n\treturn `Content block ${target.entryId}:${target.blockIndex} is protected.${toolBlockSuffix} ${deletionGuidance()}`;\n}\n\nexport function formatProtectedToolDependencyError(\n\ttranscript: CompactableTranscript,\n\tblockedTarget: ContextDeletionTarget,\n\tcontext: string,\n): string {\n\tconst protectedMessage = formatProtectedDeletionError(transcript, blockedTarget);\n\treturn `${context} ${protectedMessage}`;\n}\n\n// Keep legacy protection phrases recognizable for callers handling errors\n// produced by older compaction plans and extension versions.\nexport function isProtectedContextDeletionErrorMessage(message: string): boolean {\n\treturn (\n\t\t/\\bprotected\\b/i.test(message) ||\n\t\t/Cannot delete (?:recent context entry|content block .* because entry .* is one of the last)/u.test(message) ||\n\t\t/latest assistant message|active assistant tool-use turn|completed assistant tool-use turn|thinking\\/redacted_thinking block in (?:the latest|a retained) assistant message/u.test(message)\n\t);\n}\n\nexport function assertNoRecentContextDeletionTargets(\n\ttranscript: CompactableTranscript,\n\ttargets: readonly ContextDeletionTarget[],\n): void {\n\tconst recentEntryIds = getRecentContextEntryIds(transcript);\n\tfor (const target of targets) {\n\t\tif (recentEntryIds.has(target.entryId)) {\n\t\t\tthrow new Error(formatRecentContextDeletionError(transcript, target));\n\t\t}\n\t}\n}\n\nexport function latestAssistantEntry(\n\ttranscript: CompactableTranscript,\n\tdeletedEntryIds: ReadonlySet<string> = new Set<string>(),\n): CompactableTranscriptEntry | undefined {\n\tfor (let index = transcript.entries.length - 1; index >= 0; index--) {\n\t\tconst entry = transcript.entries[index];\n\t\tif (entry.role === \"assistant\" && !deletedEntryIds.has(entry.entryId)) return entry;\n\t}\n\treturn undefined;\n}\n\nexport function findAssistantThinkingContentBlockDeletionViolation(\n\ttranscript: CompactableTranscript,\n\ttargets: readonly ContextDeletionTarget[],\n): Extract<ContextDeletionTarget, { kind: \"content_block\" }> | undefined {\n\tconst deletedEntryIds = getDeletedEntryIds(targets);\n\tfor (const target of targets) {\n\t\tif (target.kind !== \"content_block\") continue;\n\t\tif (deletedEntryIds.has(target.entryId)) continue;\n\t\tconst entry = findTranscriptEntry(transcript, target.entryId);\n\t\tif (entry && assistantEntryHasThinkingContentBlock(entry)) return target;\n\t}\n\treturn undefined;\n}\n\nexport function findLatestAssistantThinkingDeletionViolation(\n\ttranscript: CompactableTranscript,\n\ttargets: readonly ContextDeletionTarget[],\n): ContextDeletionTarget | undefined {\n\tconst violation = findAssistantTurnDeletionViolation(transcript, targets);\n\tif (!violation) return undefined;\n\treturn targets.find((target) => target.kind === \"entry\" && target.entryId === violation.entryId);\n}\n\nexport function assertNoAssistantThinkingContentBlockDeletionTargets(\n\ttranscript: CompactableTranscript,\n\ttargets: readonly ContextDeletionTarget[],\n): void {\n\tconst violation = findAssistantThinkingContentBlockDeletionViolation(transcript, targets);\n\tif (!violation) return;\n\tthrow new Error(\n\t\t`Cannot delete content block ${violation.entryId}:${violation.blockIndex} because a thinking/redacted_thinking block in a retained assistant message must remain unmodified; retained assistant messages containing thinking/redacted_thinking content blocks are all-or-nothing`,\n\t);\n}\n\nexport function assertNoLatestAssistantThinkingDeletionTargets(\n\ttranscript: CompactableTranscript,\n\ttargets: readonly ContextDeletionTarget[],\n): void {\n\tconst violation = findAssistantTurnDeletionViolation(transcript, targets);\n\tif (!violation) return;\n\tif (violation.active) {\n\t\tthrow new Error(\n\t\t\t`Cannot delete assistant entry ${violation.entryId} because the active assistant tool-use turn must retain every thinking/redacted_thinking-bearing assistant entry`,\n\t\t);\n\t}\n\tthrow new Error(\n\t\t`Cannot delete assistant entry ${violation.entryId} because a completed assistant tool-use turn must retain all or omit all thinking/redacted_thinking-bearing assistant entries`,\n\t);\n}\n\nexport function isToolCallBlockDeleted(\n\tentry: CompactableTranscriptEntry,\n\tcallId: string,\n\tdeletedEntryIds: ReadonlySet<string>,\n\tdeletedContentBlocks: ReadonlyMap<string, ReadonlySet<number>>,\n): boolean {\n\tif (deletedEntryIds.has(entry.entryId)) return true;\n\tconst deletedBlocks = deletedContentBlocks.get(entry.entryId);\n\tif (!deletedBlocks) return false;\n\treturn entry.contentBlocks.some((block) => block.toolCallId === callId && deletedBlocks.has(block.blockIndex));\n}\n\nexport function toolCallBlockIndexes(entry: CompactableTranscriptEntry, callId: string): number[] {\n\treturn entry.contentBlocks\n\t\t.filter((block) => block.toolCallId === callId)\n\t\t.map((block) => block.blockIndex);\n}\n\nexport function addTarget(targets: ContextDeletionTarget[], target: ContextDeletionTarget): boolean {\n\tif (targets.some((existing) => targetKey(existing) === targetKey(target))) return false;\n\ttargets.push(target);\n\treturn true;\n}\n\nexport function deleteEntryTarget(targets: ContextDeletionTarget[], entryId: string): boolean {\n\tlet changed = false;\n\tfor (let index = targets.length - 1; index >= 0; index--) {\n\t\tconst target = targets[index];\n\t\tif (target.kind === \"content_block\" && target.entryId === entryId) {\n\t\t\ttargets.splice(index, 1);\n\t\t\tchanged = true;\n\t\t}\n\t}\n\treturn addTarget(targets, { kind: \"entry\", entryId }) || changed;\n}\n\nexport function mergeContextDeletionTargets(\n\tbaseTargets: readonly ContextDeletionTarget[],\n\tadditionalTargets: readonly ContextDeletionTarget[],\n): ContextDeletionTarget[] {\n\tconst targets = [...baseTargets];\n\tfor (const target of additionalTargets) {\n\t\tif (target.kind === \"entry\") {\n\t\t\tdeleteEntryTarget(targets, target.entryId);\n\t\t\tcontinue;\n\t\t}\n\t\tif (!getDeletedEntryIds(targets).has(target.entryId)) {\n\t\t\taddTarget(targets, target);\n\t\t}\n\t}\n\treturn targets;\n}\n\nexport function canonicalizeEntryTargets(\n\ttranscript: CompactableTranscript,\n\ttargets: ContextDeletionTarget[],\n\tentry: CompactableTranscriptEntry,\n): boolean {\n\tif (!canDeleteTarget(transcript, { kind: \"entry\", entryId: entry.entryId })) return false;\n\tif (getDeletedEntryIds(targets).has(entry.entryId)) return false;\n\tconst deletedBlocks = getDeletedContentBlocks(targets).get(entry.entryId);\n\tif (!deletedBlocks || !entry.contentBlocks.every((block) => deletedBlocks.has(block.blockIndex))) return false;\n\t// Only repair/promote when dependency reconciliation reaches this entry. Non-tool entries that\n\t// request every block individually stay invalid so the assistant must choose explicit entry deletion.\n\treturn deleteEntryTarget(targets, entry.entryId);\n}\n\nexport function addToolCallDeletion(\n\ttranscript: CompactableTranscript,\n\ttargets: ContextDeletionTarget[],\n\tentry: CompactableTranscriptEntry,\n\tcallId: string,\n): boolean {\n\tif (assistantEntryHasThinkingContentBlock(entry)) {\n\t\tif (!canDeleteTarget(transcript, { kind: \"entry\", entryId: entry.entryId })) return false;\n\t\treturn deleteEntryTarget(targets, entry.entryId);\n\t}\n\n\tlet changed = false;\n\tfor (const blockIndex of toolCallBlockIndexes(entry, callId)) {\n\t\tconst target: ContextDeletionTarget = { kind: \"content_block\", entryId: entry.entryId, blockIndex };\n\t\tif (!canDeleteTarget(transcript, target)) continue;\n\t\tif (!getDeletedEntryIds(targets).has(entry.entryId)) {\n\t\t\tchanged = addTarget(targets, target) || changed;\n\t\t}\n\t}\n\treturn canonicalizeEntryTargets(transcript, targets, entry) || changed;\n}\n\n/** Whether a task-bearing entry remains provider-visible after proposed block deletions. */\nexport function isTaskBearingEntry(\n\tentry: CompactableTranscriptEntry,\n\tdeletedContentBlocks: ReadonlySet<number> = new Set<number>(),\n): boolean {\n\tconst taskRole =\n\t\tentry.role === \"user\" ||\n\t\tentry.role === \"custom\" ||\n\t\tentry.role === \"branchSummary\" ||\n\t\tentry.entryType === \"branch_summary\";\n\treturn taskRole && transcriptEntryStartsNewTurn(entry, deletedContentBlocks);\n}\n\nexport function isRecentTarget(transcript: CompactableTranscript, target: ContextDeletionTarget): boolean {\n\tconst entry = transcript.entries.find((candidate) => candidate.entryId === target.entryId);\n\treturn entry !== undefined && isRecentContextEntry(entry, transcript);\n}\n\nexport function isStaleUserImageOnlyEntry(transcript: CompactableTranscript, entry: CompactableTranscriptEntry): boolean {\n\tif (entry.role !== \"user\" || isRecentContextEntry(entry, transcript)) return false;\n\tconst visibleBlocks = entry.contentBlocks.filter((block) => compactableContentBlockIsLlmVisible(entry, block));\n\tif (visibleBlocks.length === 0 || !visibleBlocks.every((block) => block.type === \"image\")) return false;\n\treturn transcript.entries.some(\n\t\t(candidate) => candidate.entryId !== entry.entryId && isTaskBearingEntry(candidate),\n\t);\n}\n\nexport function canDeleteStaleUserImageContentBlock(\n\ttranscript: CompactableTranscript,\n\ttarget: ContextDeletionTarget,\n): boolean {\n\tif (target.kind !== \"content_block\") return false;\n\tconst entry = transcript.entries.find((candidate) => candidate.entryId === target.entryId);\n\tif (!entry || entry.role !== \"user\" || isRecentTarget(transcript, target)) return false;\n\tconst block = entry.contentBlocks.find((candidate) => candidate.blockIndex === target.blockIndex);\n\tif (!block || block.type !== \"image\") return false;\n\treturn entry.contentBlocks.some(\n\t\t(candidate) =>\n\t\t\tcandidate.blockIndex !== target.blockIndex &&\n\t\t\tcandidate.type !== \"image\" &&\n\t\t\tcompactableContentBlockIsLlmVisible(entry, candidate),\n\t);\n}\n\nexport function canDeleteTarget(transcript: CompactableTranscript, target: ContextDeletionTarget): boolean {\n\tconst entry = transcript.entries.find((candidate) => candidate.entryId === target.entryId);\n\tif (!entry) return false;\n\tif (isRecentTarget(transcript, target)) return false;\n\tif (target.kind === \"entry\") return isStaleUserImageOnlyEntry(transcript, entry) || !entry.protected;\n\tconst block = entry.contentBlocks.find((candidate) => candidate.blockIndex === target.blockIndex);\n\tif (!block) return false;\n\tif (canDeleteStaleUserImageContentBlock(transcript, target)) return true;\n\tif (entry.protected) return false;\n\treturn !block.protected;\n}\n\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context-deletion-tool-helpers.d.ts","sourceRoot":"","sources":["../../../src/core/compaction/context-deletion-tool-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AACnE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAC3E,OAAO,KAAK,EAAE,wBAAwB,EAAE,0BAA0B,EAAE,MAAM,wCAAwC,CAAC;AAiBnH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAExD;AACD,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAkB5D;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,OAAO,GAAG,MAAM,CAUjG;AAED,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAK3D;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAGtH;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEhF;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAIpE;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAM9F;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,SAAS,qBAAqB,EAAE,EAAE,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAKtH;AAED,wBAAgB,gBAAgB,CAC/B,UAAU,EAAE,qBAAqB,EAAE,EACnC,OAAO,EAAE,wBAAwB,EAAE,EACnC,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,EACxB,SAAS,EAAE,qBAAqB,EAChC,KAAK,EAAE,wBAAwB,GAC7B,IAAI,CAMN;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,0BAA0B,EAAE,EAAE,KAAK,EAAE,wBAAwB,GAAG,IAAI,CAQlH;AAED,wBAAgB,6BAA6B,CAC5C,UAAU,EAAE,SAAS,qBAAqB,EAAE,EAC5C,OAAO,EAAE,SAAS,wBAAwB,EAAE,EAC5C,cAAc,EAAE,SAAS,qBAAqB,EAAE,EAChD,UAAU,EAAE,qBAAqB,EACjC,OAAO,EAAE,0BAA0B,EAAE,GACnC;IAAE,UAAU,EAAE,qBAAqB,EAAE,CAAC;IAAC,OAAO,EAAE,wBAAwB,EAAE,CAAA;CAAE,CAkD9E","sourcesContent":["import type { ContextDeletionTarget } from \"../session-manager.ts\";\nimport type { CompactableTranscript } from \"./context-compaction-types.ts\";\nimport type { ContextGrepDeletionMatch, ContextGrepDeletionSkipped } from \"./context-deletion-tool-definitions.ts\";\nimport {\n\tCONTEXT_GREP_DELETE_MAX_REGEX_PATTERN_CHARS,\n\tCONTEXT_GREP_DELETE_MAX_REGEX_SCAN_CHARS,\n} from \"./context-deletion-tool-definitions.ts\";\nimport { formatErrorMessage } from \"./context-compaction-metrics.ts\";\nimport { validateContextDeletionRequest } from \"./context-deletion-application.ts\";\nimport {\n\tdeletionRequestFromTargets,\n\tfindLatestAssistantThinkingDeletionViolation,\n\tgetDeletedContentBlocks,\n\tgetDeletedEntryIds,\n\tisProtectedContextDeletionErrorMessage,\n\tmergeContextDeletionTargets,\n\ttargetKey,\n} from \"./context-deletion-targets.ts\";\n\nexport function escapeRegExpLiteral(text: string): string {\n\treturn text.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\nexport function assertSafeRegexPattern(pattern: string): void {\n\tif (pattern.length > CONTEXT_GREP_DELETE_MAX_REGEX_PATTERN_CHARS) {\n\t\tthrow new Error(\n\t\t\t`Regex pattern is too long (${pattern.length} characters); maximum is ${CONTEXT_GREP_DELETE_MAX_REGEX_PATTERN_CHARS}`,\n\t\t);\n\t}\n\n\t// Heuristic ReDoS guard for common catastrophic-backtracking shapes. JavaScript's RegExp engine\n\t// does not expose a timeout, so reject nested quantified groups and backreferences instead of\n\t// relying only on transcript scan-size caps.\n\tconst hasNestedQuantifiedGroup = /\\((?:[^()\\\\]|\\\\.)*[+*](?:[^()\\\\]|\\\\.)*\\)\\s*(?:[+*]|\\{\\d)/u.test(pattern);\n\tconst hasQuantifiedAlternation = /\\((?:[^()\\\\]|\\\\.)*\\|(?:[^()\\\\]|\\\\.)*\\)\\s*(?:[+*]|\\{\\d)/u.test(pattern);\n\tconst hasBackreference = /\\\\[1-9]/u.test(pattern);\n\tif (hasNestedQuantifiedGroup || hasQuantifiedAlternation || hasBackreference) {\n\t\tthrow new Error(\n\t\t\t\"Regex pattern is not allowed because it may cause excessive backtracking; use a literal pattern or exact deletion targets instead.\",\n\t\t);\n\t}\n}\n\nexport function createGrepMatcher(pattern: string, regex: boolean, caseSensitive: boolean): RegExp {\n\tif (regex) {\n\t\tassertSafeRegexPattern(pattern);\n\t}\n\n\ttry {\n\t\treturn new RegExp(regex ? pattern : escapeRegExpLiteral(pattern), caseSensitive ? \"u\" : \"iu\");\n\t} catch (error) {\n\t\tthrow new Error(`Invalid grep ${regex ? \"regex\" : \"pattern\"}: ${formatErrorMessage(error)}`);\n\t}\n}\n\nexport function assertSafeRegexScan(scanChars: number): void {\n\tif (scanChars <= CONTEXT_GREP_DELETE_MAX_REGEX_SCAN_CHARS) return;\n\tthrow new Error(\n\t\t`Regex grep would scan ${scanChars} characters; maximum is ${CONTEXT_GREP_DELETE_MAX_REGEX_SCAN_CHARS}. Use a literal pattern or exact deletion targets instead.`,\n\t);\n}\n\nexport function clampInteger(value: number | undefined, defaultValue: number, minimum: number, maximum: number): number {\n\tif (value === undefined) return defaultValue;\n\treturn Math.max(minimum, Math.min(maximum, value));\n}\n\nexport function textSlice(text: string, offset: number, maxChars: number): string {\n\treturn text.slice(offset, Math.min(text.length, offset + maxChars));\n}\n\nexport function findMatchIndex(matcher: RegExp, text: string): number {\n\tconst match = matcher.exec(text);\n\tmatcher.lastIndex = 0;\n\treturn match?.index ?? -1;\n}\n\nexport function snippetForMatch(text: string, matchIndex: number, contextChars: number): string {\n\tconst start = Math.max(0, matchIndex - contextChars);\n\tconst end = Math.min(text.length, matchIndex + contextChars);\n\tconst prefix = start > 0 ? \"…\" : \"\";\n\tconst suffix = end < text.length ? \"…\" : \"\";\n\treturn `${prefix}${text.slice(start, end)}${suffix}`;\n}\n\nexport function currentTargetDeleted(targets: readonly ContextDeletionTarget[], target: ContextDeletionTarget): boolean {\n\tconst deletedEntryIds = getDeletedEntryIds(targets);\n\tif (deletedEntryIds.has(target.entryId)) return true;\n\tif (target.kind === \"entry\") return false;\n\treturn getDeletedContentBlocks(targets).get(target.entryId)?.has(target.blockIndex) === true;\n}\n\nexport function addGrepCandidate(\n\tcandidates: ContextDeletionTarget[],\n\tmatches: ContextGrepDeletionMatch[],\n\tseenTargets: Set<string>,\n\tcandidate: ContextDeletionTarget,\n\tmatch: ContextGrepDeletionMatch,\n): void {\n\tconst key = targetKey(candidate);\n\tif (seenTargets.has(key)) return;\n\tseenTargets.add(key);\n\tcandidates.push(candidate);\n\tmatches.push(match);\n}\n\nexport function pushProtectedGrepSkip(skipped: ContextGrepDeletionSkipped[], match: ContextGrepDeletionMatch): void {\n\tskipped.push({\n\t\tentryId: match.entryId,\n\t\ttarget: match.target,\n\t\t...(match.blockIndex === undefined ? {} : { blockIndex: match.blockIndex }),\n\t\treason: match.target === \"content_block\" ? \"protected_block\" : \"protected_entry\",\n\t\ttext: match.text,\n\t});\n}\n\nexport function filterProtectedGrepCandidates(\n\tcandidates: readonly ContextDeletionTarget[],\n\tmatches: readonly ContextGrepDeletionMatch[],\n\tcurrentTargets: readonly ContextDeletionTarget[],\n\ttranscript: CompactableTranscript,\n\tskipped: ContextGrepDeletionSkipped[],\n): { candidates: ContextDeletionTarget[]; matches: ContextGrepDeletionMatch[] } {\n\tconst eligibleCandidates: ContextDeletionTarget[] = [];\n\tconst eligibleMatches: ContextGrepDeletionMatch[] = [];\n\tfor (let index = 0; index < candidates.length; index++) {\n\t\tconst candidate = candidates[index];\n\t\tconst match = matches[index];\n\t\tif (!candidate || !match) continue;\n\t\ttry {\n\t\t\tconst mergedTargets = mergeContextDeletionTargets(currentTargets, [candidate]);\n\t\t\tvalidateContextDeletionRequest(deletionRequestFromTargets(mergedTargets), transcript);\n\t\t\teligibleCandidates.push(candidate);\n\t\t\teligibleMatches.push(match);\n\t\t} catch (error) {\n\t\t\tconst message = formatErrorMessage(error);\n\t\t\tif (isProtectedContextDeletionErrorMessage(message)) {\n\t\t\t\tpushProtectedGrepSkip(skipped, match);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\teligibleCandidates.push(candidate);\n\t\t\teligibleMatches.push(match);\n\t\t}\n\t}\n\n\t// Some latest-assistant thinking violations only become visible after a grep batch also\n\t// deletes newer assistant entries. Classify the newly-unsafe grep candidates as\n\t// protected/skipped before maxMatches, expectedMatchCount, stats, or removals are computed.\n\tlet changed = true;\n\twhile (changed) {\n\t\tchanged = false;\n\t\tconst mergedTargets = mergeContextDeletionTargets(currentTargets, eligibleCandidates);\n\t\tconst violation = findLatestAssistantThinkingDeletionViolation(transcript, mergedTargets);\n\t\tif (!violation) continue;\n\t\tconst violationKey = targetKey(violation);\n\t\tlet violationIndex = eligibleCandidates.findIndex((candidate) => targetKey(candidate) === violationKey);\n\t\tif (violationIndex < 0) {\n\t\t\tviolationIndex = eligibleCandidates.findIndex((_candidate, candidateIndex) => {\n\t\t\t\tconst remainingCandidates = eligibleCandidates.filter((_candidateToKeep, index) => index !== candidateIndex);\n\t\t\t\tconst remainingTargets = mergeContextDeletionTargets(currentTargets, remainingCandidates);\n\t\t\t\tconst remainingViolation = findLatestAssistantThinkingDeletionViolation(transcript, remainingTargets);\n\t\t\t\treturn !remainingViolation || targetKey(remainingViolation) !== violationKey;\n\t\t\t});\n\t\t}\n\t\tif (violationIndex < 0) continue;\n\t\tconst [skippedMatch] = eligibleMatches.splice(violationIndex, 1);\n\t\teligibleCandidates.splice(violationIndex, 1);\n\t\tif (skippedMatch) pushProtectedGrepSkip(skipped, skippedMatch);\n\t\tchanged = true;\n\t}\n\n\treturn { candidates: eligibleCandidates, matches: eligibleMatches };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"context-deletion-tool-helpers.d.ts","sourceRoot":"","sources":["../../../src/core/compaction/context-deletion-tool-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AACnE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAC3E,OAAO,KAAK,EAAE,wBAAwB,EAAE,0BAA0B,EAAE,MAAM,wCAAwC,CAAC;AAoBnH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAExD;AACD,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAkB5D;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,OAAO,GAAG,MAAM,CAUjG;AAED,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAK3D;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAGtH;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEhF;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAIpE;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAM9F;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,SAAS,qBAAqB,EAAE,EAAE,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAKtH;AAED,wBAAgB,gBAAgB,CAC/B,UAAU,EAAE,qBAAqB,EAAE,EACnC,OAAO,EAAE,wBAAwB,EAAE,EACnC,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,EACxB,SAAS,EAAE,qBAAqB,EAChC,KAAK,EAAE,wBAAwB,GAC7B,IAAI,CAMN;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,0BAA0B,EAAE,EAAE,KAAK,EAAE,wBAAwB,GAAG,IAAI,CAQlH;AAoCD,wBAAgB,6BAA6B,CAC5C,UAAU,EAAE,SAAS,qBAAqB,EAAE,EAC5C,OAAO,EAAE,SAAS,wBAAwB,EAAE,EAC5C,cAAc,EAAE,SAAS,qBAAqB,EAAE,EAChD,UAAU,EAAE,qBAAqB,EACjC,OAAO,EAAE,0BAA0B,EAAE,GACnC;IAAE,UAAU,EAAE,qBAAqB,EAAE,CAAC;IAAC,OAAO,EAAE,wBAAwB,EAAE,CAAA;CAAE,CAmG9E","sourcesContent":["import type { ContextDeletionTarget } from \"../session-manager.ts\";\nimport type { CompactableTranscript } from \"./context-compaction-types.ts\";\nimport type { ContextGrepDeletionMatch, ContextGrepDeletionSkipped } from \"./context-deletion-tool-definitions.ts\";\nimport {\n\tCONTEXT_GREP_DELETE_MAX_REGEX_PATTERN_CHARS,\n\tCONTEXT_GREP_DELETE_MAX_REGEX_SCAN_CHARS,\n} from \"./context-deletion-tool-definitions.ts\";\nimport { formatErrorMessage } from \"./context-compaction-metrics.ts\";\nimport { reconcileToolDependencies, validateContextDeletionRequest } from \"./context-deletion-application.ts\";\nimport {\n\tdeletionRequestFromTargets,\n\tgetDeletedContentBlocks,\n\tgetDeletedEntryIds,\n\tmergeContextDeletionTargets,\n\ttargetKey,\n} from \"./context-deletion-targets.ts\";\nimport {\n\tanalyzeCompactableAssistantTurns,\n\tisTranscriptEntryEffectivelyDeleted,\n\ttranscriptEntryStartsNewTurn,\n} from \"./context-assistant-turns.js\";\n\nexport function escapeRegExpLiteral(text: string): string {\n\treturn text.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\nexport function assertSafeRegexPattern(pattern: string): void {\n\tif (pattern.length > CONTEXT_GREP_DELETE_MAX_REGEX_PATTERN_CHARS) {\n\t\tthrow new Error(\n\t\t\t`Regex pattern is too long (${pattern.length} characters); maximum is ${CONTEXT_GREP_DELETE_MAX_REGEX_PATTERN_CHARS}`,\n\t\t);\n\t}\n\n\t// Heuristic ReDoS guard for common catastrophic-backtracking shapes. JavaScript's RegExp engine\n\t// does not expose a timeout, so reject nested quantified groups and backreferences instead of\n\t// relying only on transcript scan-size caps.\n\tconst hasNestedQuantifiedGroup = /\\((?:[^()\\\\]|\\\\.)*[+*](?:[^()\\\\]|\\\\.)*\\)\\s*(?:[+*]|\\{\\d)/u.test(pattern);\n\tconst hasQuantifiedAlternation = /\\((?:[^()\\\\]|\\\\.)*\\|(?:[^()\\\\]|\\\\.)*\\)\\s*(?:[+*]|\\{\\d)/u.test(pattern);\n\tconst hasBackreference = /\\\\[1-9]/u.test(pattern);\n\tif (hasNestedQuantifiedGroup || hasQuantifiedAlternation || hasBackreference) {\n\t\tthrow new Error(\n\t\t\t\"Regex pattern is not allowed because it may cause excessive backtracking; use a literal pattern or exact deletion targets instead.\",\n\t\t);\n\t}\n}\n\nexport function createGrepMatcher(pattern: string, regex: boolean, caseSensitive: boolean): RegExp {\n\tif (regex) {\n\t\tassertSafeRegexPattern(pattern);\n\t}\n\n\ttry {\n\t\treturn new RegExp(regex ? pattern : escapeRegExpLiteral(pattern), caseSensitive ? \"u\" : \"iu\");\n\t} catch (error) {\n\t\tthrow new Error(`Invalid grep ${regex ? \"regex\" : \"pattern\"}: ${formatErrorMessage(error)}`);\n\t}\n}\n\nexport function assertSafeRegexScan(scanChars: number): void {\n\tif (scanChars <= CONTEXT_GREP_DELETE_MAX_REGEX_SCAN_CHARS) return;\n\tthrow new Error(\n\t\t`Regex grep would scan ${scanChars} characters; maximum is ${CONTEXT_GREP_DELETE_MAX_REGEX_SCAN_CHARS}. Use a literal pattern or exact deletion targets instead.`,\n\t);\n}\n\nexport function clampInteger(value: number | undefined, defaultValue: number, minimum: number, maximum: number): number {\n\tif (value === undefined) return defaultValue;\n\treturn Math.max(minimum, Math.min(maximum, value));\n}\n\nexport function textSlice(text: string, offset: number, maxChars: number): string {\n\treturn text.slice(offset, Math.min(text.length, offset + maxChars));\n}\n\nexport function findMatchIndex(matcher: RegExp, text: string): number {\n\tconst match = matcher.exec(text);\n\tmatcher.lastIndex = 0;\n\treturn match?.index ?? -1;\n}\n\nexport function snippetForMatch(text: string, matchIndex: number, contextChars: number): string {\n\tconst start = Math.max(0, matchIndex - contextChars);\n\tconst end = Math.min(text.length, matchIndex + contextChars);\n\tconst prefix = start > 0 ? \"…\" : \"\";\n\tconst suffix = end < text.length ? \"…\" : \"\";\n\treturn `${prefix}${text.slice(start, end)}${suffix}`;\n}\n\nexport function currentTargetDeleted(targets: readonly ContextDeletionTarget[], target: ContextDeletionTarget): boolean {\n\tconst deletedEntryIds = getDeletedEntryIds(targets);\n\tif (deletedEntryIds.has(target.entryId)) return true;\n\tif (target.kind === \"entry\") return false;\n\treturn getDeletedContentBlocks(targets).get(target.entryId)?.has(target.blockIndex) === true;\n}\n\nexport function addGrepCandidate(\n\tcandidates: ContextDeletionTarget[],\n\tmatches: ContextGrepDeletionMatch[],\n\tseenTargets: Set<string>,\n\tcandidate: ContextDeletionTarget,\n\tmatch: ContextGrepDeletionMatch,\n): void {\n\tconst key = targetKey(candidate);\n\tif (seenTargets.has(key)) return;\n\tseenTargets.add(key);\n\tcandidates.push(candidate);\n\tmatches.push(match);\n}\n\nexport function pushProtectedGrepSkip(skipped: ContextGrepDeletionSkipped[], match: ContextGrepDeletionMatch): void {\n\tskipped.push({\n\t\tentryId: match.entryId,\n\t\ttarget: match.target,\n\t\t...(match.blockIndex === undefined ? {} : { blockIndex: match.blockIndex }),\n\t\treason: match.target === \"content_block\" ? \"protected_block\" : \"protected_entry\",\n\t\ttext: match.text,\n\t});\n}\n\nfunction assistantTurnsForTargets(\n\ttranscript: CompactableTranscript,\n\ttargets: readonly ContextDeletionTarget[],\n) {\n\tconst reconciled = reconcileToolDependencies(transcript, targets);\n\treturn { reconciled, ...analyzeCompactableAssistantTurns(transcript, reconciled) };\n}\n\nfunction candidateRemovesBoundary(\n\ttranscript: CompactableTranscript,\n\tcurrentTargets: readonly ContextDeletionTarget[],\n\tcandidate: ContextDeletionTarget,\n): boolean {\n\tconst entry = transcript.entries.find((item) => item.entryId === candidate.entryId);\n\tif (!entry) return false;\n\tconst beforeEntries = getDeletedEntryIds(currentTargets);\n\tconst beforeBlocks = getDeletedContentBlocks(currentTargets);\n\tconst before =\n\t\t!isTranscriptEntryEffectivelyDeleted(entry, beforeEntries, beforeBlocks) &&\n\t\ttranscriptEntryStartsNewTurn(entry, beforeBlocks.get(entry.entryId));\n\tif (!before) return false;\n\ttry {\n\t\tconst after = assistantTurnsForTargets(transcript, mergeContextDeletionTargets(currentTargets, [candidate]));\n\t\treturn isTranscriptEntryEffectivelyDeleted(entry, after.deletedEntryIds, after.deletedContentBlocks) ||\n\t\t\t!transcriptEntryStartsNewTurn(entry, after.deletedContentBlocks.get(entry.entryId));\n\t} catch {\n\t\treturn true;\n\t}\n}\n\ninterface SemanticCandidate {\n\tindex: number;\n\taffectedTurns: Set<number>;\n}\nexport function filterProtectedGrepCandidates(\n\tcandidates: readonly ContextDeletionTarget[],\n\tmatches: readonly ContextGrepDeletionMatch[],\n\tcurrentTargets: readonly ContextDeletionTarget[],\n\ttranscript: CompactableTranscript,\n\tskipped: ContextGrepDeletionSkipped[],\n): { candidates: ContextDeletionTarget[]; matches: ContextGrepDeletionMatch[] } {\n\tconst rejected = new Set<number>();\n\tconst accepted = new Set<number>();\n\tlet acceptedTargets = [...currentTargets];\n\tconst base = assistantTurnsForTargets(transcript, currentTargets);\n\tconst signedTurnByEntryId = new Map<string, number>();\n\tbase.turns.forEach((turn, turnIndex) => {\n\t\tfor (const entryId of turn.signedThinkingEntryIds) signedTurnByEntryId.set(entryId, turnIndex);\n\t});\n\tconst boundaries: number[] = [];\n\tconst ordinary: number[] = [];\n\tconst semantic: SemanticCandidate[] = [];\n\n\tfor (let index = 0; index < candidates.length; index++) {\n\t\tconst candidate = candidates[index]!;\n\t\tif (candidateRemovesBoundary(transcript, currentTargets, candidate)) {\n\t\t\tboundaries.push(index);\n\t\t\tcontinue;\n\t\t}\n\t\ttry {\n\t\t\tconst single = assistantTurnsForTargets(\n\t\t\t\ttranscript,\n\t\t\t\tmergeContextDeletionTargets(currentTargets, [candidate]),\n\t\t\t);\n\t\t\tconst affectedTurns = new Set<number>();\n\t\t\tfor (const entryId of single.deletedEntryIds) {\n\t\t\t\tif (base.deletedEntryIds.has(entryId)) continue;\n\t\t\t\tconst turnIndex = signedTurnByEntryId.get(entryId);\n\t\t\t\tif (turnIndex !== undefined) affectedTurns.add(turnIndex);\n\t\t\t}\n\t\t\tif (affectedTurns.size === 0) ordinary.push(index);\n\t\t\telse semantic.push({ index, affectedTurns });\n\t\t} catch {\n\t\t\trejected.add(index);\n\t\t}\n\t}\n\n\tconst components: SemanticCandidate[][] = [];\n\tfor (const item of semantic) {\n\t\tconst overlapping = components.filter((component) =>\n\t\t\tcomponent.some((member) => [...member.affectedTurns].some((turn) => item.affectedTurns.has(turn))),\n\t\t);\n\t\tif (overlapping.length === 0) {\n\t\t\tcomponents.push([item]);\n\t\t\tcontinue;\n\t\t}\n\t\tconst merged = [item, ...overlapping.flat()];\n\t\tfor (const component of overlapping) components.splice(components.indexOf(component), 1);\n\t\tcomponents.push(merged.sort((left, right) => left.index - right.index));\n\t}\n\n\tfor (const component of components.sort((left, right) => left[0]!.index - right[0]!.index)) {\n\t\tconst indexes = component.map((item) => item.index);\n\t\tconst proposed = mergeContextDeletionTargets(acceptedTargets, indexes.map((index) => candidates[index]!));\n\t\tlet complete = true;\n\t\ttry {\n\t\t\tconst effect = assistantTurnsForTargets(transcript, proposed);\n\t\t\tconst affectedTurns = new Set(component.flatMap((item) => [...item.affectedTurns]));\n\t\t\tfor (const turnIndex of affectedTurns) {\n\t\t\t\tconst turn = base.turns[turnIndex]!;\n\t\t\t\tif (turn.active || !turn.signedThinkingEntryIds.every((entryId) => effect.deletedEntryIds.has(entryId))) {\n\t\t\t\t\tcomplete = false;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (complete) validateContextDeletionRequest(deletionRequestFromTargets(proposed), transcript);\n\t\t} catch {\n\t\t\tcomplete = false;\n\t\t}\n\t\tif (!complete) {\n\t\t\tfor (const index of indexes) rejected.add(index);\n\t\t\tcontinue;\n\t\t}\n\t\tacceptedTargets = proposed;\n\t\tfor (const index of indexes) accepted.add(index);\n\t}\n\n\tconst acceptIndividually = (indexes: readonly number[]): void => {\n\t\tfor (const index of indexes) {\n\t\t\tconst proposed = mergeContextDeletionTargets(acceptedTargets, [candidates[index]!]);\n\t\t\ttry {\n\t\t\t\tvalidateContextDeletionRequest(deletionRequestFromTargets(proposed), transcript);\n\t\t\t\tacceptedTargets = proposed;\n\t\t\t\taccepted.add(index);\n\t\t\t} catch {\n\t\t\t\trejected.add(index);\n\t\t\t}\n\t\t}\n\t};\n\tacceptIndividually(ordinary);\n\tacceptIndividually(boundaries);\n\n\tfor (let index = 0; index < matches.length; index++) {\n\t\tif (rejected.has(index)) pushProtectedGrepSkip(skipped, matches[index]!);\n\t}\n\treturn {\n\t\tcandidates: candidates.filter((_candidate, index) => accepted.has(index)),\n\t\tmatches: matches.filter((_match, index) => accepted.has(index)),\n\t};\n}\n"]}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { CONTEXT_GREP_DELETE_MAX_REGEX_PATTERN_CHARS, CONTEXT_GREP_DELETE_MAX_REGEX_SCAN_CHARS, } from "./context-deletion-tool-definitions.js";
|
|
2
2
|
import { formatErrorMessage } from "./context-compaction-metrics.js";
|
|
3
|
-
import { validateContextDeletionRequest } from "./context-deletion-application.js";
|
|
4
|
-
import { deletionRequestFromTargets,
|
|
3
|
+
import { reconcileToolDependencies, validateContextDeletionRequest } from "./context-deletion-application.js";
|
|
4
|
+
import { deletionRequestFromTargets, getDeletedContentBlocks, getDeletedEntryIds, mergeContextDeletionTargets, targetKey, } from "./context-deletion-targets.js";
|
|
5
|
+
import { analyzeCompactableAssistantTurns, isTranscriptEntryEffectivelyDeleted, transcriptEntryStartsNewTurn, } from "./context-assistant-turns.js";
|
|
5
6
|
export function escapeRegExpLiteral(text) {
|
|
6
7
|
return text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
7
8
|
}
|
|
@@ -80,58 +81,130 @@ export function pushProtectedGrepSkip(skipped, match) {
|
|
|
80
81
|
text: match.text,
|
|
81
82
|
});
|
|
82
83
|
}
|
|
84
|
+
function assistantTurnsForTargets(transcript, targets) {
|
|
85
|
+
const reconciled = reconcileToolDependencies(transcript, targets);
|
|
86
|
+
return { reconciled, ...analyzeCompactableAssistantTurns(transcript, reconciled) };
|
|
87
|
+
}
|
|
88
|
+
function candidateRemovesBoundary(transcript, currentTargets, candidate) {
|
|
89
|
+
const entry = transcript.entries.find((item) => item.entryId === candidate.entryId);
|
|
90
|
+
if (!entry)
|
|
91
|
+
return false;
|
|
92
|
+
const beforeEntries = getDeletedEntryIds(currentTargets);
|
|
93
|
+
const beforeBlocks = getDeletedContentBlocks(currentTargets);
|
|
94
|
+
const before = !isTranscriptEntryEffectivelyDeleted(entry, beforeEntries, beforeBlocks) &&
|
|
95
|
+
transcriptEntryStartsNewTurn(entry, beforeBlocks.get(entry.entryId));
|
|
96
|
+
if (!before)
|
|
97
|
+
return false;
|
|
98
|
+
try {
|
|
99
|
+
const after = assistantTurnsForTargets(transcript, mergeContextDeletionTargets(currentTargets, [candidate]));
|
|
100
|
+
return isTranscriptEntryEffectivelyDeleted(entry, after.deletedEntryIds, after.deletedContentBlocks) ||
|
|
101
|
+
!transcriptEntryStartsNewTurn(entry, after.deletedContentBlocks.get(entry.entryId));
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
return true;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
83
107
|
export function filterProtectedGrepCandidates(candidates, matches, currentTargets, transcript, skipped) {
|
|
84
|
-
const
|
|
85
|
-
const
|
|
108
|
+
const rejected = new Set();
|
|
109
|
+
const accepted = new Set();
|
|
110
|
+
let acceptedTargets = [...currentTargets];
|
|
111
|
+
const base = assistantTurnsForTargets(transcript, currentTargets);
|
|
112
|
+
const signedTurnByEntryId = new Map();
|
|
113
|
+
base.turns.forEach((turn, turnIndex) => {
|
|
114
|
+
for (const entryId of turn.signedThinkingEntryIds)
|
|
115
|
+
signedTurnByEntryId.set(entryId, turnIndex);
|
|
116
|
+
});
|
|
117
|
+
const boundaries = [];
|
|
118
|
+
const ordinary = [];
|
|
119
|
+
const semantic = [];
|
|
86
120
|
for (let index = 0; index < candidates.length; index++) {
|
|
87
121
|
const candidate = candidates[index];
|
|
88
|
-
|
|
89
|
-
|
|
122
|
+
if (candidateRemovesBoundary(transcript, currentTargets, candidate)) {
|
|
123
|
+
boundaries.push(index);
|
|
90
124
|
continue;
|
|
91
|
-
try {
|
|
92
|
-
const mergedTargets = mergeContextDeletionTargets(currentTargets, [candidate]);
|
|
93
|
-
validateContextDeletionRequest(deletionRequestFromTargets(mergedTargets), transcript);
|
|
94
|
-
eligibleCandidates.push(candidate);
|
|
95
|
-
eligibleMatches.push(match);
|
|
96
125
|
}
|
|
97
|
-
|
|
98
|
-
const
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
126
|
+
try {
|
|
127
|
+
const single = assistantTurnsForTargets(transcript, mergeContextDeletionTargets(currentTargets, [candidate]));
|
|
128
|
+
const affectedTurns = new Set();
|
|
129
|
+
for (const entryId of single.deletedEntryIds) {
|
|
130
|
+
if (base.deletedEntryIds.has(entryId))
|
|
131
|
+
continue;
|
|
132
|
+
const turnIndex = signedTurnByEntryId.get(entryId);
|
|
133
|
+
if (turnIndex !== undefined)
|
|
134
|
+
affectedTurns.add(turnIndex);
|
|
102
135
|
}
|
|
103
|
-
|
|
104
|
-
|
|
136
|
+
if (affectedTurns.size === 0)
|
|
137
|
+
ordinary.push(index);
|
|
138
|
+
else
|
|
139
|
+
semantic.push({ index, affectedTurns });
|
|
140
|
+
}
|
|
141
|
+
catch {
|
|
142
|
+
rejected.add(index);
|
|
105
143
|
}
|
|
106
144
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
changed = false;
|
|
113
|
-
const mergedTargets = mergeContextDeletionTargets(currentTargets, eligibleCandidates);
|
|
114
|
-
const violation = findLatestAssistantThinkingDeletionViolation(transcript, mergedTargets);
|
|
115
|
-
if (!violation)
|
|
145
|
+
const components = [];
|
|
146
|
+
for (const item of semantic) {
|
|
147
|
+
const overlapping = components.filter((component) => component.some((member) => [...member.affectedTurns].some((turn) => item.affectedTurns.has(turn))));
|
|
148
|
+
if (overlapping.length === 0) {
|
|
149
|
+
components.push([item]);
|
|
116
150
|
continue;
|
|
117
|
-
const violationKey = targetKey(violation);
|
|
118
|
-
let violationIndex = eligibleCandidates.findIndex((candidate) => targetKey(candidate) === violationKey);
|
|
119
|
-
if (violationIndex < 0) {
|
|
120
|
-
violationIndex = eligibleCandidates.findIndex((_candidate, candidateIndex) => {
|
|
121
|
-
const remainingCandidates = eligibleCandidates.filter((_candidateToKeep, index) => index !== candidateIndex);
|
|
122
|
-
const remainingTargets = mergeContextDeletionTargets(currentTargets, remainingCandidates);
|
|
123
|
-
const remainingViolation = findLatestAssistantThinkingDeletionViolation(transcript, remainingTargets);
|
|
124
|
-
return !remainingViolation || targetKey(remainingViolation) !== violationKey;
|
|
125
|
-
});
|
|
126
151
|
}
|
|
127
|
-
|
|
152
|
+
const merged = [item, ...overlapping.flat()];
|
|
153
|
+
for (const component of overlapping)
|
|
154
|
+
components.splice(components.indexOf(component), 1);
|
|
155
|
+
components.push(merged.sort((left, right) => left.index - right.index));
|
|
156
|
+
}
|
|
157
|
+
for (const component of components.sort((left, right) => left[0].index - right[0].index)) {
|
|
158
|
+
const indexes = component.map((item) => item.index);
|
|
159
|
+
const proposed = mergeContextDeletionTargets(acceptedTargets, indexes.map((index) => candidates[index]));
|
|
160
|
+
let complete = true;
|
|
161
|
+
try {
|
|
162
|
+
const effect = assistantTurnsForTargets(transcript, proposed);
|
|
163
|
+
const affectedTurns = new Set(component.flatMap((item) => [...item.affectedTurns]));
|
|
164
|
+
for (const turnIndex of affectedTurns) {
|
|
165
|
+
const turn = base.turns[turnIndex];
|
|
166
|
+
if (turn.active || !turn.signedThinkingEntryIds.every((entryId) => effect.deletedEntryIds.has(entryId))) {
|
|
167
|
+
complete = false;
|
|
168
|
+
break;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
if (complete)
|
|
172
|
+
validateContextDeletionRequest(deletionRequestFromTargets(proposed), transcript);
|
|
173
|
+
}
|
|
174
|
+
catch {
|
|
175
|
+
complete = false;
|
|
176
|
+
}
|
|
177
|
+
if (!complete) {
|
|
178
|
+
for (const index of indexes)
|
|
179
|
+
rejected.add(index);
|
|
128
180
|
continue;
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
181
|
+
}
|
|
182
|
+
acceptedTargets = proposed;
|
|
183
|
+
for (const index of indexes)
|
|
184
|
+
accepted.add(index);
|
|
185
|
+
}
|
|
186
|
+
const acceptIndividually = (indexes) => {
|
|
187
|
+
for (const index of indexes) {
|
|
188
|
+
const proposed = mergeContextDeletionTargets(acceptedTargets, [candidates[index]]);
|
|
189
|
+
try {
|
|
190
|
+
validateContextDeletionRequest(deletionRequestFromTargets(proposed), transcript);
|
|
191
|
+
acceptedTargets = proposed;
|
|
192
|
+
accepted.add(index);
|
|
193
|
+
}
|
|
194
|
+
catch {
|
|
195
|
+
rejected.add(index);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
};
|
|
199
|
+
acceptIndividually(ordinary);
|
|
200
|
+
acceptIndividually(boundaries);
|
|
201
|
+
for (let index = 0; index < matches.length; index++) {
|
|
202
|
+
if (rejected.has(index))
|
|
203
|
+
pushProtectedGrepSkip(skipped, matches[index]);
|
|
134
204
|
}
|
|
135
|
-
return {
|
|
205
|
+
return {
|
|
206
|
+
candidates: candidates.filter((_candidate, index) => accepted.has(index)),
|
|
207
|
+
matches: matches.filter((_match, index) => accepted.has(index)),
|
|
208
|
+
};
|
|
136
209
|
}
|
|
137
210
|
//# sourceMappingURL=context-deletion-tool-helpers.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context-deletion-tool-helpers.js","sourceRoot":"","sources":["../../../src/core/compaction/context-deletion-tool-helpers.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ContextDeletionTarget } from \"../session-manager.ts\";\nimport type { CompactableTranscript } from \"./context-compaction-types.ts\";\nimport type { ContextGrepDeletionMatch, ContextGrepDeletionSkipped } from \"./context-deletion-tool-definitions.ts\";\nimport {\n\tCONTEXT_GREP_DELETE_MAX_REGEX_PATTERN_CHARS,\n\tCONTEXT_GREP_DELETE_MAX_REGEX_SCAN_CHARS,\n} from \"./context-deletion-tool-definitions.ts\";\nimport { formatErrorMessage } from \"./context-compaction-metrics.ts\";\nimport { validateContextDeletionRequest } from \"./context-deletion-application.ts\";\nimport {\n\tdeletionRequestFromTargets,\n\tfindLatestAssistantThinkingDeletionViolation,\n\tgetDeletedContentBlocks,\n\tgetDeletedEntryIds,\n\tisProtectedContextDeletionErrorMessage,\n\tmergeContextDeletionTargets,\n\ttargetKey,\n} from \"./context-deletion-targets.ts\";\n\nexport function escapeRegExpLiteral(text: string): string {\n\treturn text.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\nexport function assertSafeRegexPattern(pattern: string): void {\n\tif (pattern.length > CONTEXT_GREP_DELETE_MAX_REGEX_PATTERN_CHARS) {\n\t\tthrow new Error(\n\t\t\t`Regex pattern is too long (${pattern.length} characters); maximum is ${CONTEXT_GREP_DELETE_MAX_REGEX_PATTERN_CHARS}`,\n\t\t);\n\t}\n\n\t// Heuristic ReDoS guard for common catastrophic-backtracking shapes. JavaScript's RegExp engine\n\t// does not expose a timeout, so reject nested quantified groups and backreferences instead of\n\t// relying only on transcript scan-size caps.\n\tconst hasNestedQuantifiedGroup = /\\((?:[^()\\\\]|\\\\.)*[+*](?:[^()\\\\]|\\\\.)*\\)\\s*(?:[+*]|\\{\\d)/u.test(pattern);\n\tconst hasQuantifiedAlternation = /\\((?:[^()\\\\]|\\\\.)*\\|(?:[^()\\\\]|\\\\.)*\\)\\s*(?:[+*]|\\{\\d)/u.test(pattern);\n\tconst hasBackreference = /\\\\[1-9]/u.test(pattern);\n\tif (hasNestedQuantifiedGroup || hasQuantifiedAlternation || hasBackreference) {\n\t\tthrow new Error(\n\t\t\t\"Regex pattern is not allowed because it may cause excessive backtracking; use a literal pattern or exact deletion targets instead.\",\n\t\t);\n\t}\n}\n\nexport function createGrepMatcher(pattern: string, regex: boolean, caseSensitive: boolean): RegExp {\n\tif (regex) {\n\t\tassertSafeRegexPattern(pattern);\n\t}\n\n\ttry {\n\t\treturn new RegExp(regex ? pattern : escapeRegExpLiteral(pattern), caseSensitive ? \"u\" : \"iu\");\n\t} catch (error) {\n\t\tthrow new Error(`Invalid grep ${regex ? \"regex\" : \"pattern\"}: ${formatErrorMessage(error)}`);\n\t}\n}\n\nexport function assertSafeRegexScan(scanChars: number): void {\n\tif (scanChars <= CONTEXT_GREP_DELETE_MAX_REGEX_SCAN_CHARS) return;\n\tthrow new Error(\n\t\t`Regex grep would scan ${scanChars} characters; maximum is ${CONTEXT_GREP_DELETE_MAX_REGEX_SCAN_CHARS}. Use a literal pattern or exact deletion targets instead.`,\n\t);\n}\n\nexport function clampInteger(value: number | undefined, defaultValue: number, minimum: number, maximum: number): number {\n\tif (value === undefined) return defaultValue;\n\treturn Math.max(minimum, Math.min(maximum, value));\n}\n\nexport function textSlice(text: string, offset: number, maxChars: number): string {\n\treturn text.slice(offset, Math.min(text.length, offset + maxChars));\n}\n\nexport function findMatchIndex(matcher: RegExp, text: string): number {\n\tconst match = matcher.exec(text);\n\tmatcher.lastIndex = 0;\n\treturn match?.index ?? -1;\n}\n\nexport function snippetForMatch(text: string, matchIndex: number, contextChars: number): string {\n\tconst start = Math.max(0, matchIndex - contextChars);\n\tconst end = Math.min(text.length, matchIndex + contextChars);\n\tconst prefix = start > 0 ? \"…\" : \"\";\n\tconst suffix = end < text.length ? \"…\" : \"\";\n\treturn `${prefix}${text.slice(start, end)}${suffix}`;\n}\n\nexport function currentTargetDeleted(targets: readonly ContextDeletionTarget[], target: ContextDeletionTarget): boolean {\n\tconst deletedEntryIds = getDeletedEntryIds(targets);\n\tif (deletedEntryIds.has(target.entryId)) return true;\n\tif (target.kind === \"entry\") return false;\n\treturn getDeletedContentBlocks(targets).get(target.entryId)?.has(target.blockIndex) === true;\n}\n\nexport function addGrepCandidate(\n\tcandidates: ContextDeletionTarget[],\n\tmatches: ContextGrepDeletionMatch[],\n\tseenTargets: Set<string>,\n\tcandidate: ContextDeletionTarget,\n\tmatch: ContextGrepDeletionMatch,\n): void {\n\tconst key = targetKey(candidate);\n\tif (seenTargets.has(key)) return;\n\tseenTargets.add(key);\n\tcandidates.push(candidate);\n\tmatches.push(match);\n}\n\nexport function pushProtectedGrepSkip(skipped: ContextGrepDeletionSkipped[], match: ContextGrepDeletionMatch): void {\n\tskipped.push({\n\t\tentryId: match.entryId,\n\t\ttarget: match.target,\n\t\t...(match.blockIndex === undefined ? {} : { blockIndex: match.blockIndex }),\n\t\treason: match.target === \"content_block\" ? \"protected_block\" : \"protected_entry\",\n\t\ttext: match.text,\n\t});\n}\n\nexport function filterProtectedGrepCandidates(\n\tcandidates: readonly ContextDeletionTarget[],\n\tmatches: readonly ContextGrepDeletionMatch[],\n\tcurrentTargets: readonly ContextDeletionTarget[],\n\ttranscript: CompactableTranscript,\n\tskipped: ContextGrepDeletionSkipped[],\n): { candidates: ContextDeletionTarget[]; matches: ContextGrepDeletionMatch[] } {\n\tconst eligibleCandidates: ContextDeletionTarget[] = [];\n\tconst eligibleMatches: ContextGrepDeletionMatch[] = [];\n\tfor (let index = 0; index < candidates.length; index++) {\n\t\tconst candidate = candidates[index];\n\t\tconst match = matches[index];\n\t\tif (!candidate || !match) continue;\n\t\ttry {\n\t\t\tconst mergedTargets = mergeContextDeletionTargets(currentTargets, [candidate]);\n\t\t\tvalidateContextDeletionRequest(deletionRequestFromTargets(mergedTargets), transcript);\n\t\t\teligibleCandidates.push(candidate);\n\t\t\teligibleMatches.push(match);\n\t\t} catch (error) {\n\t\t\tconst message = formatErrorMessage(error);\n\t\t\tif (isProtectedContextDeletionErrorMessage(message)) {\n\t\t\t\tpushProtectedGrepSkip(skipped, match);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\teligibleCandidates.push(candidate);\n\t\t\teligibleMatches.push(match);\n\t\t}\n\t}\n\n\t// Some latest-assistant thinking violations only become visible after a grep batch also\n\t// deletes newer assistant entries. Classify the newly-unsafe grep candidates as\n\t// protected/skipped before maxMatches, expectedMatchCount, stats, or removals are computed.\n\tlet changed = true;\n\twhile (changed) {\n\t\tchanged = false;\n\t\tconst mergedTargets = mergeContextDeletionTargets(currentTargets, eligibleCandidates);\n\t\tconst violation = findLatestAssistantThinkingDeletionViolation(transcript, mergedTargets);\n\t\tif (!violation) continue;\n\t\tconst violationKey = targetKey(violation);\n\t\tlet violationIndex = eligibleCandidates.findIndex((candidate) => targetKey(candidate) === violationKey);\n\t\tif (violationIndex < 0) {\n\t\t\tviolationIndex = eligibleCandidates.findIndex((_candidate, candidateIndex) => {\n\t\t\t\tconst remainingCandidates = eligibleCandidates.filter((_candidateToKeep, index) => index !== candidateIndex);\n\t\t\t\tconst remainingTargets = mergeContextDeletionTargets(currentTargets, remainingCandidates);\n\t\t\t\tconst remainingViolation = findLatestAssistantThinkingDeletionViolation(transcript, remainingTargets);\n\t\t\t\treturn !remainingViolation || targetKey(remainingViolation) !== violationKey;\n\t\t\t});\n\t\t}\n\t\tif (violationIndex < 0) continue;\n\t\tconst [skippedMatch] = eligibleMatches.splice(violationIndex, 1);\n\t\teligibleCandidates.splice(violationIndex, 1);\n\t\tif (skippedMatch) pushProtectedGrepSkip(skipped, skippedMatch);\n\t\tchanged = true;\n\t}\n\n\treturn { candidates: eligibleCandidates, matches: eligibleMatches };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"context-deletion-tool-helpers.js","sourceRoot":"","sources":["../../../src/core/compaction/context-deletion-tool-helpers.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ContextDeletionTarget } from \"../session-manager.ts\";\nimport type { CompactableTranscript } from \"./context-compaction-types.ts\";\nimport type { ContextGrepDeletionMatch, ContextGrepDeletionSkipped } from \"./context-deletion-tool-definitions.ts\";\nimport {\n\tCONTEXT_GREP_DELETE_MAX_REGEX_PATTERN_CHARS,\n\tCONTEXT_GREP_DELETE_MAX_REGEX_SCAN_CHARS,\n} from \"./context-deletion-tool-definitions.ts\";\nimport { formatErrorMessage } from \"./context-compaction-metrics.ts\";\nimport { reconcileToolDependencies, validateContextDeletionRequest } from \"./context-deletion-application.ts\";\nimport {\n\tdeletionRequestFromTargets,\n\tgetDeletedContentBlocks,\n\tgetDeletedEntryIds,\n\tmergeContextDeletionTargets,\n\ttargetKey,\n} from \"./context-deletion-targets.ts\";\nimport {\n\tanalyzeCompactableAssistantTurns,\n\tisTranscriptEntryEffectivelyDeleted,\n\ttranscriptEntryStartsNewTurn,\n} from \"./context-assistant-turns.js\";\n\nexport function escapeRegExpLiteral(text: string): string {\n\treturn text.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\nexport function assertSafeRegexPattern(pattern: string): void {\n\tif (pattern.length > CONTEXT_GREP_DELETE_MAX_REGEX_PATTERN_CHARS) {\n\t\tthrow new Error(\n\t\t\t`Regex pattern is too long (${pattern.length} characters); maximum is ${CONTEXT_GREP_DELETE_MAX_REGEX_PATTERN_CHARS}`,\n\t\t);\n\t}\n\n\t// Heuristic ReDoS guard for common catastrophic-backtracking shapes. JavaScript's RegExp engine\n\t// does not expose a timeout, so reject nested quantified groups and backreferences instead of\n\t// relying only on transcript scan-size caps.\n\tconst hasNestedQuantifiedGroup = /\\((?:[^()\\\\]|\\\\.)*[+*](?:[^()\\\\]|\\\\.)*\\)\\s*(?:[+*]|\\{\\d)/u.test(pattern);\n\tconst hasQuantifiedAlternation = /\\((?:[^()\\\\]|\\\\.)*\\|(?:[^()\\\\]|\\\\.)*\\)\\s*(?:[+*]|\\{\\d)/u.test(pattern);\n\tconst hasBackreference = /\\\\[1-9]/u.test(pattern);\n\tif (hasNestedQuantifiedGroup || hasQuantifiedAlternation || hasBackreference) {\n\t\tthrow new Error(\n\t\t\t\"Regex pattern is not allowed because it may cause excessive backtracking; use a literal pattern or exact deletion targets instead.\",\n\t\t);\n\t}\n}\n\nexport function createGrepMatcher(pattern: string, regex: boolean, caseSensitive: boolean): RegExp {\n\tif (regex) {\n\t\tassertSafeRegexPattern(pattern);\n\t}\n\n\ttry {\n\t\treturn new RegExp(regex ? pattern : escapeRegExpLiteral(pattern), caseSensitive ? \"u\" : \"iu\");\n\t} catch (error) {\n\t\tthrow new Error(`Invalid grep ${regex ? \"regex\" : \"pattern\"}: ${formatErrorMessage(error)}`);\n\t}\n}\n\nexport function assertSafeRegexScan(scanChars: number): void {\n\tif (scanChars <= CONTEXT_GREP_DELETE_MAX_REGEX_SCAN_CHARS) return;\n\tthrow new Error(\n\t\t`Regex grep would scan ${scanChars} characters; maximum is ${CONTEXT_GREP_DELETE_MAX_REGEX_SCAN_CHARS}. Use a literal pattern or exact deletion targets instead.`,\n\t);\n}\n\nexport function clampInteger(value: number | undefined, defaultValue: number, minimum: number, maximum: number): number {\n\tif (value === undefined) return defaultValue;\n\treturn Math.max(minimum, Math.min(maximum, value));\n}\n\nexport function textSlice(text: string, offset: number, maxChars: number): string {\n\treturn text.slice(offset, Math.min(text.length, offset + maxChars));\n}\n\nexport function findMatchIndex(matcher: RegExp, text: string): number {\n\tconst match = matcher.exec(text);\n\tmatcher.lastIndex = 0;\n\treturn match?.index ?? -1;\n}\n\nexport function snippetForMatch(text: string, matchIndex: number, contextChars: number): string {\n\tconst start = Math.max(0, matchIndex - contextChars);\n\tconst end = Math.min(text.length, matchIndex + contextChars);\n\tconst prefix = start > 0 ? \"…\" : \"\";\n\tconst suffix = end < text.length ? \"…\" : \"\";\n\treturn `${prefix}${text.slice(start, end)}${suffix}`;\n}\n\nexport function currentTargetDeleted(targets: readonly ContextDeletionTarget[], target: ContextDeletionTarget): boolean {\n\tconst deletedEntryIds = getDeletedEntryIds(targets);\n\tif (deletedEntryIds.has(target.entryId)) return true;\n\tif (target.kind === \"entry\") return false;\n\treturn getDeletedContentBlocks(targets).get(target.entryId)?.has(target.blockIndex) === true;\n}\n\nexport function addGrepCandidate(\n\tcandidates: ContextDeletionTarget[],\n\tmatches: ContextGrepDeletionMatch[],\n\tseenTargets: Set<string>,\n\tcandidate: ContextDeletionTarget,\n\tmatch: ContextGrepDeletionMatch,\n): void {\n\tconst key = targetKey(candidate);\n\tif (seenTargets.has(key)) return;\n\tseenTargets.add(key);\n\tcandidates.push(candidate);\n\tmatches.push(match);\n}\n\nexport function pushProtectedGrepSkip(skipped: ContextGrepDeletionSkipped[], match: ContextGrepDeletionMatch): void {\n\tskipped.push({\n\t\tentryId: match.entryId,\n\t\ttarget: match.target,\n\t\t...(match.blockIndex === undefined ? {} : { blockIndex: match.blockIndex }),\n\t\treason: match.target === \"content_block\" ? \"protected_block\" : \"protected_entry\",\n\t\ttext: match.text,\n\t});\n}\n\nfunction assistantTurnsForTargets(\n\ttranscript: CompactableTranscript,\n\ttargets: readonly ContextDeletionTarget[],\n) {\n\tconst reconciled = reconcileToolDependencies(transcript, targets);\n\treturn { reconciled, ...analyzeCompactableAssistantTurns(transcript, reconciled) };\n}\n\nfunction candidateRemovesBoundary(\n\ttranscript: CompactableTranscript,\n\tcurrentTargets: readonly ContextDeletionTarget[],\n\tcandidate: ContextDeletionTarget,\n): boolean {\n\tconst entry = transcript.entries.find((item) => item.entryId === candidate.entryId);\n\tif (!entry) return false;\n\tconst beforeEntries = getDeletedEntryIds(currentTargets);\n\tconst beforeBlocks = getDeletedContentBlocks(currentTargets);\n\tconst before =\n\t\t!isTranscriptEntryEffectivelyDeleted(entry, beforeEntries, beforeBlocks) &&\n\t\ttranscriptEntryStartsNewTurn(entry, beforeBlocks.get(entry.entryId));\n\tif (!before) return false;\n\ttry {\n\t\tconst after = assistantTurnsForTargets(transcript, mergeContextDeletionTargets(currentTargets, [candidate]));\n\t\treturn isTranscriptEntryEffectivelyDeleted(entry, after.deletedEntryIds, after.deletedContentBlocks) ||\n\t\t\t!transcriptEntryStartsNewTurn(entry, after.deletedContentBlocks.get(entry.entryId));\n\t} catch {\n\t\treturn true;\n\t}\n}\n\ninterface SemanticCandidate {\n\tindex: number;\n\taffectedTurns: Set<number>;\n}\nexport function filterProtectedGrepCandidates(\n\tcandidates: readonly ContextDeletionTarget[],\n\tmatches: readonly ContextGrepDeletionMatch[],\n\tcurrentTargets: readonly ContextDeletionTarget[],\n\ttranscript: CompactableTranscript,\n\tskipped: ContextGrepDeletionSkipped[],\n): { candidates: ContextDeletionTarget[]; matches: ContextGrepDeletionMatch[] } {\n\tconst rejected = new Set<number>();\n\tconst accepted = new Set<number>();\n\tlet acceptedTargets = [...currentTargets];\n\tconst base = assistantTurnsForTargets(transcript, currentTargets);\n\tconst signedTurnByEntryId = new Map<string, number>();\n\tbase.turns.forEach((turn, turnIndex) => {\n\t\tfor (const entryId of turn.signedThinkingEntryIds) signedTurnByEntryId.set(entryId, turnIndex);\n\t});\n\tconst boundaries: number[] = [];\n\tconst ordinary: number[] = [];\n\tconst semantic: SemanticCandidate[] = [];\n\n\tfor (let index = 0; index < candidates.length; index++) {\n\t\tconst candidate = candidates[index]!;\n\t\tif (candidateRemovesBoundary(transcript, currentTargets, candidate)) {\n\t\t\tboundaries.push(index);\n\t\t\tcontinue;\n\t\t}\n\t\ttry {\n\t\t\tconst single = assistantTurnsForTargets(\n\t\t\t\ttranscript,\n\t\t\t\tmergeContextDeletionTargets(currentTargets, [candidate]),\n\t\t\t);\n\t\t\tconst affectedTurns = new Set<number>();\n\t\t\tfor (const entryId of single.deletedEntryIds) {\n\t\t\t\tif (base.deletedEntryIds.has(entryId)) continue;\n\t\t\t\tconst turnIndex = signedTurnByEntryId.get(entryId);\n\t\t\t\tif (turnIndex !== undefined) affectedTurns.add(turnIndex);\n\t\t\t}\n\t\t\tif (affectedTurns.size === 0) ordinary.push(index);\n\t\t\telse semantic.push({ index, affectedTurns });\n\t\t} catch {\n\t\t\trejected.add(index);\n\t\t}\n\t}\n\n\tconst components: SemanticCandidate[][] = [];\n\tfor (const item of semantic) {\n\t\tconst overlapping = components.filter((component) =>\n\t\t\tcomponent.some((member) => [...member.affectedTurns].some((turn) => item.affectedTurns.has(turn))),\n\t\t);\n\t\tif (overlapping.length === 0) {\n\t\t\tcomponents.push([item]);\n\t\t\tcontinue;\n\t\t}\n\t\tconst merged = [item, ...overlapping.flat()];\n\t\tfor (const component of overlapping) components.splice(components.indexOf(component), 1);\n\t\tcomponents.push(merged.sort((left, right) => left.index - right.index));\n\t}\n\n\tfor (const component of components.sort((left, right) => left[0]!.index - right[0]!.index)) {\n\t\tconst indexes = component.map((item) => item.index);\n\t\tconst proposed = mergeContextDeletionTargets(acceptedTargets, indexes.map((index) => candidates[index]!));\n\t\tlet complete = true;\n\t\ttry {\n\t\t\tconst effect = assistantTurnsForTargets(transcript, proposed);\n\t\t\tconst affectedTurns = new Set(component.flatMap((item) => [...item.affectedTurns]));\n\t\t\tfor (const turnIndex of affectedTurns) {\n\t\t\t\tconst turn = base.turns[turnIndex]!;\n\t\t\t\tif (turn.active || !turn.signedThinkingEntryIds.every((entryId) => effect.deletedEntryIds.has(entryId))) {\n\t\t\t\t\tcomplete = false;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (complete) validateContextDeletionRequest(deletionRequestFromTargets(proposed), transcript);\n\t\t} catch {\n\t\t\tcomplete = false;\n\t\t}\n\t\tif (!complete) {\n\t\t\tfor (const index of indexes) rejected.add(index);\n\t\t\tcontinue;\n\t\t}\n\t\tacceptedTargets = proposed;\n\t\tfor (const index of indexes) accepted.add(index);\n\t}\n\n\tconst acceptIndividually = (indexes: readonly number[]): void => {\n\t\tfor (const index of indexes) {\n\t\t\tconst proposed = mergeContextDeletionTargets(acceptedTargets, [candidates[index]!]);\n\t\t\ttry {\n\t\t\t\tvalidateContextDeletionRequest(deletionRequestFromTargets(proposed), transcript);\n\t\t\t\tacceptedTargets = proposed;\n\t\t\t\taccepted.add(index);\n\t\t\t} catch {\n\t\t\t\trejected.add(index);\n\t\t\t}\n\t\t}\n\t};\n\tacceptIndividually(ordinary);\n\tacceptIndividually(boundaries);\n\n\tfor (let index = 0; index < matches.length; index++) {\n\t\tif (rejected.has(index)) pushProtectedGrepSkip(skipped, matches[index]!);\n\t}\n\treturn {\n\t\tcandidates: candidates.filter((_candidate, index) => accepted.has(index)),\n\t\tmatches: matches.filter((_match, index) => accepted.has(index)),\n\t};\n}\n"]}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import type { AgentMessage } from "@earendil-works/pi-agent-core";
|
|
2
2
|
import { type SessionEntry } from "../session-manager.ts";
|
|
3
3
|
import type { CompactionSettings } from "./compaction.ts";
|
|
4
|
-
import { type
|
|
4
|
+
import { type ContextCompactionPreparation, type ContextCompactionRunOptions } from "./context-compaction-types.ts";
|
|
5
5
|
export declare function isExcludedFromLlmContext(message: AgentMessage): boolean;
|
|
6
|
-
export declare function assistantEntryHasThinkingContentBlock(entry: CompactableTranscriptEntry): boolean;
|
|
7
6
|
export declare function hasAssistantError(message: AgentMessage): boolean;
|
|
8
7
|
export declare function hasToolResultError(message: AgentMessage): boolean;
|
|
9
8
|
export declare function hasFailedBashExecution(message: AgentMessage): boolean;
|