@code-yeongyu/senpi 2026.8.30 → 2026.9.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 +174 -2
- package/README.md +3 -0
- 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 +161 -14
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/compaction/compaction-execution.d.ts +14 -0
- package/dist/core/compaction/compaction-execution.d.ts.map +1 -0
- package/dist/core/compaction/compaction-execution.js +121 -0
- package/dist/core/compaction/compaction-execution.js.map +1 -0
- package/dist/core/compaction/compaction-settings.d.ts +17 -0
- package/dist/core/compaction/compaction-settings.d.ts.map +1 -0
- package/dist/core/compaction/compaction-settings.js +17 -0
- package/dist/core/compaction/compaction-settings.js.map +1 -0
- package/dist/core/compaction/compaction.d.ts +13 -26
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +7 -136
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/compaction/ideal-compaction-settings.d.ts +9 -0
- package/dist/core/compaction/ideal-compaction-settings.d.ts.map +1 -0
- package/dist/core/compaction/ideal-compaction-settings.js +7 -0
- package/dist/core/compaction/ideal-compaction-settings.js.map +1 -0
- package/dist/core/compaction-settings-access.d.ts +19 -0
- package/dist/core/compaction-settings-access.d.ts.map +1 -0
- package/dist/core/compaction-settings-access.js +10 -0
- package/dist/core/compaction-settings-access.js.map +1 -0
- package/dist/core/compaction-settings-resolver.d.ts +22 -0
- package/dist/core/compaction-settings-resolver.d.ts.map +1 -0
- package/dist/core/compaction-settings-resolver.js +46 -0
- package/dist/core/compaction-settings-resolver.js.map +1 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry.d.ts +9 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry.js +10 -3
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/context-pipeline.d.ts +24 -0
- package/dist/core/extensions/builtin/compaction/context-pipeline.d.ts.map +1 -0
- package/dist/core/extensions/builtin/compaction/context-pipeline.js +43 -0
- package/dist/core/extensions/builtin/compaction/context-pipeline.js.map +1 -0
- package/dist/core/extensions/builtin/compaction/deterministic-fallback.d.ts +1 -1
- package/dist/core/extensions/builtin/compaction/deterministic-fallback.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/deterministic-fallback.js +8 -2
- package/dist/core/extensions/builtin/compaction/deterministic-fallback.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/emergency-prune.d.ts +17 -0
- package/dist/core/extensions/builtin/compaction/emergency-prune.d.ts.map +1 -0
- package/dist/core/extensions/builtin/compaction/emergency-prune.js +64 -0
- package/dist/core/extensions/builtin/compaction/emergency-prune.js.map +1 -0
- package/dist/core/extensions/builtin/compaction/extension-wiring.d.ts +27 -0
- package/dist/core/extensions/builtin/compaction/extension-wiring.d.ts.map +1 -0
- package/dist/core/extensions/builtin/compaction/extension-wiring.js +84 -0
- package/dist/core/extensions/builtin/compaction/extension-wiring.js.map +1 -0
- package/dist/core/extensions/builtin/compaction/idle-retry.d.ts +1 -1
- package/dist/core/extensions/builtin/compaction/idle-retry.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/idle-retry.js +1 -1
- package/dist/core/extensions/builtin/compaction/idle-retry.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/idle.d.ts +1 -0
- package/dist/core/extensions/builtin/compaction/idle.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/idle.js +13 -2
- package/dist/core/extensions/builtin/compaction/idle.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/index.d.ts +1 -1
- package/dist/core/extensions/builtin/compaction/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/index.js +152 -154
- package/dist/core/extensions/builtin/compaction/index.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/log.d.ts +1 -1
- package/dist/core/extensions/builtin/compaction/log.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/log.js +2 -0
- package/dist/core/extensions/builtin/compaction/log.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/model-selection.d.ts +14 -0
- package/dist/core/extensions/builtin/compaction/model-selection.d.ts.map +1 -0
- package/dist/core/extensions/builtin/compaction/model-selection.js +37 -0
- package/dist/core/extensions/builtin/compaction/model-selection.js.map +1 -0
- package/dist/core/extensions/builtin/compaction/model-usability-budget.d.ts +30 -0
- package/dist/core/extensions/builtin/compaction/model-usability-budget.d.ts.map +1 -0
- package/dist/core/extensions/builtin/compaction/model-usability-budget.js +74 -0
- package/dist/core/extensions/builtin/compaction/model-usability-budget.js.map +1 -0
- package/dist/core/extensions/builtin/compaction/openai-remote-dependencies.d.ts +9 -0
- package/dist/core/extensions/builtin/compaction/openai-remote-dependencies.d.ts.map +1 -0
- package/dist/core/extensions/builtin/compaction/openai-remote-dependencies.js +2 -0
- package/dist/core/extensions/builtin/compaction/openai-remote-dependencies.js.map +1 -0
- package/dist/core/extensions/builtin/compaction/openai-remote.d.ts +3 -6
- package/dist/core/extensions/builtin/compaction/openai-remote.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/openai-remote.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/orchestration.d.ts +46 -0
- package/dist/core/extensions/builtin/compaction/orchestration.d.ts.map +1 -0
- package/dist/core/extensions/builtin/compaction/orchestration.js +103 -0
- package/dist/core/extensions/builtin/compaction/orchestration.js.map +1 -0
- package/dist/core/extensions/builtin/compaction/policy.d.ts +12 -2
- package/dist/core/extensions/builtin/compaction/policy.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/policy.js +52 -26
- package/dist/core/extensions/builtin/compaction/policy.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/speculation-lead.d.ts +8 -0
- package/dist/core/extensions/builtin/compaction/speculation-lead.d.ts.map +1 -0
- package/dist/core/extensions/builtin/compaction/speculation-lead.js +17 -0
- package/dist/core/extensions/builtin/compaction/speculation-lead.js.map +1 -0
- package/dist/core/extensions/builtin/compaction/speculative-job.d.ts +22 -0
- package/dist/core/extensions/builtin/compaction/speculative-job.d.ts.map +1 -0
- package/dist/core/extensions/builtin/compaction/speculative-job.js +16 -0
- package/dist/core/extensions/builtin/compaction/speculative-job.js.map +1 -0
- package/dist/core/extensions/builtin/compaction/speculative-summary.d.ts +23 -0
- package/dist/core/extensions/builtin/compaction/speculative-summary.d.ts.map +1 -0
- package/dist/core/extensions/builtin/compaction/speculative-summary.js +132 -0
- package/dist/core/extensions/builtin/compaction/speculative-summary.js.map +1 -0
- package/dist/core/extensions/builtin/compaction/speculative.d.ts +8 -13
- package/dist/core/extensions/builtin/compaction/speculative.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/speculative.js +21 -197
- package/dist/core/extensions/builtin/compaction/speculative.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/token-budget-reminder.d.ts +24 -0
- package/dist/core/extensions/builtin/compaction/token-budget-reminder.d.ts.map +1 -0
- package/dist/core/extensions/builtin/compaction/token-budget-reminder.js +25 -0
- package/dist/core/extensions/builtin/compaction/token-budget-reminder.js.map +1 -0
- package/dist/core/extensions/builtin/compaction/tool-admission.d.ts +27 -0
- package/dist/core/extensions/builtin/compaction/tool-admission.d.ts.map +1 -0
- package/dist/core/extensions/builtin/compaction/tool-admission.js +56 -0
- package/dist/core/extensions/builtin/compaction/tool-admission.js.map +1 -0
- package/dist/core/extensions/builtin/hooks/trust-state-json.d.ts +5 -0
- package/dist/core/extensions/builtin/hooks/trust-state-json.d.ts.map +1 -0
- package/dist/core/extensions/builtin/hooks/trust-state-json.js +76 -0
- package/dist/core/extensions/builtin/hooks/trust-state-json.js.map +1 -0
- package/dist/core/extensions/builtin/hooks/trust-storage.d.ts +7 -1
- package/dist/core/extensions/builtin/hooks/trust-storage.d.ts.map +1 -1
- package/dist/core/extensions/builtin/hooks/trust-storage.js +60 -8
- package/dist/core/extensions/builtin/hooks/trust-storage.js.map +1 -1
- package/dist/core/extensions/builtin/hooks/trust.d.ts +1 -2
- package/dist/core/extensions/builtin/hooks/trust.d.ts.map +1 -1
- package/dist/core/extensions/builtin/hooks/trust.js +1 -72
- package/dist/core/extensions/builtin/hooks/trust.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-fable-5-1.d.ts +3 -0
- package/dist/core/extensions/builtin/prompt-preset/claude-fable-5-1.d.ts.map +1 -0
- package/dist/core/extensions/builtin/prompt-preset/claude-fable-5-1.js +108 -0
- package/dist/core/extensions/builtin/prompt-preset/claude-fable-5-1.js.map +1 -0
- package/dist/core/extensions/builtin/prompt-preset/presets.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/presets.js +11 -0
- package/dist/core/extensions/builtin/prompt-preset/presets.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/settings.d.ts +1 -1
- package/dist/core/extensions/builtin/prompt-preset/settings.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/settings.js +1 -0
- package/dist/core/extensions/builtin/prompt-preset/settings.js.map +1 -1
- package/dist/core/extensions/builtin/recommended-models/index.d.ts +1 -1
- package/dist/core/extensions/builtin/recommended-models/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/recommended-models/index.js +1 -1
- package/dist/core/extensions/builtin/recommended-models/index.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/runtime-session.d.ts +11 -0
- package/dist/core/extensions/builtin/terminal/runtime-session.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/runtime-session.js +18 -2
- package/dist/core/extensions/builtin/terminal/runtime-session.js.map +1 -1
- package/dist/core/extensions/builtin/ttsr/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/ttsr/index.js +4 -0
- package/dist/core/extensions/builtin/ttsr/index.js.map +1 -1
- package/dist/core/extensions/builtin/ttsr/manager.d.ts +2 -0
- package/dist/core/extensions/builtin/ttsr/manager.d.ts.map +1 -1
- package/dist/core/extensions/builtin/ttsr/manager.js +28 -1
- package/dist/core/extensions/builtin/ttsr/manager.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +5 -0
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +7 -0
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/retry-fallback/controller.d.ts +14 -0
- package/dist/core/retry-fallback/controller.d.ts.map +1 -1
- package/dist/core/retry-fallback/controller.js +33 -3
- package/dist/core/retry-fallback/controller.js.map +1 -1
- package/dist/core/retry-fallback/log.js +1 -1
- package/dist/core/retry-fallback/log.js.map +1 -1
- package/dist/core/retry-fallback/settings.d.ts.map +1 -1
- package/dist/core/retry-fallback/settings.js +1 -0
- package/dist/core/retry-fallback/settings.js.map +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +5 -0
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-activity.d.ts +47 -0
- package/dist/core/session-activity.d.ts.map +1 -0
- package/dist/core/session-activity.js +58 -0
- package/dist/core/session-activity.js.map +1 -0
- package/dist/core/session-manager.d.ts +8 -12
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +118 -7
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/session-resident-store.d.ts +8 -1
- package/dist/core/session-resident-store.d.ts.map +1 -1
- package/dist/core/session-resident-store.js +12 -5
- package/dist/core/session-resident-store.js.map +1 -1
- package/dist/core/settings-manager.d.ts +8 -85
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +9 -17
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/settings-public-types.d.ts +11 -0
- package/dist/core/settings-public-types.d.ts.map +1 -0
- package/dist/core/settings-public-types.js +2 -0
- package/dist/core/settings-public-types.js.map +1 -0
- package/dist/core/settings-shapes.d.ts +36 -0
- package/dist/core/settings-shapes.d.ts.map +1 -0
- package/dist/core/settings-shapes.js +2 -0
- package/dist/core/settings-shapes.js.map +1 -0
- package/dist/core/shared-host-policy.d.ts +6 -0
- package/dist/core/shared-host-policy.d.ts.map +1 -0
- package/dist/core/shared-host-policy.js +7 -0
- package/dist/core/shared-host-policy.js.map +1 -0
- package/dist/core/terminal-settings.d.ts +22 -0
- package/dist/core/terminal-settings.d.ts.map +1 -0
- package/dist/core/terminal-settings.js +2 -0
- package/dist/core/terminal-settings.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts +4 -4
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +27 -11
- package/dist/main.js.map +1 -1
- package/dist/modes/app-server/daemon/process.d.ts +13 -2
- package/dist/modes/app-server/daemon/process.d.ts.map +1 -1
- package/dist/modes/app-server/daemon/process.js +58 -12
- package/dist/modes/app-server/daemon/process.js.map +1 -1
- package/dist/modes/app-server/daemon.js +65 -7
- package/dist/modes/app-server/daemon.js.map +1 -1
- package/dist/modes/index.d.ts +1 -1
- package/dist/modes/index.d.ts.map +1 -1
- package/dist/modes/index.js +1 -1
- package/dist/modes/index.js.map +1 -1
- package/dist/modes/interactive/interactive-host-runtime.d.ts +84 -1
- package/dist/modes/interactive/interactive-host-runtime.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-host-runtime.js +435 -112
- package/dist/modes/interactive/interactive-host-runtime.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +11 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +59 -6
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/tips/catalog/ethos-tips.js +1 -1
- package/dist/modes/interactive/tips/catalog/ethos-tips.js.map +1 -1
- package/dist/modes/rpc/connection-handler.d.ts +12 -5
- package/dist/modes/rpc/connection-handler.d.ts.map +1 -1
- package/dist/modes/rpc/connection-handler.js +180 -25
- package/dist/modes/rpc/connection-handler.js.map +1 -1
- package/dist/modes/rpc/custom-capability.d.ts +2 -0
- package/dist/modes/rpc/custom-capability.d.ts.map +1 -1
- package/dist/modes/rpc/custom-capability.js +2 -0
- package/dist/modes/rpc/custom-capability.js.map +1 -1
- package/dist/modes/rpc/host-ensure.d.ts +17 -0
- package/dist/modes/rpc/host-ensure.d.ts.map +1 -1
- package/dist/modes/rpc/host-ensure.js +150 -23
- package/dist/modes/rpc/host-ensure.js.map +1 -1
- package/dist/modes/rpc/host-lifecycle.d.ts +54 -0
- package/dist/modes/rpc/host-lifecycle.d.ts.map +1 -1
- package/dist/modes/rpc/host-lifecycle.js +259 -69
- package/dist/modes/rpc/host-lifecycle.js.map +1 -1
- package/dist/modes/rpc/host-watchdog.d.ts +2 -2
- package/dist/modes/rpc/host-watchdog.d.ts.map +1 -1
- package/dist/modes/rpc/host-watchdog.js +89 -21
- package/dist/modes/rpc/host-watchdog.js.map +1 -1
- package/dist/modes/rpc/multi-session-host.d.ts +38 -0
- package/dist/modes/rpc/multi-session-host.d.ts.map +1 -1
- package/dist/modes/rpc/multi-session-host.js +149 -61
- package/dist/modes/rpc/multi-session-host.js.map +1 -1
- package/dist/modes/rpc/ownership-safe-lock.d.ts +14 -0
- package/dist/modes/rpc/ownership-safe-lock.d.ts.map +1 -0
- package/dist/modes/rpc/ownership-safe-lock.js +87 -0
- package/dist/modes/rpc/ownership-safe-lock.js.map +1 -0
- package/dist/modes/rpc/rpc-client.d.ts +13 -2
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +46 -12
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +21 -3
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js +1 -0
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/modes/rpc/session-binding.d.ts +2 -1
- package/dist/modes/rpc/session-binding.d.ts.map +1 -1
- package/dist/modes/rpc/session-binding.js +1 -0
- package/dist/modes/rpc/session-binding.js.map +1 -1
- package/dist/modes/rpc/session-command-router.d.ts +54 -1
- package/dist/modes/rpc/session-command-router.d.ts.map +1 -1
- package/dist/modes/rpc/session-command-router.js +180 -3
- package/dist/modes/rpc/session-command-router.js.map +1 -1
- package/dist/modes/rpc/session-event-writer.d.ts +18 -0
- package/dist/modes/rpc/session-event-writer.d.ts.map +1 -1
- package/dist/modes/rpc/session-event-writer.js +88 -8
- package/dist/modes/rpc/session-event-writer.js.map +1 -1
- package/dist/modes/rpc/session-registry.d.ts +11 -1
- package/dist/modes/rpc/session-registry.d.ts.map +1 -1
- package/dist/modes/rpc/session-registry.js +25 -0
- package/dist/modes/rpc/session-registry.js.map +1 -1
- package/dist/modes/rpc/socket-transport.d.ts +13 -0
- package/dist/modes/rpc/socket-transport.d.ts.map +1 -0
- package/dist/modes/rpc/socket-transport.js +92 -0
- package/dist/modes/rpc/socket-transport.js.map +1 -0
- package/dist/modes/rpc/widget-line-renderer.d.ts +17 -0
- package/dist/modes/rpc/widget-line-renderer.d.ts.map +1 -0
- package/dist/modes/rpc/widget-line-renderer.js +73 -0
- package/dist/modes/rpc/widget-line-renderer.js.map +1 -0
- package/dist/utils/fs-watch.d.ts.map +1 -1
- package/dist/utils/fs-watch.js +11 -2
- package/dist/utils/fs-watch.js.map +1 -1
- package/docs/app-server.md +2 -2
- package/docs/containerization.md +2 -2
- package/docs/development.md +7 -7
- package/docs/extensions.md +5 -5
- package/docs/grok-neo.md +1 -1
- package/docs/index.md +1 -1
- package/docs/packages.md +2 -2
- package/docs/quickstart.md +4 -4
- package/docs/release-guide.md +21 -21
- package/docs/rpc.md +83 -6
- package/docs/sdk.md +1 -1
- package/docs/settings.md +4 -4
- package/docs/skills.md +2 -2
- package/docs/terminal-tools.md +1 -1
- package/docs/termux.md +1 -1
- package/docs/tui.md +1 -1
- package/examples/AGENTS.md +1 -1
- package/examples/sdk/README.md +1 -1
- package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +52 -0
- package/node_modules/@code-yeongyu/senpi-codemode/README.md +2 -2
- package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
- package/node_modules/@code-yeongyu/senpi-codemode/src/extension/skill-contribution.ts +71 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/index.ts +3 -1
- package/node_modules/@code-yeongyu/senpi-codemode/src/skill/bun-1-4/SKILL.md +44 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/skill/bun-1-4/references/breaking-changes.md +75 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/skill/bun-1-4/references/build.md +114 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/skill/bun-1-4/references/dev-tooling.md +34 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/skill/bun-1-4/references/http-networking.md +113 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/skill/bun-1-4/references/install.md +93 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/skill/bun-1-4/references/node-compat-platforms.md +36 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/skill/bun-1-4/references/performance.md +33 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/skill/bun-1-4/references/runtime-apis.md +156 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/skill/bun-1-4/references/security.md +52 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/skill/bun-1-4/references/test.md +103 -0
- package/node_modules/@earendil-works/pi-agent-core/README.md +3 -0
- package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
- package/node_modules/@earendil-works/pi-ai/README.md +6 -3
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js +24 -7
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.d.ts +7 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.js +316 -2
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-conversation-rotation.d.ts +4 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-conversation-rotation.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-conversation-rotation.js +23 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-conversation-rotation.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.d.ts +24 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js +20 -2
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.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/amazon-bedrock.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/anthropic.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/google.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/groq.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/nvidia.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/opengateway.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/vercel-ai-gateway.json +1 -1
- package/node_modules/@earendil-works/pi-ai/package.json +2 -2
- package/node_modules/@earendil-works/pi-pty/dist/screen-operations.d.ts +42 -0
- package/node_modules/@earendil-works/pi-pty/dist/screen-operations.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-pty/dist/screen-operations.js +34 -0
- package/node_modules/@earendil-works/pi-pty/dist/screen-operations.js.map +1 -0
- package/node_modules/@earendil-works/pi-pty/dist/screen-text.d.ts +8 -0
- package/node_modules/@earendil-works/pi-pty/dist/screen-text.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-pty/dist/screen-text.js +51 -0
- package/node_modules/@earendil-works/pi-pty/dist/screen-text.js.map +1 -0
- package/node_modules/@earendil-works/pi-pty/dist/screen.d.ts +45 -0
- package/node_modules/@earendil-works/pi-pty/dist/screen.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-pty/dist/screen.js +178 -55
- package/node_modules/@earendil-works/pi-pty/dist/screen.js.map +1 -1
- package/node_modules/@earendil-works/pi-pty/package.json +1 -1
- package/node_modules/@earendil-works/pi-telemetry/README.md +6 -3
- package/node_modules/@earendil-works/pi-telemetry/package.json +1 -1
- package/node_modules/@earendil-works/pi-tui/README.md +5 -4
- package/node_modules/@earendil-works/pi-tui/native/darwin/README.md +2 -2
- package/node_modules/@earendil-works/pi-tui/native/win32/README.md +2 -2
- package/node_modules/@earendil-works/pi-tui/package.json +1 -1
- package/package.json +7 -7
|
@@ -32,6 +32,13 @@ export declare const CURSOR_STREAM_HEALTH_HEARTBEAT_ONLY_THRESHOLD_MS: number;
|
|
|
32
32
|
export declare const CURSOR_TURN_END_DRAIN_TIMEOUT_MS = 5000;
|
|
33
33
|
/** Reduce caller-supplied headers to what this HTTP/2 request can legally carry. */
|
|
34
34
|
export declare function sanitizeCursorCallerHeaders(headers: Record<string, string> | undefined): Record<string, string>;
|
|
35
|
+
/** Size telemetry for the conversation caches (#1024 verification seam). */
|
|
36
|
+
export declare function getCursorConversationCacheStats(): {
|
|
37
|
+
conversations: number;
|
|
38
|
+
states: number;
|
|
39
|
+
blobBytes: number;
|
|
40
|
+
keys: string[];
|
|
41
|
+
};
|
|
35
42
|
export declare function frameConnectMessage(data: Uint8Array, flags?: number): Buffer;
|
|
36
43
|
/**
|
|
37
44
|
* Maps an opaque HTTP/2 negotiation failure into an actionable error. The
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cursor-agent.d.ts","sourceRoot":"","sources":["../../src/api/cursor-agent.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,KAAK,KAAK,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"cursor-agent.d.ts","sourceRoot":"","sources":["../../src/api/cursor-agent.ts"],"names":[],"mappings":"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"}
|
|
@@ -21,6 +21,7 @@ import { create, fromBinary, fromJson, toBinary, toJson } from "@bufbuild/protob
|
|
|
21
21
|
import { ValueSchema } from "@bufbuild/protobuf/wkt";
|
|
22
22
|
import { CURSOR_COMPOSER_PROMPT, isCursorComposerModel } from "../cursor/composer-prompt.js";
|
|
23
23
|
import { calculateCost } from "../models.js";
|
|
24
|
+
import { registerSessionResourceCleanup } from "../session-resources.js";
|
|
24
25
|
import { clearStreamingPartialJson, kCursorExecResolved, kStreamingBlockIndex, kStreamingBlockKind, kStreamingEnvelopeId, kStreamingLastParseLen, kStreamingPartialJson, } from "../utils/block-symbols.js";
|
|
25
26
|
import { AssistantMessageEventStream } from "../utils/event-stream.js";
|
|
26
27
|
import { providerHeadersToRecord } from "../utils/headers.js";
|
|
@@ -103,6 +104,294 @@ const NOT_IMPLEMENTED = "Not implemented by this client";
|
|
|
103
104
|
/** Bare gRPC `resource_exhausted` end-streams (also inside a Connect error message). */
|
|
104
105
|
const conversationStateCache = new Map();
|
|
105
106
|
const conversationBlobStores = new Map();
|
|
107
|
+
/** Cache key -> the senpi session that owns it, so session teardown can evict. */
|
|
108
|
+
const conversationCacheKeySessions = new Map();
|
|
109
|
+
/**
|
|
110
|
+
* Defensive ceiling on how many conversations stay cached (#1024), enforced
|
|
111
|
+
* PER OWNING SESSION: the maps are process-global, so a global cap would let
|
|
112
|
+
* one session's churn forget another session's live conversation key (its
|
|
113
|
+
* retry/resume then re-enters with empty state and silently loses history).
|
|
114
|
+
* Eviction is FIFO by first use within the overflowing session, never touching
|
|
115
|
+
* another session's keys nor a conversation with a request in flight.
|
|
116
|
+
*/
|
|
117
|
+
const DEFAULT_CONVERSATION_CACHE_LIMIT = 64;
|
|
118
|
+
/**
|
|
119
|
+
* Defensive ceiling on the bytes one conversation's blob store may retain.
|
|
120
|
+
* Blobs are content-addressed and every live turn's history is re-stored each
|
|
121
|
+
* request, so evicting from the cold end only drops blobs no longer referenced
|
|
122
|
+
* by the rebuilt conversation state. Blobs the in-flight request references are
|
|
123
|
+
* pinned for the duration of the stream, because the server resolves them by id
|
|
124
|
+
* mid-turn and an evicted id would come back as an empty blob (silent context
|
|
125
|
+
* loss or a failed request).
|
|
126
|
+
*/
|
|
127
|
+
const DEFAULT_CONVERSATION_BLOB_LIMIT_BYTES = 256 * 1024 * 1024;
|
|
128
|
+
/**
|
|
129
|
+
* Ceiling on the blob bytes ALL cached conversations may retain in one process.
|
|
130
|
+
* The per-conversation cap alone multiplies out to (count cap x byte cap) per
|
|
131
|
+
* session, so this is the number that actually bounds the process. Trimming is
|
|
132
|
+
* cold-conversation-first and never touches a live conversation or a pinned
|
|
133
|
+
* blob, so it can only drop history that a later turn re-stores from
|
|
134
|
+
* `context.messages` anyway.
|
|
135
|
+
*/
|
|
136
|
+
const DEFAULT_CONVERSATION_TOTAL_BLOB_LIMIT_BYTES = 1024 * 1024 * 1024;
|
|
137
|
+
function readPositiveIntEnv(raw, fallback) {
|
|
138
|
+
const parsed = Number(raw);
|
|
139
|
+
return Number.isFinite(parsed) && parsed > 0 ? Math.floor(parsed) : fallback;
|
|
140
|
+
}
|
|
141
|
+
function conversationCacheLimit() {
|
|
142
|
+
return readPositiveIntEnv(process.env.PI_CURSOR_CONVERSATION_CACHE_LIMIT, DEFAULT_CONVERSATION_CACHE_LIMIT);
|
|
143
|
+
}
|
|
144
|
+
function conversationBlobLimitBytes() {
|
|
145
|
+
return readPositiveIntEnv(process.env.PI_CURSOR_CONVERSATION_BLOB_LIMIT_BYTES, DEFAULT_CONVERSATION_BLOB_LIMIT_BYTES);
|
|
146
|
+
}
|
|
147
|
+
function conversationTotalBlobLimitBytes() {
|
|
148
|
+
return readPositiveIntEnv(process.env.PI_CURSOR_CONVERSATION_TOTAL_BLOB_LIMIT_BYTES, DEFAULT_CONVERSATION_TOTAL_BLOB_LIMIT_BYTES);
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* A conversation's blob store with byte accounting, true LRU ordering and
|
|
152
|
+
* pinning for the request currently being built or streamed.
|
|
153
|
+
*
|
|
154
|
+
* Both `set` and `get` re-insert the key, so iteration order is least-recently
|
|
155
|
+
* used first: the cold end is the dead weight (pre-compaction turns, superseded
|
|
156
|
+
* server pushes) while everything this turn touched sits at the hot end.
|
|
157
|
+
*
|
|
158
|
+
* While a request holds pins (`beginRequestPins` .. `releaseRequestPins`),
|
|
159
|
+
* every blob it stores or the server reads back is pinned and exempt from cap
|
|
160
|
+
* eviction. If the pinned set alone exceeds the budget the store stays
|
|
161
|
+
* temporarily over budget and logs once, rather than answering the server's
|
|
162
|
+
* `getBlobArgs` with an empty blob mid-turn; releasing the pins trims it back.
|
|
163
|
+
*/
|
|
164
|
+
class ConversationBlobStore extends Map {
|
|
165
|
+
constructor() {
|
|
166
|
+
super(...arguments);
|
|
167
|
+
this.blobBytes = 0;
|
|
168
|
+
this.pinnedKeys = new Set();
|
|
169
|
+
/** Nesting depth of in-flight requests pinning into this store. */
|
|
170
|
+
this.pinHolders = 0;
|
|
171
|
+
this.warnedOverBudget = false;
|
|
172
|
+
}
|
|
173
|
+
set(key, value) {
|
|
174
|
+
const previous = super.get(key);
|
|
175
|
+
if (previous !== undefined) {
|
|
176
|
+
this.blobBytes -= previous.byteLength;
|
|
177
|
+
super.delete(key);
|
|
178
|
+
}
|
|
179
|
+
this.blobBytes += value.byteLength;
|
|
180
|
+
super.set(key, value);
|
|
181
|
+
if (this.pinHolders > 0)
|
|
182
|
+
this.pinnedKeys.add(key);
|
|
183
|
+
this.trimToBudget();
|
|
184
|
+
return this;
|
|
185
|
+
}
|
|
186
|
+
get(key) {
|
|
187
|
+
const value = super.get(key);
|
|
188
|
+
if (value === undefined)
|
|
189
|
+
return undefined;
|
|
190
|
+
// Recency promotion: a blob the server just asked for is live context, so
|
|
191
|
+
// it must not sit at the eviction end of the map.
|
|
192
|
+
super.delete(key);
|
|
193
|
+
super.set(key, value);
|
|
194
|
+
if (this.pinHolders > 0)
|
|
195
|
+
this.pinnedKeys.add(key);
|
|
196
|
+
return value;
|
|
197
|
+
}
|
|
198
|
+
delete(key) {
|
|
199
|
+
const existing = super.get(key);
|
|
200
|
+
this.pinnedKeys.delete(key);
|
|
201
|
+
if (existing === undefined)
|
|
202
|
+
return super.delete(key);
|
|
203
|
+
this.blobBytes -= existing.byteLength;
|
|
204
|
+
return super.delete(key);
|
|
205
|
+
}
|
|
206
|
+
clear() {
|
|
207
|
+
this.blobBytes = 0;
|
|
208
|
+
this.pinnedKeys.clear();
|
|
209
|
+
super.clear();
|
|
210
|
+
}
|
|
211
|
+
get totalBytes() {
|
|
212
|
+
return this.blobBytes;
|
|
213
|
+
}
|
|
214
|
+
get pinnedCount() {
|
|
215
|
+
return this.pinnedKeys.size;
|
|
216
|
+
}
|
|
217
|
+
/** Starts pinning everything the request touches; balanced by `releaseRequestPins`. */
|
|
218
|
+
beginRequestPins() {
|
|
219
|
+
this.pinHolders += 1;
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Evicts unpinned blobs, least recently used first, until at most `keepBytes`
|
|
223
|
+
* remain in this store. Returns the bytes actually released.
|
|
224
|
+
*/
|
|
225
|
+
shedUnpinnedBytes(keepBytes) {
|
|
226
|
+
let released = 0;
|
|
227
|
+
for (const [key, value] of this) {
|
|
228
|
+
if (this.blobBytes <= keepBytes)
|
|
229
|
+
break;
|
|
230
|
+
if (this.pinnedKeys.has(key))
|
|
231
|
+
continue;
|
|
232
|
+
this.blobBytes -= value.byteLength;
|
|
233
|
+
released += value.byteLength;
|
|
234
|
+
super.delete(key);
|
|
235
|
+
}
|
|
236
|
+
return released;
|
|
237
|
+
}
|
|
238
|
+
/** Drops this request's pins once its stream settled, then re-applies the cap. */
|
|
239
|
+
releaseRequestPins() {
|
|
240
|
+
if (this.pinHolders === 0)
|
|
241
|
+
return;
|
|
242
|
+
this.pinHolders -= 1;
|
|
243
|
+
if (this.pinHolders > 0)
|
|
244
|
+
return;
|
|
245
|
+
this.pinnedKeys.clear();
|
|
246
|
+
this.warnedOverBudget = false;
|
|
247
|
+
this.trimToBudget();
|
|
248
|
+
}
|
|
249
|
+
trimToBudget() {
|
|
250
|
+
const limit = conversationBlobLimitBytes();
|
|
251
|
+
if (this.blobBytes <= limit)
|
|
252
|
+
return;
|
|
253
|
+
for (const [key, value] of this) {
|
|
254
|
+
if (this.blobBytes <= limit)
|
|
255
|
+
break;
|
|
256
|
+
if (this.pinnedKeys.has(key))
|
|
257
|
+
continue;
|
|
258
|
+
this.blobBytes -= value.byteLength;
|
|
259
|
+
super.delete(key);
|
|
260
|
+
}
|
|
261
|
+
if (this.blobBytes <= limit || this.warnedOverBudget)
|
|
262
|
+
return;
|
|
263
|
+
this.warnedOverBudget = true;
|
|
264
|
+
// Breaking the live request is worse than holding its working set: report
|
|
265
|
+
// the overshoot and keep every pinned blob resolvable until the turn ends.
|
|
266
|
+
console.warn(`[cursor-agent] conversation blob store over budget: ${this.blobBytes} bytes pinned by the in-flight request exceed the ${limit} byte cap (${this.pinnedKeys.size} pinned blobs); the cap applies again when the stream settles`);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
function registerConversationCacheKey(sessionId, conversationId) {
|
|
270
|
+
if (!sessionId)
|
|
271
|
+
return;
|
|
272
|
+
conversationCacheKeySessions.set(conversationId, sessionId);
|
|
273
|
+
}
|
|
274
|
+
function forgetConversationCacheKey(conversationId) {
|
|
275
|
+
conversationStateCache.delete(conversationId);
|
|
276
|
+
conversationBlobStores.delete(conversationId);
|
|
277
|
+
conversationCacheKeySessions.delete(conversationId);
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Conversation keys with a request in flight. A live conversation is never a
|
|
281
|
+
* cap-eviction candidate: its state and blobs are what the running stream (and
|
|
282
|
+
* its retry/resume attempt) reads back.
|
|
283
|
+
*/
|
|
284
|
+
const liveConversationKeys = new Map();
|
|
285
|
+
function retainLiveConversation(conversationId) {
|
|
286
|
+
liveConversationKeys.set(conversationId, (liveConversationKeys.get(conversationId) ?? 0) + 1);
|
|
287
|
+
}
|
|
288
|
+
function releaseLiveConversation(conversationId) {
|
|
289
|
+
const holders = liveConversationKeys.get(conversationId);
|
|
290
|
+
if (holders === undefined)
|
|
291
|
+
return;
|
|
292
|
+
if (holders <= 1)
|
|
293
|
+
liveConversationKeys.delete(conversationId);
|
|
294
|
+
else
|
|
295
|
+
liveConversationKeys.set(conversationId, holders - 1);
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Trims the overflowing session's own conversations, oldest first. Keys owned by
|
|
299
|
+
* other sessions are untouchable (the maps are process-global but the budget is
|
|
300
|
+
* per session), and neither the newest key nor any conversation with a request
|
|
301
|
+
* in flight is evictable. Keys with no owning session (raw SDK use without
|
|
302
|
+
* `sessionId`) share one bucket keyed by `undefined`.
|
|
303
|
+
*/
|
|
304
|
+
function enforceConversationCacheLimit(newestKey, sessionId) {
|
|
305
|
+
const limit = conversationCacheLimit();
|
|
306
|
+
const owner = sessionId ?? conversationCacheKeySessions.get(newestKey);
|
|
307
|
+
const ownedKeys = [...conversationBlobStores.keys()].filter((key) => conversationCacheKeySessions.get(key) === owner);
|
|
308
|
+
let owned = ownedKeys.length;
|
|
309
|
+
for (const key of ownedKeys) {
|
|
310
|
+
if (owned <= limit)
|
|
311
|
+
return;
|
|
312
|
+
if (key === newestKey)
|
|
313
|
+
continue;
|
|
314
|
+
if (liveConversationKeys.has(key))
|
|
315
|
+
continue;
|
|
316
|
+
forgetConversationCacheKey(key);
|
|
317
|
+
owned -= 1;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Applies the process-global blob ceiling across every cached conversation.
|
|
322
|
+
* Cold conversations are shed first (least recently used key order); a live
|
|
323
|
+
* conversation is only shed after every cold one, and pinned blobs are never
|
|
324
|
+
* dropped, so an in-flight request keeps every id the server can ask for.
|
|
325
|
+
*/
|
|
326
|
+
function enforceConversationTotalBlobLimit() {
|
|
327
|
+
const limit = conversationTotalBlobLimitBytes();
|
|
328
|
+
let total = 0;
|
|
329
|
+
for (const store of conversationBlobStores.values())
|
|
330
|
+
total += store.totalBytes;
|
|
331
|
+
if (total <= limit)
|
|
332
|
+
return;
|
|
333
|
+
const cold = [];
|
|
334
|
+
const live = [];
|
|
335
|
+
for (const entry of conversationBlobStores) {
|
|
336
|
+
(liveConversationKeys.has(entry[0]) ? live : cold).push(entry);
|
|
337
|
+
}
|
|
338
|
+
for (const [key, store] of [...cold, ...live]) {
|
|
339
|
+
if (total <= limit)
|
|
340
|
+
break;
|
|
341
|
+
total -= store.shedUnpinnedBytes(Math.max(0, store.totalBytes - (total - limit)));
|
|
342
|
+
if (store.size === 0 && !liveConversationKeys.has(key))
|
|
343
|
+
forgetConversationCacheKey(key);
|
|
344
|
+
}
|
|
345
|
+
if (total <= limit)
|
|
346
|
+
return;
|
|
347
|
+
console.warn(`[cursor-agent] cursor conversation blobs total ${total} bytes over the ${limit} byte process ceiling; the remainder is pinned by in-flight requests and is released when their streams settle`);
|
|
348
|
+
}
|
|
349
|
+
function getOrCreateConversationBlobStore(conversationId, sessionId) {
|
|
350
|
+
const existing = conversationBlobStores.get(conversationId);
|
|
351
|
+
if (existing)
|
|
352
|
+
return existing;
|
|
353
|
+
const store = new ConversationBlobStore();
|
|
354
|
+
conversationBlobStores.set(conversationId, store);
|
|
355
|
+
enforceConversationCacheLimit(conversationId, sessionId);
|
|
356
|
+
return store;
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* Drops every cache entry owned by `sessionId`. With no session id this is a
|
|
360
|
+
* global teardown and clears everything (mirrors the codex WS cleanup).
|
|
361
|
+
*/
|
|
362
|
+
function releaseConversationCacheForSession(sessionId) {
|
|
363
|
+
if (sessionId === undefined) {
|
|
364
|
+
conversationStateCache.clear();
|
|
365
|
+
conversationBlobStores.clear();
|
|
366
|
+
conversationCacheKeySessions.clear();
|
|
367
|
+
// An explicit global teardown owns the bookkeeping too; a stale live hold
|
|
368
|
+
// would otherwise make a future same-named key permanently unevictable.
|
|
369
|
+
liveConversationKeys.clear();
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
for (const [key, owner] of conversationCacheKeySessions) {
|
|
373
|
+
if (owner !== sessionId)
|
|
374
|
+
continue;
|
|
375
|
+
conversationStateCache.delete(key);
|
|
376
|
+
conversationBlobStores.delete(key);
|
|
377
|
+
conversationCacheKeySessions.delete(key);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
registerSessionResourceCleanup((sessionId) => {
|
|
381
|
+
releaseConversationCacheForSession(sessionId);
|
|
382
|
+
});
|
|
383
|
+
/** Size telemetry for the conversation caches (#1024 verification seam). */
|
|
384
|
+
export function getCursorConversationCacheStats() {
|
|
385
|
+
let blobBytes = 0;
|
|
386
|
+
for (const store of conversationBlobStores.values())
|
|
387
|
+
blobBytes += store.totalBytes;
|
|
388
|
+
return {
|
|
389
|
+
conversations: conversationBlobStores.size,
|
|
390
|
+
states: conversationStateCache.size,
|
|
391
|
+
blobBytes,
|
|
392
|
+
keys: [...conversationBlobStores.keys()],
|
|
393
|
+
};
|
|
394
|
+
}
|
|
106
395
|
/**
|
|
107
396
|
* Base conversation id → rotated wire id. Cursor's backend can pin a
|
|
108
397
|
* per-conversation rejection (bare `resource_exhausted`, zero tokens) to one
|
|
@@ -285,6 +574,9 @@ export const stream = (model, context, options) => {
|
|
|
285
574
|
rejectH2 = reject;
|
|
286
575
|
});
|
|
287
576
|
let attemptSawCheckpoint = false;
|
|
577
|
+
// This attempt's live hold and blob pins, released when it settles.
|
|
578
|
+
let attemptLiveKey;
|
|
579
|
+
let attemptPinnedStore;
|
|
288
580
|
try {
|
|
289
581
|
const apiKey = options?.apiKey;
|
|
290
582
|
if (!apiKey) {
|
|
@@ -292,8 +584,15 @@ export const stream = (model, context, options) => {
|
|
|
292
584
|
}
|
|
293
585
|
baseConversationId = options?.conversationId ?? options?.sessionId ?? randomUUID();
|
|
294
586
|
conversationId = rotationStore().getWireId(baseConversationId);
|
|
295
|
-
|
|
296
|
-
|
|
587
|
+
registerConversationCacheKey(options?.sessionId, conversationId);
|
|
588
|
+
// Claim the conversation before the cap can see it: the count cap never
|
|
589
|
+
// evicts a live key, and every blob this attempt touches stays pinned
|
|
590
|
+
// until the stream settles.
|
|
591
|
+
attemptLiveKey = conversationId;
|
|
592
|
+
retainLiveConversation(conversationId);
|
|
593
|
+
const blobStore = getOrCreateConversationBlobStore(conversationId, options?.sessionId);
|
|
594
|
+
attemptPinnedStore = blobStore;
|
|
595
|
+
blobStore.beginRequestPins();
|
|
297
596
|
const cachedState = conversationStateCache.get(conversationId);
|
|
298
597
|
const { requestBytes, conversationState, requestedModel, modelDetails } = await buildGrpcRequest(model, context, options, {
|
|
299
598
|
conversationId,
|
|
@@ -306,6 +605,9 @@ export const stream = (model, context, options) => {
|
|
|
306
605
|
pinnedRequestedModel ??= requestedModel;
|
|
307
606
|
pinnedModelDetails ??= modelDetails;
|
|
308
607
|
conversationStateCache.set(conversationId, conversationState);
|
|
608
|
+
// This request's working set is pinned now, so the process ceiling can
|
|
609
|
+
// reclaim from cold conversations without touching what it needs.
|
|
610
|
+
enforceConversationTotalBlobLimit();
|
|
309
611
|
const requestContextTools = buildMcpToolDefinitions(context.tools);
|
|
310
612
|
const baseUrl = model.baseUrl || CURSOR_API_URL;
|
|
311
613
|
const requestPath = "/agent.v1.AgentService/Run";
|
|
@@ -625,6 +927,13 @@ export const stream = (model, context, options) => {
|
|
|
625
927
|
const blobs = conversationBlobStores.get(conversationId);
|
|
626
928
|
if (blobs)
|
|
627
929
|
conversationBlobStores.set(decision.wireId, blobs);
|
|
930
|
+
registerConversationCacheKey(options?.sessionId, decision.wireId);
|
|
931
|
+
enforceConversationCacheLimit(decision.wireId, options?.sessionId);
|
|
932
|
+
// The rotated key fully replaces the old one: later attempts
|
|
933
|
+
// resolve through rotationStore().getWireId, so keeping the
|
|
934
|
+
// pre-rotation entries is a pure leak (#1024).
|
|
935
|
+
if (decision.wireId !== conversationId)
|
|
936
|
+
forgetConversationCacheKey(conversationId);
|
|
628
937
|
retryAttempt = true;
|
|
629
938
|
}
|
|
630
939
|
else {
|
|
@@ -640,6 +949,11 @@ export const stream = (model, context, options) => {
|
|
|
640
949
|
}
|
|
641
950
|
}
|
|
642
951
|
finally {
|
|
952
|
+
attemptPinnedStore?.releaseRequestPins();
|
|
953
|
+
if (attemptLiveKey !== undefined)
|
|
954
|
+
releaseLiveConversation(attemptLiveKey);
|
|
955
|
+
if (attemptPinnedStore)
|
|
956
|
+
enforceConversationTotalBlobLimit();
|
|
643
957
|
if (heartbeatTimer) {
|
|
644
958
|
clearInterval(heartbeatTimer);
|
|
645
959
|
heartbeatTimer = null;
|