@code-yeongyu/senpi 2026.9.15-2 → 2026.9.16-2
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 +48 -0
- package/README.md +1 -1
- package/dist/core/agent-session.d.ts +28 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +111 -13
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +4 -2
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/compaction/stream-watchdog.d.ts +56 -2
- package/dist/core/compaction/stream-watchdog.d.ts.map +1 -1
- package/dist/core/compaction/stream-watchdog.js +93 -15
- package/dist/core/compaction/stream-watchdog.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-binding.d.ts +6 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-binding.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-binding.js +17 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-binding.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-continuity.d.ts +4 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-continuity.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-continuity.js +31 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-continuity.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-reattach.d.ts +2 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-reattach.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-reattach.js +16 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-reattach.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-wiring.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-wiring.js +19 -8
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-wiring.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-stream.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-stream.js +2 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-stream.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/deterministic-fallback.d.ts +13 -1
- package/dist/core/extensions/builtin/compaction/deterministic-fallback.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/deterministic-fallback.js +66 -2
- package/dist/core/extensions/builtin/compaction/deterministic-fallback.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/index.js +16 -10
- package/dist/core/extensions/builtin/compaction/index.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/speculative-summary.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/speculative-summary.js +4 -2
- package/dist/core/extensions/builtin/compaction/speculative-summary.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/speculative.d.ts +8 -1
- package/dist/core/extensions/builtin/compaction/speculative.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/speculative.js +31 -7
- package/dist/core/extensions/builtin/compaction/speculative.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/transient-failure.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/transient-failure.js +6 -3
- package/dist/core/extensions/builtin/compaction/transient-failure.js.map +1 -1
- package/dist/core/extensions/kernel-tools-context.d.ts +13 -0
- package/dist/core/extensions/kernel-tools-context.d.ts.map +1 -0
- package/dist/core/extensions/kernel-tools-context.js +3 -0
- package/dist/core/extensions/kernel-tools-context.js.map +1 -0
- package/dist/core/extensions/runner.d.ts +19 -0
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +103 -1
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +21 -0
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/keybindings.d.ts +5 -0
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +1 -0
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/retry-fallback/settings.d.ts +3 -0
- package/dist/core/retry-fallback/settings.d.ts.map +1 -1
- package/dist/core/retry-fallback/settings.js.map +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +1 -0
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager.d.ts +27 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +78 -5
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/session-resident-store.d.ts +33 -7
- package/dist/core/session-resident-store.d.ts.map +1 -1
- package/dist/core/session-resident-store.js +163 -14
- package/dist/core/session-resident-store.js.map +1 -1
- package/dist/core/session-write-reservation.d.ts +6 -0
- package/dist/core/session-write-reservation.d.ts.map +1 -1
- package/dist/core/session-write-reservation.js +19 -0
- package/dist/core/session-write-reservation.js.map +1 -1
- package/dist/core/settings-manager.d.ts +35 -1
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +62 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +2 -1
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/tools/index.d.ts +1 -1
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +4 -3
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/read.d.ts +3 -1
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +16 -2
- package/dist/core/tools/read.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/modes/interactive/components/assistant-render-descriptors.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-render-descriptors.js +12 -5
- package/dist/modes/interactive/components/assistant-render-descriptors.js.map +1 -1
- package/dist/modes/interactive/components/extension-input.d.ts +2 -0
- package/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-input.js +5 -0
- package/dist/modes/interactive/components/extension-input.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +19 -2
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +66 -14
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/tips/catalog/session-tips.js +1 -1
- package/dist/modes/interactive/tips/catalog/session-tips.js.map +1 -1
- package/dist/modes/interactive/working-status.d.ts +3 -2
- package/dist/modes/interactive/working-status.d.ts.map +1 -1
- package/dist/modes/interactive/working-status.js +17 -4
- package/dist/modes/interactive/working-status.js.map +1 -1
- package/dist/modes/print-mode.d.ts +1 -1
- package/dist/modes/print-mode.d.ts.map +1 -1
- package/dist/modes/print-mode.js +5 -1
- package/dist/modes/print-mode.js.map +1 -1
- package/docs/extensions.md +5 -2
- package/docs/keybindings.md +1 -0
- package/docs/session-format.md +1 -1
- package/docs/sessions.md +3 -3
- package/docs/settings.md +31 -1
- package/docs/usage.md +1 -1
- package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +35 -0
- package/node_modules/@code-yeongyu/senpi-codemode/README.md +24 -0
- package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
- package/node_modules/@code-yeongyu/senpi-codemode/src/bridge/http-server.ts +7 -1
- package/node_modules/@code-yeongyu/senpi-codemode/src/bridge/kernel-tools-protocol.ts +85 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/bridge/protocol.ts +6 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/bridges/agent-bridge.ts +30 -11
- package/node_modules/@code-yeongyu/senpi-codemode/src/extension/session-manager.ts +11 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/index.ts +10 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/jl/prelude.jl +46 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/jl/runner.jl +1 -1
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/context-manager.ts +29 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-contract.ts +12 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-context.d.ts +13 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-context.js +7 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-define.d.ts +10 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-define.js +12 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-errors.js +22 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-errors.ts +26 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-host.ts +134 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-naming.js +28 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-parse.d.ts +5 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-parse.js +255 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-pump.js +105 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-registry.d.ts +27 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-registry.js +127 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-schema.js +69 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-tools-types.ts +42 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/prelude.ts +2 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-core.js +26 -3
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-runtime.js +20 -8
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-slot.ts +6 -1
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-startup.ts +9 -7
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/workpool.js +37 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/kernel-tools-unavailable.ts +5 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/py/kernel.ts +13 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/py/prelude.py +57 -3
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/rb/prelude.rb +13 -2
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/rb/workpool.rb +38 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/shared/subprocess-kernel.ts +13 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/shared/subprocess-queue.ts +2 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/prompt/eval-prompt-template.ts +4 -2
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/cell-handler.ts +31 -3
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/run-eval-cell.ts +52 -30
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/types.ts +2 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js +30 -3
- package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/agent.d.ts +5 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/agent.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/agent.js +2 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/agent.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/empty-assistant-recovery.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/empty-assistant-recovery.js +51 -12
- package/node_modules/@earendil-works/pi-agent-core/dist/empty-assistant-recovery.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/read.d.ts +3 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/read.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/read.js +18 -3
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/tools/read.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/brace-scanner.d.ts +4 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/brace-scanner.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/brace-scanner.js +268 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/brace-scanner.js.map +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/header-protection.d.ts +18 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/header-protection.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/header-protection.js +69 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/header-protection.js.map +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/index.d.ts +27 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/index.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/index.js +118 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/index.js.map +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/lexical-context.d.ts +21 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/lexical-context.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/lexical-context.js +24 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/lexical-context.js.map +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/lexical-spans.d.ts +12 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/lexical-spans.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/lexical-spans.js +92 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/lexical-spans.js.map +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/types.d.ts +47 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/types.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/types.js +8 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/read-folders/types.js.map +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/segmented-read-view.d.ts +52 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/segmented-read-view.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/segmented-read-view.js +155 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/segmented-read-view.js.map +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/index.d.ts +4 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/index.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/index.js +3 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/index.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/stream-throughput-watchdog.d.ts +101 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/stream-throughput-watchdog.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/stream-throughput-watchdog.js +178 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/stream-throughput-watchdog.js.map +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/types.d.ts +9 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/types.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/types.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
- package/node_modules/@earendil-works/pi-ai/dist/index.d.ts +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/index.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/index.js +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/index.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/alibaba-token-plan.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/amazon-bedrock.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/fireworks.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/qwen-token-plan.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/empty-response-errors.d.ts +15 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/empty-response-errors.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/empty-response-errors.js +15 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/empty-response-errors.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry.d.ts +24 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js +92 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/package.json +2 -2
- package/node_modules/@earendil-works/pi-pty/package.json +1 -1
- package/node_modules/@earendil-works/pi-telemetry/package.json +1 -1
- package/node_modules/@earendil-works/pi-tui/package.json +1 -1
- package/package.json +7 -7
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { hasCredentialHeaders, isContextOverflow, isRetryableAssistantError, isRetryableErrorMessage, retryTransientCall, } from "@earendil-works/pi-ai";
|
|
2
2
|
import { DEFAULT_COMPACTION_SETTINGS, estimateContextTokens, estimateTokens, prepareCompaction, } from "../../../compaction/index.js";
|
|
3
|
-
import { StreamDurationBudgetError, StreamIdleTimeoutError, summarizationMaxDurationMs, } from "../../../compaction/stream-watchdog.js";
|
|
3
|
+
import { createSummarizationDeadline, StreamDurationBudgetError, StreamIdleTimeoutError, SummarizationTotalBudgetError, summarizationMaxDurationMs, summarizationTotalBudgetMs, } from "../../../compaction/stream-watchdog.js";
|
|
4
4
|
import { createWarmAnchorSnapshot, isWarmSummaryAnchorValid, } from "../../../compaction/warm-anchor.js";
|
|
5
|
+
import { CredentialFailoverError, TURN_RETRY_SUPPRESSION_PREFIX } from "../../../credential-pool/failover.js";
|
|
5
6
|
import { convertToLlm } from "../../../messages.js";
|
|
6
7
|
import { pruneToolResults } from "./emergency-prune.js";
|
|
7
8
|
import { allowOverflowRetry, boundSummarizationInput, SUMMARIZATION_INPUT_BUDGET_RATIO, SummarizationOverflowExhaustedError, shrinkSummarizationInputForOverflowRetry, } from "./overflow-retry.js";
|
|
@@ -23,11 +24,12 @@ function approxTokens(text) {
|
|
|
23
24
|
return Math.ceil(text.length / 4);
|
|
24
25
|
}
|
|
25
26
|
export class SummaryRequestError extends Error {
|
|
26
|
-
constructor(message, transient, failureKind) {
|
|
27
|
+
constructor(message, transient, failureKind, refused = false) {
|
|
27
28
|
super(message);
|
|
28
29
|
this.name = "SummaryRequestError";
|
|
29
30
|
this.transient = transient;
|
|
30
31
|
this.failureKind = failureKind;
|
|
32
|
+
this.refused = refused;
|
|
31
33
|
}
|
|
32
34
|
}
|
|
33
35
|
const UPSTREAM_STREAM_TRUNCATED_PATTERN = /(?:^|[^A-Za-z0-9_])upstream_stream_truncated(?:[^A-Za-z0-9_]|$)/;
|
|
@@ -35,7 +37,8 @@ const UPSTREAM_STREAM_TRUNCATED_PATTERN = /(?:^|[^A-Za-z0-9_])upstream_stream_tr
|
|
|
35
37
|
* Only failures with no cheaper recovery earn another billed request.
|
|
36
38
|
*
|
|
37
39
|
* Every class that `classifyRequiredCompactionFallbackFailure` recognizes
|
|
38
|
-
* (watchdog timeouts,
|
|
40
|
+
* (watchdog timeouts, the compaction-wide total budget, terminal provider and
|
|
41
|
+
* credential failures, `upstream-stream-truncated`, overflow exhaustion,
|
|
39
42
|
* empty-summary generation failures) already
|
|
40
43
|
* has a deterministic zero-LLM recovery, and context overflow is answered by
|
|
41
44
|
* shrinking the input in the surrounding loop - replaying those would pay for a
|
|
@@ -46,18 +49,32 @@ const UPSTREAM_STREAM_TRUNCATED_PATTERN = /(?:^|[^A-Za-z0-9_])upstream_stream_tr
|
|
|
46
49
|
function isRetryableSummaryAttempt(error) {
|
|
47
50
|
if (error instanceof StreamDurationBudgetError || error instanceof StreamIdleTimeoutError)
|
|
48
51
|
return false;
|
|
52
|
+
if (error instanceof SummarizationTotalBudgetError)
|
|
53
|
+
return false;
|
|
49
54
|
if (error instanceof SummarizationOverflowExhaustedError)
|
|
50
55
|
return false;
|
|
51
56
|
if (error instanceof SummaryGenerationError)
|
|
52
57
|
return false;
|
|
58
|
+
// Mirrors the `summarization-provider-failure` class: credential rotation has
|
|
59
|
+
// already spent every slot it may spend, and the marker means output was
|
|
60
|
+
// committed, so another billed attempt buys nothing the fallback cannot
|
|
61
|
+
// rebuild for free. Message text alone must not re-authorize it - the wrapped
|
|
62
|
+
// provider detail can read as transient (#1741).
|
|
63
|
+
if (error instanceof CredentialFailoverError)
|
|
64
|
+
return false;
|
|
65
|
+
if (error instanceof Error && error.message.startsWith(TURN_RETRY_SUPPRESSION_PREFIX))
|
|
66
|
+
return false;
|
|
53
67
|
if (error instanceof SummaryRequestError)
|
|
54
68
|
return error.failureKind === undefined && error.transient;
|
|
55
69
|
if (error instanceof Error)
|
|
56
70
|
return isRetryableErrorMessage(error.message);
|
|
57
71
|
return false;
|
|
58
72
|
}
|
|
73
|
+
function isRefusalStop(response) {
|
|
74
|
+
return response.stopDetails?.type === "refusal" || response.stopDetails?.type === "sensitive";
|
|
75
|
+
}
|
|
59
76
|
function summaryRequestFailureKind(response) {
|
|
60
|
-
if (response
|
|
77
|
+
if (isRefusalStop(response))
|
|
61
78
|
return undefined;
|
|
62
79
|
return UPSTREAM_STREAM_TRUNCATED_PATTERN.test(response.errorMessage ?? "") ? "upstream-stream-truncated" : undefined;
|
|
63
80
|
}
|
|
@@ -145,6 +162,10 @@ export async function runExtensionCompaction(context, snapshot, signal, onProgre
|
|
|
145
162
|
});
|
|
146
163
|
const promptTokens = approxTokens(prompt.user);
|
|
147
164
|
let messages = boundSummarizationInput(pruneToolResults([...requestSnapshot.preparation.messagesToSummarize, ...requestSnapshot.preparation.turnPrefixMessages], requestSnapshot.contextWindow, SUMMARIZATION_INPUT_BUDGET_RATIO), requestSnapshot.contextWindow, promptTokens);
|
|
165
|
+
// One deadline for the whole compaction. The per-attempt budget scales with the
|
|
166
|
+
// input and every retry re-arms it, so without this a large session could hold
|
|
167
|
+
// the turn for attempt-budget x attempts with no bound the user can predict.
|
|
168
|
+
const deadline = createSummarizationDeadline(summarizationTotalBudgetMs(requestSnapshot.preparation.settings.summarizationMaxDurationMs));
|
|
148
169
|
const overflowRetryStartMs = Date.now();
|
|
149
170
|
let overflowAttempts = 0;
|
|
150
171
|
const summarizationToolsOffered = (requestSnapshot.tools?.length ?? 0) > 0;
|
|
@@ -175,7 +196,9 @@ export async function runExtensionCompaction(context, snapshot, signal, onProgre
|
|
|
175
196
|
const attempt = await generateSummaryMessage({
|
|
176
197
|
context,
|
|
177
198
|
forbidToolCalls: toolUseRetrySpent,
|
|
178
|
-
|
|
199
|
+
// Re-clamped per attempt, not per loop turn: a retry that starts
|
|
200
|
+
// near the deadline gets only what is left, and none starts past it.
|
|
201
|
+
maxDurationMs: deadline.attemptBudgetMs(attemptBudgetMs),
|
|
179
202
|
messages: currentMessages,
|
|
180
203
|
onProgress,
|
|
181
204
|
prompt,
|
|
@@ -192,10 +215,11 @@ export async function runExtensionCompaction(context, snapshot, signal, onProgre
|
|
|
192
215
|
attempt.stopReason === "error" &&
|
|
193
216
|
!isContextOverflow(attempt, snapshot.contextWindow)) {
|
|
194
217
|
const failureKind = summaryRequestFailureKind(attempt);
|
|
195
|
-
throw new SummaryRequestError(attempt.errorMessage || "Compaction summary request failed", failureKind !== undefined || isRetryableAssistantError(attempt), failureKind);
|
|
218
|
+
throw new SummaryRequestError(attempt.errorMessage || "Compaction summary request failed", failureKind !== undefined || isRetryableAssistantError(attempt), failureKind, isRefusalStop(attempt));
|
|
196
219
|
}
|
|
197
220
|
return attempt;
|
|
198
221
|
}, (error) => retryEligible &&
|
|
222
|
+
deadline.remainingMs() > 0 &&
|
|
199
223
|
allowSummarizationRetry(Date.now() - retryStartedMs, attemptBudgetMs) &&
|
|
200
224
|
isRetryableSummaryAttempt(error), DEFAULT_SUMMARIZATION_RETRY_POLICY, signal);
|
|
201
225
|
}
|
|
@@ -228,7 +252,7 @@ export async function runExtensionCompaction(context, snapshot, signal, onProgre
|
|
|
228
252
|
// truncation class here so downstream recovery never trusts arbitrary
|
|
229
253
|
// thrown error text as authorization for destructive context reduction.
|
|
230
254
|
const failureKind = summaryRequestFailureKind(response);
|
|
231
|
-
throw new SummaryRequestError(response.errorMessage || "Compaction summary request failed", failureKind !== undefined || isRetryableAssistantError(response), failureKind);
|
|
255
|
+
throw new SummaryRequestError(response.errorMessage || "Compaction summary request failed", failureKind !== undefined || isRetryableAssistantError(response), failureKind, isRefusalStop(response));
|
|
232
256
|
}
|
|
233
257
|
const summary = getSummaryText(response);
|
|
234
258
|
if (!summary) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"speculative.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/compaction/speculative.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentMessage } from \"@earendil-works/pi-agent-core\";\nimport {\n\ttype AssistantMessage,\n\thasCredentialHeaders,\n\tisContextOverflow,\n\tisRetryableAssistantError,\n\tisRetryableErrorMessage,\n\ttype Message,\n\ttype Model,\n\tretryTransientCall,\n\ttype Tool,\n} from \"@earendil-works/pi-ai\";\nimport {\n\ttype CompactionPreparation,\n\ttype CompactionResult,\n\tDEFAULT_COMPACTION_SETTINGS,\n\testimateContextTokens,\n\testimateTokens,\n\tprepareCompaction,\n} from \"../../../compaction/index.ts\";\nimport {\n\tStreamDurationBudgetError,\n\tStreamIdleTimeoutError,\n\tsummarizationMaxDurationMs,\n} from \"../../../compaction/stream-watchdog.ts\";\nimport {\n\tcreateWarmAnchorSnapshot,\n\tisWarmSummaryAnchorValid,\n\ttype WarmAnchorSnapshot,\n} from \"../../../compaction/warm-anchor.ts\";\nimport { convertToLlm } from \"../../../messages.ts\";\nimport type { ModelRegistry } from \"../../../model-registry.ts\";\nimport type { ReadonlySessionManager } from \"../../../session-manager.ts\";\nimport type { ApplyCompactionResult, ContextUsage, ProviderRequestPreparation } from \"../../types.ts\";\nimport { pruneToolResults } from \"./emergency-prune.ts\";\nimport {\n\tallowOverflowRetry,\n\tboundSummarizationInput,\n\tSUMMARIZATION_INPUT_BUDGET_RATIO,\n\tSummarizationOverflowExhaustedError,\n\tshrinkSummarizationInputForOverflowRetry,\n} from \"./overflow-retry.ts\";\nimport { computeEffectiveKeepRecentTokens, computeEffectiveThreshold } from \"./policy.ts\";\nimport { buildPrompt, type MergedCompactionPromptVariant } from \"./prompts.ts\";\nimport { generateSummaryMessage, getSummaryText, isAssistantMessage } from \"./speculative-summary.ts\";\n\nimport { allowSummarizationRetry, DEFAULT_SUMMARIZATION_RETRY_POLICY } from \"./summarization-retry.ts\";\n\nimport { extractTaskIntent, resolveInheritedTaskIntent } from \"./task-intent.ts\";\n\nexport {\n\tcreateEmergencyPruneLatch,\n\ttype EmergencyPruneLatch,\n\thardLimitEmergencyPrune,\n\ttruncateContextMessages,\n} from \"./emergency-prune.ts\";\n\nimport { computeStructuralYield } from \"./yield.ts\";\n\nconst DEFAULT_CONTEXT_WINDOW = 200_000;\n// Hysteresis: the emergency prune engages at EMERGENCY_CONTEXT_TARGET_RATIO but only\n// releases once the context falls below this lower ratio. A single threshold makes a\n// session parked near the limit alternate between the pruned and un-pruned history on\n// consecutive requests; because pruning rewrites old tool results, every alternation\n// invalidates the provider prompt-cache prefix and re-bills the whole conversation.\nconst SUMMARY_SCHEMA = \"senpi.compaction.summary.v1\";\ntype CompactionProgressCallback = (delta: string) => void;\n\nexport interface SpeculativeCompactionContext {\n\tmodel: Model<any> | undefined;\n\tsessionManager: ReadonlySessionManager;\n\tmodelRegistry?: ModelRegistry;\n\tgetContextUsage(): ContextUsage | undefined;\n\tgetCompactionSettings?(): CompactionPreparation[\"settings\"];\n\tgetMessageRevision(): number;\n\tgetSystemPrompt?(): string;\n\tprepareProviderRequest?(messages: AgentMessage[]): Promise<ProviderRequestPreparation>;\n\tisIdle?(): boolean;\n\tapplyCompaction(\n\t\tprecomputed: CompactionResult,\n\t\toptions: {\n\t\t\treason: \"extension\";\n\t\t\texpectedRevision?: number;\n\t\t\texpectedWarmAnchor?: WarmAnchorSnapshot;\n\t\t\tsignal?: AbortSignal;\n\t\t},\n\t): Promise<ApplyCompactionResult>;\n}\n\nexport interface SpeculativeCompactionSnapshot {\n\tgeneration: number;\n\texpectedRevision: number;\n\tmodel: Model<any>;\n\tcontextWindow: number;\n\tpreparation: CompactionPreparation;\n\tbranchEntries?: ReturnType<ReadonlySessionManager[\"getBranch\"]>;\n\tpromptVariant: MergedCompactionPromptVariant;\n\torigin?: \"speculative\" | \"blocking\" | \"core-route\";\n\tcustomInstructions?: string;\n\t/** Agent system prompt; used to make the summarization request look like normal agent traffic. */\n\tsystemPrompt?: string;\n\t/** Agent tool definitions; forwarded so the request shape matches normal agent traffic. */\n\ttools?: Tool[];\n}\n\nexport type SpeculativeCompactionResult = ApplyCompactionResult | { applied: false; reason: \"unavailable\" | \"failed\" };\n\nfunction approxTokens(text: string): number {\n\treturn Math.ceil(text.length / 4);\n}\n\n/**\n * Summary-generation failure with a user-facing diagnosis. Distinct from a\n * user abort (which resolves `undefined`): callers surface `message` on the\n * manual route and degrade to \"unavailable\" on automatic routes.\n */\n/**\n * Provider `error` stop during summarization, carrying the metadata-aware\n * transient classification from the full assistant message. A refusal whose\n * text happens to look retryable must still surface loudly; the message\n * string alone cannot encode that.\n */\nexport type SummaryRequestFailureKind = \"upstream-stream-truncated\";\n\nexport class SummaryRequestError extends Error {\n\treadonly transient: boolean;\n\treadonly failureKind?: SummaryRequestFailureKind;\n\n\tconstructor(message: string, transient: boolean, failureKind?: SummaryRequestFailureKind) {\n\t\tsuper(message);\n\t\tthis.name = \"SummaryRequestError\";\n\t\tthis.transient = transient;\n\t\tthis.failureKind = failureKind;\n\t}\n}\n\nconst UPSTREAM_STREAM_TRUNCATED_PATTERN = /(?:^|[^A-Za-z0-9_])upstream_stream_truncated(?:[^A-Za-z0-9_]|$)/;\n\n/**\n * Only failures with no cheaper recovery earn another billed request.\n *\n * Every class that `classifyRequiredCompactionFallbackFailure` recognizes\n * (watchdog timeouts, `upstream-stream-truncated`, overflow exhaustion,\n * empty-summary generation failures) already\n * has a deterministic zero-LLM recovery, and context overflow is answered by\n * shrinking the input in the surrounding loop - replaying those would pay for a\n * summarization the fallback can rebuild for free. The classes checked here are\n * mirrored from that classifier rather than imported, because\n * `deterministic-fallback.ts` imports this module.\n */\nfunction isRetryableSummaryAttempt(error: unknown): boolean {\n\tif (error instanceof StreamDurationBudgetError || error instanceof StreamIdleTimeoutError) return false;\n\tif (error instanceof SummarizationOverflowExhaustedError) return false;\n\tif (error instanceof SummaryGenerationError) return false;\n\tif (error instanceof SummaryRequestError) return error.failureKind === undefined && error.transient;\n\tif (error instanceof Error) return isRetryableErrorMessage(error.message);\n\treturn false;\n}\n\nfunction summaryRequestFailureKind(response: AssistantMessage): SummaryRequestFailureKind | undefined {\n\tif (response.stopDetails?.type === \"refusal\" || response.stopDetails?.type === \"sensitive\") return undefined;\n\treturn UPSTREAM_STREAM_TRUNCATED_PATTERN.test(response.errorMessage ?? \"\") ? \"upstream-stream-truncated\" : undefined;\n}\n\nexport class SummaryGenerationError extends Error {\n\treadonly kind: \"auth\" | \"empty-summary\";\n\n\tconstructor(kind: \"auth\" | \"empty-summary\", message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"SummaryGenerationError\";\n\t\tthis.kind = kind;\n\t}\n}\n\n/**\n * Output budget for one summarization request. Adaptive-thinking models emit\n * reasoning tokens before the summary text, so the legacy flat 8192 cap could\n * be consumed entirely by thinking, ending the stream with zero text blocks.\n * Grant generous headroom, clamped to what the model can actually emit and to\n * half the context window: providers that enforce input + output <= window\n * would otherwise reject the request for models advertising contextWindow ==\n * maxTokens (every summarization request also carries conversation input).\n */\n\nexport function getPromptVariant(options: {\n\treason: string;\n\tpreparation: { previousSummary?: string; isSplitTurn: boolean };\n}): MergedCompactionPromptVariant {\n\tif (options.reason === \"branch\") return \"branch\";\n\tif (options.preparation.previousSummary) return \"update\";\n\tif (options.preparation.isSplitTurn) return \"turn_prefix\";\n\treturn \"default\";\n}\n\nexport function createSpeculativeCompactionSnapshot(\n\tcontext: SpeculativeCompactionContext,\n\toptions: {\n\t\tcustomInstructions?: string;\n\t\tgeneration: number;\n\t\torigin?: \"speculative\" | \"blocking\" | \"core-route\";\n\t\ttools?: Tool[];\n\t},\n): SpeculativeCompactionSnapshot | undefined {\n\tconst model = context.model;\n\tif (!model) return undefined;\n\n\tconst expectedRevision = context.getMessageRevision();\n\tconst branchEntries = context.sessionManager.getBranch();\n\tconst contextWindow = context.getContextUsage()?.contextWindow ?? model.contextWindow ?? DEFAULT_CONTEXT_WINDOW;\n\tconst settings = context.getCompactionSettings?.() ?? DEFAULT_COMPACTION_SETTINGS;\n\tconst thresholdRatio = computeEffectiveThreshold(contextWindow);\n\tconst preparation = prepareCompaction(branchEntries, {\n\t\t...settings,\n\t\tkeepRecentTokens: computeEffectiveKeepRecentTokens(settings.keepRecentTokens, contextWindow, thresholdRatio),\n\t});\n\tif (!preparation) return undefined;\n\n\treturn {\n\t\t...options,\n\t\texpectedRevision,\n\t\tmodel,\n\t\tcontextWindow,\n\t\tpreparation,\n\t\tbranchEntries,\n\t\tpromptVariant: getPromptVariant({ reason: \"extension\", preparation }),\n\t\tsystemPrompt: context.getSystemPrompt?.(),\n\t};\n}\n\n/**\n * Generate a compaction summary for the snapshot. Resolves `undefined` only\n * when the request was aborted (caller signal or an aborted stream); every\n * other failure throws — {@link SummaryGenerationError} for diagnosable\n * generation failures, the raw provider error otherwise. Abort is checked\n * before and after credential resolution so a cancelled request never\n * misreports as an auth failure.\n */\nexport async function runExtensionCompaction(\n\tcontext: SpeculativeCompactionContext,\n\tsnapshot: SpeculativeCompactionSnapshot,\n\tsignal?: AbortSignal,\n\tonProgress?: CompactionProgressCallback,\n): Promise<CompactionResult | undefined> {\n\tif (signal?.aborted) return undefined;\n\tconst auth = await context.modelRegistry?.getApiKeyAndHeaders(snapshot.model);\n\tif (signal?.aborted) return undefined;\n\t// A provider is authenticated for summarization by either a resolved key or a\n\t// credential request header: `headers`-authenticated providers (models.json and\n\t// extension providers alike) never resolve an apiKey, yet their normal agent\n\t// turns are fully authenticated.\n\tif (!auth?.ok || !(auth.apiKey || hasCredentialHeaders(auth.headers))) {\n\t\tconst detail =\n\t\t\tauth && !auth.ok ? auth.error : `no credentials resolved for provider \"${snapshot.model.provider}\"`;\n\t\tthrow new SummaryGenerationError(\"auth\", `summarization credentials unavailable: ${detail}`);\n\t}\n\tconst requestSnapshot = auth.baseUrl\n\t\t? { ...snapshot, model: { ...snapshot.model, baseUrl: auth.baseUrl } }\n\t\t: snapshot;\n\n\tconst prompt = buildPrompt({\n\t\tvariant: requestSnapshot.promptVariant,\n\t\tpreviousSummary: requestSnapshot.preparation.previousSummary,\n\t\ttaskIntent: resolveInheritedTaskIntent(requestSnapshot.branchEntries ?? []),\n\t\tcustomInstructions: requestSnapshot.customInstructions,\n\t});\n\tconst promptTokens = approxTokens(prompt.user);\n\tlet messages = boundSummarizationInput(\n\t\tpruneToolResults(\n\t\t\t[...requestSnapshot.preparation.messagesToSummarize, ...requestSnapshot.preparation.turnPrefixMessages],\n\t\t\trequestSnapshot.contextWindow,\n\t\t\tSUMMARIZATION_INPUT_BUDGET_RATIO,\n\t\t),\n\t\trequestSnapshot.contextWindow,\n\t\tpromptTokens,\n\t);\n\tconst overflowRetryStartMs = Date.now();\n\tlet overflowAttempts = 0;\n\tconst summarizationToolsOffered = (requestSnapshot.tools?.length ?? 0) > 0;\n\tlet toolUseRetrySpent = false;\n\n\twhile (true) {\n\t\tif (signal?.aborted) return undefined;\n\t\tlet response: Message | undefined;\n\t\tconst currentMessages = messages;\n\t\tconst retryStartedMs = Date.now();\n\t\t// Only the routes that block the user's turn retry here. The speculative\n\t\t// warm-up owns its own bounded retry (`idle-retry.ts`) with idle/breaker\n\t\t// guards re-evaluated between attempts, and a failed warm job must stay\n\t\t// inheritable so the next blocking route degrades on it instead of paying\n\t\t// for a second request.\n\t\tconst retryEligible = snapshot.origin === \"core-route\" || snapshot.origin === \"blocking\";\n\t\t// The attempt budget and the retry gate share one input-size-scaled number,\n\t\t// so a large session gets both a proportional attempt deadline and room to\n\t\t// retry transient failures without the 120s-era retry budget disqualifying\n\t\t// every slow attempt (#1068).\n\t\tconst attemptBudgetMs = summarizationMaxDurationMs(\n\t\t\tmessages.reduce((total, message) => total + estimateTokens(message), 0),\n\t\t\tsnapshot.preparation.settings.summarizationMaxDurationMs,\n\t\t);\n\t\ttry {\n\t\t\t// The provider `error` stop is raised INSIDE the retried producer so a\n\t\t\t// transient summarization failure spends the shared retry budget. The\n\t\t\t// surrounding loop keeps overflow shrinking and abort handling, which\n\t\t\t// must never be answered by replaying the same request.\n\t\t\tresponse = await retryTransientCall(\n\t\t\t\tasync () => {\n\t\t\t\t\tconst attempt = await generateSummaryMessage({\n\t\t\t\t\t\tcontext,\n\t\t\t\t\t\tforbidToolCalls: toolUseRetrySpent,\n\t\t\t\t\t\tmaxDurationMs: attemptBudgetMs,\n\t\t\t\t\t\tmessages: currentMessages,\n\t\t\t\t\t\tonProgress,\n\t\t\t\t\t\tprompt,\n\t\t\t\t\t\tsignal,\n\t\t\t\t\t\tsnapshot: requestSnapshot,\n\t\t\t\t\t\tauth: {\n\t\t\t\t\t\t\tapiKey: auth.apiKey,\n\t\t\t\t\t\t\theaders: auth.headers,\n\t\t\t\t\t\t\textraBody: auth.extraBody,\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t\tif (\n\t\t\t\t\t\tattempt &&\n\t\t\t\t\t\tisAssistantMessage(attempt) &&\n\t\t\t\t\t\tattempt.stopReason === \"error\" &&\n\t\t\t\t\t\t!isContextOverflow(attempt, snapshot.contextWindow)\n\t\t\t\t\t) {\n\t\t\t\t\t\tconst failureKind = summaryRequestFailureKind(attempt);\n\t\t\t\t\t\tthrow new SummaryRequestError(\n\t\t\t\t\t\t\tattempt.errorMessage || \"Compaction summary request failed\",\n\t\t\t\t\t\t\tfailureKind !== undefined || isRetryableAssistantError(attempt),\n\t\t\t\t\t\t\tfailureKind,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\treturn attempt;\n\t\t\t\t},\n\t\t\t\t(error) =>\n\t\t\t\t\tretryEligible &&\n\t\t\t\t\tallowSummarizationRetry(Date.now() - retryStartedMs, attemptBudgetMs) &&\n\t\t\t\t\tisRetryableSummaryAttempt(error),\n\t\t\t\tDEFAULT_SUMMARIZATION_RETRY_POLICY,\n\t\t\t\tsignal,\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tif (signal?.aborted) return undefined;\n\t\t\tthrow error;\n\t\t}\n\t\tif (!response) return undefined;\n\n\t\tif (isAssistantMessage(response) && isContextOverflow(response, snapshot.contextWindow)) {\n\t\t\toverflowAttempts++;\n\t\t\tconst elapsedMs = Date.now() - overflowRetryStartMs;\n\t\t\tconst retryMessages = allowOverflowRetry(overflowAttempts, elapsedMs)\n\t\t\t\t? shrinkSummarizationInputForOverflowRetry(messages, snapshot.contextWindow, promptTokens)\n\t\t\t\t: undefined;\n\t\t\tif (!retryMessages) {\n\t\t\t\tthrow new SummarizationOverflowExhaustedError(overflowAttempts, elapsedMs);\n\t\t\t}\n\t\t\tmessages = retryMessages;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (isAssistantMessage(response) && response.stopReason === \"aborted\") {\n\t\t\t// A partial summary from an aborted stream must never be applied.\n\t\t\treturn undefined;\n\t\t}\n\n\t\tif (isAssistantMessage(response) && response.stopReason === \"error\") {\n\t\t\t// Surface the real provider failure instead of silently degrading\n\t\t\t// into a generic \"Compaction cancelled\". Preserve the structured\n\t\t\t// truncation class here so downstream recovery never trusts arbitrary\n\t\t\t// thrown error text as authorization for destructive context reduction.\n\t\t\tconst failureKind = summaryRequestFailureKind(response);\n\t\t\tthrow new SummaryRequestError(\n\t\t\t\tresponse.errorMessage || \"Compaction summary request failed\",\n\t\t\t\tfailureKind !== undefined || isRetryableAssistantError(response),\n\t\t\t\tfailureKind,\n\t\t\t);\n\t\t}\n\n\t\tconst summary = getSummaryText(response);\n\t\tif (!summary) {\n\t\t\tconst stopReason = isAssistantMessage(response) ? response.stopReason : \"unknown\";\n\t\t\t// A summarizer can hijack the forwarded agent tools and answer with a\n\t\t\t// bare tool call (observed on openai-codex gpt-5.6-sol, 2026-08-31),\n\t\t\t// which used to surface as a terminal empty-summary failure. Spend one\n\t\t\t// retry with tool calling forbidden; the tools stay in the request\n\t\t\t// because Anthropic rejects tool_use history without the tools param.\n\t\t\tif (stopReason === \"toolUse\" && summarizationToolsOffered && !toolUseRetrySpent) {\n\t\t\t\ttoolUseRetrySpent = true;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tthrow new SummaryGenerationError(\n\t\t\t\t\"empty-summary\",\n\t\t\t\t`summarization response contained no text (stopReason: ${stopReason})`,\n\t\t\t);\n\t\t}\n\n\t\t// Informational only: the core rejects an applied compaction that would\n\t\t// still overflow (_wouldCompactionOverflow). Rejecting here based on the\n\t\t// size of the *discarded* input made large sessions uncompactable.\n\t\tconst tokenEstimate = estimateContextTokens(convertToLlm(messages)).tokens + approxTokens(summary);\n\t\tconst parsedSummary = extractTaskIntent(summary);\n\t\tconst taskIntent = parsedSummary.taskIntent ?? resolveInheritedTaskIntent(snapshot.branchEntries ?? []);\n\n\t\treturn {\n\t\t\tsummary: parsedSummary.summaryText,\n\t\t\tfirstKeptEntryId: snapshot.preparation.firstKeptEntryId,\n\t\t\ttokensBefore: snapshot.preparation.tokensBefore,\n\t\t\tdetails: {\n\t\t\t\tschema: SUMMARY_SCHEMA,\n\t\t\t\tpromptVariant: snapshot.promptVariant,\n\t\t\t\ttokenEstimate,\n\t\t\t\tstructuralYield: computeStructuralYield({\n\t\t\t\t\tpreviousSummary: snapshot.preparation.previousSummary ?? \"\",\n\t\t\t\t\tmessagesToSummarize: snapshot.preparation.messagesToSummarize,\n\t\t\t\t\tturnPrefixMessages: snapshot.preparation.turnPrefixMessages,\n\t\t\t\t\tsummary: parsedSummary.summaryText,\n\t\t\t\t\ttokensBefore: snapshot.preparation.tokensBefore,\n\t\t\t\t}),\n\t\t\t\t...(snapshot.origin ? { origin: snapshot.origin } : {}),\n\t\t\t\t...(taskIntent ? { taskIntent } : {}),\n\t\t\t},\n\t\t};\n\t}\n}\n\nexport async function applyGeneratedCompaction(\n\tcontext: SpeculativeCompactionContext,\n\tsnapshot: SpeculativeCompactionSnapshot | undefined,\n\tgetCurrentGeneration: () => number,\n\tcompaction: CompactionResult | undefined,\n\tsignal?: AbortSignal,\n): Promise<SpeculativeCompactionResult> {\n\tconst provider = context.model?.provider;\n\tif ((provider === \"cursor\" || provider === \"cursor-cli-oauth\") && context.isIdle && !context.isIdle()) {\n\t\treturn { applied: false, reason: \"rejected\" };\n\t}\n\tif (!snapshot || !compaction) return { applied: false, reason: \"unavailable\" };\n\n\tif (snapshot.generation !== getCurrentGeneration()) {\n\t\treturn { applied: false, reason: \"stale\" };\n\t}\n\n\tconst revisionUnchanged = snapshot.expectedRevision === context.getMessageRevision();\n\tconst warmAnchor = createWarmAnchorSnapshot(snapshot.preparation.firstKeptEntryId, snapshot.branchEntries ?? []);\n\tif (\n\t\t!revisionUnchanged &&\n\t\t(!warmAnchor || !isWarmSummaryAnchorValid(warmAnchor, context.sessionManager.getBranch()))\n\t) {\n\t\treturn { applied: false, reason: \"stale\" };\n\t}\n\n\treturn await context.applyCompaction(compaction, {\n\t\treason: \"extension\",\n\t\t...(revisionUnchanged || !warmAnchor\n\t\t\t? { expectedRevision: snapshot.expectedRevision }\n\t\t\t: { expectedWarmAnchor: warmAnchor }),\n\t\tsignal,\n\t});\n}\n\nexport async function applySpeculativeCompaction(\n\tcontext: SpeculativeCompactionContext,\n\tsnapshot: SpeculativeCompactionSnapshot | undefined,\n\tgetCurrentGeneration: () => number,\n\tgenerate: () => Promise<CompactionResult | undefined>,\n): Promise<SpeculativeCompactionResult> {\n\tif (!snapshot) return { applied: false, reason: \"unavailable\" };\n\n\tconst compaction = await generate();\n\treturn await applyGeneratedCompaction(context, snapshot, getCurrentGeneration, compaction);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"speculative.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/compaction/speculative.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentMessage } from \"@earendil-works/pi-agent-core\";\nimport {\n\ttype AssistantMessage,\n\thasCredentialHeaders,\n\tisContextOverflow,\n\tisRetryableAssistantError,\n\tisRetryableErrorMessage,\n\ttype Message,\n\ttype Model,\n\tretryTransientCall,\n\ttype Tool,\n} from \"@earendil-works/pi-ai\";\nimport {\n\ttype CompactionPreparation,\n\ttype CompactionResult,\n\tDEFAULT_COMPACTION_SETTINGS,\n\testimateContextTokens,\n\testimateTokens,\n\tprepareCompaction,\n} from \"../../../compaction/index.ts\";\nimport {\n\tcreateSummarizationDeadline,\n\tStreamDurationBudgetError,\n\tStreamIdleTimeoutError,\n\tSummarizationTotalBudgetError,\n\tsummarizationMaxDurationMs,\n\tsummarizationTotalBudgetMs,\n} from \"../../../compaction/stream-watchdog.ts\";\nimport {\n\tcreateWarmAnchorSnapshot,\n\tisWarmSummaryAnchorValid,\n\ttype WarmAnchorSnapshot,\n} from \"../../../compaction/warm-anchor.ts\";\nimport { CredentialFailoverError, TURN_RETRY_SUPPRESSION_PREFIX } from \"../../../credential-pool/failover.ts\";\nimport { convertToLlm } from \"../../../messages.ts\";\nimport type { ModelRegistry } from \"../../../model-registry.ts\";\nimport type { ReadonlySessionManager } from \"../../../session-manager.ts\";\nimport type { ApplyCompactionResult, ContextUsage, ProviderRequestPreparation } from \"../../types.ts\";\nimport { pruneToolResults } from \"./emergency-prune.ts\";\nimport {\n\tallowOverflowRetry,\n\tboundSummarizationInput,\n\tSUMMARIZATION_INPUT_BUDGET_RATIO,\n\tSummarizationOverflowExhaustedError,\n\tshrinkSummarizationInputForOverflowRetry,\n} from \"./overflow-retry.ts\";\nimport { computeEffectiveKeepRecentTokens, computeEffectiveThreshold } from \"./policy.ts\";\nimport { buildPrompt, type MergedCompactionPromptVariant } from \"./prompts.ts\";\nimport { generateSummaryMessage, getSummaryText, isAssistantMessage } from \"./speculative-summary.ts\";\n\nimport { allowSummarizationRetry, DEFAULT_SUMMARIZATION_RETRY_POLICY } from \"./summarization-retry.ts\";\n\nimport { extractTaskIntent, resolveInheritedTaskIntent } from \"./task-intent.ts\";\n\nexport {\n\tcreateEmergencyPruneLatch,\n\ttype EmergencyPruneLatch,\n\thardLimitEmergencyPrune,\n\ttruncateContextMessages,\n} from \"./emergency-prune.ts\";\n\nimport { computeStructuralYield } from \"./yield.ts\";\n\nconst DEFAULT_CONTEXT_WINDOW = 200_000;\n// Hysteresis: the emergency prune engages at EMERGENCY_CONTEXT_TARGET_RATIO but only\n// releases once the context falls below this lower ratio. A single threshold makes a\n// session parked near the limit alternate between the pruned and un-pruned history on\n// consecutive requests; because pruning rewrites old tool results, every alternation\n// invalidates the provider prompt-cache prefix and re-bills the whole conversation.\nconst SUMMARY_SCHEMA = \"senpi.compaction.summary.v1\";\ntype CompactionProgressCallback = (delta: string) => void;\n\nexport interface SpeculativeCompactionContext {\n\tmodel: Model<any> | undefined;\n\tsessionManager: ReadonlySessionManager;\n\tmodelRegistry?: ModelRegistry;\n\tgetContextUsage(): ContextUsage | undefined;\n\tgetCompactionSettings?(): CompactionPreparation[\"settings\"];\n\tgetMessageRevision(): number;\n\tgetSystemPrompt?(): string;\n\tprepareProviderRequest?(messages: AgentMessage[]): Promise<ProviderRequestPreparation>;\n\tisIdle?(): boolean;\n\tapplyCompaction(\n\t\tprecomputed: CompactionResult,\n\t\toptions: {\n\t\t\treason: \"extension\";\n\t\t\texpectedRevision?: number;\n\t\t\texpectedWarmAnchor?: WarmAnchorSnapshot;\n\t\t\tsignal?: AbortSignal;\n\t\t},\n\t): Promise<ApplyCompactionResult>;\n}\n\nexport interface SpeculativeCompactionSnapshot {\n\tgeneration: number;\n\texpectedRevision: number;\n\tmodel: Model<any>;\n\tcontextWindow: number;\n\tpreparation: CompactionPreparation;\n\tbranchEntries?: ReturnType<ReadonlySessionManager[\"getBranch\"]>;\n\tpromptVariant: MergedCompactionPromptVariant;\n\torigin?: \"speculative\" | \"blocking\" | \"core-route\";\n\tcustomInstructions?: string;\n\t/** Agent system prompt; used to make the summarization request look like normal agent traffic. */\n\tsystemPrompt?: string;\n\t/** Agent tool definitions; forwarded so the request shape matches normal agent traffic. */\n\ttools?: Tool[];\n}\n\nexport type SpeculativeCompactionResult = ApplyCompactionResult | { applied: false; reason: \"unavailable\" | \"failed\" };\n\nfunction approxTokens(text: string): number {\n\treturn Math.ceil(text.length / 4);\n}\n\n/**\n * Summary-generation failure with a user-facing diagnosis. Distinct from a\n * user abort (which resolves `undefined`): callers surface `message` on the\n * manual route and degrade to \"unavailable\" on automatic routes.\n */\n/**\n * Provider `error` stop during summarization, carrying the metadata-aware\n * transient classification from the full assistant message. A refusal whose\n * text happens to look retryable must still surface loudly; the message\n * string alone cannot encode that.\n */\nexport type SummaryRequestFailureKind = \"upstream-stream-truncated\";\n\nexport class SummaryRequestError extends Error {\n\treadonly transient: boolean;\n\treadonly failureKind?: SummaryRequestFailureKind;\n\t/**\n\t * The provider refused the request (refusal/sensitive stop details) rather\n\t * than failing it. Carried explicitly because the message text cannot encode\n\t * it, and because a refusal must never authorize destructive context\n\t * reduction: dropping older detail would not make the model comply.\n\t */\n\treadonly refused: boolean;\n\n\tconstructor(message: string, transient: boolean, failureKind?: SummaryRequestFailureKind, refused = false) {\n\t\tsuper(message);\n\t\tthis.name = \"SummaryRequestError\";\n\t\tthis.transient = transient;\n\t\tthis.failureKind = failureKind;\n\t\tthis.refused = refused;\n\t}\n}\n\nconst UPSTREAM_STREAM_TRUNCATED_PATTERN = /(?:^|[^A-Za-z0-9_])upstream_stream_truncated(?:[^A-Za-z0-9_]|$)/;\n\n/**\n * Only failures with no cheaper recovery earn another billed request.\n *\n * Every class that `classifyRequiredCompactionFallbackFailure` recognizes\n * (watchdog timeouts, the compaction-wide total budget, terminal provider and\n * credential failures, `upstream-stream-truncated`, overflow exhaustion,\n * empty-summary generation failures) already\n * has a deterministic zero-LLM recovery, and context overflow is answered by\n * shrinking the input in the surrounding loop - replaying those would pay for a\n * summarization the fallback can rebuild for free. The classes checked here are\n * mirrored from that classifier rather than imported, because\n * `deterministic-fallback.ts` imports this module.\n */\nfunction isRetryableSummaryAttempt(error: unknown): boolean {\n\tif (error instanceof StreamDurationBudgetError || error instanceof StreamIdleTimeoutError) return false;\n\tif (error instanceof SummarizationTotalBudgetError) return false;\n\tif (error instanceof SummarizationOverflowExhaustedError) return false;\n\tif (error instanceof SummaryGenerationError) return false;\n\t// Mirrors the `summarization-provider-failure` class: credential rotation has\n\t// already spent every slot it may spend, and the marker means output was\n\t// committed, so another billed attempt buys nothing the fallback cannot\n\t// rebuild for free. Message text alone must not re-authorize it - the wrapped\n\t// provider detail can read as transient (#1741).\n\tif (error instanceof CredentialFailoverError) return false;\n\tif (error instanceof Error && error.message.startsWith(TURN_RETRY_SUPPRESSION_PREFIX)) return false;\n\tif (error instanceof SummaryRequestError) return error.failureKind === undefined && error.transient;\n\tif (error instanceof Error) return isRetryableErrorMessage(error.message);\n\treturn false;\n}\n\nfunction isRefusalStop(response: AssistantMessage): boolean {\n\treturn response.stopDetails?.type === \"refusal\" || response.stopDetails?.type === \"sensitive\";\n}\n\nfunction summaryRequestFailureKind(response: AssistantMessage): SummaryRequestFailureKind | undefined {\n\tif (isRefusalStop(response)) return undefined;\n\treturn UPSTREAM_STREAM_TRUNCATED_PATTERN.test(response.errorMessage ?? \"\") ? \"upstream-stream-truncated\" : undefined;\n}\n\nexport class SummaryGenerationError extends Error {\n\treadonly kind: \"auth\" | \"empty-summary\";\n\n\tconstructor(kind: \"auth\" | \"empty-summary\", message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"SummaryGenerationError\";\n\t\tthis.kind = kind;\n\t}\n}\n\n/**\n * Output budget for one summarization request. Adaptive-thinking models emit\n * reasoning tokens before the summary text, so the legacy flat 8192 cap could\n * be consumed entirely by thinking, ending the stream with zero text blocks.\n * Grant generous headroom, clamped to what the model can actually emit and to\n * half the context window: providers that enforce input + output <= window\n * would otherwise reject the request for models advertising contextWindow ==\n * maxTokens (every summarization request also carries conversation input).\n */\n\nexport function getPromptVariant(options: {\n\treason: string;\n\tpreparation: { previousSummary?: string; isSplitTurn: boolean };\n}): MergedCompactionPromptVariant {\n\tif (options.reason === \"branch\") return \"branch\";\n\tif (options.preparation.previousSummary) return \"update\";\n\tif (options.preparation.isSplitTurn) return \"turn_prefix\";\n\treturn \"default\";\n}\n\nexport function createSpeculativeCompactionSnapshot(\n\tcontext: SpeculativeCompactionContext,\n\toptions: {\n\t\tcustomInstructions?: string;\n\t\tgeneration: number;\n\t\torigin?: \"speculative\" | \"blocking\" | \"core-route\";\n\t\ttools?: Tool[];\n\t},\n): SpeculativeCompactionSnapshot | undefined {\n\tconst model = context.model;\n\tif (!model) return undefined;\n\n\tconst expectedRevision = context.getMessageRevision();\n\tconst branchEntries = context.sessionManager.getBranch();\n\tconst contextWindow = context.getContextUsage()?.contextWindow ?? model.contextWindow ?? DEFAULT_CONTEXT_WINDOW;\n\tconst settings = context.getCompactionSettings?.() ?? DEFAULT_COMPACTION_SETTINGS;\n\tconst thresholdRatio = computeEffectiveThreshold(contextWindow);\n\tconst preparation = prepareCompaction(branchEntries, {\n\t\t...settings,\n\t\tkeepRecentTokens: computeEffectiveKeepRecentTokens(settings.keepRecentTokens, contextWindow, thresholdRatio),\n\t});\n\tif (!preparation) return undefined;\n\n\treturn {\n\t\t...options,\n\t\texpectedRevision,\n\t\tmodel,\n\t\tcontextWindow,\n\t\tpreparation,\n\t\tbranchEntries,\n\t\tpromptVariant: getPromptVariant({ reason: \"extension\", preparation }),\n\t\tsystemPrompt: context.getSystemPrompt?.(),\n\t};\n}\n\n/**\n * Generate a compaction summary for the snapshot. Resolves `undefined` only\n * when the request was aborted (caller signal or an aborted stream); every\n * other failure throws — {@link SummaryGenerationError} for diagnosable\n * generation failures, the raw provider error otherwise. Abort is checked\n * before and after credential resolution so a cancelled request never\n * misreports as an auth failure.\n */\nexport async function runExtensionCompaction(\n\tcontext: SpeculativeCompactionContext,\n\tsnapshot: SpeculativeCompactionSnapshot,\n\tsignal?: AbortSignal,\n\tonProgress?: CompactionProgressCallback,\n): Promise<CompactionResult | undefined> {\n\tif (signal?.aborted) return undefined;\n\tconst auth = await context.modelRegistry?.getApiKeyAndHeaders(snapshot.model);\n\tif (signal?.aborted) return undefined;\n\t// A provider is authenticated for summarization by either a resolved key or a\n\t// credential request header: `headers`-authenticated providers (models.json and\n\t// extension providers alike) never resolve an apiKey, yet their normal agent\n\t// turns are fully authenticated.\n\tif (!auth?.ok || !(auth.apiKey || hasCredentialHeaders(auth.headers))) {\n\t\tconst detail =\n\t\t\tauth && !auth.ok ? auth.error : `no credentials resolved for provider \"${snapshot.model.provider}\"`;\n\t\tthrow new SummaryGenerationError(\"auth\", `summarization credentials unavailable: ${detail}`);\n\t}\n\tconst requestSnapshot = auth.baseUrl\n\t\t? { ...snapshot, model: { ...snapshot.model, baseUrl: auth.baseUrl } }\n\t\t: snapshot;\n\n\tconst prompt = buildPrompt({\n\t\tvariant: requestSnapshot.promptVariant,\n\t\tpreviousSummary: requestSnapshot.preparation.previousSummary,\n\t\ttaskIntent: resolveInheritedTaskIntent(requestSnapshot.branchEntries ?? []),\n\t\tcustomInstructions: requestSnapshot.customInstructions,\n\t});\n\tconst promptTokens = approxTokens(prompt.user);\n\tlet messages = boundSummarizationInput(\n\t\tpruneToolResults(\n\t\t\t[...requestSnapshot.preparation.messagesToSummarize, ...requestSnapshot.preparation.turnPrefixMessages],\n\t\t\trequestSnapshot.contextWindow,\n\t\t\tSUMMARIZATION_INPUT_BUDGET_RATIO,\n\t\t),\n\t\trequestSnapshot.contextWindow,\n\t\tpromptTokens,\n\t);\n\t// One deadline for the whole compaction. The per-attempt budget scales with the\n\t// input and every retry re-arms it, so without this a large session could hold\n\t// the turn for attempt-budget x attempts with no bound the user can predict.\n\tconst deadline = createSummarizationDeadline(\n\t\tsummarizationTotalBudgetMs(requestSnapshot.preparation.settings.summarizationMaxDurationMs),\n\t);\n\tconst overflowRetryStartMs = Date.now();\n\tlet overflowAttempts = 0;\n\tconst summarizationToolsOffered = (requestSnapshot.tools?.length ?? 0) > 0;\n\tlet toolUseRetrySpent = false;\n\n\twhile (true) {\n\t\tif (signal?.aborted) return undefined;\n\t\tlet response: Message | undefined;\n\t\tconst currentMessages = messages;\n\t\tconst retryStartedMs = Date.now();\n\t\t// Only the routes that block the user's turn retry here. The speculative\n\t\t// warm-up owns its own bounded retry (`idle-retry.ts`) with idle/breaker\n\t\t// guards re-evaluated between attempts, and a failed warm job must stay\n\t\t// inheritable so the next blocking route degrades on it instead of paying\n\t\t// for a second request.\n\t\tconst retryEligible = snapshot.origin === \"core-route\" || snapshot.origin === \"blocking\";\n\t\t// The attempt budget and the retry gate share one input-size-scaled number,\n\t\t// so a large session gets both a proportional attempt deadline and room to\n\t\t// retry transient failures without the 120s-era retry budget disqualifying\n\t\t// every slow attempt (#1068).\n\t\tconst attemptBudgetMs = summarizationMaxDurationMs(\n\t\t\tmessages.reduce((total, message) => total + estimateTokens(message), 0),\n\t\t\tsnapshot.preparation.settings.summarizationMaxDurationMs,\n\t\t);\n\t\ttry {\n\t\t\t// The provider `error` stop is raised INSIDE the retried producer so a\n\t\t\t// transient summarization failure spends the shared retry budget. The\n\t\t\t// surrounding loop keeps overflow shrinking and abort handling, which\n\t\t\t// must never be answered by replaying the same request.\n\t\t\tresponse = await retryTransientCall(\n\t\t\t\tasync () => {\n\t\t\t\t\tconst attempt = await generateSummaryMessage({\n\t\t\t\t\t\tcontext,\n\t\t\t\t\t\tforbidToolCalls: toolUseRetrySpent,\n\t\t\t\t\t\t// Re-clamped per attempt, not per loop turn: a retry that starts\n\t\t\t\t\t\t// near the deadline gets only what is left, and none starts past it.\n\t\t\t\t\t\tmaxDurationMs: deadline.attemptBudgetMs(attemptBudgetMs),\n\t\t\t\t\t\tmessages: currentMessages,\n\t\t\t\t\t\tonProgress,\n\t\t\t\t\t\tprompt,\n\t\t\t\t\t\tsignal,\n\t\t\t\t\t\tsnapshot: requestSnapshot,\n\t\t\t\t\t\tauth: {\n\t\t\t\t\t\t\tapiKey: auth.apiKey,\n\t\t\t\t\t\t\theaders: auth.headers,\n\t\t\t\t\t\t\textraBody: auth.extraBody,\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t\tif (\n\t\t\t\t\t\tattempt &&\n\t\t\t\t\t\tisAssistantMessage(attempt) &&\n\t\t\t\t\t\tattempt.stopReason === \"error\" &&\n\t\t\t\t\t\t!isContextOverflow(attempt, snapshot.contextWindow)\n\t\t\t\t\t) {\n\t\t\t\t\t\tconst failureKind = summaryRequestFailureKind(attempt);\n\t\t\t\t\t\tthrow new SummaryRequestError(\n\t\t\t\t\t\t\tattempt.errorMessage || \"Compaction summary request failed\",\n\t\t\t\t\t\t\tfailureKind !== undefined || isRetryableAssistantError(attempt),\n\t\t\t\t\t\t\tfailureKind,\n\t\t\t\t\t\t\tisRefusalStop(attempt),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\treturn attempt;\n\t\t\t\t},\n\t\t\t\t(error) =>\n\t\t\t\t\tretryEligible &&\n\t\t\t\t\tdeadline.remainingMs() > 0 &&\n\t\t\t\t\tallowSummarizationRetry(Date.now() - retryStartedMs, attemptBudgetMs) &&\n\t\t\t\t\tisRetryableSummaryAttempt(error),\n\t\t\t\tDEFAULT_SUMMARIZATION_RETRY_POLICY,\n\t\t\t\tsignal,\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tif (signal?.aborted) return undefined;\n\t\t\tthrow error;\n\t\t}\n\t\tif (!response) return undefined;\n\n\t\tif (isAssistantMessage(response) && isContextOverflow(response, snapshot.contextWindow)) {\n\t\t\toverflowAttempts++;\n\t\t\tconst elapsedMs = Date.now() - overflowRetryStartMs;\n\t\t\tconst retryMessages = allowOverflowRetry(overflowAttempts, elapsedMs)\n\t\t\t\t? shrinkSummarizationInputForOverflowRetry(messages, snapshot.contextWindow, promptTokens)\n\t\t\t\t: undefined;\n\t\t\tif (!retryMessages) {\n\t\t\t\tthrow new SummarizationOverflowExhaustedError(overflowAttempts, elapsedMs);\n\t\t\t}\n\t\t\tmessages = retryMessages;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (isAssistantMessage(response) && response.stopReason === \"aborted\") {\n\t\t\t// A partial summary from an aborted stream must never be applied.\n\t\t\treturn undefined;\n\t\t}\n\n\t\tif (isAssistantMessage(response) && response.stopReason === \"error\") {\n\t\t\t// Surface the real provider failure instead of silently degrading\n\t\t\t// into a generic \"Compaction cancelled\". Preserve the structured\n\t\t\t// truncation class here so downstream recovery never trusts arbitrary\n\t\t\t// thrown error text as authorization for destructive context reduction.\n\t\t\tconst failureKind = summaryRequestFailureKind(response);\n\t\t\tthrow new SummaryRequestError(\n\t\t\t\tresponse.errorMessage || \"Compaction summary request failed\",\n\t\t\t\tfailureKind !== undefined || isRetryableAssistantError(response),\n\t\t\t\tfailureKind,\n\t\t\t\tisRefusalStop(response),\n\t\t\t);\n\t\t}\n\n\t\tconst summary = getSummaryText(response);\n\t\tif (!summary) {\n\t\t\tconst stopReason = isAssistantMessage(response) ? response.stopReason : \"unknown\";\n\t\t\t// A summarizer can hijack the forwarded agent tools and answer with a\n\t\t\t// bare tool call (observed on openai-codex gpt-5.6-sol, 2026-08-31),\n\t\t\t// which used to surface as a terminal empty-summary failure. Spend one\n\t\t\t// retry with tool calling forbidden; the tools stay in the request\n\t\t\t// because Anthropic rejects tool_use history without the tools param.\n\t\t\tif (stopReason === \"toolUse\" && summarizationToolsOffered && !toolUseRetrySpent) {\n\t\t\t\ttoolUseRetrySpent = true;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tthrow new SummaryGenerationError(\n\t\t\t\t\"empty-summary\",\n\t\t\t\t`summarization response contained no text (stopReason: ${stopReason})`,\n\t\t\t);\n\t\t}\n\n\t\t// Informational only: the core rejects an applied compaction that would\n\t\t// still overflow (_wouldCompactionOverflow). Rejecting here based on the\n\t\t// size of the *discarded* input made large sessions uncompactable.\n\t\tconst tokenEstimate = estimateContextTokens(convertToLlm(messages)).tokens + approxTokens(summary);\n\t\tconst parsedSummary = extractTaskIntent(summary);\n\t\tconst taskIntent = parsedSummary.taskIntent ?? resolveInheritedTaskIntent(snapshot.branchEntries ?? []);\n\n\t\treturn {\n\t\t\tsummary: parsedSummary.summaryText,\n\t\t\tfirstKeptEntryId: snapshot.preparation.firstKeptEntryId,\n\t\t\ttokensBefore: snapshot.preparation.tokensBefore,\n\t\t\tdetails: {\n\t\t\t\tschema: SUMMARY_SCHEMA,\n\t\t\t\tpromptVariant: snapshot.promptVariant,\n\t\t\t\ttokenEstimate,\n\t\t\t\tstructuralYield: computeStructuralYield({\n\t\t\t\t\tpreviousSummary: snapshot.preparation.previousSummary ?? \"\",\n\t\t\t\t\tmessagesToSummarize: snapshot.preparation.messagesToSummarize,\n\t\t\t\t\tturnPrefixMessages: snapshot.preparation.turnPrefixMessages,\n\t\t\t\t\tsummary: parsedSummary.summaryText,\n\t\t\t\t\ttokensBefore: snapshot.preparation.tokensBefore,\n\t\t\t\t}),\n\t\t\t\t...(snapshot.origin ? { origin: snapshot.origin } : {}),\n\t\t\t\t...(taskIntent ? { taskIntent } : {}),\n\t\t\t},\n\t\t};\n\t}\n}\n\nexport async function applyGeneratedCompaction(\n\tcontext: SpeculativeCompactionContext,\n\tsnapshot: SpeculativeCompactionSnapshot | undefined,\n\tgetCurrentGeneration: () => number,\n\tcompaction: CompactionResult | undefined,\n\tsignal?: AbortSignal,\n): Promise<SpeculativeCompactionResult> {\n\tconst provider = context.model?.provider;\n\tif ((provider === \"cursor\" || provider === \"cursor-cli-oauth\") && context.isIdle && !context.isIdle()) {\n\t\treturn { applied: false, reason: \"rejected\" };\n\t}\n\tif (!snapshot || !compaction) return { applied: false, reason: \"unavailable\" };\n\n\tif (snapshot.generation !== getCurrentGeneration()) {\n\t\treturn { applied: false, reason: \"stale\" };\n\t}\n\n\tconst revisionUnchanged = snapshot.expectedRevision === context.getMessageRevision();\n\tconst warmAnchor = createWarmAnchorSnapshot(snapshot.preparation.firstKeptEntryId, snapshot.branchEntries ?? []);\n\tif (\n\t\t!revisionUnchanged &&\n\t\t(!warmAnchor || !isWarmSummaryAnchorValid(warmAnchor, context.sessionManager.getBranch()))\n\t) {\n\t\treturn { applied: false, reason: \"stale\" };\n\t}\n\n\treturn await context.applyCompaction(compaction, {\n\t\treason: \"extension\",\n\t\t...(revisionUnchanged || !warmAnchor\n\t\t\t? { expectedRevision: snapshot.expectedRevision }\n\t\t\t: { expectedWarmAnchor: warmAnchor }),\n\t\tsignal,\n\t});\n}\n\nexport async function applySpeculativeCompaction(\n\tcontext: SpeculativeCompactionContext,\n\tsnapshot: SpeculativeCompactionSnapshot | undefined,\n\tgetCurrentGeneration: () => number,\n\tgenerate: () => Promise<CompactionResult | undefined>,\n): Promise<SpeculativeCompactionResult> {\n\tif (!snapshot) return { applied: false, reason: \"unavailable\" };\n\n\tconst compaction = await generate();\n\treturn await applyGeneratedCompaction(context, snapshot, getCurrentGeneration, compaction);\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transient-failure.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/compaction/transient-failure.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"transient-failure.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/compaction/transient-failure.ts"],"names":[],"mappings":"AAyBA,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAMxF"}
|
|
@@ -9,17 +9,20 @@
|
|
|
9
9
|
*
|
|
10
10
|
* Provider `error` stops carry metadata-aware classification through
|
|
11
11
|
* `SummaryRequestError` (a refusal whose text merely looks retryable stays
|
|
12
|
-
* loud). Watchdog trips — a stalled stream
|
|
13
|
-
* wall-clock budget
|
|
12
|
+
* loud). Watchdog trips — a stalled stream, a stream that outlived its
|
|
13
|
+
* wall-clock budget, or a compaction that outlived its total budget — are
|
|
14
|
+
* infrastructure-slowness outcomes and always degrade.
|
|
14
15
|
* Everything else falls back to the shared message classifier.
|
|
15
16
|
*/
|
|
16
17
|
import { isRetryableErrorMessage } from "@earendil-works/pi-ai";
|
|
17
|
-
import { StreamDurationBudgetError, StreamIdleTimeoutError } from "../../../compaction/stream-watchdog.js";
|
|
18
|
+
import { StreamDurationBudgetError, StreamIdleTimeoutError, SummarizationTotalBudgetError, } from "../../../compaction/stream-watchdog.js";
|
|
18
19
|
import { SummarizationOverflowExhaustedError } from "./overflow-retry.js";
|
|
19
20
|
import { SummaryRequestError } from "./speculative.js";
|
|
20
21
|
export function isTransientSummarizationFailure(error, message) {
|
|
21
22
|
if (error instanceof StreamDurationBudgetError || error instanceof StreamIdleTimeoutError)
|
|
22
23
|
return true;
|
|
24
|
+
if (error instanceof SummarizationTotalBudgetError)
|
|
25
|
+
return true;
|
|
23
26
|
if (error instanceof SummaryRequestError)
|
|
24
27
|
return error.transient;
|
|
25
28
|
if (error instanceof SummarizationOverflowExhaustedError)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transient-failure.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/compaction/transient-failure.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"transient-failure.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/compaction/transient-failure.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EACN,yBAAyB,EACzB,sBAAsB,EACtB,6BAA6B,GAC7B,MAAM,wCAAwC,CAAC;AAChD,OAAO,EAAE,mCAAmC,EAAE,MAAM,qBAAqB,CAAC;AAC1E,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAEvD,MAAM,UAAU,+BAA+B,CAAC,KAAc,EAAE,OAAe;IAC9E,IAAI,KAAK,YAAY,yBAAyB,IAAI,KAAK,YAAY,sBAAsB;QAAE,OAAO,IAAI,CAAC;IACvG,IAAI,KAAK,YAAY,6BAA6B;QAAE,OAAO,IAAI,CAAC;IAChE,IAAI,KAAK,YAAY,mBAAmB;QAAE,OAAO,KAAK,CAAC,SAAS,CAAC;IACjE,IAAI,KAAK,YAAY,mCAAmC;QAAE,OAAO,IAAI,CAAC;IACtE,OAAO,uBAAuB,CAAC,OAAO,CAAC,CAAC;AACzC,CAAC","sourcesContent":["/**\n * Classifies a summarization failure as transient (degrade quietly through the\n * compaction failure path) or terminal (surface loudly).\n *\n * Transient failures must not escape as extension errors: the runner would print\n * a raw stack on top of the `compaction_end` message the user already saw, while\n * the turn's own provider request surfaces the same outage again through the\n * normal retry path.\n *\n * Provider `error` stops carry metadata-aware classification through\n * `SummaryRequestError` (a refusal whose text merely looks retryable stays\n * loud). Watchdog trips — a stalled stream, a stream that outlived its\n * wall-clock budget, or a compaction that outlived its total budget — are\n * infrastructure-slowness outcomes and always degrade.\n * Everything else falls back to the shared message classifier.\n */\nimport { isRetryableErrorMessage } from \"@earendil-works/pi-ai\";\nimport {\n\tStreamDurationBudgetError,\n\tStreamIdleTimeoutError,\n\tSummarizationTotalBudgetError,\n} from \"../../../compaction/stream-watchdog.ts\";\nimport { SummarizationOverflowExhaustedError } from \"./overflow-retry.ts\";\nimport { SummaryRequestError } from \"./speculative.ts\";\n\nexport function isTransientSummarizationFailure(error: unknown, message: string): boolean {\n\tif (error instanceof StreamDurationBudgetError || error instanceof StreamIdleTimeoutError) return true;\n\tif (error instanceof SummarizationTotalBudgetError) return true;\n\tif (error instanceof SummaryRequestError) return error.transient;\n\tif (error instanceof SummarizationOverflowExhaustedError) return true;\n\treturn isRetryableErrorMessage(message);\n}\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
|
+
export type ExtensionKernelTools = {
|
|
3
|
+
describe(names: readonly string[]): Promise<unknown>;
|
|
4
|
+
invoke(request: {
|
|
5
|
+
name: string;
|
|
6
|
+
kernel_generation: number;
|
|
7
|
+
definition_revision: number;
|
|
8
|
+
args: unknown;
|
|
9
|
+
call_id: string;
|
|
10
|
+
}, signal?: AbortSignal): Promise<unknown>;
|
|
11
|
+
};
|
|
12
|
+
export declare const kernelToolsStorage: AsyncLocalStorage<ExtensionKernelTools>;
|
|
13
|
+
//# sourceMappingURL=kernel-tools-context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kernel-tools-context.d.ts","sourceRoot":"","sources":["../../../src/core/extensions/kernel-tools-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD,MAAM,MAAM,oBAAoB,GAAG;IAClC,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACrD,MAAM,CACL,OAAO,EAAE;QACR,IAAI,EAAE,MAAM,CAAC;QACb,iBAAiB,EAAE,MAAM,CAAC;QAC1B,mBAAmB,EAAE,MAAM,CAAC;QAC5B,IAAI,EAAE,OAAO,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;KAChB,EACD,MAAM,CAAC,EAAE,WAAW,GAClB,OAAO,CAAC,OAAO,CAAC,CAAC;CACpB,CAAC;AAEF,eAAO,MAAM,kBAAkB,yCAAgD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kernel-tools-context.js","sourceRoot":"","sources":["../../../src/core/extensions/kernel-tools-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAgBrD,MAAM,CAAC,MAAM,kBAAkB,GAAG,IAAI,iBAAiB,EAAwB,CAAC","sourcesContent":["import { AsyncLocalStorage } from \"node:async_hooks\";\n\nexport type ExtensionKernelTools = {\n\tdescribe(names: readonly string[]): Promise<unknown>;\n\tinvoke(\n\t\trequest: {\n\t\t\tname: string;\n\t\t\tkernel_generation: number;\n\t\t\tdefinition_revision: number;\n\t\t\targs: unknown;\n\t\t\tcall_id: string;\n\t\t},\n\t\tsignal?: AbortSignal,\n\t): Promise<unknown>;\n};\n\nexport const kernelToolsStorage = new AsyncLocalStorage<ExtensionKernelTools>();\n"]}
|
|
@@ -97,6 +97,9 @@ export type ShutdownHandler = () => void;
|
|
|
97
97
|
/**
|
|
98
98
|
* Helper function to emit session_shutdown event to extensions.
|
|
99
99
|
* Returns true if the event was emitted, false if there were no handlers.
|
|
100
|
+
*
|
|
101
|
+
* Each handler runs under the host's shutdown budget (see
|
|
102
|
+
* `ExtensionRunner.emit`), so a hung extension cannot hold teardown hostage.
|
|
100
103
|
*/
|
|
101
104
|
export declare function emitSessionShutdownEvent(extensionRunner: ExtensionRunner, event: SessionShutdownEvent): Promise<boolean>;
|
|
102
105
|
export declare function emitProjectTrustEvent(extensionsResult: LoadExtensionsResult, event: ProjectTrustEvent, ctx: ProjectTrustContext): Promise<{
|
|
@@ -232,6 +235,22 @@ export declare class ExtensionRunner {
|
|
|
232
235
|
createContext(excludeBeforeProviderRequestExtensionPath?: string): ExtensionContext;
|
|
233
236
|
createCommandContext(): ExtensionCommandContext;
|
|
234
237
|
private isSessionBeforeEvent;
|
|
238
|
+
/**
|
|
239
|
+
* Host budget for `session_shutdown` handlers, read from settings once per
|
|
240
|
+
* shutdown emission (teardown runs once per runner, so a settings edit takes
|
|
241
|
+
* effect without a reload). A malformed value must never break teardown, so
|
|
242
|
+
* an invalid setting is reported and the shipped defaults are used.
|
|
243
|
+
*/
|
|
244
|
+
private resolveSessionShutdownBudget;
|
|
245
|
+
/**
|
|
246
|
+
* Runs one `session_shutdown` handler under the host budget. The handler sees
|
|
247
|
+
* the budget through `event.signal`, which this runner aborts at the hard cap;
|
|
248
|
+
* the host then stops waiting (the handler itself keeps running detached),
|
|
249
|
+
* reports an extension error and lets teardown continue with the next handler.
|
|
250
|
+
* Handler rejections are rethrown so emit()'s existing error path reports them
|
|
251
|
+
* exactly as before.
|
|
252
|
+
*/
|
|
253
|
+
private runSessionShutdownHandler;
|
|
235
254
|
emit<TEvent extends RunnerEmitEvent>(event: TEvent): Promise<RunnerEmitResult<TEvent>>;
|
|
236
255
|
emitModelSelect(event: ModelSelectEvent): Promise<ModelSelectEventResult | undefined>;
|
|
237
256
|
emitMessageEnd(event: MessageEndEvent): Promise<AgentMessage | undefined>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../../src/core/extensions/runner.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../../src/core/extensions/runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,9 +7,10 @@ import { theme } from "../../modes/interactive/theme/theme.js";
|
|
|
7
7
|
import { stripAnsi } from "../../utils/ansi.js";
|
|
8
8
|
import { createEventBus, EXTENSION_RPC_EVENT_CHANNEL } from "../event-bus.js";
|
|
9
9
|
import { getSessionContextEntryId, SESSION_CONTEXT_ENTRY_ID } from "../session-manager.js";
|
|
10
|
-
import { SettingsManager } from "../settings-manager.js";
|
|
10
|
+
import { DEFAULT_SESSION_SHUTDOWN_HANDLER_TIMEOUT_MS, DEFAULT_SESSION_SHUTDOWN_HANDLER_WARN_MS, SettingsManager, } from "../settings-manager.js";
|
|
11
11
|
import { goalFilePath } from "./builtin/goal/persistence.js";
|
|
12
12
|
import { goalStoreRef } from "./builtin/goal/store-ref.js";
|
|
13
|
+
import { kernelToolsStorage } from "./kernel-tools-context.js";
|
|
13
14
|
import { drainPendingProviderRegistrations } from "./loader.js";
|
|
14
15
|
// Extension shortcuts compete with canonical keybinding ids from keybindings.json.
|
|
15
16
|
// Only editor-global shortcuts are reserved here. Picker-specific bindings are not.
|
|
@@ -75,6 +76,9 @@ function sanitizedToolHookStatusMessage(message) {
|
|
|
75
76
|
/**
|
|
76
77
|
* Helper function to emit session_shutdown event to extensions.
|
|
77
78
|
* Returns true if the event was emitted, false if there were no handlers.
|
|
79
|
+
*
|
|
80
|
+
* Each handler runs under the host's shutdown budget (see
|
|
81
|
+
* `ExtensionRunner.emit`), so a hung extension cannot hold teardown hostage.
|
|
78
82
|
*/
|
|
79
83
|
export async function emitSessionShutdownEvent(extensionRunner, event) {
|
|
80
84
|
if (extensionRunner.hasHandlers("session_shutdown")) {
|
|
@@ -837,6 +841,10 @@ export class ExtensionRunner {
|
|
|
837
841
|
runner.assertActive();
|
|
838
842
|
return runner.getSignalFn();
|
|
839
843
|
},
|
|
844
|
+
get kernelTools() {
|
|
845
|
+
runner.assertActive();
|
|
846
|
+
return kernelToolsStorage.getStore();
|
|
847
|
+
},
|
|
840
848
|
abort: (source) => {
|
|
841
849
|
runner.assertActive();
|
|
842
850
|
runner.abortFn(source);
|
|
@@ -987,14 +995,108 @@ export class ExtensionRunner {
|
|
|
987
995
|
event.type === "session_before_compact" ||
|
|
988
996
|
event.type === "session_before_tree");
|
|
989
997
|
}
|
|
998
|
+
/**
|
|
999
|
+
* Host budget for `session_shutdown` handlers, read from settings once per
|
|
1000
|
+
* shutdown emission (teardown runs once per runner, so a settings edit takes
|
|
1001
|
+
* effect without a reload). A malformed value must never break teardown, so
|
|
1002
|
+
* an invalid setting is reported and the shipped defaults are used.
|
|
1003
|
+
*/
|
|
1004
|
+
resolveSessionShutdownBudget() {
|
|
1005
|
+
try {
|
|
1006
|
+
const settings = SettingsManager.create(this.cwd, this.getAgentDirFn(), {
|
|
1007
|
+
projectTrusted: this.isProjectTrustedFn(),
|
|
1008
|
+
});
|
|
1009
|
+
return {
|
|
1010
|
+
warnMs: settings.getSessionShutdownHandlerWarnMs(),
|
|
1011
|
+
timeoutMs: settings.getSessionShutdownHandlerTimeoutMs(),
|
|
1012
|
+
};
|
|
1013
|
+
}
|
|
1014
|
+
catch (err) {
|
|
1015
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
1016
|
+
console.warn(`Using the default session_shutdown handler budget (warn ${DEFAULT_SESSION_SHUTDOWN_HANDLER_WARN_MS}ms, hard cap ${DEFAULT_SESSION_SHUTDOWN_HANDLER_TIMEOUT_MS}ms): ${message}`);
|
|
1017
|
+
return {
|
|
1018
|
+
warnMs: DEFAULT_SESSION_SHUTDOWN_HANDLER_WARN_MS,
|
|
1019
|
+
timeoutMs: DEFAULT_SESSION_SHUTDOWN_HANDLER_TIMEOUT_MS,
|
|
1020
|
+
};
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
/**
|
|
1024
|
+
* Runs one `session_shutdown` handler under the host budget. The handler sees
|
|
1025
|
+
* the budget through `event.signal`, which this runner aborts at the hard cap;
|
|
1026
|
+
* the host then stops waiting (the handler itself keeps running detached),
|
|
1027
|
+
* reports an extension error and lets teardown continue with the next handler.
|
|
1028
|
+
* Handler rejections are rethrown so emit()'s existing error path reports them
|
|
1029
|
+
* exactly as before.
|
|
1030
|
+
*/
|
|
1031
|
+
async runSessionShutdownHandler(extensionPath, event, handler, budget) {
|
|
1032
|
+
const controller = new AbortController();
|
|
1033
|
+
const startedAt = Date.now();
|
|
1034
|
+
let outcome;
|
|
1035
|
+
// Settle the handler through a captured outcome so a late rejection after a
|
|
1036
|
+
// timeout is already handled instead of becoming an unhandled rejection.
|
|
1037
|
+
const settled = Promise.resolve(handler({ ...event, signal: controller.signal }, this.createContext(extensionPath))).then(() => {
|
|
1038
|
+
outcome = { ok: true };
|
|
1039
|
+
}, (error) => {
|
|
1040
|
+
outcome = { ok: false, error };
|
|
1041
|
+
});
|
|
1042
|
+
if (budget.warnMs > 0 || budget.timeoutMs > 0) {
|
|
1043
|
+
let warnTimer;
|
|
1044
|
+
let capTimer;
|
|
1045
|
+
let timedOut = false;
|
|
1046
|
+
try {
|
|
1047
|
+
timedOut = await new Promise((resolve) => {
|
|
1048
|
+
if (budget.warnMs > 0) {
|
|
1049
|
+
warnTimer = setTimeout(() => {
|
|
1050
|
+
const capNote = budget.timeoutMs > 0 ? ` (hard cap ${budget.timeoutMs}ms)` : "";
|
|
1051
|
+
console.warn(`Extension ${extensionPath} is still running its session_shutdown handler after ${Date.now() - startedAt}ms${capNote}.`);
|
|
1052
|
+
}, budget.warnMs);
|
|
1053
|
+
}
|
|
1054
|
+
if (budget.timeoutMs > 0) {
|
|
1055
|
+
capTimer = setTimeout(() => resolve(true), budget.timeoutMs);
|
|
1056
|
+
}
|
|
1057
|
+
void settled.then(() => resolve(false));
|
|
1058
|
+
});
|
|
1059
|
+
}
|
|
1060
|
+
finally {
|
|
1061
|
+
clearTimeout(warnTimer);
|
|
1062
|
+
clearTimeout(capTimer);
|
|
1063
|
+
}
|
|
1064
|
+
if (timedOut) {
|
|
1065
|
+
controller.abort(new Error(`session_shutdown handler timed out after ${budget.timeoutMs}ms`));
|
|
1066
|
+
this.emitError({
|
|
1067
|
+
extensionPath,
|
|
1068
|
+
event: "session_shutdown",
|
|
1069
|
+
error: `handler timed out after ${budget.timeoutMs}ms`,
|
|
1070
|
+
});
|
|
1071
|
+
return;
|
|
1072
|
+
}
|
|
1073
|
+
}
|
|
1074
|
+
else {
|
|
1075
|
+
await settled;
|
|
1076
|
+
}
|
|
1077
|
+
if (outcome && !outcome.ok) {
|
|
1078
|
+
throw outcome.error;
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
990
1081
|
async emit(event) {
|
|
991
1082
|
let result;
|
|
1083
|
+
// session_shutdown is the one host-bounded event: a hung handler must not hold
|
|
1084
|
+
// Ctrl+C / quit / reload / new / resume hostage. Every other event still awaits
|
|
1085
|
+
// its handlers without a cap (ask-user and approval dialogs legitimately block).
|
|
1086
|
+
// The budget is resolved lazily so runners with no shutdown handler read no settings.
|
|
1087
|
+
const isSessionShutdown = event.type === "session_shutdown";
|
|
1088
|
+
let shutdownBudget;
|
|
992
1089
|
for (const ext of this.extensions) {
|
|
993
1090
|
const handlers = ext.handlers.get(event.type);
|
|
994
1091
|
if (!handlers || handlers.length === 0)
|
|
995
1092
|
continue;
|
|
996
1093
|
for (const handler of handlers) {
|
|
997
1094
|
try {
|
|
1095
|
+
if (isSessionShutdown) {
|
|
1096
|
+
shutdownBudget ??= this.resolveSessionShutdownBudget();
|
|
1097
|
+
await this.runSessionShutdownHandler(ext.path, event, handler, shutdownBudget);
|
|
1098
|
+
continue;
|
|
1099
|
+
}
|
|
998
1100
|
const handlerResult = await handler(event, this.createContext(ext.path));
|
|
999
1101
|
if (this.isSessionBeforeEvent(event) && handlerResult) {
|
|
1000
1102
|
result = handlerResult;
|