@code-yeongyu/senpi 2026.9.7 → 2026.9.8

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.
Files changed (323) hide show
  1. package/CHANGELOG.md +79 -0
  2. package/dist/core/agent-session.d.ts +40 -3
  3. package/dist/core/agent-session.d.ts.map +1 -1
  4. package/dist/core/agent-session.js +159 -40
  5. package/dist/core/agent-session.js.map +1 -1
  6. package/dist/core/compaction/compaction.d.ts.map +1 -1
  7. package/dist/core/compaction/compaction.js +2 -1
  8. package/dist/core/compaction/compaction.js.map +1 -1
  9. package/dist/core/dynamic-prompt/working-task.js +1 -1
  10. package/dist/core/dynamic-prompt/working-task.js.map +1 -1
  11. package/dist/core/extensions/builtin/cache-keepalive/index.d.ts.map +1 -1
  12. package/dist/core/extensions/builtin/cache-keepalive/index.js +4 -21
  13. package/dist/core/extensions/builtin/cache-keepalive/index.js.map +1 -1
  14. package/dist/core/extensions/builtin/claude-sdk-oauth/account-command.d.ts +2 -0
  15. package/dist/core/extensions/builtin/claude-sdk-oauth/account-command.d.ts.map +1 -1
  16. package/dist/core/extensions/builtin/claude-sdk-oauth/account-command.js +10 -25
  17. package/dist/core/extensions/builtin/claude-sdk-oauth/account-command.js.map +1 -1
  18. package/dist/core/extensions/builtin/claude-sdk-oauth/session-binding.d.ts.map +1 -1
  19. package/dist/core/extensions/builtin/claude-sdk-oauth/session-binding.js +36 -19
  20. package/dist/core/extensions/builtin/claude-sdk-oauth/session-binding.js.map +1 -1
  21. package/dist/core/extensions/builtin/claude-sdk-oauth/session-commit-boundary.d.ts.map +1 -1
  22. package/dist/core/extensions/builtin/claude-sdk-oauth/session-commit-boundary.js +21 -10
  23. package/dist/core/extensions/builtin/claude-sdk-oauth/session-commit-boundary.js.map +1 -1
  24. package/dist/core/extensions/builtin/claude-sdk-oauth/session-continuity.d.ts +4 -17
  25. package/dist/core/extensions/builtin/claude-sdk-oauth/session-continuity.d.ts.map +1 -1
  26. package/dist/core/extensions/builtin/claude-sdk-oauth/session-continuity.js +23 -33
  27. package/dist/core/extensions/builtin/claude-sdk-oauth/session-continuity.js.map +1 -1
  28. package/dist/core/extensions/builtin/claude-sdk-oauth/session-stream.d.ts.map +1 -1
  29. package/dist/core/extensions/builtin/claude-sdk-oauth/session-stream.js +1 -0
  30. package/dist/core/extensions/builtin/claude-sdk-oauth/session-stream.js.map +1 -1
  31. package/dist/core/extensions/builtin/claude-sdk-oauth/session-sync.d.ts.map +1 -1
  32. package/dist/core/extensions/builtin/claude-sdk-oauth/session-sync.js +5 -3
  33. package/dist/core/extensions/builtin/claude-sdk-oauth/session-sync.js.map +1 -1
  34. package/dist/core/extensions/builtin/claude-sdk-oauth/session-turn-attempt.d.ts.map +1 -1
  35. package/dist/core/extensions/builtin/claude-sdk-oauth/session-turn-attempt.js +8 -3
  36. package/dist/core/extensions/builtin/claude-sdk-oauth/session-turn-attempt.js.map +1 -1
  37. package/dist/core/extensions/builtin/claude-sdk-oauth/tools.d.ts +6 -5
  38. package/dist/core/extensions/builtin/claude-sdk-oauth/tools.d.ts.map +1 -1
  39. package/dist/core/extensions/builtin/claude-sdk-oauth/tools.js +6 -5
  40. package/dist/core/extensions/builtin/claude-sdk-oauth/tools.js.map +1 -1
  41. package/dist/core/extensions/builtin/compaction/circuit-breaker.d.ts +8 -0
  42. package/dist/core/extensions/builtin/compaction/circuit-breaker.d.ts.map +1 -1
  43. package/dist/core/extensions/builtin/compaction/circuit-breaker.js +8 -0
  44. package/dist/core/extensions/builtin/compaction/circuit-breaker.js.map +1 -1
  45. package/dist/core/extensions/builtin/compaction/deterministic-fallback.d.ts +8 -0
  46. package/dist/core/extensions/builtin/compaction/deterministic-fallback.d.ts.map +1 -1
  47. package/dist/core/extensions/builtin/compaction/deterministic-fallback.js +125 -20
  48. package/dist/core/extensions/builtin/compaction/deterministic-fallback.js.map +1 -1
  49. package/dist/core/extensions/builtin/compaction/fallback-failed-turn-normalization.d.ts +18 -0
  50. package/dist/core/extensions/builtin/compaction/fallback-failed-turn-normalization.d.ts.map +1 -0
  51. package/dist/core/extensions/builtin/compaction/fallback-failed-turn-normalization.js +20 -0
  52. package/dist/core/extensions/builtin/compaction/fallback-failed-turn-normalization.js.map +1 -0
  53. package/dist/core/extensions/builtin/compaction/index.d.ts.map +1 -1
  54. package/dist/core/extensions/builtin/compaction/index.js +54 -11
  55. package/dist/core/extensions/builtin/compaction/index.js.map +1 -1
  56. package/dist/core/extensions/builtin/compaction/lane-policy.d.ts +3 -0
  57. package/dist/core/extensions/builtin/compaction/lane-policy.d.ts.map +1 -1
  58. package/dist/core/extensions/builtin/compaction/lane-policy.js +47 -23
  59. package/dist/core/extensions/builtin/compaction/lane-policy.js.map +1 -1
  60. package/dist/core/extensions/builtin/goal/agent-end-continuation.d.ts.map +1 -1
  61. package/dist/core/extensions/builtin/goal/agent-end-continuation.js +11 -0
  62. package/dist/core/extensions/builtin/goal/agent-end-continuation.js.map +1 -1
  63. package/dist/core/extensions/builtin/goal/cache-warm-renderer.js +6 -4
  64. package/dist/core/extensions/builtin/goal/cache-warm-renderer.js.map +1 -1
  65. package/dist/core/extensions/builtin/goal/cache-warm.d.ts +25 -1
  66. package/dist/core/extensions/builtin/goal/cache-warm.d.ts.map +1 -1
  67. package/dist/core/extensions/builtin/goal/cache-warm.js +29 -10
  68. package/dist/core/extensions/builtin/goal/cache-warm.js.map +1 -1
  69. package/dist/core/extensions/builtin/goal/continuation.d.ts +3 -1
  70. package/dist/core/extensions/builtin/goal/continuation.d.ts.map +1 -1
  71. package/dist/core/extensions/builtin/goal/continuation.js +17 -2
  72. package/dist/core/extensions/builtin/goal/continuation.js.map +1 -1
  73. package/dist/core/extensions/builtin/goal/lifecycle-helpers.d.ts.map +1 -1
  74. package/dist/core/extensions/builtin/goal/lifecycle-helpers.js +1 -0
  75. package/dist/core/extensions/builtin/goal/lifecycle-helpers.js.map +1 -1
  76. package/dist/core/extensions/builtin/goal/monitor-continuation.d.ts +1 -1
  77. package/dist/core/extensions/builtin/goal/monitor-continuation.d.ts.map +1 -1
  78. package/dist/core/extensions/builtin/goal/monitor-continuation.js +8 -3
  79. package/dist/core/extensions/builtin/goal/monitor-continuation.js.map +1 -1
  80. package/dist/core/extensions/builtin/gpt-account.d.ts +5 -1
  81. package/dist/core/extensions/builtin/gpt-account.d.ts.map +1 -1
  82. package/dist/core/extensions/builtin/gpt-account.js +9 -26
  83. package/dist/core/extensions/builtin/gpt-account.js.map +1 -1
  84. package/dist/core/extensions/builtin/hooks/plugin-manifest.js +2 -2
  85. package/dist/core/extensions/builtin/hooks/plugin-manifest.js.map +1 -1
  86. package/dist/core/extensions/builtin/hooks/safety.js +2 -2
  87. package/dist/core/extensions/builtin/hooks/safety.js.map +1 -1
  88. package/dist/core/extensions/builtin/monitor-state-event.d.ts +18 -0
  89. package/dist/core/extensions/builtin/monitor-state-event.d.ts.map +1 -1
  90. package/dist/core/extensions/builtin/monitor-state-event.js +23 -0
  91. package/dist/core/extensions/builtin/monitor-state-event.js.map +1 -1
  92. package/dist/core/extensions/builtin/oauth-login-interaction.d.ts +24 -0
  93. package/dist/core/extensions/builtin/oauth-login-interaction.d.ts.map +1 -0
  94. package/dist/core/extensions/builtin/oauth-login-interaction.js +77 -0
  95. package/dist/core/extensions/builtin/oauth-login-interaction.js.map +1 -0
  96. package/dist/core/extensions/builtin/permission-system/external-dir.d.ts.map +1 -1
  97. package/dist/core/extensions/builtin/permission-system/external-dir.js +5 -51
  98. package/dist/core/extensions/builtin/permission-system/external-dir.js.map +1 -1
  99. package/dist/core/extensions/builtin/permission-system/parsers.d.ts.map +1 -1
  100. package/dist/core/extensions/builtin/permission-system/parsers.js +5 -7
  101. package/dist/core/extensions/builtin/permission-system/parsers.js.map +1 -1
  102. package/dist/core/extensions/builtin/prompt-preset/claude-fable-5-1.js +1 -1
  103. package/dist/core/extensions/builtin/prompt-preset/claude-fable-5-1.js.map +1 -1
  104. package/dist/core/extensions/builtin/prompt-preset/claude-fable-5.js +1 -1
  105. package/dist/core/extensions/builtin/prompt-preset/claude-fable-5.js.map +1 -1
  106. package/dist/core/extensions/builtin/prompt-preset/execution-tooling.d.ts +14 -7
  107. package/dist/core/extensions/builtin/prompt-preset/execution-tooling.d.ts.map +1 -1
  108. package/dist/core/extensions/builtin/prompt-preset/execution-tooling.js +34 -13
  109. package/dist/core/extensions/builtin/prompt-preset/execution-tooling.js.map +1 -1
  110. package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.d.ts +6 -10
  111. package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.d.ts.map +1 -1
  112. package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.js +14 -9
  113. package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.js.map +1 -1
  114. package/dist/core/extensions/builtin/prompt-preset/gpt-6-astra.d.ts +15 -15
  115. package/dist/core/extensions/builtin/prompt-preset/gpt-6-astra.d.ts.map +1 -1
  116. package/dist/core/extensions/builtin/prompt-preset/gpt-6-astra.js +49 -21
  117. package/dist/core/extensions/builtin/prompt-preset/gpt-6-astra.js.map +1 -1
  118. package/dist/core/extensions/builtin/prompt-preset/kimi-k3.js +1 -1
  119. package/dist/core/extensions/builtin/prompt-preset/kimi-k3.js.map +1 -1
  120. package/dist/core/extensions/builtin/service-tier.d.ts +2 -0
  121. package/dist/core/extensions/builtin/service-tier.d.ts.map +1 -1
  122. package/dist/core/extensions/builtin/service-tier.js +17 -1
  123. package/dist/core/extensions/builtin/service-tier.js.map +1 -1
  124. package/dist/core/extensions/builtin/terminal/durable-command.d.ts.map +1 -1
  125. package/dist/core/extensions/builtin/terminal/durable-command.js +3 -0
  126. package/dist/core/extensions/builtin/terminal/durable-command.js.map +1 -1
  127. package/dist/core/extensions/builtin/terminal/durable-file.d.ts.map +1 -1
  128. package/dist/core/extensions/builtin/terminal/durable-file.js +2 -0
  129. package/dist/core/extensions/builtin/terminal/durable-file.js.map +1 -1
  130. package/dist/core/extensions/builtin/terminal/extension.d.ts.map +1 -1
  131. package/dist/core/extensions/builtin/terminal/extension.js +14 -2
  132. package/dist/core/extensions/builtin/terminal/extension.js.map +1 -1
  133. package/dist/core/extensions/builtin/terminal/monitor-notify.d.ts.map +1 -1
  134. package/dist/core/extensions/builtin/terminal/monitor-notify.js +27 -5
  135. package/dist/core/extensions/builtin/terminal/monitor-notify.js.map +1 -1
  136. package/dist/core/extensions/builtin/terminal/monitor-registry.d.ts +17 -0
  137. package/dist/core/extensions/builtin/terminal/monitor-registry.d.ts.map +1 -1
  138. package/dist/core/extensions/builtin/terminal/monitor-registry.js +76 -14
  139. package/dist/core/extensions/builtin/terminal/monitor-registry.js.map +1 -1
  140. package/dist/core/extensions/builtin/terminal/notify.d.ts +2 -0
  141. package/dist/core/extensions/builtin/terminal/notify.d.ts.map +1 -1
  142. package/dist/core/extensions/builtin/terminal/notify.js +6 -1
  143. package/dist/core/extensions/builtin/terminal/notify.js.map +1 -1
  144. package/dist/core/extensions/builtin/terminal/session-bundle.d.ts +3 -1
  145. package/dist/core/extensions/builtin/terminal/session-bundle.d.ts.map +1 -1
  146. package/dist/core/extensions/builtin/terminal/session-bundle.js +13 -0
  147. package/dist/core/extensions/builtin/terminal/session-bundle.js.map +1 -1
  148. package/dist/core/extensions/builtin/terminal/shared.d.ts +13 -2
  149. package/dist/core/extensions/builtin/terminal/shared.d.ts.map +1 -1
  150. package/dist/core/extensions/builtin/terminal/shared.js +15 -2
  151. package/dist/core/extensions/builtin/terminal/shared.js.map +1 -1
  152. package/dist/core/extensions/builtin/terminal/tools/monitor.d.ts.map +1 -1
  153. package/dist/core/extensions/builtin/terminal/tools/monitor.js +8 -1
  154. package/dist/core/extensions/builtin/terminal/tools/monitor.js.map +1 -1
  155. package/dist/core/extensions/builtin/tool-search/index.d.ts.map +1 -1
  156. package/dist/core/extensions/builtin/tool-search/index.js +1 -0
  157. package/dist/core/extensions/builtin/tool-search/index.js.map +1 -1
  158. package/dist/core/extensions/builtin/tool-search/service.d.ts +4 -0
  159. package/dist/core/extensions/builtin/tool-search/service.d.ts.map +1 -1
  160. package/dist/core/extensions/builtin/tool-search/service.js +11 -0
  161. package/dist/core/extensions/builtin/tool-search/service.js.map +1 -1
  162. package/dist/core/extensions/runner.d.ts +1 -0
  163. package/dist/core/extensions/runner.d.ts.map +1 -1
  164. package/dist/core/extensions/runner.js +8 -1
  165. package/dist/core/extensions/runner.js.map +1 -1
  166. package/dist/core/extensions/types.d.ts +9 -0
  167. package/dist/core/extensions/types.d.ts.map +1 -1
  168. package/dist/core/extensions/types.js.map +1 -1
  169. package/dist/core/high-reasoning-warning.d.ts.map +1 -1
  170. package/dist/core/high-reasoning-warning.js +4 -6
  171. package/dist/core/high-reasoning-warning.js.map +1 -1
  172. package/dist/core/sdk.d.ts +1 -1
  173. package/dist/core/sdk.d.ts.map +1 -1
  174. package/dist/core/sdk.js +25 -6
  175. package/dist/core/sdk.js.map +1 -1
  176. package/dist/core/settings-manager.js +1 -1
  177. package/dist/core/settings-manager.js.map +1 -1
  178. package/dist/core/settings-shapes.js.map +1 -1
  179. package/dist/core/tools/bounded-realpath.d.ts +28 -0
  180. package/dist/core/tools/bounded-realpath.d.ts.map +1 -0
  181. package/dist/core/tools/bounded-realpath.js +53 -0
  182. package/dist/core/tools/bounded-realpath.js.map +1 -0
  183. package/dist/core/tools/file-mutation-queue.d.ts.map +1 -1
  184. package/dist/core/tools/file-mutation-queue.js +15 -13
  185. package/dist/core/tools/file-mutation-queue.js.map +1 -1
  186. package/dist/core/tools/filesystem-policy.d.ts +7 -0
  187. package/dist/core/tools/filesystem-policy.d.ts.map +1 -1
  188. package/dist/core/tools/filesystem-policy.js +25 -15
  189. package/dist/core/tools/filesystem-policy.js.map +1 -1
  190. package/dist/core/trust-manager.d.ts.map +1 -1
  191. package/dist/core/trust-manager.js +13 -2
  192. package/dist/core/trust-manager.js.map +1 -1
  193. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  194. package/dist/modes/interactive/interactive-mode.js +1 -0
  195. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  196. package/dist/modes/interactive/tips/catalog/memory-tips.d.ts.map +1 -1
  197. package/dist/modes/interactive/tips/catalog/memory-tips.js +6 -0
  198. package/dist/modes/interactive/tips/catalog/memory-tips.js.map +1 -1
  199. package/dist/modes/interactive/tips/catalog/subagent-tips.d.ts.map +1 -1
  200. package/dist/modes/interactive/tips/catalog/subagent-tips.js +6 -0
  201. package/dist/modes/interactive/tips/catalog/subagent-tips.js.map +1 -1
  202. package/dist/modes/rpc/host-lifecycle.d.ts.map +1 -1
  203. package/dist/modes/rpc/host-lifecycle.js +31 -5
  204. package/dist/modes/rpc/host-lifecycle.js.map +1 -1
  205. package/dist/modes/rpc/host-watchdog.d.ts +11 -0
  206. package/dist/modes/rpc/host-watchdog.d.ts.map +1 -1
  207. package/dist/modes/rpc/host-watchdog.js +16 -2
  208. package/dist/modes/rpc/host-watchdog.js.map +1 -1
  209. package/dist/modes/rpc/multi-session-host.d.ts.map +1 -1
  210. package/dist/modes/rpc/multi-session-host.js +54 -16
  211. package/dist/modes/rpc/multi-session-host.js.map +1 -1
  212. package/dist/modes/rpc/socket-ownership.d.ts +46 -0
  213. package/dist/modes/rpc/socket-ownership.d.ts.map +1 -0
  214. package/dist/modes/rpc/socket-ownership.js +178 -0
  215. package/dist/modes/rpc/socket-ownership.js.map +1 -0
  216. package/dist/utils/fs-watch.d.ts +17 -0
  217. package/dist/utils/fs-watch.d.ts.map +1 -1
  218. package/dist/utils/fs-watch.js +38 -10
  219. package/dist/utils/fs-watch.js.map +1 -1
  220. package/dist/utils/paths.d.ts +33 -0
  221. package/dist/utils/paths.d.ts.map +1 -1
  222. package/dist/utils/paths.js +109 -3
  223. package/dist/utils/paths.js.map +1 -1
  224. package/docs/development.md +3 -2
  225. package/docs/providers.md +5 -1
  226. package/docs/settings.md +1 -0
  227. package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +31 -0
  228. package/node_modules/@code-yeongyu/senpi-codemode/README.md +14 -1
  229. package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
  230. package/node_modules/@code-yeongyu/senpi-codemode/src/bridge/protocol.ts +1 -0
  231. package/node_modules/@code-yeongyu/senpi-codemode/src/extension/runtime-factory.ts +3 -0
  232. package/node_modules/@code-yeongyu/senpi-codemode/src/extension/session-manager.ts +7 -0
  233. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/AGENTS.md +7 -0
  234. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/jl/kernel.ts +4 -0
  235. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-contract.ts +3 -0
  236. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-core.js +29 -0
  237. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-indirect-eval.js +10 -6
  238. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-shell-capture.d.ts +16 -0
  239. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-shell-capture.js +44 -8
  240. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-startup.ts +1 -0
  241. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/py/kernel-contract.ts +3 -0
  242. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/py/transport.ts +9 -1
  243. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/rb/kernel.ts +4 -0
  244. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/session-env.ts +56 -0
  245. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/shared/subprocess-contract.ts +3 -0
  246. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/shared/subprocess-kernel.ts +9 -1
  247. package/node_modules/@code-yeongyu/senpi-codemode/src/output/output-meta.ts +26 -2
  248. package/node_modules/@code-yeongyu/senpi-codemode/src/prompt/eval-prompt.ts +17 -24
  249. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/image.ts +12 -3
  250. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  251. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js +2 -2
  252. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js.map +1 -1
  253. package/node_modules/@earendil-works/pi-agent-core/dist/assistant-terminal-state.d.ts +7 -0
  254. package/node_modules/@earendil-works/pi-agent-core/dist/assistant-terminal-state.d.ts.map +1 -1
  255. package/node_modules/@earendil-works/pi-agent-core/dist/assistant-terminal-state.js +19 -0
  256. package/node_modules/@earendil-works/pi-agent-core/dist/assistant-terminal-state.js.map +1 -1
  257. package/node_modules/@earendil-works/pi-agent-core/dist/empty-assistant-recovery.d.ts.map +1 -1
  258. package/node_modules/@earendil-works/pi-agent-core/dist/empty-assistant-recovery.js +24 -16
  259. package/node_modules/@earendil-works/pi-agent-core/dist/empty-assistant-recovery.js.map +1 -1
  260. package/node_modules/@earendil-works/pi-agent-core/dist/index.d.ts +1 -1
  261. package/node_modules/@earendil-works/pi-agent-core/dist/index.d.ts.map +1 -1
  262. package/node_modules/@earendil-works/pi-agent-core/dist/index.js +1 -1
  263. package/node_modules/@earendil-works/pi-agent-core/dist/index.js.map +1 -1
  264. package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
  265. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.d.ts.map +1 -1
  266. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js +47 -178
  267. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js.map +1 -1
  268. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-tool-references.d.ts +3 -0
  269. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-tool-references.d.ts.map +1 -0
  270. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-tool-references.js +260 -0
  271. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-tool-references.js.map +1 -0
  272. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.d.ts.map +1 -1
  273. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js +1 -0
  274. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js.map +1 -1
  275. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.d.ts.map +1 -1
  276. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js +1 -0
  277. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js.map +1 -1
  278. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/anthropic-callback-listener.d.ts +40 -0
  279. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/anthropic-callback-listener.d.ts.map +1 -0
  280. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/anthropic-callback-listener.js +138 -0
  281. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/anthropic-callback-listener.js.map +1 -0
  282. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/anthropic.d.ts +2 -3
  283. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/anthropic.d.ts.map +1 -1
  284. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/anthropic.js +42 -139
  285. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/anthropic.js.map +1 -1
  286. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/authorization-input.d.ts +6 -0
  287. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/authorization-input.d.ts.map +1 -0
  288. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/authorization-input.js +29 -0
  289. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/authorization-input.js.map +1 -0
  290. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/error-details.d.ts +3 -0
  291. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/error-details.d.ts.map +1 -0
  292. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/error-details.js +20 -0
  293. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/error-details.js.map +1 -0
  294. package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
  295. package/node_modules/@earendil-works/pi-ai/dist/providers/data/amazon-bedrock.json +1 -1
  296. package/node_modules/@earendil-works/pi-ai/dist/providers/data/azure-openai-responses.json +1 -1
  297. package/node_modules/@earendil-works/pi-ai/dist/providers/data/fireworks.json +1 -1
  298. package/node_modules/@earendil-works/pi-ai/dist/providers/data/github-copilot.json +1 -1
  299. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openai-codex.json +1 -1
  300. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openai.json +1 -1
  301. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode.json +1 -1
  302. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opengateway.json +1 -1
  303. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
  304. package/node_modules/@earendil-works/pi-ai/dist/providers/data/vercel-ai-gateway.json +1 -1
  305. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/recovery-stream-terminal.d.ts.map +1 -1
  306. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/recovery-stream-terminal.js +16 -1
  307. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/recovery-stream-terminal.js.map +1 -1
  308. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts +7 -0
  309. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts.map +1 -1
  310. package/node_modules/@earendil-works/pi-ai/dist/types.js.map +1 -1
  311. package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.d.ts +1 -1
  312. package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.d.ts.map +1 -1
  313. package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.js +14 -3
  314. package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.js.map +1 -1
  315. package/node_modules/@earendil-works/pi-ai/dist/utils/server-fallback-receipt.d.ts +2 -1
  316. package/node_modules/@earendil-works/pi-ai/dist/utils/server-fallback-receipt.d.ts.map +1 -1
  317. package/node_modules/@earendil-works/pi-ai/dist/utils/server-fallback-receipt.js +16 -0
  318. package/node_modules/@earendil-works/pi-ai/dist/utils/server-fallback-receipt.js.map +1 -1
  319. package/node_modules/@earendil-works/pi-ai/package.json +2 -2
  320. package/node_modules/@earendil-works/pi-pty/package.json +1 -1
  321. package/node_modules/@earendil-works/pi-telemetry/package.json +1 -1
  322. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  323. package/package.json +7 -7
@@ -43,7 +43,7 @@ import { areExperimentalFeaturesEnabled } from "./experimental.js";
43
43
  import { exportSessionToHtml } from "./export-html/index.js";
44
44
  import { createToolHtmlRenderer } from "./export-html/tool-renderer.js";
45
45
  import { ModelUsabilityBudgetError, projectModelUsabilityBudget, } from "./extensions/builtin/compaction/model-usability-budget.js";
46
- import { resolveReserveTokens } from "./extensions/builtin/compaction/policy.js";
46
+ import { resolveEffectiveReserveTokens, resolveReserveTokens, shouldTriggerCompaction, } from "./extensions/builtin/compaction/policy.js";
47
47
  import { WAKE_SOURCE_STATE_EVENT } from "./extensions/builtin/monitor-state-event.js";
48
48
  import { CODEX_RESPONSES_API } from "./extensions/builtin/service-tier.js";
49
49
  import { deriveExtensionRegistrationId } from "./extensions/builtin/tool-search/engine/marker.js";
@@ -1137,6 +1137,31 @@ export class AgentSession {
1137
1137
  }
1138
1138
  _incrementMessageRevision() {
1139
1139
  this._messageRevision++;
1140
+ // A revision bump alone is not evidence that the rejected context changed:
1141
+ // releasing here let a synthetic bump retry the unchanged oversized context
1142
+ // (#7921 case 6). Release only once the context actually shrank.
1143
+ this._releaseBlockedPostCompactionAdmissionIfReduced();
1144
+ }
1145
+ /** Byte-derived size of the context an admission decision would carry. */
1146
+ _blockedAdmissionContentTokens() {
1147
+ return estimateMessagesTokens(filterContextExcludedMessages(this.agent.state.messages));
1148
+ }
1149
+ /** A compaction that genuinely reduced the context clears the blocked state. */
1150
+ _releaseBlockedPostCompactionAdmissionIfReduced() {
1151
+ const blocked = this._blockedPostCompactionAssistant;
1152
+ if (blocked === undefined)
1153
+ return;
1154
+ if (this._blockedAdmissionContentTokens() < blocked.contentTokens) {
1155
+ this._blockedPostCompactionAssistant = undefined;
1156
+ }
1157
+ }
1158
+ /**
1159
+ * Unconditional release for manual `/compact`, the user's explicit remedy. An
1160
+ * ordinary user prompt is deliberately not a release: it only adds context, so
1161
+ * it cannot make the rejected context admissible, and the pre-prompt gate
1162
+ * already owns its own fail-closed rejection for that route.
1163
+ */
1164
+ _releaseBlockedPostCompactionAdmission() {
1140
1165
  this._blockedPostCompactionAssistant = undefined;
1141
1166
  }
1142
1167
  getMessageRevision() {
@@ -1386,7 +1411,11 @@ export class AgentSession {
1386
1411
  return undefined;
1387
1412
  }
1388
1413
  const model = this.model;
1389
- if (!model || this._isAssistantFromBeforeLatestCompaction(message)) {
1414
+ // Narrowed to the stale usage number itself: pre-boundary provenance does
1415
+ // not exempt a context whose own content already exceeds the policy.
1416
+ if (!model)
1417
+ return undefined;
1418
+ if (this._isAssistantFromBeforeLatestCompaction(message) && !this._exceedsPolicyByContentEstimate()) {
1390
1419
  return undefined;
1391
1420
  }
1392
1421
  const sameModel = isSameOverflowSource(message, model, this._modelRuntime.getCompatibilityRequestConfig(model).upstreamModelId);
@@ -1422,13 +1451,31 @@ export class AgentSession {
1422
1451
  if (compactionEntry &&
1423
1452
  usageMessage?.role === "assistant" &&
1424
1453
  this._isAssistantFromBeforeLatestCompaction(usageMessage)) {
1425
- return undefined;
1454
+ // Drop only the stale usage number; the messages themselves still count.
1455
+ const contentTokens = estimateMessagesTokens(messages);
1456
+ return shouldCompact(contentTokens, model.contextWindow, settings) ? "threshold" : undefined;
1426
1457
  }
1427
1458
  }
1428
1459
  contextTokens = estimate.tokens;
1429
1460
  }
1430
1461
  return shouldCompact(contextTokens, model.contextWindow, settings) ? "threshold" : undefined;
1431
1462
  }
1463
+ /**
1464
+ * Content measured by bytes, ignoring every provider usage number. The
1465
+ * stale-usage exemptions below only claim that a usage figure measured before
1466
+ * the accepted compaction boundary is not evidence of current pressure; they
1467
+ * must not exempt the messages themselves, because fresh post-boundary content
1468
+ * (a large tool result, late steering) is measurable without any usage report
1469
+ * (#7921 case 5).
1470
+ */
1471
+ _exceedsPolicyByContentEstimate() {
1472
+ const model = this.model;
1473
+ if (!model)
1474
+ return false;
1475
+ const settings = this._getCompactionSettings();
1476
+ const contextTokens = estimateMessagesTokens(filterContextExcludedMessages(this.agent.state.messages));
1477
+ return shouldCompact(contextTokens, model.contextWindow, settings);
1478
+ }
1432
1479
  _hasPendingPostCompactionUsageExemption(message) {
1433
1480
  return (this._skipNextPostCompactionAssistantCheck &&
1434
1481
  !this._assistantsPendingAtCompaction.has(message) &&
@@ -4285,6 +4332,9 @@ export class AgentSession {
4285
4332
  const model = this.model;
4286
4333
  if (!model)
4287
4334
  throw new Error(formatNoModelSelectedMessage());
4335
+ // Manual compaction is the user's explicit remedy for a blocked admission
4336
+ // (#7921 case 6).
4337
+ this._releaseBlockedPostCompactionAdmission();
4288
4338
  const pathEntries = this.sessionManager.getBranch();
4289
4339
  const settings = cursorOverflowCompactionSettings(this._getCompactionSettings(), model.provider, "manual");
4290
4340
  if (!prepareCompaction(pathEntries, settings)) {
@@ -4842,10 +4892,9 @@ export class AgentSession {
4842
4892
  * @returns Whether the post-run loop should call `agent.continue()` for overflow recovery or queued messages
4843
4893
  */
4844
4894
  async _enforceCompactionBeforeProvider(assistantMessage, skipAbortedCheck, inlineReason, retryAfterCompaction = false) {
4895
+ this._releaseBlockedPostCompactionAdmissionIfReduced();
4845
4896
  const blockedAdmission = this._blockedPostCompactionAssistant;
4846
- if (blockedAdmission !== undefined &&
4847
- blockedAdmission.assistant === assistantMessage &&
4848
- blockedAdmission.revision === this._messageRevision) {
4897
+ if (blockedAdmission !== undefined && blockedAdmission.assistant === assistantMessage) {
4849
4898
  throw new RequiredCompactionError();
4850
4899
  }
4851
4900
  const settings = this._getCompactionSettings();
@@ -4877,12 +4926,28 @@ export class AgentSession {
4877
4926
  }
4878
4927
  throw new RequiredCompactionError();
4879
4928
  }
4929
+ /**
4930
+ * Pending queued input the provider will also carry on this turn. Steering and
4931
+ * follow-up text enqueued after the admission projection was assembled - by a
4932
+ * `before_agent_start` handler, an extension action, or the user racing the
4933
+ * gate - is drained into the same run, so the final gate must measure it
4934
+ * (#7921 case 5).
4935
+ */
4936
+ _pendingQueuedInputMessages() {
4937
+ const timestamp = Date.now();
4938
+ return [...this._steeringMessages, ...this._followUpMessages].map((text) => ({
4939
+ role: "user",
4940
+ content: [{ type: "text", text }],
4941
+ timestamp,
4942
+ }));
4943
+ }
4880
4944
  /**
4881
4945
  * The normal pre-prompt check only estimates persisted session context. This
4882
4946
  * final gate also includes turn-local messages which the provider will see:
4883
- * the current prompt, next-turn custom messages, and before_agent_start
4884
- * additions. Compaction rewrites only session context, so callers retain and
4885
- * reapply their already-assembled one-shot additions after it succeeds.
4947
+ * the current prompt, next-turn custom messages, before_agent_start additions,
4948
+ * and steering or follow-up input queued after that projection was assembled.
4949
+ * Compaction rewrites only session context, so callers retain and reapply
4950
+ * their already-assembled one-shot additions after it succeeds.
4886
4951
  */
4887
4952
  async _enforceFinalProviderAdmission(messages) {
4888
4953
  // User-only prompts are deliberately admitted without this gate: prompt
@@ -4890,18 +4955,24 @@ export class AgentSession {
4890
4955
  // (issues #531/#886), so oversized user prompts rely on threshold
4891
4956
  // compaction — which also samples the local transcript estimate — and on
4892
4957
  // provider-overflow recovery. This gate closes the separate gap opened by
4893
- // turn-local custom additions, which the pre-prompt check cannot observe.
4894
- if (!messages.some((message) => message.role === "custom"))
4958
+ // turn-local custom additions and by late queued input, neither of which the
4959
+ // pre-prompt check can observe.
4960
+ const lateQueuedMessages = this._pendingQueuedInputMessages();
4961
+ if (!messages.some((message) => message.role === "custom") && lateQueuedMessages.length === 0)
4895
4962
  return;
4896
4963
  const model = this.model;
4897
4964
  if (!model)
4898
4965
  return;
4899
4966
  const settings = this._getCompactionSettings();
4900
- const reserveTokens = settings.reserveScalingEnabled === false
4901
- ? settings.reserveTokens
4902
- : resolveReserveTokens(model.contextWindow, settings.reserveTokens);
4967
+ const reserveTokens = resolveEffectiveReserveTokens(model.contextWindow, settings);
4903
4968
  const isOversized = () => {
4904
- const providerMessages = filterContextExcludedMessages([...this.agent.state.messages, ...messages]);
4969
+ const providerMessages = filterContextExcludedMessages([
4970
+ ...this.agent.state.messages,
4971
+ ...messages,
4972
+ // Re-read the queues on every sample: this closure is evaluated again
4973
+ // after compaction, when more input may have arrived.
4974
+ ...this._pendingQueuedInputMessages(),
4975
+ ]);
4905
4976
  const estimate = estimateContextTokens(providerMessages);
4906
4977
  const usageMessage = estimate.lastUsageIndex === null ? undefined : providerMessages[estimate.lastUsageIndex];
4907
4978
  // Kept assistant usage can describe the pre-compaction request. Once a
@@ -4945,7 +5016,12 @@ export class AgentSession {
4945
5016
  // compaction boundary. This prevents a stale pre-compaction usage/error
4946
5017
  // from retriggering compaction on the first prompt after compaction.
4947
5018
  const compactionEntry = getLatestCompactionEntry(this.sessionManager.getBranch());
4948
- if (this._isAssistantFromBeforeLatestCompaction(assistantMessage)) {
5019
+ // The inline (pre-prompt) caller re-samples the current context itself and
5020
+ // owns the fail-closed rejection, so only the automatic route needs the
5021
+ // narrowed exemption here: fresh post-boundary content still counts even
5022
+ // though this message's own usage predates the boundary (#7921 case 5).
5023
+ if (this._isAssistantFromBeforeLatestCompaction(assistantMessage) &&
5024
+ (inlineReason !== undefined || !this._exceedsPolicyByContentEstimate())) {
4949
5025
  return false;
4950
5026
  }
4951
5027
  // Case 1: Overflow - LLM returned context overflow error.
@@ -4980,7 +5056,7 @@ export class AgentSession {
4980
5056
  getLatestCompactionEntry(this.sessionManager.getBranch()) !== null) {
4981
5057
  this._blockedPostCompactionAssistant = {
4982
5058
  assistant: assistantMessage,
4983
- revision: this._messageRevision,
5059
+ contentTokens: this._blockedAdmissionContentTokens(),
4984
5060
  };
4985
5061
  }
4986
5062
  return compacted;
@@ -5046,6 +5122,7 @@ export class AgentSession {
5046
5122
  // This ensures sessions that hit persistent API errors (e.g. 529) or malformed zero-usage
5047
5123
  // responses can still compact and do not reset context accounting.
5048
5124
  let contextTokens;
5125
+ let staleUsageContentTokens;
5049
5126
  if (inlineReason) {
5050
5127
  const messages = filterContextExcludedMessages(this.sessionManager.buildSessionContext().messages);
5051
5128
  contextTokens = estimateContextTokens(messages).tokens;
@@ -5066,10 +5143,13 @@ export class AgentSession {
5066
5143
  if (compactionEntry &&
5067
5144
  usageMsg.role === "assistant" &&
5068
5145
  this._isAssistantFromBeforeLatestCompaction(usageMsg)) {
5069
- return false;
5146
+ // Drop only the stale usage number; the messages themselves still count.
5147
+ staleUsageContentTokens = estimateMessagesTokens(messages);
5148
+ if (!shouldCompact(staleUsageContentTokens, contextWindow, settings))
5149
+ return false;
5070
5150
  }
5071
5151
  }
5072
- contextTokens = estimate.tokens;
5152
+ contextTokens = staleUsageContentTokens ?? estimate.tokens;
5073
5153
  }
5074
5154
  }
5075
5155
  if (shouldCompact(contextTokens, contextWindow, settings)) {
@@ -5084,7 +5164,7 @@ export class AgentSession {
5084
5164
  getLatestCompactionEntry(this.sessionManager.getBranch()) !== null) {
5085
5165
  this._blockedPostCompactionAssistant = {
5086
5166
  assistant: assistantMessage,
5087
- revision: this._messageRevision,
5167
+ contentTokens: this._blockedAdmissionContentTokens(),
5088
5168
  };
5089
5169
  }
5090
5170
  return compacted;
@@ -5177,11 +5257,27 @@ export class AgentSession {
5177
5257
  const contextTokens = usageMessage?.role === "assistant" && this._isAssistantFromBeforeLatestCompaction(usageMessage)
5178
5258
  ? estimateMessagesTokens(canonicalMessages)
5179
5259
  : estimate.tokens;
5180
- if (!shouldCompact(contextTokens, model.contextWindow, settings))
5260
+ // An explicit user prompt passes the proactive policy in the compaction
5261
+ // extension's before_agent_start, which automatic continuations never emit.
5262
+ // Sampling the same predicate here makes both routes compact at the same
5263
+ // usage instead of letting a continuation ride past the threshold up to the
5264
+ // hard valve (#7921 case 4).
5265
+ const atHardLimit = shouldCompact(contextTokens, model.contextWindow, settings);
5266
+ const overProactiveThreshold = shouldTriggerCompaction({
5267
+ tokens: contextTokens,
5268
+ contextWindow: model.contextWindow,
5269
+ percent: model.contextWindow > 0 ? (contextTokens / model.contextWindow) * 100 : 0,
5270
+ }, model.contextWindow, settings);
5271
+ if (!atHardLimit && !overProactiveThreshold)
5181
5272
  return;
5182
5273
  const compacted = await this._runPrePromptCompaction(this._findLastAssistantMessage(), true, "pre_prompt");
5183
5274
  if (!compacted) {
5184
- if (this._isCompactionOnCooldown() || this._isCompactionDelegated() || this._hasSupersedingCompactionClaim()) {
5275
+ // Proactive pressure alone must never brick an automatic continuation:
5276
+ // only the hard reserve valve stays fail-closed (#531/#886).
5277
+ if (!atHardLimit ||
5278
+ this._isCompactionOnCooldown() ||
5279
+ this._isCompactionDelegated() ||
5280
+ this._hasSupersedingCompactionClaim()) {
5185
5281
  return;
5186
5282
  }
5187
5283
  throw new RequiredCompactionError();
@@ -5675,6 +5771,7 @@ export class AgentSession {
5675
5771
  }, {
5676
5772
  getModel: () => this.model,
5677
5773
  getServiceTier: () => this.serviceTier,
5774
+ getEffectiveServiceTier: () => this.effectiveServiceTier,
5678
5775
  getScopedModels: () => this._scopedModels,
5679
5776
  isIdle: () => this.isIdle,
5680
5777
  getAgentDir: () => this._agentDir,
@@ -6182,6 +6279,14 @@ export class AgentSession {
6182
6279
  !message.content.some((content) => content.type === "toolCall") &&
6183
6280
  this._retryFallback.canTryFallback());
6184
6281
  }
6282
+ _takeNativeToolSearchInjectionFailure() {
6283
+ try {
6284
+ return getToolSearchService().takeNativeInjectionFailure();
6285
+ }
6286
+ catch {
6287
+ return null;
6288
+ }
6289
+ }
6185
6290
  _getProviderRetryDelayMs(errorMessage) {
6186
6291
  const markerMs = parseRetryAfterMsMarker(errorMessage);
6187
6292
  if (markerMs !== undefined)
@@ -6290,6 +6395,7 @@ export class AgentSession {
6290
6395
  const hardErrorFallback = options.hardErrorFallback === true;
6291
6396
  const sameModelRemint = options.sameModelRemint === true;
6292
6397
  let switchedFallback = false;
6398
+ let sameModelNativeRecovery = false;
6293
6399
  let is429TierRouted = false;
6294
6400
  let hintTierDelayMs;
6295
6401
  const tryFallback = async (reason, failure) => {
@@ -6322,25 +6428,38 @@ export class AgentSession {
6322
6428
  }
6323
6429
  }
6324
6430
  else if (hardErrorFallback) {
6325
- // A non-retryable provider failure must never replay on the same model.
6326
- // Billing-class failures never recover on this account, so the fallback
6327
- // switch pins as the session model instead of reverting after the cooldown.
6328
- const reason = isBillingErrorMessage(errorMessage) ? "billing" : "hard-error";
6329
- switchedFallback = await tryFallback(reason, { errorMessage });
6330
- if (!switchedFallback) {
6331
- const exhaustedChainKey = this._retryFallback.exhaustedChainKey;
6332
- if (exhaustedChainKey) {
6333
- this._emit({
6334
- type: "retry_fallback_exhausted",
6335
- chainKey: exhaustedChainKey,
6336
- lastError: errorMessage,
6337
- });
6431
+ // A rejected native tool-search request is recoverable in place: the
6432
+ // adapter is disabled for the session on the 400, so the SAME model can
6433
+ // succeed on the immediate next attempt and the fallback chain must not
6434
+ // demote the user to a weaker model. The pending flag is consumed once,
6435
+ // so a second rejection takes the ordinary hard-error path below.
6436
+ const nativeSearchFailure = this._takeNativeToolSearchInjectionFailure();
6437
+ if (nativeSearchFailure !== null) {
6438
+ sameModelNativeRecovery = true;
6439
+ // The recovery starts fresh, mirroring the fallback branch's attempt bookkeeping.
6440
+ this._retryAttempt = 1;
6441
+ }
6442
+ else {
6443
+ // A non-retryable provider failure must never replay on the same model.
6444
+ // Billing-class failures never recover on this account, so the fallback
6445
+ // switch pins as the session model instead of reverting after the cooldown.
6446
+ const reason = isBillingErrorMessage(errorMessage) ? "billing" : "hard-error";
6447
+ switchedFallback = await tryFallback(reason, { errorMessage });
6448
+ if (!switchedFallback) {
6449
+ const exhaustedChainKey = this._retryFallback.exhaustedChainKey;
6450
+ if (exhaustedChainKey) {
6451
+ this._emit({
6452
+ type: "retry_fallback_exhausted",
6453
+ chainKey: exhaustedChainKey,
6454
+ lastError: errorMessage,
6455
+ });
6456
+ }
6457
+ this._resolveRetry();
6458
+ return "not-handled";
6338
6459
  }
6339
- this._resolveRetry();
6340
- return "not-handled";
6460
+ // The fallback starts fresh; the failed model's transient attempts do not carry over.
6461
+ this._retryAttempt = 1;
6341
6462
  }
6342
- // The fallback starts fresh; the failed model's transient attempts do not carry over.
6343
- this._retryAttempt = 1;
6344
6463
  }
6345
6464
  else if (isRefusal) {
6346
6465
  // Refusals are only retried through a new chain candidate. They never use
@@ -6635,7 +6754,7 @@ export class AgentSession {
6635
6754
  // stay deterministic; provider-derived hints on the non-429 path remain
6636
6755
  // authoritative and fallback switches stay exact.
6637
6756
  const localExponentialMs = retryBackoffDelayMs(retryProfile.turn.backoff, this._retryAttempt, this._retryRandom());
6638
- const delayMs = switchedFallback
6757
+ const delayMs = switchedFallback || sameModelNativeRecovery
6639
6758
  ? 0
6640
6759
  : is429TierRouted
6641
6760
  ? (hintTierDelayMs ?? providerDelayMs ?? localExponentialMs)