@code-yeongyu/senpi 2026.9.10 → 2026.9.12-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 +123 -0
- package/dist/core/agent-session-runtime.d.ts.map +1 -1
- package/dist/core/agent-session-runtime.js +5 -1
- package/dist/core/agent-session-runtime.js.map +1 -1
- package/dist/core/agent-session.d.ts +70 -9
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +183 -140
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-storage.d.ts +2 -0
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +49 -17
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/brand.d.ts +5 -0
- package/dist/core/brand.d.ts.map +1 -1
- package/dist/core/brand.js +13 -0
- package/dist/core/brand.js.map +1 -1
- package/dist/core/changelog-source.d.ts +8 -0
- package/dist/core/changelog-source.d.ts.map +1 -0
- package/dist/core/changelog-source.js +19 -0
- package/dist/core/changelog-source.js.map +1 -0
- package/dist/core/credential-accounts.d.ts +3 -0
- package/dist/core/credential-accounts.d.ts.map +1 -1
- package/dist/core/credential-accounts.js +20 -1
- package/dist/core/credential-accounts.js.map +1 -1
- package/dist/core/credential-pool/classify.d.ts.map +1 -1
- package/dist/core/credential-pool/classify.js +8 -0
- package/dist/core/credential-pool/classify.js.map +1 -1
- package/dist/core/cursor-history-admission.d.ts +50 -0
- package/dist/core/cursor-history-admission.d.ts.map +1 -0
- package/dist/core/cursor-history-admission.js +130 -0
- package/dist/core/cursor-history-admission.js.map +1 -0
- package/dist/core/extensions/builtin/account/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/account/index.js +7 -3
- package/dist/core/extensions/builtin/account/index.js.map +1 -1
- package/dist/core/extensions/builtin/account-display-name.d.ts +7 -0
- package/dist/core/extensions/builtin/account-display-name.d.ts.map +1 -0
- package/dist/core/extensions/builtin/account-display-name.js +40 -0
- package/dist/core/extensions/builtin/account-display-name.js.map +1 -0
- package/dist/core/extensions/builtin/ask-user/format.d.ts.map +1 -1
- package/dist/core/extensions/builtin/ask-user/format.js +7 -2
- package/dist/core/extensions/builtin/ask-user/format.js.map +1 -1
- package/dist/core/extensions/builtin/ask-user/pending.d.ts.map +1 -1
- package/dist/core/extensions/builtin/ask-user/pending.js +3 -0
- package/dist/core/extensions/builtin/ask-user/pending.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/account-command.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/account-command.js +21 -9
- package/dist/core/extensions/builtin/claude-sdk-oauth/account-command.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/account-management.d.ts +1 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/account-management.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/account-management.js +11 -6
- package/dist/core/extensions/builtin/claude-sdk-oauth/account-management.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/accounts.d.ts +9 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/accounts.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/accounts.js +10 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/accounts.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-binding.js +3 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-binding.js.map +1 -1
- 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 +19 -10
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-reattach.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/settings.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/settings.js +3 -9
- package/dist/core/extensions/builtin/claude-sdk-oauth/settings.js.map +1 -1
- package/dist/core/extensions/builtin/config-reload/routine-settings.d.ts.map +1 -1
- package/dist/core/extensions/builtin/config-reload/routine-settings.js +1 -0
- package/dist/core/extensions/builtin/config-reload/routine-settings.js.map +1 -1
- package/dist/core/extensions/builtin/cursor-cli-oauth/account-command.d.ts.map +1 -1
- package/dist/core/extensions/builtin/cursor-cli-oauth/account-command.js +5 -3
- package/dist/core/extensions/builtin/cursor-cli-oauth/account-command.js.map +1 -1
- package/dist/core/extensions/builtin/cursor-cli-oauth/accounts.d.ts +1 -0
- package/dist/core/extensions/builtin/cursor-cli-oauth/accounts.d.ts.map +1 -1
- package/dist/core/extensions/builtin/cursor-cli-oauth/accounts.js.map +1 -1
- package/dist/core/extensions/builtin/cursor-cli-oauth/models.d.ts.map +1 -1
- package/dist/core/extensions/builtin/cursor-cli-oauth/models.js +2 -1
- package/dist/core/extensions/builtin/cursor-cli-oauth/models.js.map +1 -1
- package/dist/core/extensions/builtin/cursor-cli-oauth/settings.d.ts.map +1 -1
- package/dist/core/extensions/builtin/cursor-cli-oauth/settings.js +3 -9
- package/dist/core/extensions/builtin/cursor-cli-oauth/settings.js.map +1 -1
- package/dist/core/extensions/builtin/goal/agent-end-continuation.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/agent-end-continuation.js +13 -1
- package/dist/core/extensions/builtin/goal/agent-end-continuation.js.map +1 -1
- package/dist/core/extensions/builtin/goal/prompt.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/prompt.js +11 -8
- package/dist/core/extensions/builtin/goal/prompt.js.map +1 -1
- package/dist/core/extensions/builtin/goal/terminal-provider-error.d.ts +1 -0
- package/dist/core/extensions/builtin/goal/terminal-provider-error.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/terminal-provider-error.js +28 -0
- package/dist/core/extensions/builtin/goal/terminal-provider-error.js.map +1 -1
- package/dist/core/extensions/builtin/goal/todo-gate.js +2 -2
- package/dist/core/extensions/builtin/goal/todo-gate.js.map +1 -1
- package/dist/core/extensions/builtin/goal/tool-registration.js +2 -2
- package/dist/core/extensions/builtin/goal/tool-registration.js.map +1 -1
- package/dist/core/extensions/builtin/gpt-account.d.ts.map +1 -1
- package/dist/core/extensions/builtin/gpt-account.js +19 -8
- package/dist/core/extensions/builtin/gpt-account.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/deepseek-v4-1-flash.d.ts +3 -0
- package/dist/core/extensions/builtin/prompt-preset/deepseek-v4-1-flash.d.ts.map +1 -0
- package/dist/core/extensions/builtin/prompt-preset/deepseek-v4-1-flash.js +19 -0
- package/dist/core/extensions/builtin/prompt-preset/deepseek-v4-1-flash.js.map +1 -0
- package/dist/core/extensions/builtin/prompt-preset/gpt-6-astra.d.ts +6 -6
- package/dist/core/extensions/builtin/prompt-preset/gpt-6-astra.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/gpt-6-astra.js +26 -7
- package/dist/core/extensions/builtin/prompt-preset/gpt-6-astra.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/presets.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/presets.js +29 -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/high-reasoning-warning.d.ts.map +1 -1
- package/dist/core/high-reasoning-warning.js +5 -1
- package/dist/core/high-reasoning-warning.js.map +1 -1
- package/dist/core/manual-continue.d.ts +14 -0
- package/dist/core/manual-continue.d.ts.map +1 -1
- package/dist/core/manual-continue.js +13 -0
- package/dist/core/manual-continue.js.map +1 -1
- package/dist/core/model-runtime.d.ts.map +1 -1
- package/dist/core/model-runtime.js +2 -2
- package/dist/core/model-runtime.js.map +1 -1
- package/dist/core/remote-catalog-merge.d.ts +16 -0
- package/dist/core/remote-catalog-merge.d.ts.map +1 -0
- package/dist/core/remote-catalog-merge.js +75 -0
- package/dist/core/remote-catalog-merge.js.map +1 -0
- package/dist/core/remote-catalog-provider.d.ts +3 -0
- package/dist/core/remote-catalog-provider.d.ts.map +1 -1
- package/dist/core/remote-catalog-provider.js +12 -40
- package/dist/core/remote-catalog-provider.js.map +1 -1
- package/dist/core/session-entry-materializer.d.ts +12 -0
- package/dist/core/session-entry-materializer.d.ts.map +1 -0
- package/dist/core/session-entry-materializer.js +26 -0
- package/dist/core/session-entry-materializer.js.map +1 -0
- package/dist/core/session-manager.d.ts +38 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +60 -21
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/session-write-reservation.d.ts +9 -0
- package/dist/core/session-write-reservation.d.ts.map +1 -1
- package/dist/core/session-write-reservation.js +33 -0
- package/dist/core/session-write-reservation.js.map +1 -1
- package/dist/core/settings-manager.d.ts +3 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +10 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/modes/app-server/daemon/process.d.ts +6 -1
- package/dist/modes/app-server/daemon/process.d.ts.map +1 -1
- package/dist/modes/app-server/daemon/process.js +23 -4
- package/dist/modes/app-server/daemon/process.js.map +1 -1
- package/dist/modes/app-server/protocol/account.d.ts +2 -0
- package/dist/modes/app-server/protocol/account.d.ts.map +1 -1
- package/dist/modes/app-server/protocol/account.js.map +1 -1
- package/dist/modes/interactive/components/ask-user-async-widget.d.ts +2 -0
- package/dist/modes/interactive/components/ask-user-async-widget.d.ts.map +1 -1
- package/dist/modes/interactive/components/ask-user-async-widget.js +17 -1
- package/dist/modes/interactive/components/ask-user-async-widget.js.map +1 -1
- package/dist/modes/interactive/components/ask-user-question-keys.d.ts +1 -1
- package/dist/modes/interactive/components/ask-user-question-keys.d.ts.map +1 -1
- package/dist/modes/interactive/components/ask-user-question-keys.js +65 -17
- package/dist/modes/interactive/components/ask-user-question-keys.js.map +1 -1
- package/dist/modes/interactive/components/ask-user-question-render.d.ts +2 -1
- package/dist/modes/interactive/components/ask-user-question-render.d.ts.map +1 -1
- package/dist/modes/interactive/components/ask-user-question-render.js +39 -9
- package/dist/modes/interactive/components/ask-user-question-render.js.map +1 -1
- package/dist/modes/interactive/components/ask-user-question-state.d.ts +14 -4
- package/dist/modes/interactive/components/ask-user-question-state.d.ts.map +1 -1
- package/dist/modes/interactive/components/ask-user-question-state.js +63 -6
- package/dist/modes/interactive/components/ask-user-question-state.js.map +1 -1
- package/dist/modes/interactive/components/ask-user-question.d.ts +2 -0
- package/dist/modes/interactive/components/ask-user-question.d.ts.map +1 -1
- package/dist/modes/interactive/components/ask-user-question.js +27 -14
- package/dist/modes/interactive/components/ask-user-question.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +51 -19
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/login-dialog.d.ts +11 -0
- package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/dist/modes/interactive/components/login-dialog.js +29 -9
- package/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/tree-selector.js +7 -0
- package/dist/modes/interactive/components/tree-selector.js.map +1 -1
- package/dist/modes/interactive/help-content.d.ts.map +1 -1
- package/dist/modes/interactive/help-content.js +4 -0
- package/dist/modes/interactive/help-content.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +13 -4
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +46 -17
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/tips/catalog/input-tips.js +1 -1
- package/dist/modes/interactive/tips/catalog/input-tips.js.map +1 -1
- package/dist/modes/rpc/connection-handler.d.ts.map +1 -1
- package/dist/modes/rpc/connection-handler.js +3 -1
- package/dist/modes/rpc/connection-handler.js.map +1 -1
- package/dist/modes/rpc/connection-question-bridge.js +1 -1
- package/dist/modes/rpc/connection-question-bridge.js.map +1 -1
- package/dist/modes/rpc/host-ensure.d.ts.map +1 -1
- package/dist/modes/rpc/host-ensure.js +33 -11
- package/dist/modes/rpc/host-ensure.js.map +1 -1
- package/dist/modes/rpc/host-lifecycle.d.ts +14 -0
- package/dist/modes/rpc/host-lifecycle.d.ts.map +1 -1
- package/dist/modes/rpc/host-lifecycle.js +31 -5
- package/dist/modes/rpc/host-lifecycle.js.map +1 -1
- package/dist/modes/rpc/rpc-input-validation.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-input-validation.js +2 -0
- package/dist/modes/rpc/rpc-input-validation.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +4 -1
- 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-path-reservations.d.ts +30 -0
- package/dist/modes/rpc/session-path-reservations.d.ts.map +1 -0
- package/dist/modes/rpc/session-path-reservations.js +58 -0
- package/dist/modes/rpc/session-path-reservations.js.map +1 -0
- package/dist/modes/rpc/session-registry.d.ts +3 -1
- package/dist/modes/rpc/session-registry.d.ts.map +1 -1
- package/dist/modes/rpc/session-registry.js.map +1 -1
- package/dist/modes/rpc/session-worker-client.d.ts +10 -8
- package/dist/modes/rpc/session-worker-client.d.ts.map +1 -1
- package/dist/modes/rpc/session-worker-client.js +14 -23
- package/dist/modes/rpc/session-worker-client.js.map +1 -1
- package/dist/modes/rpc/session-worker-credit.d.ts +17 -0
- package/dist/modes/rpc/session-worker-credit.d.ts.map +1 -0
- package/dist/modes/rpc/session-worker-credit.js +39 -0
- package/dist/modes/rpc/session-worker-credit.js.map +1 -0
- package/dist/modes/rpc/session-worker-protocol.d.ts +10 -0
- package/dist/modes/rpc/session-worker-protocol.d.ts.map +1 -1
- package/dist/modes/rpc/session-worker-protocol.js +2 -0
- package/dist/modes/rpc/session-worker-protocol.js.map +1 -1
- package/dist/modes/rpc/session-worker-signals.d.ts +7 -0
- package/dist/modes/rpc/session-worker-signals.d.ts.map +1 -0
- package/dist/modes/rpc/session-worker-signals.js +19 -0
- package/dist/modes/rpc/session-worker-signals.js.map +1 -0
- package/dist/modes/rpc/session-worker.js +12 -16
- package/dist/modes/rpc/session-worker.js.map +1 -1
- package/dist/modes/rpc/worker-session-registry.d.ts +12 -0
- package/dist/modes/rpc/worker-session-registry.d.ts.map +1 -1
- package/dist/modes/rpc/worker-session-registry.js +51 -24
- package/dist/modes/rpc/worker-session-registry.js.map +1 -1
- package/dist/utils/changelog.d.ts +3 -1
- package/dist/utils/changelog.d.ts.map +1 -1
- package/dist/utils/changelog.js +89 -23
- package/dist/utils/changelog.js.map +1 -1
- package/dist/utils/paths.d.ts +5 -0
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +14 -1
- package/dist/utils/paths.js.map +1 -1
- package/docs/app-server.md +6 -0
- package/docs/extensions.md +19 -3
- package/docs/rpc.md +24 -6
- package/docs/settings.md +2 -1
- package/docs/tui.md +1 -1
- package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +52 -0
- package/node_modules/@code-yeongyu/senpi-codemode/README.md +5 -4
- package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
- package/node_modules/@code-yeongyu/senpi-codemode/src/output/streaming-output-buffer.ts +58 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/output/streaming-output.ts +9 -64
- package/node_modules/@code-yeongyu/senpi-codemode/src/prompt/eval-prompt-template.ts +1 -1
- package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent/measure.d.ts +11 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent/measure.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent/measure.js +18 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent/measure.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.d.ts +1 -1
- 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 +5 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/discovery.d.ts +19 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/discovery.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/discovery.js +135 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/discovery.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/frames.d.ts +23 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/frames.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/frames.js +71 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/frames.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/gen/cascade_pb.d.ts +1261 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/gen/cascade_pb.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/gen/cascade_pb.js +431 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/gen/cascade_pb.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/metadata.d.ts +42 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/metadata.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/metadata.js +68 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/metadata.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/paths.d.ts +43 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/paths.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/paths.js +43 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/paths.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/request.d.ts +36 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/request.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/request.js +158 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/request.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/stream-state.d.ts +26 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/stream-state.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/stream-state.js +145 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/stream-state.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/trailer.d.ts +16 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/trailer.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/trailer.js +69 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/trailer.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/types.d.ts +12 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/types.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/types.js +3 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/types.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/unary.d.ts +26 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/unary.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/unary.js +61 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/unary.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/wire.d.ts +8 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/wire.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/wire.js +8 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent/wire.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent.d.ts +22 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent.js +217 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent.lazy.d.ts +5 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent.lazy.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent.lazy.js +23 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/devin-agent.lazy.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/devin-callback.d.ts +25 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/devin-callback.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/devin-callback.js +124 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/devin-callback.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/devin-token.d.ts +18 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/devin-token.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/devin-token.js +101 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/devin-token.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/devin.d.ts +19 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/devin.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/devin.js +116 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/devin.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/kimi-coding.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/kimi-coding.js +5 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/kimi-coding.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/kimi-identity.d.ts +24 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/kimi-identity.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/kimi-identity.js +86 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/kimi-identity.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/load.d.ts +2 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/load.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/load.js +5 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/load.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/pool/slots.d.ts +51 -4
- package/node_modules/@earendil-works/pi-ai/dist/auth/pool/slots.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/pool/slots.js +196 -7
- package/node_modules/@earendil-works/pi-ai/dist/auth/pool/slots.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/resolve.d.ts +8 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/resolve.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/resolve.js +10 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/resolve.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/types.d.ts +9 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/types.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/types.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/bun-oauth.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/bun-oauth.js +2 -0
- package/node_modules/@earendil-works/pi-ai/dist/bun-oauth.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/compat.d.ts +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/compat.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/compat.js +3 -0
- package/node_modules/@earendil-works/pi-ai/dist/compat.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/cursor/context-limit-store.d.ts +32 -0
- package/node_modules/@earendil-works/pi-ai/dist/cursor/context-limit-store.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/cursor/context-limit-store.js +62 -0
- package/node_modules/@earendil-works/pi-ai/dist/cursor/context-limit-store.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/cursor/store-migration.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/cursor/store-migration.js +2 -1
- package/node_modules/@earendil-works/pi-ai/dist/cursor/store-migration.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js +4 -4
- package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/index.d.ts +1 -1
- 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 -1
- package/node_modules/@earendil-works/pi-ai/dist/index.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/model.d.ts +11 -1
- package/node_modules/@earendil-works/pi-ai/dist/model.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/model.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/models.d.ts +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/models.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/models.js +14 -5
- package/node_modules/@earendil-works/pi-ai/dist/models.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/all.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/all.js +2 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/all.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/cursor.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/cursor.js +2 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/cursor.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/baseten.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/huggingface.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode-go.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/venice.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/dist/providers/devin.d.ts +12 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/devin.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/devin.js +62 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/devin.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/devin.models.d.ts +12 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/devin.models.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/devin.models.js +37 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/devin.models.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/types.d.ts +3 -1
- package/node_modules/@earendil-works/pi-ai/dist/types.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/types.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/cursor-context-limit.d.ts +12 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/cursor-context-limit.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/cursor-context-limit.js +93 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/cursor-context-limit.js.map +1 -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 +4 -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/dist/dollar-invocation-autocomplete.d.ts +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/dollar-invocation-autocomplete.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/dollar-invocation-autocomplete.js +55 -16
- package/node_modules/@earendil-works/pi-tui/dist/dollar-invocation-autocomplete.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/package.json +1 -1
- package/package.json +7 -7
|
@@ -18,8 +18,9 @@ import { rm } from "node:fs/promises";
|
|
|
18
18
|
import { basename, dirname } from "node:path";
|
|
19
19
|
import { isDeepStrictEqual } from "node:util";
|
|
20
20
|
import { ProviderRetryWatchdogAbortError, prepareAgentToolCall } from "@earendil-works/pi-agent-core";
|
|
21
|
-
import { contentText,
|
|
21
|
+
import { contentText, providerNotConfiguredMessage, SERVER_FALLBACK_ABORTED_DIAGNOSTIC, } from "@earendil-works/pi-ai";
|
|
22
22
|
import { cleanupSessionResources, cursorOverflowCompactionSettings, isClassifierRefusal, isContextOverflow, isCursorPayloadResourceExhausted, isCursorQuotaResourceExhausted, isCursorZeroTokenResourceExhausted, isProviderStreamStallError, isProviderTimeoutError, isRecoverableLength, isRetryableAssistantError, modelsAreEqual, resetApiProviders, shouldRetryOverflowWithoutCompact, streamSimple, } from "@earendil-works/pi-ai/compat";
|
|
23
|
+
import { getCursorContextLimit } from "@earendil-works/pi-ai/utils/cursor-context-limit";
|
|
23
24
|
import { extract429RetryAfterMs, parseRetryAfterMsMarker } from "@earendil-works/pi-ai/utils/retry-hint";
|
|
24
25
|
import { retryBackoffDelayMs } from "@earendil-works/pi-ai/utils/retry-profile/backoff";
|
|
25
26
|
import { getAgentDir } from "../config.js";
|
|
@@ -37,12 +38,14 @@ import { calculateContextTokens, collectEntriesForBranchSummary, compact, estima
|
|
|
37
38
|
import { CompactionLifecycleCoordinator } from "./compaction/lifecycle.js";
|
|
38
39
|
import { isTurnStuckOnContextOverflow } from "./compaction/stuck-overflow.js";
|
|
39
40
|
import { isWarmSummaryAnchorValid } from "./compaction/warm-anchor.js";
|
|
41
|
+
import { admitCursorHistory, cursorAdmissionBudgetBytes } from "./cursor-history-admission.js";
|
|
40
42
|
import { DEFAULT_THINKING_LEVEL } from "./defaults.js";
|
|
41
43
|
import { buildDynamicSystemPrompt } from "./dynamic-prompt/index.js";
|
|
42
44
|
import { AssistantEditError, assertExpectedLeaf, assistantTextEquals, buildEditedAssistantMessage, SessionStreamingError, } from "./edited-assistant-message.js";
|
|
43
45
|
import { areExperimentalFeaturesEnabled } from "./experimental.js";
|
|
44
46
|
import { exportSessionToHtml } from "./export-html/index.js";
|
|
45
47
|
import { createToolHtmlRenderer } from "./export-html/tool-renderer.js";
|
|
48
|
+
import { CLAUDE_SDK_OAUTH_PROVIDER_ID } from "./extensions/builtin/claude-sdk-oauth/account-management.js";
|
|
46
49
|
import { ModelUsabilityBudgetError, projectModelUsabilityBudget, } from "./extensions/builtin/compaction/model-usability-budget.js";
|
|
47
50
|
import { resolveEffectiveReserveTokens, resolveReserveTokens, shouldTriggerCompaction, } from "./extensions/builtin/compaction/policy.js";
|
|
48
51
|
import { createResumeCompactionRequirement, } from "./extensions/builtin/compaction/resume-admission.js";
|
|
@@ -55,8 +58,8 @@ import { ExecuteToolError, ExtensionRunner, wrapRegisteredTools, } from "./exten
|
|
|
55
58
|
import { emitSessionShutdownEvent } from "./extensions/runner.js";
|
|
56
59
|
import { normalizeToolExposure, RUNTIME_EXTENSION_PATH } from "./extensions/types.js";
|
|
57
60
|
import { shouldWarnHighReasoning } from "./high-reasoning-warning.js";
|
|
58
|
-
import { MANUAL_CONTINUE_CUSTOM_TYPE, MANUAL_CONTINUE_DIRECTIVE } from "./manual-continue.js";
|
|
59
|
-
import {
|
|
61
|
+
import { isManualContinueSubmission, MANUAL_CONTINUE_CUSTOM_TYPE, MANUAL_CONTINUE_DIRECTIVE, } from "./manual-continue.js";
|
|
62
|
+
import { filterContextExcludedMessages } from "./messages.js";
|
|
60
63
|
import { ModelRegistry } from "./model-registry.js";
|
|
61
64
|
import { getModelNarrowingPatterns, resolveModelScope } from "./model-resolver.js";
|
|
62
65
|
import { PROMPT_CACHE_SAFE_WAIT_ENV, resolvePromptCacheSafeWaitSeconds } from "./prompt-cache-budget.js";
|
|
@@ -334,121 +337,11 @@ function isSameOverflowSource(message, model, upstreamModelId) {
|
|
|
334
337
|
const THINKING_LEVELS_WITH_MAX = ["off", "minimal", "low", "medium", "high", "xhigh", "max"];
|
|
335
338
|
/** Caps explicit skill expansion so one prompt cannot consume unbounded context. */
|
|
336
339
|
export const MAX_SKILL_EXPANSIONS_PER_PROMPT = 5;
|
|
337
|
-
/**
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
export
|
|
342
|
-
if (!Array.isArray(messages) || messages.length === 0)
|
|
343
|
-
return { messages, changed: false };
|
|
344
|
-
const segmenter = new Intl.Segmenter(undefined, { granularity: "grapheme" });
|
|
345
|
-
const markerChars = [...segmenter.segment(CURSOR_TRUNCATION_MARKER)].length;
|
|
346
|
-
const result = messages.slice();
|
|
347
|
-
let changed = false;
|
|
348
|
-
// Apply the per-result character cap first, independent of the aggregate wire cap.
|
|
349
|
-
for (let messageIndex = result.length - 1; messageIndex >= 0; messageIndex--) {
|
|
350
|
-
const message = result[messageIndex];
|
|
351
|
-
if (message.role !== "toolResult" || !Array.isArray(message.content))
|
|
352
|
-
continue;
|
|
353
|
-
let content = message.content;
|
|
354
|
-
for (let partIndex = content.length - 1; partIndex >= 0; partIndex--) {
|
|
355
|
-
const part = content[partIndex];
|
|
356
|
-
if (part.type === "image" && typeof part.data === "string")
|
|
357
|
-
continue;
|
|
358
|
-
if (part.type !== "text" || typeof part.text !== "string")
|
|
359
|
-
continue;
|
|
360
|
-
const graphemes = [...segmenter.segment(part.text)].map((item) => item.segment);
|
|
361
|
-
if (graphemes.length <= maxChars)
|
|
362
|
-
continue;
|
|
363
|
-
const kept = graphemes.slice(0, Math.max(0, maxChars - markerChars)).join("");
|
|
364
|
-
const nextText = kept + CURSOR_TRUNCATION_MARKER;
|
|
365
|
-
content = content === message.content ? content.slice() : content;
|
|
366
|
-
content[partIndex] = { ...part, text: nextText };
|
|
367
|
-
result[messageIndex] = { ...message, content };
|
|
368
|
-
changed = true;
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
const measure = (candidate) => {
|
|
372
|
-
const converted = convert(candidate);
|
|
373
|
-
const activeUserMessageIndex = converted.at(-1)?.role === "user" ? converted.length - 1 : -1;
|
|
374
|
-
return measureCursorHistorySerializedBytes(converted, activeUserMessageIndex);
|
|
375
|
-
};
|
|
376
|
-
const fits = (candidate = result) => measure(candidate) <= maxBytes;
|
|
377
|
-
if (fits())
|
|
378
|
-
return { messages: changed ? result : messages, changed };
|
|
379
|
-
// Empty the oldest result bodies. Search the monotonic prefix of candidates
|
|
380
|
-
// rather than serializing once for every result (admission must stay bounded).
|
|
381
|
-
const emptyToolResult = (message) => {
|
|
382
|
-
if (message.role !== "toolResult" || !Array.isArray(message.content))
|
|
383
|
-
return message;
|
|
384
|
-
const emptiedContent = message.content.map((part) => part.type === "text" ? { ...part, text: "" } : part.type === "image" ? { ...part, data: "" } : part);
|
|
385
|
-
const content = emptiedContent.filter((part, index) => {
|
|
386
|
-
if (index === 0)
|
|
387
|
-
return true;
|
|
388
|
-
const previous = emptiedContent[index - 1];
|
|
389
|
-
const empty = part.type === "text" ? part.text === "" : part.type === "image" && part.data === "";
|
|
390
|
-
const previousEmpty = previous.type === "text" ? previous.text === "" : previous.type === "image" && previous.data === "";
|
|
391
|
-
return !empty || !previousEmpty;
|
|
392
|
-
});
|
|
393
|
-
return { ...message, content };
|
|
394
|
-
};
|
|
395
|
-
const toolResultIndexes = result.flatMap((message, index) => message.role === "toolResult" && Array.isArray(message.content) ? [index] : []);
|
|
396
|
-
const withEmptyPrefix = (count) => {
|
|
397
|
-
const candidate = result.slice();
|
|
398
|
-
for (let i = 0; i < count; i++)
|
|
399
|
-
candidate[toolResultIndexes[i]] = emptyToolResult(candidate[toolResultIndexes[i]]);
|
|
400
|
-
return candidate;
|
|
401
|
-
};
|
|
402
|
-
let low = 0;
|
|
403
|
-
let high = toolResultIndexes.length;
|
|
404
|
-
while (low < high) {
|
|
405
|
-
const middle = Math.floor((low + high) / 2);
|
|
406
|
-
if (fits(withEmptyPrefix(middle + 1)))
|
|
407
|
-
high = middle;
|
|
408
|
-
else
|
|
409
|
-
low = middle + 1;
|
|
410
|
-
}
|
|
411
|
-
const emptyCount = Math.min(low + 1, toolResultIndexes.length);
|
|
412
|
-
if (emptyCount > 0) {
|
|
413
|
-
result.splice(0, result.length, ...withEmptyPrefix(emptyCount));
|
|
414
|
-
changed = true;
|
|
415
|
-
}
|
|
416
|
-
if (fits())
|
|
417
|
-
return { messages: changed ? result : messages, changed };
|
|
418
|
-
// If metadata alone exceeds the cap, discard the oldest complete turns. This
|
|
419
|
-
// search is also monotonic and avoids quadratic whole-history reserialization.
|
|
420
|
-
const turnRanges = [];
|
|
421
|
-
const isConvertedUser = (message) => convert([message])[0]?.role === "user";
|
|
422
|
-
for (let index = 0; index < result.length; index++) {
|
|
423
|
-
if (!isConvertedUser(result[index]))
|
|
424
|
-
continue;
|
|
425
|
-
const nextUser = result.findIndex((message, nextIndex) => nextIndex > index && isConvertedUser(message));
|
|
426
|
-
turnRanges.push([index, nextUser < 0 ? result.length : nextUser]);
|
|
427
|
-
}
|
|
428
|
-
const withoutTurns = (count) => {
|
|
429
|
-
if (count === 0)
|
|
430
|
-
return result;
|
|
431
|
-
const start = turnRanges[0]?.[0] ?? 0;
|
|
432
|
-
const end = turnRanges[count - 1]?.[1] ?? start;
|
|
433
|
-
return [...result.slice(0, start), ...result.slice(end)];
|
|
434
|
-
};
|
|
435
|
-
low = 0;
|
|
436
|
-
high = turnRanges.length;
|
|
437
|
-
while (low < high) {
|
|
438
|
-
const middle = Math.floor((low + high) / 2);
|
|
439
|
-
if (fits(withoutTurns(middle + 1)))
|
|
440
|
-
high = middle;
|
|
441
|
-
else
|
|
442
|
-
low = middle + 1;
|
|
443
|
-
}
|
|
444
|
-
const turnCount = Math.min(low + 1, turnRanges.length);
|
|
445
|
-
if (turnCount > 0) {
|
|
446
|
-
const next = withoutTurns(turnCount);
|
|
447
|
-
result.splice(0, result.length, ...next);
|
|
448
|
-
changed = true;
|
|
449
|
-
}
|
|
450
|
-
return { messages: changed ? result : messages, changed };
|
|
451
|
-
}
|
|
340
|
+
/**
|
|
341
|
+
* Cursor admission lives in its own module; the names stay exported here so
|
|
342
|
+
* existing importers keep resolving them.
|
|
343
|
+
*/
|
|
344
|
+
export { CURSOR_TOOL_RESULT_MAX_CHARS, truncateToolResultBodies } from "./cursor-history-admission.js";
|
|
452
345
|
// ============================================================================
|
|
453
346
|
// AgentSession Class
|
|
454
347
|
// ============================================================================
|
|
@@ -904,6 +797,20 @@ export class AgentSession {
|
|
|
904
797
|
usage: hookResult?.usage,
|
|
905
798
|
};
|
|
906
799
|
}
|
|
800
|
+
/**
|
|
801
|
+
* Cursor states a model's real context ceiling on every conversation
|
|
802
|
+
* checkpoint. Once observed, it replaces the catalog guess on the live model
|
|
803
|
+
* so context usage, compaction thresholds and admission all size against the
|
|
804
|
+
* window the server will actually enforce.
|
|
805
|
+
*/
|
|
806
|
+
_applyObservedCursorContextWindow(model) {
|
|
807
|
+
const observed = getCursorContextLimit(model.id);
|
|
808
|
+
if (observed === undefined || observed <= 0 || observed === model.contextWindow)
|
|
809
|
+
return;
|
|
810
|
+
const previous = model.contextWindow;
|
|
811
|
+
model.contextWindow = observed;
|
|
812
|
+
this._sessionLogger.info("cursor_context_window_observed", { modelId: model.id, previous, observed });
|
|
813
|
+
}
|
|
907
814
|
_installAgentNextTurnRefresh() {
|
|
908
815
|
const previousPrepareNextTurnWithContext = this.agent.prepareNextTurnWithContext ??
|
|
909
816
|
(this.agent.prepareNextTurn
|
|
@@ -912,10 +819,33 @@ export class AgentSession {
|
|
|
912
819
|
const previousTransformContext = this.agent.transformContext;
|
|
913
820
|
this.agent.transformContext = async (messages, signal) => {
|
|
914
821
|
const transformed = previousTransformContext ? await previousTransformContext(messages, signal) : messages;
|
|
915
|
-
|
|
916
|
-
|
|
822
|
+
const model = this.model;
|
|
823
|
+
if (model?.provider !== "cursor" && model?.provider !== "cursor-cli-oauth")
|
|
824
|
+
return transformed;
|
|
825
|
+
this._applyObservedCursorContextWindow(model);
|
|
826
|
+
const budgetBytes = cursorAdmissionBudgetBytes(model.contextWindow);
|
|
827
|
+
const admission = admitCursorHistory({
|
|
828
|
+
messages: transformed,
|
|
829
|
+
budgetBytes,
|
|
830
|
+
convert: (candidate) => this.agent.convertToLlm(candidate),
|
|
831
|
+
});
|
|
832
|
+
if (admission.blankedToolResults > 0) {
|
|
833
|
+
this._sessionLogger.info("cursor_admission_truncated", {
|
|
834
|
+
blankedToolResults: admission.blankedToolResults,
|
|
835
|
+
bytesBefore: admission.bytesBefore,
|
|
836
|
+
bytesAfter: admission.bytesAfter,
|
|
837
|
+
budgetBytes,
|
|
838
|
+
});
|
|
839
|
+
}
|
|
840
|
+
if (admission.overBudget) {
|
|
841
|
+
// The request is still admitted: Cursor answers an oversized history
|
|
842
|
+
// with a 0-token resource_exhausted, which the session layer compacts.
|
|
843
|
+
this._sessionLogger.warn("cursor_admission_over_budget", {
|
|
844
|
+
bytes: admission.bytesAfter,
|
|
845
|
+
budgetBytes,
|
|
846
|
+
});
|
|
917
847
|
}
|
|
918
|
-
return transformed;
|
|
848
|
+
return admission.messages ?? transformed;
|
|
919
849
|
};
|
|
920
850
|
this.agent.prepareNextTurnWithContext = async (turn, signal) => {
|
|
921
851
|
// Enforce compaction only when this prepare precedes an actual provider
|
|
@@ -1700,9 +1630,14 @@ export class AgentSession {
|
|
|
1700
1630
|
const hardErrorFallbackEligible = this._isHardErrorFallbackEligible(msg);
|
|
1701
1631
|
const cursorZeroTokenRe = isCursorZeroTokenResourceExhausted(msg);
|
|
1702
1632
|
const cursorQuotaRe = isCursorQuotaResourceExhausted(msg, this.model?.contextWindow ?? 0);
|
|
1633
|
+
const claudeSdkSameModelRemint = this._isClaudeSdkSameModelRemintError(msg);
|
|
1703
1634
|
const retryCanAdmitProvider = !userAbortSuppressedQueuedContinuation &&
|
|
1704
1635
|
this.settingsManager.getRetrySettings().enabled &&
|
|
1705
|
-
(retryableError ||
|
|
1636
|
+
(retryableError ||
|
|
1637
|
+
hardErrorFallbackEligible ||
|
|
1638
|
+
cursorZeroTokenRe ||
|
|
1639
|
+
cursorQuotaRe ||
|
|
1640
|
+
claudeSdkSameModelRemint);
|
|
1706
1641
|
let compactedBeforeRetry = false;
|
|
1707
1642
|
if (retryCanAdmitProvider &&
|
|
1708
1643
|
requiredAutoCompaction &&
|
|
@@ -1725,6 +1660,9 @@ export class AgentSession {
|
|
|
1725
1660
|
this._retireFailedRetryAssistant(msg);
|
|
1726
1661
|
retryOutcome = await this._handleRetryableError(msg, { hardErrorFallback: true });
|
|
1727
1662
|
}
|
|
1663
|
+
else if (claudeSdkSameModelRemint) {
|
|
1664
|
+
retryOutcome = await this._handleRetryableError(msg, { sameModelRemint: true });
|
|
1665
|
+
}
|
|
1728
1666
|
else if (retryableError) {
|
|
1729
1667
|
retryOutcome = await this._handleRetryableError(msg);
|
|
1730
1668
|
}
|
|
@@ -2791,7 +2729,11 @@ export class AgentSession {
|
|
|
2791
2729
|
// empty session, or a "." carrying image attachments (the user is sending
|
|
2792
2730
|
// the images, not asking to continue), falls through to ordinary prompt
|
|
2793
2731
|
// handling below.
|
|
2794
|
-
if (
|
|
2732
|
+
if (isManualContinueSubmission({
|
|
2733
|
+
text,
|
|
2734
|
+
hasMessages: this.agent.state.messages.length > 0,
|
|
2735
|
+
hasImages: (options?.images?.length ?? 0) > 0,
|
|
2736
|
+
})) {
|
|
2795
2737
|
await this.sendCustomMessage({
|
|
2796
2738
|
customType: MANUAL_CONTINUE_CUSTOM_TYPE,
|
|
2797
2739
|
content: MANUAL_CONTINUE_DIRECTIVE,
|
|
@@ -3782,10 +3724,67 @@ export class AgentSession {
|
|
|
3782
3724
|
async setSessionModel(model) {
|
|
3783
3725
|
return this._setModel(model, false);
|
|
3784
3726
|
}
|
|
3727
|
+
/**
|
|
3728
|
+
* #1526: every switch guard rejects before `_switchActiveModel` appends its
|
|
3729
|
+
* `model_change`, so a refused switch used to leave no entry, no event, and
|
|
3730
|
+
* no log line - indistinguishable from a switch the user never attempted.
|
|
3731
|
+
* Record the refusal, then rethrow the original error unchanged.
|
|
3732
|
+
*/
|
|
3733
|
+
_recordRejectedModelChange(model, error) {
|
|
3734
|
+
const budget = error instanceof ModelUsabilityBudgetError ? error.projection : undefined;
|
|
3735
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
3736
|
+
const reason = budget ? "context-budget" : "auth";
|
|
3737
|
+
const numbers = budget
|
|
3738
|
+
? {
|
|
3739
|
+
contextWindow: budget.contextWindow,
|
|
3740
|
+
liveContextTokens: budget.liveContextTokens,
|
|
3741
|
+
requiredTokens: budget.requiredTokens,
|
|
3742
|
+
shortfallTokens: budget.shortfallTokens,
|
|
3743
|
+
safetyMarginProfile: budget.safetyMarginProfile,
|
|
3744
|
+
}
|
|
3745
|
+
: {};
|
|
3746
|
+
this.sessionManager.appendModelChangeRejected({
|
|
3747
|
+
provider: model.provider,
|
|
3748
|
+
modelId: model.id,
|
|
3749
|
+
reason,
|
|
3750
|
+
detail,
|
|
3751
|
+
...numbers,
|
|
3752
|
+
});
|
|
3753
|
+
this._emit({ type: "model_change_rejected", model, reason, detail, ...numbers });
|
|
3754
|
+
}
|
|
3755
|
+
/**
|
|
3756
|
+
* The admission only selects wording, and the switch wording's remedy
|
|
3757
|
+
* ("Compact the session, ...") is executable only when there is context to
|
|
3758
|
+
* compact. `_setModel` is also reachable from `session_start` (the
|
|
3759
|
+
* `recommended-models` builtin switches the model there), so derive the
|
|
3760
|
+
* admission from the branch instead of hardcoding a switch: with conversation
|
|
3761
|
+
* context this is a switch, on an empty session it is still a cold start.
|
|
3762
|
+
*/
|
|
3763
|
+
_modelSwitchAdmission() {
|
|
3764
|
+
return this.sessionManager.hasContextMessages() ? "switch" : "start";
|
|
3765
|
+
}
|
|
3766
|
+
/**
|
|
3767
|
+
* The single guard seam for a model switch (#1526): every site that can
|
|
3768
|
+
* refuse a switch - the `_setModel` pre-flight, the post-`model_select`
|
|
3769
|
+
* revalidation in `_switchActiveModel`, and both cycle guards - records the
|
|
3770
|
+
* refusal and rethrows the original error unchanged, so no refusal is
|
|
3771
|
+
* observable on one path and invisible on its sibling.
|
|
3772
|
+
*/
|
|
3773
|
+
_assertModelUsableForSwitch(model, liveContextTokens) {
|
|
3774
|
+
try {
|
|
3775
|
+
this.assertModelUsable(model, liveContextTokens, { admission: this._modelSwitchAdmission() });
|
|
3776
|
+
}
|
|
3777
|
+
catch (error) {
|
|
3778
|
+
this._recordRejectedModelChange(model, error);
|
|
3779
|
+
throw error;
|
|
3780
|
+
}
|
|
3781
|
+
}
|
|
3785
3782
|
async _setModel(model, updateGlobalDefaults) {
|
|
3786
|
-
this.
|
|
3783
|
+
this._assertModelUsableForSwitch(model, this._getDownswitchLiveContextTokens(model));
|
|
3787
3784
|
if (!(await this._modelRuntime.checkAuth(model.provider))) {
|
|
3788
|
-
|
|
3785
|
+
const error = new Error(`No API key for ${model.provider}/${model.id}`);
|
|
3786
|
+
this._recordRejectedModelChange(model, error);
|
|
3787
|
+
throw error;
|
|
3789
3788
|
}
|
|
3790
3789
|
// A manual model change abandons any active fallback window; if a fallback
|
|
3791
3790
|
// retry sleep is still pending, cancel it so no surprise continuation fires.
|
|
@@ -3859,7 +3858,7 @@ export class AgentSession {
|
|
|
3859
3858
|
const systemPromptChange = opts.emitModelSelect
|
|
3860
3859
|
? await this._emitModelSelect(model, previousModel, opts.modelSelectSource)
|
|
3861
3860
|
: undefined;
|
|
3862
|
-
this.
|
|
3861
|
+
this._assertModelUsableForSwitch(model, liveContextTokens);
|
|
3863
3862
|
if (opts.appendSessionEntry) {
|
|
3864
3863
|
this.sessionManager.appendModelChange(model.provider, model.id, opts.entryReason, previousModel?.provider, previousModel?.id);
|
|
3865
3864
|
}
|
|
@@ -3959,7 +3958,7 @@ export class AgentSession {
|
|
|
3959
3958
|
const alternatives = favoriteModels.filter((entry) => !modelsAreEqual(entry.model, currentModel));
|
|
3960
3959
|
const onlyAlternative = alternatives.length === 1 ? alternatives[0] : undefined;
|
|
3961
3960
|
if (onlyAlternative) {
|
|
3962
|
-
this.
|
|
3961
|
+
this._assertModelUsableForSwitch(onlyAlternative.model, this._getDownswitchLiveContextTokens(onlyAlternative.model));
|
|
3963
3962
|
}
|
|
3964
3963
|
return {
|
|
3965
3964
|
model: currentModel,
|
|
@@ -3970,7 +3969,7 @@ export class AgentSession {
|
|
|
3970
3969
|
}
|
|
3971
3970
|
const next = favoriteModels[selectedIndex];
|
|
3972
3971
|
const liveContextTokens = this._getDownswitchLiveContextTokens(next.model);
|
|
3973
|
-
this.
|
|
3972
|
+
this._assertModelUsableForSwitch(next.model, liveContextTokens);
|
|
3974
3973
|
const invalidatesCompaction = this._modelSelectionChangesContext(currentModel, next.model) ||
|
|
3975
3974
|
currentModel?.provider !== next.model.provider ||
|
|
3976
3975
|
currentModel?.id !== next.model.id;
|
|
@@ -3981,25 +3980,30 @@ export class AgentSession {
|
|
|
3981
3980
|
this._retryFallback.clearForManualModelChange(next.model);
|
|
3982
3981
|
const thinking = this._getThinkingForModelSwitch(next.model, next.thinkingLevel, next.thinkingSelection);
|
|
3983
3982
|
this.agent.state.model = next.model;
|
|
3984
|
-
this.sessionManager.appendModelChange(next.model.provider, next.model.id);
|
|
3985
|
-
this.settingsManager.setDefaultModelAndProvider(next.model.provider, next.model.id);
|
|
3986
3983
|
const previousTier = this._currentServiceTier;
|
|
3987
3984
|
const previousFastMode = this.isFastModeActive();
|
|
3988
3985
|
this._currentServiceTier = this._resolveServiceTier(next.model, next.serviceTier);
|
|
3989
3986
|
// Apply thinking level and provenance from the favorite projection or remembered preference.
|
|
3990
3987
|
this._setThinkingLevel(thinking.level, false, thinking.selection);
|
|
3991
|
-
// Post-switch, same contract as _switchActiveModel: the level in force AFTER the cycle.
|
|
3992
|
-
this._emit({
|
|
3993
|
-
type: "model_changed",
|
|
3994
|
-
model: next.model,
|
|
3995
|
-
thinkingLevel: this.thinkingLevel,
|
|
3996
|
-
source: "cycle",
|
|
3997
|
-
});
|
|
3998
|
-
this._emitServiceTierChangeIfNeeded(previousTier, previousFastMode);
|
|
3999
3988
|
const previousSystemPrompt = this.agent.state.systemPrompt;
|
|
4000
3989
|
try {
|
|
4001
3990
|
const systemPromptChange = await this._emitModelSelect(next.model, currentModel, "cycle");
|
|
4002
|
-
|
|
3991
|
+
// #1526: the `model_select` hook may have grown the system prompt, so the
|
|
3992
|
+
// switch is not decided yet. Nothing durable - no `model_change`, no global
|
|
3993
|
+
// default - may be written before this guard accepts, or a refused cycle
|
|
3994
|
+
// would resume on a model that never ran (the ordering `_switchActiveModel`
|
|
3995
|
+
// already uses).
|
|
3996
|
+
this._assertModelUsableForSwitch(next.model, liveContextTokens);
|
|
3997
|
+
this.sessionManager.appendModelChange(next.model.provider, next.model.id);
|
|
3998
|
+
this.settingsManager.setDefaultModelAndProvider(next.model.provider, next.model.id);
|
|
3999
|
+
// Post-switch, same contract as _switchActiveModel: the level in force AFTER the cycle.
|
|
4000
|
+
this._emit({
|
|
4001
|
+
type: "model_changed",
|
|
4002
|
+
model: next.model,
|
|
4003
|
+
thinkingLevel: this.thinkingLevel,
|
|
4004
|
+
source: "cycle",
|
|
4005
|
+
});
|
|
4006
|
+
this._emitServiceTierChangeIfNeeded(previousTier, previousFastMode);
|
|
4003
4007
|
const cycleResult = {
|
|
4004
4008
|
model: next.model,
|
|
4005
4009
|
thinkingLevel: this.thinkingLevel,
|
|
@@ -4017,6 +4021,7 @@ export class AgentSession {
|
|
|
4017
4021
|
else
|
|
4018
4022
|
delete this.agent.state.model;
|
|
4019
4023
|
this.agent.state.systemPrompt = previousSystemPrompt;
|
|
4024
|
+
this._currentServiceTier = previousTier;
|
|
4020
4025
|
throw error;
|
|
4021
4026
|
}
|
|
4022
4027
|
}
|
|
@@ -4821,7 +4826,11 @@ export class AgentSession {
|
|
|
4821
4826
|
// Size the same retained context that will be admitted to Cursor. Persisted JSONL
|
|
4822
4827
|
// remains verbatim, but the in-memory request representation is bounded first.
|
|
4823
4828
|
if (model.provider === "cursor" || model.provider === "cursor-cli-oauth") {
|
|
4824
|
-
simulatedMessages =
|
|
4829
|
+
simulatedMessages =
|
|
4830
|
+
admitCursorHistory({
|
|
4831
|
+
messages: simulatedMessages,
|
|
4832
|
+
budgetBytes: cursorAdmissionBudgetBytes(model.contextWindow),
|
|
4833
|
+
}).messages ?? simulatedMessages;
|
|
4825
4834
|
}
|
|
4826
4835
|
const contextTokens = estimateMessagesTokens(filterContextExcludedMessages(simulatedMessages));
|
|
4827
4836
|
const settings = this._getCompactionSettings();
|
|
@@ -6336,8 +6345,42 @@ export class AgentSession {
|
|
|
6336
6345
|
this.agent.state.messages = messages.slice(lastUser);
|
|
6337
6346
|
return true;
|
|
6338
6347
|
}
|
|
6348
|
+
_isClaudeSdkSessionLockError(message) {
|
|
6349
|
+
return (message.errorMessage ?? "").includes("Lock file is already being held");
|
|
6350
|
+
}
|
|
6351
|
+
_isClaudeSdkInvalidRequestError(message) {
|
|
6352
|
+
return message.errorMessage === "invalid_request";
|
|
6353
|
+
}
|
|
6354
|
+
/**
|
|
6355
|
+
* Claude-SDK-only quirks that a provider hop cannot fix: the session.json
|
|
6356
|
+
* lock is held by this session's own subprocess, and a bare `invalid_request`
|
|
6357
|
+
* from the SDK boundary carries no provider-neutral meaning. Both are scoped
|
|
6358
|
+
* to the Claude SDK lane, because the SAME wording from another provider is
|
|
6359
|
+
* an ordinary failure whose classification (transient retry, or hard-error
|
|
6360
|
+
* fallback) must not change. Provider-agnostic classes - the stream-stall
|
|
6361
|
+
* watchdog above all - stay out of this predicate: they already consume the
|
|
6362
|
+
* shared same-model budget through `isRetryableAssistantError` and must still
|
|
6363
|
+
* escalate to the fallback chain when that budget runs out.
|
|
6364
|
+
*/
|
|
6365
|
+
_isClaudeSdkSameModelRemintError(message) {
|
|
6366
|
+
if (this.model?.provider !== CLAUDE_SDK_OAUTH_PROVIDER_ID)
|
|
6367
|
+
return false;
|
|
6368
|
+
return this._isClaudeSdkSessionLockError(message) || this._isClaudeSdkInvalidRequestError(message);
|
|
6369
|
+
}
|
|
6370
|
+
/**
|
|
6371
|
+
* The Claude SDK lane owns its own account pool: an auth miss there is
|
|
6372
|
+
* repaired or failed over inside the pool, so hopping to another provider
|
|
6373
|
+
* would abandon the user's Claude subscription on a recoverable miss. Every
|
|
6374
|
+
* other provider keeps the configured fallback-chain hop.
|
|
6375
|
+
*/
|
|
6376
|
+
_isClaudeSdkAuthMissError(message) {
|
|
6377
|
+
return (this.model?.provider === CLAUDE_SDK_OAUTH_PROVIDER_ID &&
|
|
6378
|
+
message.errorMessage === providerNotConfiguredMessage(CLAUDE_SDK_OAUTH_PROVIDER_ID));
|
|
6379
|
+
}
|
|
6339
6380
|
_isHardErrorFallbackEligible(message) {
|
|
6340
6381
|
return (!message.errorMessage?.startsWith(TURN_RETRY_SUPPRESSION_PREFIX) &&
|
|
6382
|
+
!this._isClaudeSdkAuthMissError(message) &&
|
|
6383
|
+
!this._isClaudeSdkSameModelRemintError(message) &&
|
|
6341
6384
|
message.stopReason === "error" &&
|
|
6342
6385
|
!isContextOverflow(message, this.model?.contextWindow ?? 0) &&
|
|
6343
6386
|
!this._isCursorPayloadOverflow(message) &&
|