@code-yeongyu/senpi 2026.8.24 → 2026.8.25
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 +81 -0
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +24 -9
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/file-processor.d.ts.map +1 -1
- package/dist/cli/file-processor.js +2 -1
- package/dist/cli/file-processor.js.map +1 -1
- package/dist/config.d.ts +6 -3
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +24 -14
- package/dist/config.js.map +1 -1
- package/dist/core/agent-abort-provenance.d.ts.map +1 -1
- package/dist/core/agent-abort-provenance.js +5 -1
- package/dist/core/agent-abort-provenance.js.map +1 -1
- package/dist/core/agent-session.d.ts +11 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +125 -29
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-storage.d.ts +4 -0
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +35 -8
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/brand.d.ts +2 -0
- package/dist/core/brand.d.ts.map +1 -1
- package/dist/core/brand.js +1 -0
- package/dist/core/brand.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +1 -0
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +24 -8
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/defaults.d.ts +1 -0
- package/dist/core/defaults.d.ts.map +1 -1
- package/dist/core/defaults.js +9 -0
- package/dist/core/defaults.js.map +1 -1
- package/dist/core/extensions/builtin/goal/terminal-provider-error.js +1 -1
- package/dist/core/extensions/builtin/goal/terminal-provider-error.js.map +1 -1
- package/dist/core/extensions/builtin/loop-guard/notice.d.ts.map +1 -1
- package/dist/core/extensions/builtin/loop-guard/notice.js +5 -1
- package/dist/core/extensions/builtin/loop-guard/notice.js.map +1 -1
- package/dist/core/extensions/builtin/mcp/config-schema.d.ts +2 -2
- package/dist/core/extensions/builtin/ttsr/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/ttsr/index.js +6 -6
- package/dist/core/extensions/builtin/ttsr/index.js.map +1 -1
- package/dist/core/extensions/builtin/ttsr/message-update.d.ts +10 -0
- package/dist/core/extensions/builtin/ttsr/message-update.d.ts.map +1 -0
- package/dist/core/extensions/builtin/ttsr/message-update.js +38 -0
- package/dist/core/extensions/builtin/ttsr/message-update.js.map +1 -0
- package/dist/core/extensions/builtin/ttsr/remediation.d.ts +5 -10
- package/dist/core/extensions/builtin/ttsr/remediation.d.ts.map +1 -1
- package/dist/core/extensions/builtin/ttsr/remediation.js +19 -3
- package/dist/core/extensions/builtin/ttsr/remediation.js.map +1 -1
- package/dist/core/extensions/builtin/ttsr/stream-remediation.d.ts +1 -1
- package/dist/core/extensions/builtin/ttsr/stream-remediation.d.ts.map +1 -1
- package/dist/core/extensions/builtin/ttsr/stream-remediation.js.map +1 -1
- package/dist/core/extensions/builtin/ttsr/types.d.ts +1 -1
- package/dist/core/extensions/builtin/ttsr/types.d.ts.map +1 -1
- package/dist/core/extensions/builtin/ttsr/types.js.map +1 -1
- package/dist/core/extensions/builtin/ttsr/watch.d.ts +1 -1
- package/dist/core/extensions/builtin/ttsr/watch.d.ts.map +1 -1
- package/dist/core/extensions/builtin/ttsr/watch.js +2 -2
- package/dist/core/extensions/builtin/ttsr/watch.js.map +1 -1
- package/dist/core/extensions/index.d.ts +2 -2
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +107 -45
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/types.d.ts +17 -6
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js +3 -0
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/footer-data-provider.d.ts +1 -1
- package/dist/core/footer-data-provider.js +1 -1
- package/dist/core/footer-data-provider.js.map +1 -1
- package/dist/core/keybindings.d.ts +20 -19
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +26 -5
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/model-config-schema.d.ts +17 -5
- package/dist/core/model-config-schema.d.ts.map +1 -1
- package/dist/core/model-config-schema.js +1 -1
- package/dist/core/model-config-schema.js.map +1 -1
- package/dist/core/model-config.d.ts.map +1 -1
- package/dist/core/model-config.js +7 -5
- package/dist/core/model-config.js.map +1 -1
- package/dist/core/model-resolver.d.ts +3 -2
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +3 -2
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/model-runtime.d.ts +0 -1
- package/dist/core/model-runtime.d.ts.map +1 -1
- package/dist/core/model-runtime.js +0 -18
- package/dist/core/model-runtime.js.map +1 -1
- package/dist/core/models-store.d.ts.map +1 -1
- package/dist/core/models-store.js +2 -1
- package/dist/core/models-store.js.map +1 -1
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +14 -10
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/pi-manifest.d.ts.map +1 -1
- package/dist/core/pi-manifest.js +2 -1
- package/dist/core/pi-manifest.js.map +1 -1
- package/dist/core/provider-composer.d.ts +2 -0
- package/dist/core/provider-composer.d.ts.map +1 -1
- package/dist/core/provider-composer.js +3 -6
- package/dist/core/provider-composer.js.map +1 -1
- package/dist/core/provider-display-names.d.ts.map +1 -1
- package/dist/core/provider-display-names.js +0 -1
- package/dist/core/provider-display-names.js.map +1 -1
- package/dist/core/provider-timeout-retry.d.ts.map +1 -1
- package/dist/core/provider-timeout-retry.js +8 -12
- package/dist/core/provider-timeout-retry.js.map +1 -1
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +3 -2
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/retry-fallback/profile-override.d.ts +24 -0
- package/dist/core/retry-fallback/profile-override.d.ts.map +1 -0
- package/dist/core/retry-fallback/profile-override.js +138 -0
- package/dist/core/retry-fallback/profile-override.js.map +1 -0
- package/dist/core/retry-fallback/settings.d.ts +1 -0
- package/dist/core/retry-fallback/settings.d.ts.map +1 -1
- package/dist/core/retry-fallback/settings.js.map +1 -1
- package/dist/core/sdk.d.ts +2 -2
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +20 -5
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-export.d.ts +4 -0
- package/dist/core/session-export.d.ts.map +1 -0
- package/dist/core/session-export.js +32 -0
- package/dist/core/session-export.js.map +1 -0
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +2 -1
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-diagnostics.d.ts +9 -0
- package/dist/core/settings-diagnostics.d.ts.map +1 -0
- package/dist/core/settings-diagnostics.js +21 -0
- package/dist/core/settings-diagnostics.js.map +1 -0
- package/dist/core/settings-manager.d.ts +18 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +88 -7
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +2 -1
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +11 -2
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tools/bash.d.ts +14 -1
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +35 -19
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/edit-diff.d.ts +0 -5
- package/dist/core/tools/edit-diff.d.ts.map +1 -1
- package/dist/core/tools/edit-diff.js +2 -5
- package/dist/core/tools/edit-diff.js.map +1 -1
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +3 -2
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/index.d.ts +4 -1
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +13 -1
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/powershell.d.ts +16 -0
- package/dist/core/tools/powershell.d.ts.map +1 -0
- package/dist/core/tools/powershell.js +39 -0
- package/dist/core/tools/powershell.js.map +1 -0
- package/dist/core/trust-manager.d.ts.map +1 -1
- package/dist/core/trust-manager.js +2 -1
- package/dist/core/trust-manager.js.map +1 -1
- package/dist/extensions/llama/client.d.ts +6 -0
- package/dist/extensions/llama/client.d.ts.map +1 -1
- package/dist/extensions/llama/client.js +7 -0
- package/dist/extensions/llama/client.js.map +1 -1
- package/dist/extensions/llama/provider.d.ts +3 -1
- package/dist/extensions/llama/provider.d.ts.map +1 -1
- package/dist/extensions/llama/provider.js +27 -6
- package/dist/extensions/llama/provider.js.map +1 -1
- package/dist/index.d.ts +5 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +13 -2
- package/dist/main.js.map +1 -1
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js +4 -3
- package/dist/migrations.js.map +1 -1
- package/dist/modes/app-server/daemon/probe.js +1 -1
- package/dist/modes/app-server/daemon/probe.js.map +1 -1
- package/dist/modes/app-server/daemon.js +13 -2
- package/dist/modes/app-server/daemon.js.map +1 -1
- package/dist/modes/app-server/transports/websocket-connection-handler.d.ts.map +1 -1
- package/dist/modes/app-server/transports/websocket-connection-handler.js +4 -0
- package/dist/modes/app-server/transports/websocket-connection-handler.js.map +1 -1
- package/dist/modes/interactive/aborted-error-label.d.ts +2 -0
- package/dist/modes/interactive/aborted-error-label.d.ts.map +1 -1
- package/dist/modes/interactive/aborted-error-label.js +7 -0
- package/dist/modes/interactive/aborted-error-label.js.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.d.ts +15 -3
- package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.js +68 -17
- package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
- package/dist/modes/interactive/external-editor.d.ts.map +1 -1
- package/dist/modes/interactive/external-editor.js +2 -1
- package/dist/modes/interactive/external-editor.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +6 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +19 -12
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/json-event.d.ts +16 -13
- package/dist/modes/json-event.d.ts.map +1 -1
- package/dist/modes/json-event.js +20 -6
- package/dist/modes/json-event.js.map +1 -1
- package/dist/modes/rpc/connection-handler.d.ts.map +1 -1
- package/dist/modes/rpc/connection-handler.js +3 -0
- package/dist/modes/rpc/connection-handler.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts +7 -0
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +7 -0
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +12 -0
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/package-manager-cli.d.ts +1 -0
- package/dist/package-manager-cli.d.ts.map +1 -1
- package/dist/package-manager-cli.js +186 -2
- package/dist/package-manager-cli.js.map +1 -1
- package/dist/utils/frontmatter.d.ts.map +1 -1
- package/dist/utils/frontmatter.js +2 -1
- package/dist/utils/frontmatter.js.map +1 -1
- package/dist/utils/shell.d.ts +3 -0
- package/dist/utils/shell.d.ts.map +1 -1
- package/dist/utils/shell.js +17 -5
- package/dist/utils/shell.js.map +1 -1
- package/dist/utils/syntax-highlight.d.ts +1 -0
- package/dist/utils/syntax-highlight.d.ts.map +1 -1
- package/dist/utils/syntax-highlight.js +60 -1
- package/dist/utils/syntax-highlight.js.map +1 -1
- package/dist/utils/text.d.ts +8 -0
- package/dist/utils/text.d.ts.map +1 -0
- package/dist/utils/text.js +9 -0
- package/dist/utils/text.js.map +1 -0
- package/docs/compaction.md +0 -2
- package/docs/custom-provider.md +6 -6
- package/docs/environment-variables.md +8 -8
- package/docs/extensions.md +6 -5
- package/docs/json.md +7 -2
- package/docs/keybindings.md +1 -1
- package/docs/packages.md +2 -2
- package/docs/rpc.md +32 -3
- package/docs/sdk.md +7 -2
- package/docs/settings.md +9 -1
- package/docs/terminal-setup.md +11 -9
- package/docs/usage.md +4 -1
- package/docs/windows.md +24 -2
- package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +12 -0
- package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
- package/node_modules/@code-yeongyu/senpi-codemode/src/extension/session-manager-proxy.ts +39 -5
- package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js +7 -4
- package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/agent.d.ts +2 -3
- package/node_modules/@earendil-works/pi-agent-core/dist/agent.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/agent.js +7 -6
- package/node_modules/@earendil-works/pi-agent-core/dist/agent.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/assistant-terminal-state.d.ts +4 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/assistant-terminal-state.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/assistant-terminal-state.js +8 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/assistant-terminal-state.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/index.d.ts +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/index.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/index.js +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/index.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/package.json +5 -5
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.d.ts +1 -5
- 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 +25 -13
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/azure-openai-responses.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/azure-openai-responses.js +2 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/azure-openai-responses.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/bedrock-converse-stream.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/bedrock-converse-stream.js +91 -5
- package/node_modules/@earendil-works/pi-ai/dist/api/bedrock-converse-stream.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/google-generative-ai.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/google-generative-ai.js +4 -2
- package/node_modules/@earendil-works/pi-ai/dist/api/google-generative-ai.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/google-vertex.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/google-vertex.js +4 -2
- package/node_modules/@earendil-works/pi-ai/dist/api/google-vertex.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/mistral-conversations.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/mistral-conversations.js +2 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/mistral-conversations.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js +93 -54
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js +2 -5
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/transform-messages.js +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/transform-messages.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/github-copilot.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/github-copilot.js +97 -46
- package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/github-copilot.js.map +1 -1
- 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 +1 -14
- 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/pool/slots.d.ts +50 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/pool/slots.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/pool/slots.js +129 -0
- package/node_modules/@earendil-works/pi-ai/dist/auth/pool/slots.js.map +1 -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 +3 -1
- package/node_modules/@earendil-works/pi-ai/dist/auth/resolve.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/models.d.ts +8 -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 +16 -3
- package/node_modules/@earendil-works/pi-ai/dist/models.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-ai-gateway.d.ts +3 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-ai-gateway.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-ai-gateway.js +10 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-ai-gateway.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/anthropic.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/azure-openai-responses.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/cloudflare-ai-gateway.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/openai.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/dist/providers/data/zai-coding-cn.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/zai.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/faux.d.ts +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/faux.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/faux.js +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/faux.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/kimi-coding.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/kimi-coding.js +4 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/kimi-coding.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/types.d.ts +8 -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/overflow.d.ts +16 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.js +17 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry-profile/backoff.d.ts +14 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry-profile/backoff.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry-profile/backoff.js +24 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry-profile/backoff.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry-profile/classifiers.d.ts +36 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry-profile/classifiers.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry-profile/classifiers.js +109 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry-profile/classifiers.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry-profile/failure.d.ts +12 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry-profile/failure.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry-profile/failure.js +109 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry-profile/failure.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry-profile/index.d.ts +9 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry-profile/index.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry-profile/index.js +6 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry-profile/index.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry-profile/planner.d.ts +46 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry-profile/planner.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry-profile/planner.js +41 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry-profile/planner.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry-profile/profiles.d.ts +4 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry-profile/profiles.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry-profile/profiles.js +93 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry-profile/profiles.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry-profile/types.d.ts +121 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry-profile/types.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry-profile/types.js +11 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry-profile/types.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry.d.ts +12 -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 +25 -5
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/sleep.d.ts +2 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/sleep.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/sleep.js +15 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/sleep.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/package.json +20 -16
- package/node_modules/@earendil-works/pi-pty/dist/index.d.ts +1 -0
- package/node_modules/@earendil-works/pi-pty/dist/index.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-pty/dist/index.js +1 -0
- package/node_modules/@earendil-works/pi-pty/dist/index.js.map +1 -1
- package/node_modules/@earendil-works/pi-pty/dist/session-bun.d.ts +30 -0
- package/node_modules/@earendil-works/pi-pty/dist/session-bun.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-pty/dist/session-bun.js +76 -0
- package/node_modules/@earendil-works/pi-pty/dist/session-bun.js.map +1 -0
- package/node_modules/@earendil-works/pi-pty/dist/session-types.d.ts +3 -1
- package/node_modules/@earendil-works/pi-pty/dist/session-types.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-pty/dist/session-types.js.map +1 -1
- package/node_modules/@earendil-works/pi-pty/dist/session.d.ts +2 -0
- package/node_modules/@earendil-works/pi-pty/dist/session.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-pty/dist/session.js +19 -9
- package/node_modules/@earendil-works/pi-pty/dist/session.js.map +1 -1
- package/node_modules/@earendil-works/pi-pty/package.json +1 -1
- package/node_modules/@earendil-works/pi-telemetry/package.json +3 -3
- package/node_modules/@earendil-works/pi-tui/dist/components/markdown.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/markdown.js +9 -4
- package/node_modules/@earendil-works/pi-tui/dist/components/markdown.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/settings-list.d.ts +8 -2
- package/node_modules/@earendil-works/pi-tui/dist/components/settings-list.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/settings-list.js +24 -4
- package/node_modules/@earendil-works/pi-tui/dist/components/settings-list.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/keybindings.d.ts +2 -2
- package/node_modules/@earendil-works/pi-tui/dist/keybindings.js +2 -2
- package/node_modules/@earendil-works/pi-tui/dist/keybindings.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/native-modifiers.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/native-modifiers.js +2 -8
- package/node_modules/@earendil-works/pi-tui/dist/native-modifiers.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/native-module-path.d.ts +7 -0
- package/node_modules/@earendil-works/pi-tui/dist/native-module-path.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/native-module-path.js +19 -0
- package/node_modules/@earendil-works/pi-tui/dist/native-module-path.js.map +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/terminal.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/terminal.js +4 -10
- package/node_modules/@earendil-works/pi-tui/dist/terminal.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/package.json +5 -5
- package/package.json +90 -88
- package/dist/core/radius.d.ts +0 -2
- package/dist/core/radius.d.ts.map +0 -1
- package/dist/core/radius.js +0 -2
- package/dist/core/radius.js.map +0 -1
|
@@ -16,10 +16,11 @@ import { randomUUID } from "node:crypto";
|
|
|
16
16
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
17
17
|
import { basename, dirname } from "node:path";
|
|
18
18
|
import { isDeepStrictEqual } from "node:util";
|
|
19
|
-
import { prepareAgentToolCall } from "@earendil-works/pi-agent-core";
|
|
19
|
+
import { ProviderRetryWatchdogAbortError, prepareAgentToolCall } from "@earendil-works/pi-agent-core";
|
|
20
20
|
import { contentText, SERVER_FALLBACK_ABORTED_DIAGNOSTIC } from "@earendil-works/pi-ai";
|
|
21
|
-
import { cleanupSessionResources, cursorOverflowCompactionSettings, isClassifierRefusal, isContextOverflow, isCursorPayloadResourceExhausted, isCursorZeroTokenResourceExhausted, isProviderStreamStallError, isProviderTimeoutError, isRecoverableLength, isRetryableAssistantError, modelsAreEqual, resetApiProviders, shouldRetryOverflowWithoutCompact, streamSimple, } from "@earendil-works/pi-ai/compat";
|
|
21
|
+
import { cleanupSessionResources, cursorOverflowCompactionSettings, isClassifierRefusal, isContextOverflow, isCursorPayloadResourceExhausted, isCursorQuotaResourceExhausted, isCursorZeroTokenResourceExhausted, isProviderStreamStallError, isProviderTimeoutError, isRecoverableLength, isRetryableAssistantError, modelsAreEqual, resetApiProviders, shouldRetryOverflowWithoutCompact, streamSimple, } from "@earendil-works/pi-ai/compat";
|
|
22
22
|
import { extract429RetryAfterMs, parseRetryAfterMsMarker } from "@earendil-works/pi-ai/utils/retry-hint";
|
|
23
|
+
import { retryBackoffDelayMs } from "@earendil-works/pi-ai/utils/retry-profile/backoff";
|
|
23
24
|
import { getAgentDir } from "../config.js";
|
|
24
25
|
import { getThemeByName, theme } from "../modes/interactive/theme/theme.js";
|
|
25
26
|
import { stripFrontmatter } from "../utils/frontmatter.js";
|
|
@@ -313,6 +314,15 @@ export const MAX_SKILL_EXPANSIONS_PER_PROMPT = 5;
|
|
|
313
314
|
// AgentSession Class
|
|
314
315
|
// ============================================================================
|
|
315
316
|
export class AgentSession {
|
|
317
|
+
/**
|
|
318
|
+
* Resolve the effective retry profile for the current model's provider.
|
|
319
|
+
* Falls back to the senpi-default profile when the provider declares none.
|
|
320
|
+
*/
|
|
321
|
+
_resolveRetryProfile() {
|
|
322
|
+
const providerId = this.model?.provider;
|
|
323
|
+
const declared = providerId !== undefined ? this._modelRuntime.getProvider(providerId)?.retryPolicy : undefined;
|
|
324
|
+
return this.settingsManager.resolveRetryProfile(providerId !== undefined ? { id: providerId, retryPolicy: declared } : undefined);
|
|
325
|
+
}
|
|
316
326
|
constructor(config) {
|
|
317
327
|
this._eventListeners = [];
|
|
318
328
|
this._agentEventQueue = Promise.resolve();
|
|
@@ -338,6 +348,7 @@ export class AgentSession {
|
|
|
338
348
|
this._supersededCompactionLogAttemptIds = new Set();
|
|
339
349
|
/** Messages queued to be included with the next user prompt as context ("asides"). */
|
|
340
350
|
this._pendingNextTurnMessages = [];
|
|
351
|
+
this._pendingCustomMessages = [];
|
|
341
352
|
// Queues held while the first post-compaction response is classified. Agent
|
|
342
353
|
// core otherwise drains steering immediately before AgentSession can consume
|
|
343
354
|
// the stale-usage exemption and schedule the continuation itself.
|
|
@@ -478,6 +489,7 @@ export class AgentSession {
|
|
|
478
489
|
}
|
|
479
490
|
this._selectorCooldowns = new SelectorCooldowns(config.fallbackNow ?? (() => Date.now()));
|
|
480
491
|
this._fallbackNow = config.fallbackNow ?? (() => Date.now());
|
|
492
|
+
this._retryRandom = config.retryRandom ?? Math.random;
|
|
481
493
|
this._retryFallback = new RetryFallbackController({
|
|
482
494
|
getSettings: () => this.settingsManager.getRetryFallbackSettings(),
|
|
483
495
|
registry: this._modelRegistry,
|
|
@@ -1090,7 +1102,8 @@ export class AgentSession {
|
|
|
1090
1102
|
if (!lastAssistant ||
|
|
1091
1103
|
(!this._isRetryableError(lastAssistant) &&
|
|
1092
1104
|
!this._isHardErrorFallbackEligible(lastAssistant) &&
|
|
1093
|
-
!isCursorZeroTokenResourceExhausted(lastAssistant)
|
|
1105
|
+
!isCursorZeroTokenResourceExhausted(lastAssistant) &&
|
|
1106
|
+
!isCursorQuotaResourceExhausted(lastAssistant, this.model?.contextWindow ?? 0))) {
|
|
1094
1107
|
return;
|
|
1095
1108
|
}
|
|
1096
1109
|
this._retryPromise = new Promise((resolve) => {
|
|
@@ -1256,10 +1269,17 @@ export class AgentSession {
|
|
|
1256
1269
|
if (!settings.enabled) {
|
|
1257
1270
|
return false;
|
|
1258
1271
|
}
|
|
1272
|
+
// The same-model budget comes from the resolved profile so a provider-declared
|
|
1273
|
+
// budget (e.g. kimi-code's 9) is honoured; identical to settings.maxRetries for
|
|
1274
|
+
// providers without a profile.
|
|
1275
|
+
const turnMaxRetries = this._resolveRetryProfile().turn.maxRetries;
|
|
1259
1276
|
const retryableError = this._isRetryableError(lastAssistant);
|
|
1260
1277
|
if (isCursorZeroTokenResourceExhausted(lastAssistant)) {
|
|
1261
1278
|
return true;
|
|
1262
1279
|
}
|
|
1280
|
+
if (isCursorQuotaResourceExhausted(lastAssistant, this.model?.contextWindow ?? 0)) {
|
|
1281
|
+
return this._retryFallback.canTryFallback();
|
|
1282
|
+
}
|
|
1263
1283
|
if (!retryableError && this._isHardErrorFallbackEligible(lastAssistant)) {
|
|
1264
1284
|
return true;
|
|
1265
1285
|
}
|
|
@@ -1267,9 +1287,9 @@ export class AgentSession {
|
|
|
1267
1287
|
return false;
|
|
1268
1288
|
}
|
|
1269
1289
|
if (isClassifierRefusal(lastAssistant)) {
|
|
1270
|
-
return this._retryAttempt + 1 <=
|
|
1290
|
+
return this._retryAttempt + 1 <= turnMaxRetries && this._retryFallback.canTryFallback();
|
|
1271
1291
|
}
|
|
1272
|
-
if (this._retryAttempt + 1 >
|
|
1292
|
+
if (this._retryAttempt + 1 > turnMaxRetries) {
|
|
1273
1293
|
return this._retryFallback.canTryFallback();
|
|
1274
1294
|
}
|
|
1275
1295
|
const errorMessage = lastAssistant.errorMessage || "Unknown error";
|
|
@@ -1405,9 +1425,10 @@ export class AgentSession {
|
|
|
1405
1425
|
const retryableError = this._isRetryableError(msg);
|
|
1406
1426
|
const hardErrorFallbackEligible = this._isHardErrorFallbackEligible(msg);
|
|
1407
1427
|
const cursorZeroTokenRe = isCursorZeroTokenResourceExhausted(msg);
|
|
1428
|
+
const cursorQuotaRe = isCursorQuotaResourceExhausted(msg, this.model?.contextWindow ?? 0);
|
|
1408
1429
|
const retryCanAdmitProvider = !userAbortSuppressedQueuedContinuation &&
|
|
1409
1430
|
this.settingsManager.getRetrySettings().enabled &&
|
|
1410
|
-
(retryableError || hardErrorFallbackEligible || cursorZeroTokenRe);
|
|
1431
|
+
(retryableError || hardErrorFallbackEligible || cursorZeroTokenRe || cursorQuotaRe);
|
|
1411
1432
|
let compactedBeforeRetry = false;
|
|
1412
1433
|
if (retryCanAdmitProvider &&
|
|
1413
1434
|
requiredAutoCompaction &&
|
|
@@ -1423,6 +1444,12 @@ export class AgentSession {
|
|
|
1423
1444
|
if (cursorZeroTokenRe) {
|
|
1424
1445
|
retryOutcome = await this._handleRetryableError(msg, { sameModelRemint: true });
|
|
1425
1446
|
}
|
|
1447
|
+
else if (cursorQuotaRe) {
|
|
1448
|
+
// Mid-turn Cursor errors may retain unpaired tool calls. Remove the
|
|
1449
|
+
// failed assistant before provider fallback so replay stays valid.
|
|
1450
|
+
this._retireFailedRetryAssistant(msg);
|
|
1451
|
+
retryOutcome = await this._handleRetryableError(msg, { hardErrorFallback: true });
|
|
1452
|
+
}
|
|
1426
1453
|
else if (retryableError) {
|
|
1427
1454
|
retryOutcome = await this._handleRetryableError(msg);
|
|
1428
1455
|
}
|
|
@@ -1446,6 +1473,9 @@ export class AgentSession {
|
|
|
1446
1473
|
retryOwnedDeferredQueue &&
|
|
1447
1474
|
retryOutcome === "not-handled" &&
|
|
1448
1475
|
(msg.stopReason === "error" || msg.stopReason === "aborted");
|
|
1476
|
+
if (retryOutcome === "not-handled" && cursorQuotaRe && msg.errorMessage) {
|
|
1477
|
+
msg.errorMessage = `${msg.errorMessage} (likely provider usage/quota exhaustion: conversation is well below the model context window)`;
|
|
1478
|
+
}
|
|
1449
1479
|
if (retryOutcome === "not-handled" && this._retryAttempt > 0 && msg.errorMessage) {
|
|
1450
1480
|
const attempt = this._retryAttempt;
|
|
1451
1481
|
this._retryAttempt = 0;
|
|
@@ -1700,6 +1730,7 @@ export class AgentSession {
|
|
|
1700
1730
|
};
|
|
1701
1731
|
await this._extensionRunner.emit(extensionEvent);
|
|
1702
1732
|
this._turnIndex++;
|
|
1733
|
+
this._flushPendingCustomMessages();
|
|
1703
1734
|
}
|
|
1704
1735
|
else if (event.type === "message_start") {
|
|
1705
1736
|
const extensionEvent = {
|
|
@@ -3006,12 +3037,11 @@ export class AgentSession {
|
|
|
3006
3037
|
}
|
|
3007
3038
|
await this._promptAgent(appMessage, deferredTurnClaim);
|
|
3008
3039
|
}
|
|
3040
|
+
else if (this.isStreaming) {
|
|
3041
|
+
this._pendingCustomMessages.push(appMessage);
|
|
3042
|
+
}
|
|
3009
3043
|
else {
|
|
3010
|
-
this.
|
|
3011
|
-
this.sessionManager.appendCustomMessageEntry(message.customType, message.content, message.display, message.details);
|
|
3012
|
-
this._incrementMessageRevision();
|
|
3013
|
-
this._emit({ type: "message_start", message: appMessage });
|
|
3014
|
-
this._emit({ type: "message_end", message: appMessage });
|
|
3044
|
+
this._appendCustomMessage(appMessage);
|
|
3015
3045
|
}
|
|
3016
3046
|
}
|
|
3017
3047
|
finally {
|
|
@@ -3019,6 +3049,19 @@ export class AgentSession {
|
|
|
3019
3049
|
finishSessionWork?.();
|
|
3020
3050
|
}
|
|
3021
3051
|
}
|
|
3052
|
+
_appendCustomMessage(appMessage) {
|
|
3053
|
+
this.agent.state.messages.push(appMessage);
|
|
3054
|
+
this.sessionManager.appendCustomMessageEntry(appMessage.customType, appMessage.content, appMessage.display, appMessage.details);
|
|
3055
|
+
this._incrementMessageRevision();
|
|
3056
|
+
this._emit({ type: "message_start", message: appMessage });
|
|
3057
|
+
this._emit({ type: "message_end", message: appMessage });
|
|
3058
|
+
}
|
|
3059
|
+
_flushPendingCustomMessages() {
|
|
3060
|
+
const pending = this._pendingCustomMessages;
|
|
3061
|
+
this._pendingCustomMessages = [];
|
|
3062
|
+
for (const message of pending)
|
|
3063
|
+
this._appendCustomMessage(message);
|
|
3064
|
+
}
|
|
3022
3065
|
/**
|
|
3023
3066
|
* Send a user message to the agent. Always triggers a turn.
|
|
3024
3067
|
* When the agent is streaming, use deliverAs to specify how to queue the message.
|
|
@@ -4449,11 +4492,7 @@ export class AgentSession {
|
|
|
4449
4492
|
else {
|
|
4450
4493
|
const messages = filterContextExcludedMessages(this.agent.state.messages);
|
|
4451
4494
|
const estimate = estimateContextTokens(messages);
|
|
4452
|
-
if (estimate.lastUsageIndex
|
|
4453
|
-
if (!this._isRequiredCompactionError(assistantMessage))
|
|
4454
|
-
return false;
|
|
4455
|
-
}
|
|
4456
|
-
else {
|
|
4495
|
+
if (estimate.lastUsageIndex !== null) {
|
|
4457
4496
|
// Verify the usage source is post-compaction. Kept pre-compaction messages
|
|
4458
4497
|
// have stale usage reflecting the old (larger) context and would falsely
|
|
4459
4498
|
// trigger compaction right after one just finished.
|
|
@@ -4609,7 +4648,10 @@ export class AgentSession {
|
|
|
4609
4648
|
}
|
|
4610
4649
|
},
|
|
4611
4650
|
getActiveSignal: () => this.agent.signal,
|
|
4612
|
-
abortActive: () => this.agent.abort(
|
|
4651
|
+
abortActive: () => this.agent.abort(new ProviderRetryWatchdogAbortError(`Provider retry continuation watchdog timed out after ${retryTimeoutMs}ms` +
|
|
4652
|
+
(this.agent.streamStartTimeoutMs === undefined
|
|
4653
|
+
? " (stream-start guard disabled)"
|
|
4654
|
+
: ` (stream-start guard: ${this.agent.streamStartTimeoutMs}ms)`))),
|
|
4613
4655
|
timeoutMs: retryTimeoutMs,
|
|
4614
4656
|
});
|
|
4615
4657
|
return "continued";
|
|
@@ -5560,6 +5602,9 @@ export class AgentSession {
|
|
|
5560
5602
|
*/
|
|
5561
5603
|
_degradeRateLimitedWithoutFallback(tier, hintMs, message, errorMessage) {
|
|
5562
5604
|
const settings = this.settingsManager.getRetrySettings();
|
|
5605
|
+
// Budget checks use the resolved profile (same value as settings.maxRetries
|
|
5606
|
+
// for providers without a declared profile).
|
|
5607
|
+
const turnMaxRetries = this._resolveRetryProfile().turn.maxRetries;
|
|
5563
5608
|
const hintSettings = this.settingsManager.getHintPolicySettings();
|
|
5564
5609
|
const finishTurn = (attempt, finalError) => {
|
|
5565
5610
|
const exhaustedChainKey = this._retryFallback.exhaustedChainKey;
|
|
@@ -5587,7 +5632,7 @@ export class AgentSession {
|
|
|
5587
5632
|
return undefined;
|
|
5588
5633
|
}
|
|
5589
5634
|
this._retryAttempt++;
|
|
5590
|
-
if (this._retryAttempt >
|
|
5635
|
+
if (this._retryAttempt > turnMaxRetries) {
|
|
5591
5636
|
finishTurn(this._retryAttempt - 1, message.errorMessage);
|
|
5592
5637
|
return undefined;
|
|
5593
5638
|
}
|
|
@@ -5603,6 +5648,10 @@ export class AgentSession {
|
|
|
5603
5648
|
this._resolveRetry();
|
|
5604
5649
|
return "not-handled";
|
|
5605
5650
|
}
|
|
5651
|
+
// Resolve the effective retry profile for the current provider.
|
|
5652
|
+
// Profile-driven behaviour only diverges when a provider declares one;
|
|
5653
|
+
// the senpi-default profile preserves today's tier routing exactly.
|
|
5654
|
+
const retryProfile = this._resolveRetryProfile();
|
|
5606
5655
|
// Retry promise is created synchronously in _handleAgentEvent for agent_end.
|
|
5607
5656
|
// Keep a defensive fallback here in case a future refactor bypasses that path.
|
|
5608
5657
|
if (!this._retryPromise) {
|
|
@@ -5619,7 +5668,7 @@ export class AgentSession {
|
|
|
5619
5668
|
let hintTierDelayMs;
|
|
5620
5669
|
if (sameModelRemint) {
|
|
5621
5670
|
this._retryAttempt++;
|
|
5622
|
-
if (this._retryAttempt >
|
|
5671
|
+
if (this._retryAttempt > retryProfile.turn.maxRetries) {
|
|
5623
5672
|
if (this._retryAttempt > 1) {
|
|
5624
5673
|
this._emit({
|
|
5625
5674
|
type: "auto_retry_end",
|
|
@@ -5652,7 +5701,7 @@ export class AgentSession {
|
|
|
5652
5701
|
else if (isRefusal) {
|
|
5653
5702
|
// Refusals are only retried through a new chain candidate. They never use
|
|
5654
5703
|
// same-model retries or the transient over-budget fallback escape hatch.
|
|
5655
|
-
if (this._retryAttempt + 1 >
|
|
5704
|
+
if (this._retryAttempt + 1 > retryProfile.turn.maxRetries) {
|
|
5656
5705
|
if (this._retryAttempt > 0) {
|
|
5657
5706
|
this._emit({
|
|
5658
5707
|
type: "auto_retry_end",
|
|
@@ -5693,8 +5742,8 @@ export class AgentSession {
|
|
|
5693
5742
|
}
|
|
5694
5743
|
else {
|
|
5695
5744
|
// A provider-stream stall is an ordinary transient failure: it consumes
|
|
5696
|
-
// the same bounded same-model budget (
|
|
5697
|
-
// other retryable class and escalates to the fallback chain only when
|
|
5745
|
+
// the same bounded same-model budget (the resolved profile's turn
|
|
5746
|
+
// maxRetries) as every other retryable class and escalates to the fallback chain only when
|
|
5698
5747
|
// that budget is exhausted. It is excluded from 429-class tier routing
|
|
5699
5748
|
// because a stall carries no rate-limit markers or retry-after hint.
|
|
5700
5749
|
const stallError = isProviderStreamStallError(message);
|
|
@@ -5704,7 +5753,44 @@ export class AgentSession {
|
|
|
5704
5753
|
// the cadence at a few milliseconds. Do not recompute that floor here.
|
|
5705
5754
|
const is429Class = !stallError &&
|
|
5706
5755
|
/rate.?limit|(?:^429(?=\s+\{)|(?:\bHTTP\/1\.[01]\s+|\bHTTP\s+|\bstatus(?:\s+code)?\s+|\berror\s+|\bcode\s+)429\b)|too many requests|resource.?exhausted/i.test(errorMessage);
|
|
5707
|
-
|
|
5756
|
+
// Profile-driven routing: "after-turn-budget" (Kimi) keeps 429s on the
|
|
5757
|
+
// ordinary same-model budget; "tiered" (senpi default) uses hint tiers.
|
|
5758
|
+
if (is429Class && retryProfile.fallback.rateLimited === "after-turn-budget") {
|
|
5759
|
+
// Kimi profile: 429s consume the same-model budget like any transient.
|
|
5760
|
+
// Mark tier-routed so the generic non-429 path below does not double-count.
|
|
5761
|
+
is429TierRouted = true;
|
|
5762
|
+
this._retryAttempt++;
|
|
5763
|
+
if (this._retryAttempt > retryProfile.turn.maxRetries) {
|
|
5764
|
+
switchedFallback = await this._retryFallback.tryFallback("transient", {
|
|
5765
|
+
errorMessage,
|
|
5766
|
+
retryAfterMs: this._getProviderRetryDelayMs(errorMessage),
|
|
5767
|
+
});
|
|
5768
|
+
if (switchedFallback) {
|
|
5769
|
+
this._retryAttempt = 1;
|
|
5770
|
+
}
|
|
5771
|
+
else {
|
|
5772
|
+
const exhaustedChainKey = this._retryFallback.exhaustedChainKey;
|
|
5773
|
+
if (exhaustedChainKey) {
|
|
5774
|
+
this._emit({
|
|
5775
|
+
type: "retry_fallback_exhausted",
|
|
5776
|
+
chainKey: exhaustedChainKey,
|
|
5777
|
+
lastError: errorMessage,
|
|
5778
|
+
});
|
|
5779
|
+
}
|
|
5780
|
+
this._emit({
|
|
5781
|
+
type: "auto_retry_end",
|
|
5782
|
+
success: false,
|
|
5783
|
+
attempt: this._retryAttempt - 1,
|
|
5784
|
+
finalError: message.errorMessage,
|
|
5785
|
+
});
|
|
5786
|
+
this._retryAttempt = 0;
|
|
5787
|
+
this._resetHintTierState();
|
|
5788
|
+
this._resolveRetry();
|
|
5789
|
+
return "not-handled";
|
|
5790
|
+
}
|
|
5791
|
+
}
|
|
5792
|
+
}
|
|
5793
|
+
else if (is429Class) {
|
|
5708
5794
|
const hintMs = this._getProviderRetryDelayMs(errorMessage);
|
|
5709
5795
|
const hintSettings = this.settingsManager.getHintPolicySettings();
|
|
5710
5796
|
const tier = classifyRateLimitedWait(hintMs, hintSettings);
|
|
@@ -5725,7 +5811,7 @@ export class AgentSession {
|
|
|
5725
5811
|
}
|
|
5726
5812
|
else if (tier === "tier1-in-turn") {
|
|
5727
5813
|
this._retryAttempt++;
|
|
5728
|
-
if (this._retryAttempt >
|
|
5814
|
+
if (this._retryAttempt > retryProfile.turn.maxRetries) {
|
|
5729
5815
|
// Budget exhausted within tier1; fall back.
|
|
5730
5816
|
switchedFallback = await this._retryFallback.tryFallback("transient", {
|
|
5731
5817
|
errorMessage,
|
|
@@ -5826,7 +5912,7 @@ export class AgentSession {
|
|
|
5826
5912
|
if (!is429TierRouted) {
|
|
5827
5913
|
this._retryAttempt++;
|
|
5828
5914
|
}
|
|
5829
|
-
if (!is429TierRouted && this._retryAttempt >
|
|
5915
|
+
if (!is429TierRouted && this._retryAttempt > retryProfile.turn.maxRetries) {
|
|
5830
5916
|
switchedFallback = await this._retryFallback.tryFallback("transient", {
|
|
5831
5917
|
errorMessage,
|
|
5832
5918
|
retryAfterMs: this._getProviderRetryDelayMs(errorMessage),
|
|
@@ -5859,8 +5945,13 @@ export class AgentSession {
|
|
|
5859
5945
|
}
|
|
5860
5946
|
const providerDelayMs = isRefusal || hardErrorFallback ? undefined : this._getProviderRetryDelayMs(errorMessage);
|
|
5861
5947
|
const maxRetryDelayMs = this.settingsManager.getProviderRetrySettings().maxRetryDelayMs;
|
|
5948
|
+
// Profile ceiling null (Kimi) bypasses the over-ceiling error path entirely.
|
|
5949
|
+
const profileCeiling = retryProfile.turn.serverHint.mode === "override"
|
|
5950
|
+
? retryProfile.turn.serverHint.ceiling.maxDelayMs
|
|
5951
|
+
: maxRetryDelayMs;
|
|
5952
|
+
const effectiveMaxRetryDelayMs = profileCeiling ?? Number.MAX_SAFE_INTEGER;
|
|
5862
5953
|
// For 429-class failures the tier routing replaces the over-budget gate.
|
|
5863
|
-
if (!is429TierRouted && providerDelayMs !== undefined && providerDelayMs >
|
|
5954
|
+
if (!is429TierRouted && providerDelayMs !== undefined && providerDelayMs > effectiveMaxRetryDelayMs) {
|
|
5864
5955
|
// A wait this long means the model is unavailable rather than busy, so the
|
|
5865
5956
|
// configured chain beats failing the turn. The switch is gated: the over-budget
|
|
5866
5957
|
// branch above may have already switched on this same error, and hopping again
|
|
@@ -5895,17 +5986,22 @@ export class AgentSession {
|
|
|
5895
5986
|
// 429-tier delays already carry the exponential floor from nextInTurnDelayMs /
|
|
5896
5987
|
// degradeWithoutFallback; the non-tier branch keeps its own exponential fallback.
|
|
5897
5988
|
const nonTierProviderDelayMs = providerDelayMs === 0 ? undefined : providerDelayMs;
|
|
5989
|
+
// Locally computed exponential goes through the profile's backoff policy
|
|
5990
|
+
// (cap + jitter), sampled through the injectable retryRandom seam so tests
|
|
5991
|
+
// stay deterministic; provider-derived hints on the non-429 path remain
|
|
5992
|
+
// authoritative and fallback switches stay exact.
|
|
5993
|
+
const localExponentialMs = retryBackoffDelayMs(retryProfile.turn.backoff, this._retryAttempt, this._retryRandom());
|
|
5898
5994
|
const delayMs = switchedFallback
|
|
5899
5995
|
? 0
|
|
5900
5996
|
: is429TierRouted
|
|
5901
|
-
? (hintTierDelayMs ?? providerDelayMs ??
|
|
5902
|
-
: (nonTierProviderDelayMs ??
|
|
5997
|
+
? (hintTierDelayMs ?? providerDelayMs ?? localExponentialMs)
|
|
5998
|
+
: (nonTierProviderDelayMs ?? localExponentialMs);
|
|
5903
5999
|
// Prepare before auto_retry_start so an immediate Esc can cancel the retry sleep.
|
|
5904
6000
|
this._retryAbortController = new AbortController();
|
|
5905
6001
|
this._emit({
|
|
5906
6002
|
type: "auto_retry_start",
|
|
5907
6003
|
attempt: this._retryAttempt,
|
|
5908
|
-
maxAttempts:
|
|
6004
|
+
maxAttempts: retryProfile.turn.maxRetries,
|
|
5909
6005
|
delayMs,
|
|
5910
6006
|
errorMessage,
|
|
5911
6007
|
});
|