mixdog 1.3.5 → 1.4.1

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 (515) hide show
  1. package/NOTICE.md +2 -2
  2. package/README.md +2 -2
  3. package/package.json +2 -11
  4. package/scripts/check-voice-runtime-inputs.mjs +25 -0
  5. package/scripts/daemon-stub.mjs +1 -1
  6. package/scripts/gate-local.mjs +16 -5
  7. package/scripts/latest-guard.mjs +21 -9
  8. package/scripts/lib/isolated-test-env.mjs +10 -5
  9. package/scripts/lib/run-node-tests.mjs +37 -37
  10. package/scripts/lib/scoped-temp.d.mts +16 -0
  11. package/scripts/lib/scoped-temp.mjs +123 -0
  12. package/scripts/lib/stale-temp.mjs +44 -0
  13. package/scripts/native-release-status.mjs +2 -2
  14. package/scripts/post-release-check.mjs +1 -6
  15. package/scripts/pptx-kit-index.mjs +17 -4
  16. package/scripts/recall-history-cases.json +1 -1
  17. package/scripts/suite-health.mjs +20 -2
  18. package/scripts/test-data-dir.mjs +10 -7
  19. package/scripts/test.mjs +7 -11
  20. package/src/agents/reviewer/AGENT.md +7 -11
  21. package/src/agents/reviewer/agent.json +1 -1
  22. package/src/app.mjs +4 -0
  23. package/src/defaults/shipped-history.json +22 -1
  24. package/src/defaults/skills/browser-use/SKILL.md +62 -12
  25. package/src/defaults/skills/code-tidy/SKILL.md +142 -270
  26. package/src/defaults/skills/code-tidy/references/agent-cleanup.md +4 -4
  27. package/src/defaults/skills/code-tidy/references/cleanup-report.md +31 -76
  28. package/src/defaults/skills/code-tidy/references/dead-code.md +6 -12
  29. package/src/defaults/skills/computer-use/SKILL.md +35 -9
  30. package/src/defaults/skills/setup/SKILL.md +22 -0
  31. package/src/defaults/skills/setup/references/actions.md +39 -5
  32. package/src/defaults/skills/setup/references/surfaces.md +11 -2
  33. package/src/defaults/skills/visualize/SKILL.md +2 -1
  34. package/src/lib/rules-builder.cjs +39 -20
  35. package/src/output-styles/common.md +2 -2
  36. package/src/output-styles/simple.md +1 -1
  37. package/src/rules/agent/AGENT.md +11 -10
  38. package/src/rules/lead/LEAD.md +23 -20
  39. package/src/rules/shared/05-tool-calls.md +5 -6
  40. package/src/rules/shared/10-tool-workflow.md +4 -0
  41. package/src/rules/shared/45-destructive.md +0 -2
  42. package/src/rules/shared/50-execution.md +2 -0
  43. package/src/rules/shared/60-verification.md +7 -5
  44. package/src/rules/shared/70-delivery.md +7 -9
  45. package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +29 -6
  46. package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +2 -3
  47. package/src/runtime/agent/orchestrator/agent-runtime/title-completion.mjs +3 -1
  48. package/src/runtime/agent/orchestrator/agent-trace-format.mjs +3 -1
  49. package/src/runtime/agent/orchestrator/cache-break-trace.mjs +2 -0
  50. package/src/runtime/agent/orchestrator/config.mjs +17 -1
  51. package/src/runtime/agent/orchestrator/context/collect.mjs +3 -0
  52. package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +73 -68
  53. package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +57 -2
  54. package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +3 -3
  55. package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +176 -72
  56. package/src/runtime/agent/orchestrator/mcp/client.mjs +19 -0
  57. package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +5 -2
  58. package/src/runtime/agent/orchestrator/providers/account-pool.mjs +192 -133
  59. package/src/runtime/agent/orchestrator/providers/admission-scheduler.mjs +42 -6
  60. package/src/runtime/agent/orchestrator/providers/anthropic-api-recovery.mjs +1 -1
  61. package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +7 -3
  62. package/src/runtime/agent/orchestrator/providers/anthropic-api-transport.mjs +8 -2
  63. package/src/runtime/agent/orchestrator/providers/anthropic-cache-warm.mjs +165 -0
  64. package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens-recovery.mjs +6 -2
  65. package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +2 -2
  66. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
  67. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +4 -1
  68. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/gzip-post.mjs +14 -14
  69. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/initial-status.mjs +3 -1
  70. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +159 -69
  71. package/src/runtime/agent/orchestrator/providers/anthropic-overload-fallback.mjs +25 -3
  72. package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +70 -33
  73. package/src/runtime/agent/orchestrator/providers/anthropic-turn-result.mjs +2 -2
  74. package/src/runtime/agent/orchestrator/providers/anthropic.mjs +135 -87
  75. package/src/runtime/agent/orchestrator/providers/antigravity-transport.mjs +123 -102
  76. package/src/runtime/agent/orchestrator/providers/cache-warm-admission.mjs +90 -0
  77. package/src/runtime/agent/orchestrator/providers/command-code-oauth-login.mjs +1 -10
  78. package/src/runtime/agent/orchestrator/providers/cursor-wire-transport.mjs +25 -9
  79. package/src/runtime/agent/orchestrator/providers/cursor.mjs +25 -13
  80. package/src/runtime/agent/orchestrator/providers/devin-wire-transport.mjs +1 -1
  81. package/src/runtime/agent/orchestrator/providers/devin.mjs +3 -0
  82. package/src/runtime/agent/orchestrator/providers/grok-oauth-login.mjs +210 -20
  83. package/src/runtime/agent/orchestrator/providers/lib/anthropic-prefix-trace.mjs +76 -11
  84. package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +45 -6
  85. package/src/runtime/agent/orchestrator/providers/lib/first-output-window.mjs +58 -0
  86. package/src/runtime/agent/orchestrator/providers/lib/listen-on.mjs +14 -0
  87. package/src/runtime/agent/orchestrator/providers/lib/oauth-token-utils.mjs +17 -3
  88. package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +52 -10
  89. package/src/runtime/agent/orchestrator/providers/mimo-oauth-login.mjs +1 -10
  90. package/src/runtime/agent/orchestrator/providers/model-proxy-channel.d.mts +8 -1
  91. package/src/runtime/agent/orchestrator/providers/model-proxy-channel.mjs +1 -0
  92. package/src/runtime/agent/orchestrator/providers/npm-cli-version.mjs +11 -3
  93. package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +2 -1
  94. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +1 -0
  95. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/chunk-events.mjs +9 -2
  96. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +7 -0
  97. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +14 -3
  98. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-events.mjs +4 -2
  99. package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +1 -0
  100. package/src/runtime/agent/orchestrator/providers/openai-compat-stream-common.mjs +5 -3
  101. package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +16 -3
  102. package/src/runtime/agent/orchestrator/providers/openai-compat-xai-send.mjs +1 -0
  103. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/output-items.mjs +5 -2
  104. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events.mjs +13 -3
  105. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state.mjs +13 -2
  106. package/src/runtime/agent/orchestrator/providers/openai-http-sse-watchdogs.mjs +81 -42
  107. package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +8 -0
  108. package/src/runtime/agent/orchestrator/providers/openai-oauth-login.mjs +136 -5
  109. package/src/runtime/agent/orchestrator/providers/openai-oauth-tokens.mjs +10 -9
  110. package/src/runtime/agent/orchestrator/providers/openai-ws-send/send-context.mjs +22 -3
  111. package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/attempt-context.mjs +43 -5
  112. package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/handshake-failure.mjs +3 -1
  113. package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/stream-failure.mjs +6 -3
  114. package/src/runtime/agent/orchestrator/providers/openai-ws-stream/event-switch.mjs +20 -12
  115. package/src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs +7 -1
  116. package/src/runtime/agent/orchestrator/providers/openai-ws-watchdogs.mjs +48 -22
  117. package/src/runtime/agent/orchestrator/providers/provider-error-kind.mjs +65 -1
  118. package/src/runtime/agent/orchestrator/providers/quota-reading.mjs +38 -12
  119. package/src/runtime/agent/orchestrator/providers/registry.mjs +38 -0
  120. package/src/runtime/agent/orchestrator/providers/retry-executor.mjs +39 -7
  121. package/src/runtime/agent/orchestrator/providers/statusline-route-meta.mjs +6 -0
  122. package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +49 -16
  123. package/src/runtime/agent/orchestrator/runtime-core/compaction-config-keys.mjs +62 -0
  124. package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +37 -16
  125. package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-delta.mjs +100 -23
  126. package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +7 -6
  127. package/src/runtime/agent/orchestrator/runtime-core/session-text.mjs +9 -3
  128. package/src/runtime/agent/orchestrator/runtime-core/tool-bridge.mjs +19 -4
  129. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +125 -30
  130. package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +3 -1
  131. package/src/runtime/agent/orchestrator/runtime-core/workflow.mjs +5 -2
  132. package/src/runtime/agent/orchestrator/session/cache/scoped-cache.mjs +1 -3
  133. package/src/runtime/agent/orchestrator/session/cache-warm.mjs +798 -0
  134. package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +4 -1
  135. package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +1 -8
  136. package/src/runtime/agent/orchestrator/session/compact/messages.mjs +23 -0
  137. package/src/runtime/agent/orchestrator/session/compact/observation-supersession.mjs +103 -23
  138. package/src/runtime/agent/orchestrator/session/compact/runner.mjs +280 -45
  139. package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +475 -58
  140. package/src/runtime/agent/orchestrator/session/compaction-archive.mjs +42 -17
  141. package/src/runtime/agent/orchestrator/session/context-utils.mjs +13 -1
  142. package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +163 -22
  143. package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +132 -17
  144. package/src/runtime/agent/orchestrator/session/conversation-import/convert.mjs +38 -7
  145. package/src/runtime/agent/orchestrator/session/conversation-import/imported-session.mjs +3 -0
  146. package/src/runtime/agent/orchestrator/session/conversation-import/turns.mjs +90 -22
  147. package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +4 -1
  148. package/src/runtime/agent/orchestrator/session/human-gate/gate.mjs +11 -5
  149. package/src/runtime/agent/orchestrator/session/human-gate/outbound-policy.mjs +0 -2
  150. package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +36 -4
  151. package/src/runtime/agent/orchestrator/session/human-gate/store.mjs +1 -1
  152. package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +51 -25
  153. package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +37 -3
  154. package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +3 -1
  155. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +1 -1
  156. package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +1 -1
  157. package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +13 -5
  158. package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +31 -3
  159. package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +20 -3
  160. package/src/runtime/agent/orchestrator/session/loop/tool-exec/after-hook.mjs +2 -1
  161. package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +5 -4
  162. package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +16 -2
  163. package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +16 -1
  164. package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +49 -21
  165. package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +3 -10
  166. package/src/runtime/agent/orchestrator/session/loop/tool-phase.mjs +12 -3
  167. package/src/runtime/agent/orchestrator/session/manager/ask-queue.mjs +12 -2
  168. package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +19 -1
  169. package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +133 -90
  170. package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +3 -3
  171. package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +3 -1
  172. package/src/runtime/agent/orchestrator/session/manager/ask-turn-state.mjs +31 -4
  173. package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +30 -18
  174. package/src/runtime/agent/orchestrator/session/manager/owner-route-fallbacks.mjs +24 -14
  175. package/src/runtime/agent/orchestrator/session/manager/pending-message-entry.mjs +11 -2
  176. package/src/runtime/agent/orchestrator/session/manager/provider-replay.mjs +13 -0
  177. package/src/runtime/agent/orchestrator/session/manager/route-fallback-chain.mjs +130 -0
  178. package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +27 -9
  179. package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +81 -8
  180. package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +2 -0
  181. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +27 -8
  182. package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +12 -5
  183. package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +1 -1
  184. package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +9 -4
  185. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-context.mjs +4 -0
  186. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-journal.mjs +102 -15
  187. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint.mjs +21 -5
  188. package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +9 -0
  189. package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +24 -9
  190. package/src/runtime/agent/orchestrator/session/prompt-cache-idle-gaps.mjs +113 -0
  191. package/src/runtime/agent/orchestrator/session/prompt-cache-touch-store.mjs +150 -0
  192. package/src/runtime/agent/orchestrator/session/restart-prefix-parity.fixture.mjs +154 -0
  193. package/src/runtime/agent/orchestrator/session/routine-result.mjs +36 -9
  194. package/src/runtime/agent/orchestrator/session/sensitive-projection.mjs +100 -0
  195. package/src/runtime/agent/orchestrator/session/sensitive-values.mjs +257 -0
  196. package/src/runtime/agent/orchestrator/session/side-question-store.mjs +20 -7
  197. package/src/runtime/agent/orchestrator/session/side-question.mjs +18 -0
  198. package/src/runtime/agent/orchestrator/session/skill-update-notice.mjs +60 -0
  199. package/src/runtime/agent/orchestrator/session/store/live-state.mjs +6 -3
  200. package/src/runtime/agent/orchestrator/session/store/save-delta.mjs +9 -5
  201. package/src/runtime/agent/orchestrator/session/store/serialize.mjs +9 -8
  202. package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +7 -0
  203. package/src/runtime/agent/orchestrator/session/store/session-persistence-events.mjs +29 -0
  204. package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +8 -6
  205. package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +16 -2
  206. package/src/runtime/agent/orchestrator/session/store-summary-fields.mjs +15 -0
  207. package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +81 -22
  208. package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +92 -3
  209. package/src/runtime/agent/orchestrator/session/stored-attachment-history.mjs +32 -0
  210. package/src/runtime/agent/orchestrator/session/thinking-binding.mjs +108 -0
  211. package/src/runtime/agent/orchestrator/session/tool-batch/pre-dispatch.mjs +2 -2
  212. package/src/runtime/agent/orchestrator/session/tool-batch/record-outcome.mjs +2 -1
  213. package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +79 -3
  214. package/src/runtime/agent/orchestrator/session/transcript-restore/tool-result-status.mjs +9 -7
  215. package/src/runtime/agent/orchestrator/session/transcript-restore/tool-result-text.mjs +2 -2
  216. package/src/runtime/agent/orchestrator/session/turn-failure.mjs +5 -1
  217. package/src/runtime/agent/orchestrator/stall-policy.mjs +23 -0
  218. package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +5 -2
  219. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/backgrounded-result.mjs +12 -1
  220. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/invocation-plan.mjs +2 -2
  221. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/misuse-guard.mjs +240 -0
  222. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/result-format.mjs +1 -1
  223. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/shell-cwd.mjs +38 -0
  224. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/spawn-env.mjs +4 -2
  225. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +31 -6
  226. package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +110 -26
  227. package/src/runtime/agent/orchestrator/tools/builtin/cache-layers.mjs +7 -1
  228. package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +31 -5
  229. package/src/runtime/agent/orchestrator/tools/builtin/git-worktree-tool.mjs +22 -8
  230. package/src/runtime/agent/orchestrator/tools/builtin/lib/scoped-search-flight.mjs +9 -5
  231. package/src/runtime/agent/orchestrator/tools/builtin/read-single-stream.mjs +7 -1
  232. package/src/runtime/agent/orchestrator/tools/builtin/read-streaming.mjs +6 -3
  233. package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-dispatch.mjs +1 -1
  234. package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-publication.mjs +23 -12
  235. package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-snapshot.mjs +6 -1
  236. package/src/runtime/agent/orchestrator/tools/builtin/read-tool.mjs +1 -8
  237. package/src/runtime/agent/orchestrator/tools/builtin/shell-runtime.mjs +7 -1
  238. package/src/runtime/agent/orchestrator/tools/code-graph/dispatch/federation.mjs +3 -1
  239. package/src/runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs +1 -1
  240. package/src/runtime/agent/orchestrator/tools/graph-manifest.json +13 -13
  241. package/src/runtime/agent/orchestrator/tools/lib/isolated-test-env.mjs +4 -3
  242. package/src/runtime/agent/orchestrator/tools/lib/shell-warm-standby.mjs +26 -4
  243. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +36 -13
  244. package/src/runtime/browser-bridge/action-schema.mjs +13 -2
  245. package/src/runtime/browser-bridge/client.mjs +73 -8
  246. package/src/runtime/browser-bridge/input-fields.mjs +8 -9
  247. package/src/runtime/browser-bridge/mail-links.mjs +107 -0
  248. package/src/runtime/browser-bridge/tool-defs.mjs +1 -1
  249. package/src/runtime/channels/lib/config.mjs +6 -61
  250. package/src/runtime/channels/lib/crash-log.mjs +1 -1
  251. package/src/runtime/channels/lib/event-pipeline.mjs +4 -19
  252. package/src/runtime/channels/lib/event-queue.mjs +3 -18
  253. package/src/runtime/channels/lib/owned-runtime/automation-services.mjs +2 -2
  254. package/src/runtime/channels/lib/owned-runtime/automation-start.mjs +3 -4
  255. package/src/runtime/channels/lib/owned-runtime/config-reload.mjs +4 -59
  256. package/src/runtime/channels/lib/owned-runtime/owned-start.mjs +33 -115
  257. package/src/runtime/channels/lib/owned-runtime/owned-stop.mjs +5 -22
  258. package/src/runtime/channels/lib/owned-runtime/state.mjs +2 -8
  259. package/src/runtime/channels/lib/owned-runtime.mjs +6 -23
  260. package/src/runtime/channels/lib/parent-bridge.mjs +2 -2
  261. package/src/runtime/channels/lib/runtime-paths.mjs +4 -43
  262. package/src/runtime/channels/lib/scheduler.mjs +33 -147
  263. package/src/runtime/channels/lib/schedules-db.mjs +34 -11
  264. package/src/runtime/channels/lib/status-snapshot.mjs +1 -1
  265. package/src/runtime/channels/lib/tool-dispatch.mjs +1 -2
  266. package/src/runtime/channels/lib/webhook/signature.mjs +4 -1
  267. package/src/runtime/channels/lib/webhooks-db.mjs +5 -9
  268. package/src/runtime/channels/lib/whisper-port.mjs +10 -1
  269. package/src/runtime/channels/lib/worker-bootstrap.mjs +0 -1
  270. package/src/runtime/channels/lib/worker-ipc.mjs +0 -1
  271. package/src/runtime/channels/lib/worker-main.mjs +10 -34
  272. package/src/runtime/computer-bridge/action-schema.mjs +42 -1
  273. package/src/runtime/computer-bridge/actions.mjs +9 -1
  274. package/src/runtime/computer-bridge/client.mjs +180 -8
  275. package/src/runtime/computer-bridge/core-actions.mjs +2 -2
  276. package/src/runtime/computer-bridge/error-recovery.mjs +28 -2
  277. package/src/runtime/computer-bridge/linux-action-capabilities.mjs +24 -5
  278. package/src/runtime/computer-bridge/linux-readiness.d.mts +7 -2
  279. package/src/runtime/computer-bridge/linux-readiness.mjs +65 -23
  280. package/src/runtime/computer-bridge/pending-continuation.mjs +1 -1
  281. package/src/runtime/connectors/connector-accounts-mcp.mjs +230 -0
  282. package/src/runtime/connectors/gmail-app-password.mjs +172 -39
  283. package/src/runtime/connectors/google-mcp.mjs +10 -12
  284. package/src/runtime/local-provider/server-process.mjs +2 -1
  285. package/src/runtime/media/adapters/gemini-video.mjs +4 -1
  286. package/src/runtime/media/adapters/xai-media.mjs +2 -1
  287. package/src/runtime/memory/lib/embedding-worker.mjs +6 -3
  288. package/src/runtime/memory/lib/memory-action-handlers/cycle-backfill-action.mjs +1 -7
  289. package/src/runtime/memory/lib/memory-chunk-quality.mjs +1 -6
  290. package/src/runtime/memory/lib/pg/adapter.mjs +77 -70
  291. package/src/runtime/memory/lib/pg/supervisor.mjs +24 -12
  292. package/src/runtime/memory/lib/runtime-fetcher.mjs +23 -5
  293. package/src/runtime/office/authoring/pdf-author-action.mjs +1 -6
  294. package/src/runtime/office/design/design-art-direction.mjs +29 -27
  295. package/src/runtime/office/pdf/pdf-writer.mjs +6 -1
  296. package/src/runtime/office/portable/portable-snapshot-docx.mjs +7 -1
  297. package/src/runtime/office/portable/portable-snapshot-shared.mjs +6 -1
  298. package/src/runtime/office/quality/assurance-rendered.mjs +9 -2
  299. package/src/runtime/office/quality/assurance-structure-docx.mjs +3 -1
  300. package/src/runtime/office/quality/design-review.mjs +1 -5
  301. package/src/runtime/office/quality/document-brief.mjs +1 -5
  302. package/src/runtime/office/quality/forced-break-pages.mjs +9 -6
  303. package/src/runtime/office/quality/quality-pipeline.mjs +1 -1
  304. package/src/runtime/session-search/session-search-db.mjs +73 -9
  305. package/src/runtime/session-search/session-search-ingest.mjs +110 -20
  306. package/src/runtime/shared/abort-race.mjs +89 -0
  307. package/src/runtime/shared/agent-avatar.d.mts +0 -1
  308. package/src/runtime/shared/agent-kind.mjs +4 -3
  309. package/src/runtime/shared/bot-owned-work.mjs +56 -0
  310. package/src/runtime/shared/bounded-download.mjs +8 -3
  311. package/src/runtime/shared/config.mjs +2 -13
  312. package/src/runtime/shared/connector-accounts.mjs +20 -10
  313. package/src/runtime/shared/connector-catalog.d.mts +29 -0
  314. package/src/runtime/shared/connector-catalog.mjs +150 -0
  315. package/src/runtime/shared/connector-triggers.mjs +22 -19
  316. package/src/runtime/shared/defaults-separation.mjs +2 -17
  317. package/src/runtime/shared/delegated-approval-host.mjs +103 -11
  318. package/src/runtime/shared/err-text.mjs +24 -15
  319. package/src/runtime/shared/fetch-safe-listen.d.mts +16 -0
  320. package/src/runtime/shared/fetch-safe-listen.mjs +50 -0
  321. package/src/runtime/shared/file-permissions.d.mts +0 -8
  322. package/src/runtime/shared/file-permissions.mjs +0 -11
  323. package/src/runtime/shared/git-direct.test-support.mjs +19 -0
  324. package/src/runtime/shared/handoff-artifacts.d.mts +2 -1
  325. package/src/runtime/shared/handoff-artifacts.mjs +18 -8
  326. package/src/runtime/shared/heartbeat-interval.d.mts +4 -0
  327. package/src/runtime/shared/heartbeat-interval.mjs +19 -0
  328. package/src/runtime/shared/idle-auto-clear-gate.mjs +126 -0
  329. package/src/runtime/shared/llm/cost.mjs +5 -1
  330. package/src/runtime/shared/llm/usage-rollup.mjs +1 -1
  331. package/src/runtime/shared/loopback-listener.mjs +25 -2
  332. package/src/runtime/shared/mixy-presence.mjs +22 -0
  333. package/src/runtime/shared/model-route-chain.d.mts +7 -2
  334. package/src/runtime/shared/model-route-chain.mjs +22 -4
  335. package/src/runtime/shared/open-url.mjs +10 -0
  336. package/src/runtime/shared/orchestration.d.mts +2 -0
  337. package/src/runtime/shared/pg-schema-db.mjs +27 -16
  338. package/src/runtime/shared/profile-config.cjs +1 -1
  339. package/src/runtime/shared/prompt-origin.d.mts +4 -0
  340. package/src/runtime/shared/prompt-origin.mjs +21 -0
  341. package/src/runtime/shared/provider-accounts.mjs +7 -1
  342. package/src/runtime/shared/provider-display-name.mjs +29 -0
  343. package/src/runtime/shared/provider-timeout-phase.mjs +2 -0
  344. package/src/runtime/shared/routine-trigger.d.mts +2 -0
  345. package/src/runtime/shared/routine-trigger.mjs +10 -0
  346. package/src/runtime/shared/sensitive-path-rules.d.mts +2 -10
  347. package/src/runtime/shared/sensitive-path-rules.mjs +19 -41
  348. package/src/runtime/shared/session-activity-signal.mjs +48 -1
  349. package/src/runtime/shared/session-scratch.mjs +37 -0
  350. package/src/runtime/shared/session-sidebar-host.d.mts +1 -1
  351. package/src/runtime/shared/session-sidebar-host.mjs +7 -3
  352. package/src/runtime/shared/session-turn-prelude.mjs +18 -0
  353. package/src/runtime/shared/tool-card-model/agent-surface.mjs +1 -3
  354. package/src/runtime/shared/tool-card-model/card-status.mjs +15 -2
  355. package/src/runtime/shared/tool-result-summary.mjs +2 -15
  356. package/src/runtime/shared/tool-surface.mjs +3 -0
  357. package/src/runtime/shared/tool-work-units.mjs +2 -0
  358. package/src/runtime/shared/turn-snapshot-store.mjs +13 -6
  359. package/src/runtime/shared/worktrees/contract.mjs +4 -1
  360. package/src/runtime/shared/worktrees/git.mjs +15 -0
  361. package/src/runtime/shared/worktrees/manager.mjs +87 -38
  362. package/src/runtime/shared/worktrees/test-support.mjs +14 -13
  363. package/src/runtime/terminal-bridge/client.mjs +10 -1
  364. package/src/runtime/visualize-bridge/client.mjs +29 -8
  365. package/src/runtime/visualize-bridge/tool-defs.mjs +22 -8
  366. package/src/runtime/visualize-bridge/tool-meta.d.mts +5 -0
  367. package/src/runtime/visualize-bridge/tool-meta.mjs +22 -0
  368. package/src/runtime/web-search/lib/fetch-pipeline.mjs +2 -2
  369. package/src/session-runtime/agent-home-delivery.mjs +489 -185
  370. package/src/session-runtime/agent-task-sessions.mjs +467 -229
  371. package/src/session-runtime/agent-tool-routing.mjs +8 -41
  372. package/src/session-runtime/boot/apis.mjs +9 -0
  373. package/src/session-runtime/boot/infrastructure.mjs +4 -0
  374. package/src/session-runtime/boot/providers.mjs +3 -0
  375. package/src/session-runtime/boot/tools.mjs +11 -2
  376. package/src/session-runtime/bot-status.mjs +12 -6
  377. package/src/session-runtime/bot-target.mjs +38 -0
  378. package/src/session-runtime/channel-config-api.mjs +6 -1
  379. package/src/session-runtime/config-lifecycle.mjs +6 -0
  380. package/src/session-runtime/connector-merge-migration.mjs +305 -0
  381. package/src/session-runtime/conversation-import/codex-titles.mjs +88 -0
  382. package/src/session-runtime/conversation-import/discovery.mjs +271 -25
  383. package/src/session-runtime/conversation-import/service.mjs +26 -5
  384. package/src/session-runtime/handoff-attachments.mjs +82 -31
  385. package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +144 -41
  386. package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +3 -0
  387. package/src/session-runtime/internal-tool-executor/reaction-tool.mjs +4 -1
  388. package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +8 -2
  389. package/src/session-runtime/lifecycle/cold-heir.mjs +11 -6
  390. package/src/session-runtime/lifecycle/inheritance.mjs +16 -3
  391. package/src/session-runtime/lifecycle/session-catalog.mjs +12 -2
  392. package/src/session-runtime/lifecycle/teardown/runtime-stops.mjs +50 -4
  393. package/src/session-runtime/lifecycle/teardown.mjs +23 -5
  394. package/src/session-runtime/mcp-glue/server-catalog.mjs +55 -3
  395. package/src/session-runtime/mcp-oauth-login.mjs +5 -3
  396. package/src/session-runtime/mixy-heartbeat.mjs +153 -33
  397. package/src/session-runtime/model-route/set-route.mjs +11 -2
  398. package/src/session-runtime/notification-bus.mjs +31 -117
  399. package/src/session-runtime/notification-completion-queue.mjs +54 -0
  400. package/src/session-runtime/notification-listeners.mjs +76 -0
  401. package/src/session-runtime/owned-automation-run.mjs +2 -1
  402. package/src/session-runtime/prewarm/channel-start.mjs +3 -7
  403. package/src/session-runtime/provider-catalog-cache.mjs +82 -36
  404. package/src/session-runtime/provider-models/catalog-load.mjs +23 -6
  405. package/src/session-runtime/provider-models.mjs +4 -2
  406. package/src/session-runtime/resource-mcp-api.mjs +143 -224
  407. package/src/session-runtime/resource-mcp-connector-accounts.mjs +163 -0
  408. package/src/session-runtime/resource-mcp-oauth-api.mjs +217 -0
  409. package/src/session-runtime/resource-mcp-secrets.mjs +82 -0
  410. package/src/session-runtime/resource-mcp-servers.mjs +78 -0
  411. package/src/session-runtime/resource-mcp-store.mjs +49 -0
  412. package/src/session-runtime/resource-recall-api.mjs +6 -1
  413. package/src/session-runtime/routine-owner.mjs +40 -9
  414. package/src/session-runtime/runtime-feature-gates.mjs +5 -1
  415. package/src/session-runtime/services/agent-tool/close-flow.mjs +3 -0
  416. package/src/session-runtime/services/agent-tool/execute.mjs +14 -9
  417. package/src/session-runtime/services/agent-tool/job-views/agent-list.mjs +20 -4
  418. package/src/session-runtime/services/agent-tool/model-select.mjs +48 -7
  419. package/src/session-runtime/services/agent-tool/render.mjs +71 -17
  420. package/src/session-runtime/services/agent-tool/spawn-preset.mjs +13 -4
  421. package/src/session-runtime/services/agent-tool/tag-registry.mjs +1 -0
  422. package/src/session-runtime/services/agent-tool/tool-def.mjs +9 -9
  423. package/src/session-runtime/services/agent-tool/worker-index/awaiting-user-sync.mjs +51 -0
  424. package/src/session-runtime/services/agent-tool/worker-index/disposal.mjs +55 -0
  425. package/src/session-runtime/services/agent-tool/worker-index/released-store.mjs +123 -0
  426. package/src/session-runtime/services/agent-tool/worker-index/restart-settlement.mjs +112 -0
  427. package/src/session-runtime/services/agent-tool/worker-index/row-reads.mjs +36 -0
  428. package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +2 -0
  429. package/src/session-runtime/services/agent-tool/worker-index/row-store.mjs +17 -4
  430. package/src/session-runtime/services/agent-tool/worker-index/row-writes.mjs +58 -0
  431. package/src/session-runtime/services/agent-tool/worker-index.mjs +41 -241
  432. package/src/session-runtime/services/agent-tool/worker-rows.mjs +3 -0
  433. package/src/session-runtime/services/channel-admin.mjs +7 -13
  434. package/src/session-runtime/services/channel-session-router.mjs +4 -2
  435. package/src/session-runtime/services/provider-admin.mjs +2 -1
  436. package/src/session-runtime/services/seeds.mjs +0 -28
  437. package/src/session-runtime/session-compaction-sync.mjs +27 -0
  438. package/src/session-runtime/session-create/session-options.mjs +1 -0
  439. package/src/session-runtime/settings-builtin-tools-api.mjs +11 -0
  440. package/src/session-runtime/settings-compaction-api.mjs +2 -40
  441. package/src/session-runtime/settings-system-api.mjs +13 -1
  442. package/src/session-runtime/setup-tool/agent-settings-actions.mjs +65 -0
  443. package/src/session-runtime/setup-tool/executor.mjs +145 -22
  444. package/src/session-runtime/setup-tool/extended-actions.mjs +8 -3
  445. package/src/session-runtime/setup-tool/session-route-actions.mjs +152 -0
  446. package/src/session-runtime/setup-tool/settings-contract.mjs +4 -3
  447. package/src/session-runtime/setup-tool/tool-defs.mjs +64 -5
  448. package/src/session-runtime/tool-policy/agent-profile-fold.mjs +17 -13
  449. package/src/session-runtime/tool-policy/policy-stage.mjs +17 -2
  450. package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +1 -0
  451. package/src/session-runtime/workflow-agents-api/agent-editor.mjs +5 -1
  452. package/src/session-runtime/workflow-agents-api/agent-route.mjs +15 -4
  453. package/src/session-runtime/workflow-agents-api/onboarding.mjs +3 -3
  454. package/src/session-runtime/workflow-agents-api/style-and-mode.mjs +4 -0
  455. package/src/session-runtime/workspace/transitions.mjs +25 -0
  456. package/src/session-runtime/workspace/worktree-tool.mjs +26 -9
  457. package/src/standalone/channel-transport/client-registry/client-records.mjs +65 -0
  458. package/src/standalone/channel-transport/client-registry/client-registration.mjs +118 -0
  459. package/src/standalone/channel-transport/client-registry.mjs +24 -163
  460. package/src/standalone/channel-transport.mjs +1 -1
  461. package/src/standalone/daemon-channels-loader.mjs +10 -8
  462. package/src/standalone/daemon-session-control/list-page.mjs +72 -0
  463. package/src/standalone/daemon-session-control/request.mjs +51 -0
  464. package/src/standalone/daemon-session-control/room-host.mjs +57 -0
  465. package/src/standalone/daemon-session-control/route-control.mjs +48 -0
  466. package/src/standalone/daemon-session-control/send-turn.mjs +60 -0
  467. package/src/standalone/daemon-session-control/worktree-control.mjs +40 -0
  468. package/src/standalone/daemon-session-control.mjs +142 -190
  469. package/src/standalone/daemon.mjs +26 -3
  470. package/src/standalone/session-client.mjs +7 -3
  471. package/src/standalone/session-protocol.mjs +5 -0
  472. package/src/standalone/session-service/agent-tree/agent-child.mjs +1 -0
  473. package/src/standalone/session-service/agent-tree/agent-turns.mjs +16 -12
  474. package/src/standalone/session-service/quota-resume.mjs +3 -0
  475. package/src/standalone/session-service/retention/busy.mjs +65 -1
  476. package/src/standalone/session-service/session-calls/session-action.mjs +30 -2
  477. package/src/standalone/session-service/session-calls/session-views.mjs +8 -0
  478. package/src/standalone/session-tool-output.mjs +15 -7
  479. package/src/standalone/session-transport/client-registry/client-grace.mjs +12 -9
  480. package/src/tui/app/app-view/floating-panel.jsx +7 -4
  481. package/src/tui/app/model-options.mjs +3 -28
  482. package/src/tui/app/model-picker/route-selection/fast-parameters.mjs +1 -3
  483. package/src/tui/app/model-picker/route-selection.mjs +5 -6
  484. package/src/tui/app/provider-setup/oauth-actions.mjs +38 -20
  485. package/src/tui/app/provider-setup/provider-items.mjs +8 -2
  486. package/src/tui/app/provider-setup-picker.mjs +9 -5
  487. package/src/tui/components/QuestionPanel.jsx +13 -4
  488. package/src/tui/dist/index.mjs +133 -92
  489. package/src/tui/session/agent-job-feed/model-notification.mjs +3 -0
  490. package/src/tui/session/initial-state.mjs +3 -0
  491. package/src/tui/session/notice-surface.mjs +7 -1
  492. package/src/tui/session/queue-helpers.mjs +3 -42
  493. package/src/tui/session/session-api/routes-agent-definitions.mjs +14 -2
  494. package/src/tui/session/session-api/routes-write.mjs +5 -1
  495. package/src/tui/session/session-api/routes.mjs +1 -0
  496. package/src/tui/session/session-api/settings.mjs +17 -1
  497. package/src/tui/session/session-flow/auto-clear.mjs +4 -33
  498. package/src/tui/session/session-flow/drain-closed-queue.mjs +38 -0
  499. package/src/tui/session/session-flow/drain-enqueue.mjs +86 -0
  500. package/src/tui/session/session-flow/drain-retry.mjs +35 -0
  501. package/src/tui/session/session-flow/drain.mjs +118 -149
  502. package/src/tui/session/session-flow/queue/entry-shape.mjs +5 -0
  503. package/src/tui/session/session-flow/queue/take-entries.mjs +16 -2
  504. package/src/tui/session/tool-approval-delegation.mjs +64 -0
  505. package/src/tui/session/tool-approval-request.mjs +39 -0
  506. package/src/tui/session/tool-approval-settle.mjs +62 -0
  507. package/src/tui/session/tool-approval.mjs +69 -115
  508. package/src/tui/session/tui-steering-persist.mjs +8 -1
  509. package/src/tui/session/turn-stream.mjs +19 -2
  510. package/src/tui/session/turn.mjs +1 -0
  511. package/src/ui/statusline-agents.mjs +1 -3
  512. package/src/vendor/statusline/bin/statusline-route.mjs +1 -219
  513. package/src/vendor/statusline/src/gateway/route-meta.mjs +35 -13
  514. package/scripts/code-graph-description-contract.mjs +0 -188
  515. package/src/runtime/channels/lib/owned-runtime/ownership-refresh.mjs +0 -36
@@ -0,0 +1,165 @@
1
+ // anthropic-cache-warm.mjs — the cache-warm mode both Anthropic providers
2
+ // expose as `sendCacheWarm` (session/cache-warm.mjs): one POST of the
3
+ // request the provider's own builder produces, no retry, fallback, re-send,
4
+ // wait or account rotation, and the stream cut at the first content block
5
+ // once the usage (cache read / write) has been reported. Right before the
6
+ // POST the account gate (cache-warm-admission.mjs) may skip it; a refusal is
7
+ // fed into the shared rate-limit and roster state. The request is bounded by
8
+ // the providers' own watchdogs: the first-byte timeout until the usage
9
+ // arrives, then the SSE idle timeout between events. Usage is handed to
10
+ // `onUsage` as it arrives, so a warm that fails or is aborted after the
11
+ // provider accepted it is still accounted. Every exit cancels the stream and
12
+ // aborts the transport.
13
+ import { PROVIDER_FIRST_BYTE_TIMEOUT_MS, PROVIDER_SSE_IDLE_TIMEOUT_MS } from '../stall-policy.mjs';
14
+ import { updateTurnUsage } from './anthropic-sse-turn/turn-state.mjs';
15
+ import { _anthropicSseError } from './anthropic-sse.mjs';
16
+ import { anthropicQuotaError } from './anthropic-oauth-request/initial-status.mjs';
17
+ import { cacheWarmAccountBlock, cacheWarmBlockedError, recordCacheWarmRefusal } from './cache-warm-admission.mjs';
18
+ import { scrubOAuthSecrets } from './lib/oauth-token-utils.mjs';
19
+
20
+ const SSE_LABELS = Object.freeze({ display: 'Anthropic cache warm' });
21
+
22
+ function usageSnapshot(usage) {
23
+ const { raw: _raw, ...rest } = usage;
24
+ return { ...rest };
25
+ }
26
+
27
+ // An abort deadline: `arm(ms)` (re)starts it; it fires `controller.abort`.
28
+ function watchdog(controller) {
29
+ let timer = null;
30
+ return {
31
+ arm(ms, what) {
32
+ if (timer) clearTimeout(timer);
33
+ timer = setTimeout(() => controller.abort(new Error(`cache warm ${what} timed out after ${ms}ms`)), ms);
34
+ timer.unref?.();
35
+ },
36
+ clear() {
37
+ if (timer) clearTimeout(timer);
38
+ timer = null;
39
+ },
40
+ };
41
+ }
42
+
43
+ /**
44
+ * Read a warm's SSE stream until usage is known and the first content block
45
+ * starts, or the message ends. Resolves the usage; a stream error rejects
46
+ * with `error.usage` set to what was reported before it. `onChunk` hears
47
+ * every chunk (the idle watchdog). The stream is cancelled on every exit.
48
+ */
49
+ export async function readCacheWarmStream(response, { onUsage = () => {}, onChunk = () => {} } = {}) {
50
+ const usage = { inputTokens: 0, outputTokens: 0, cachedTokens: 0, cacheWriteTokens: 0, raw: null };
51
+ let reported = false;
52
+ const report = (raw) => {
53
+ if (!raw || typeof raw !== 'object') return;
54
+ updateTurnUsage(usage, raw);
55
+ reported = true;
56
+ onUsage(usageSnapshot(usage));
57
+ };
58
+ const reader = response.body.getReader();
59
+ const decoder = new TextDecoder();
60
+ let buffer = '';
61
+ try {
62
+ for (;;) {
63
+ const { value, done } = await reader.read();
64
+ if (done) break;
65
+ buffer += decoder.decode(value, { stream: true });
66
+ let cut = buffer.indexOf('\n\n');
67
+ while (cut >= 0) {
68
+ const frame = buffer.slice(0, cut);
69
+ buffer = buffer.slice(cut + 2);
70
+ cut = buffer.indexOf('\n\n');
71
+ const data = frame
72
+ .split('\n')
73
+ .filter((line) => line.startsWith('data:'))
74
+ .map((line) => line.slice(5).trimStart())
75
+ .join('\n');
76
+ if (!data) continue;
77
+ let event;
78
+ try {
79
+ event = JSON.parse(data);
80
+ } catch {
81
+ continue;
82
+ }
83
+ if (event?.type === 'error' || event?.error) throw _anthropicSseError(event, SSE_LABELS);
84
+ if (event.type === 'message_start') report(event.message?.usage);
85
+ else if (event.type === 'message_delta') report(event.usage);
86
+ else if (event.type === 'content_block_start' && reported) {
87
+ // The prefix was read (and the cache refreshed) before any content:
88
+ // nothing generated after this point is needed.
89
+ return usageSnapshot(usage);
90
+ } else if (event.type === 'message_stop') return usageSnapshot(usage);
91
+ }
92
+ onChunk(reported);
93
+ }
94
+ } catch (error) {
95
+ if (error && typeof error === 'object' && error.usage === undefined) {
96
+ error.usage = reported ? usageSnapshot(usage) : null;
97
+ }
98
+ throw error;
99
+ } finally {
100
+ await reader.cancel().catch(() => {});
101
+ }
102
+ return usageSnapshot(usage);
103
+ }
104
+
105
+ /**
106
+ * One warm on account instance `instance` (roster account `accountId`, empty
107
+ * for a provider without a roster) of `providerName`: the account gate, then
108
+ * `post(signal)` (the provider's single POST of its built body), then the
109
+ * stream. A refusal reaches the shared rate-limit and roster state; the
110
+ * transport is aborted on every exit.
111
+ */
112
+ export async function sendAnthropicCacheWarm({
113
+ providerName,
114
+ instance,
115
+ accountId = '',
116
+ model,
117
+ opts = {},
118
+ post,
119
+ onUsage,
120
+ }) {
121
+ const blocked = cacheWarmAccountBlock(providerName, instance, {
122
+ accountId,
123
+ model,
124
+ sessionId: opts.session?.id || opts.sessionId || '',
125
+ });
126
+ if (blocked) throw cacheWarmBlockedError(blocked);
127
+ const controller = new AbortController();
128
+ const callerSignal = opts.signal;
129
+ const onCallerAbort = () => controller.abort(callerSignal.reason);
130
+ if (callerSignal?.aborted) controller.abort(callerSignal.reason);
131
+ else callerSignal?.addEventListener?.('abort', onCallerAbort, { once: true });
132
+ const deadline = watchdog(controller);
133
+ deadline.arm(PROVIDER_FIRST_BYTE_TIMEOUT_MS, 'first byte');
134
+ try {
135
+ const response = await post(controller.signal);
136
+ if (!response.ok) {
137
+ const bodyText = await response.text().catch(() => '');
138
+ throw anthropicQuotaError(response.status, response.headers, bodyText);
139
+ }
140
+ return await readCacheWarmStream(response, {
141
+ onUsage,
142
+ onChunk: (reported) => {
143
+ if (reported) deadline.arm(PROVIDER_SSE_IDLE_TIMEOUT_MS, 'stream');
144
+ },
145
+ });
146
+ } catch (error) {
147
+ // The warm's own error is what the caller needs; a failure to persist the
148
+ // refusal (quota / roster state) is reported, scrubbed, like the other
149
+ // credential and account-state write failures of the Anthropic providers.
150
+ await recordCacheWarmRefusal(providerName, instance, error, {
151
+ accountId,
152
+ model,
153
+ aborted: Boolean(callerSignal?.aborted),
154
+ }).catch((recordError) => {
155
+ process.stderr.write(
156
+ `[anthropic-cache-warm] refusal record failed: ${scrubOAuthSecrets(recordError?.message || String(recordError))}\n`
157
+ );
158
+ });
159
+ throw error;
160
+ } finally {
161
+ callerSignal?.removeEventListener?.('abort', onCallerAbort);
162
+ deadline.clear();
163
+ controller.abort(new Error('cache warm finished'));
164
+ }
165
+ }
@@ -22,11 +22,15 @@ export function parseMaxTokensContextOverflow(status, message) {
22
22
  const match = OVERFLOW_RE.exec(String(message || ''));
23
23
  if (!match) return null;
24
24
  const [inputTokens, maxTokens, contextLimit] = match.slice(1).map((value) => Number.parseInt(value, 10));
25
- return [inputTokens, maxTokens, contextLimit].every(Number.isFinite) ? { inputTokens, maxTokens, contextLimit } : null;
25
+ return [inputTokens, maxTokens, contextLimit].every(Number.isFinite)
26
+ ? { inputTokens, maxTokens, contextLimit }
27
+ : null;
26
28
  }
27
29
 
28
30
  const thinkingBudget = (body) =>
29
- body?.thinking?.type === 'enabled' && Number(body.thinking.budget_tokens) > 0 ? Number(body.thinking.budget_tokens) : 0;
31
+ body?.thinking?.type === 'enabled' && Number(body.thinking.budget_tokens) > 0
32
+ ? Number(body.thinking.budget_tokens)
33
+ : 0;
30
34
 
31
35
  /**
32
36
  * Shrink `body.max_tokens` to fit the reported context. Returns true when the
@@ -159,8 +159,8 @@ function deferredAnthropicTools(activeTools, messages, opts, provider = 'anthrop
159
159
  return sharedDeferredAnthropicTools(activeTools, messages, opts, provider);
160
160
  }
161
161
  // `provider`: the engine's name (a gateway Messages engine runs under its gateway's).
162
- export function requestAnthropicTools(tools, messages, opts, provider = 'anthropic') {
163
- return sharedRequestAnthropicTools(tools, messages, opts, provider);
162
+ export function requestAnthropicTools(tools, messages, opts, provider = 'anthropic', config = {}) {
163
+ return sharedRequestAnthropicTools(tools, messages, opts, provider, config);
164
164
  }
165
165
  // Test-only: expose the lowering so the steering-provenance test can assert
166
166
  // the API-key provider keeps steering-tagged user turns distinct (mirrors
@@ -10,7 +10,7 @@ import { createNpmVersionSource, maxSemver } from './npm-cli-version.mjs';
10
10
  // source release just to advance the user-agent version.
11
11
  // Claude Opus 5.5 requires 2.1.280 or newer. The release workflow raises this
12
12
  // to the published CLI version (scripts/sync-client-version-floors.mjs).
13
- export const DEFAULT_CLI_VERSION = '2.1.310';
13
+ export const DEFAULT_CLI_VERSION = '2.1.311';
14
14
  export const CLAUDE_CLI_NPM_PACKAGE = '@anthropic-ai/claude-code';
15
15
 
16
16
  const CACHE_SCHEMA_VERSION = 1;
@@ -15,6 +15,7 @@ import { boundProviderAuthPath } from '../../../shared/provider-auth-binding.mjs
15
15
  import { resolvePluginData } from '../../../shared/plugin-paths.mjs';
16
16
  import { modelProxyClientMode, serverModelCredentialsDisabledError } from '../../../shared/model-proxy-mode.mjs';
17
17
  import { getLlmDispatcher } from '../../../shared/llm/http-agent.mjs';
18
+ import { TIMEOUT_PHASE } from '../../../shared/provider-timeout-phase.mjs';
18
19
  import { claudeCliUserAgent, resolveCliVersion } from './anthropic-oauth-client-version.mjs';
19
20
  import {
20
21
  accountIdentityFields,
@@ -375,7 +376,9 @@ async function _refreshOAuthCredentialsUnlocked(creds) {
375
376
  return refreshed;
376
377
  } catch (err) {
377
378
  if (err?.name === 'AbortError') {
378
- throw new Error('Anthropic OAuth token refresh timed out after 30000ms');
379
+ throw Object.assign(new Error('Anthropic OAuth token refresh timed out after 30000ms'), {
380
+ timeoutPhase: TIMEOUT_PHASE.AUTH,
381
+ });
379
382
  }
380
383
  throw err;
381
384
  } finally {
@@ -12,7 +12,9 @@ import { sendGzipCompressed } from '../lib/request-compression.mjs';
12
12
  const API_URL = 'https://api.anthropic.com/v1/messages';
13
13
  export { ANTHROPIC_VERSION };
14
14
 
15
- export async function postMessages({ accessToken, requestBody, betaHeaders, signal, compress }) {
15
+ // `plain`: exactly one uncompressed POST (a cache warm), so no compression
16
+ // rejection resend can follow.
17
+ export async function postMessages({ accessToken, requestBody, betaHeaders, signal, compress, plain = false }) {
16
18
  const headers = {
17
19
  Authorization: `Bearer ${accessToken}`,
18
20
  'anthropic-version': ANTHROPIC_VERSION,
@@ -22,17 +24,15 @@ export async function postMessages({ accessToken, requestBody, betaHeaders, sign
22
24
  'x-app': 'cli',
23
25
  'Content-Type': 'application/json',
24
26
  };
25
- return sendGzipCompressed({
26
- raw: Buffer.from(JSON.stringify(requestBody)),
27
- headers,
28
- compress,
29
- send: (body, sendHeaders) =>
30
- fetch(API_URL, {
31
- method: 'POST',
32
- headers: sendHeaders,
33
- body,
34
- signal,
35
- dispatcher: getLlmDispatcher(),
36
- }),
37
- });
27
+ const raw = Buffer.from(JSON.stringify(requestBody));
28
+ const send = (body, sendHeaders) =>
29
+ fetch(API_URL, {
30
+ method: 'POST',
31
+ headers: sendHeaders,
32
+ body,
33
+ signal,
34
+ dispatcher: getLlmDispatcher(),
35
+ });
36
+ if (plain) return send(raw, headers);
37
+ return sendGzipCompressed({ raw, headers, compress, send });
38
38
  }
@@ -50,7 +50,9 @@ export function anthropicQuotaError(status, headers, bodyText = '') {
50
50
  const detail = bodyText ? `: ${String(bodyText).slice(0, 200)}` : '';
51
51
  const retry = retryAfter ? ` retryAfter=${retryAfter}` : '';
52
52
  const quota = hasQuotaHeaders(headers);
53
- const err = new Error(`Anthropic OAuth API ${status} ${quota ? 'quota/rate limit' : 'request rejected'}${retry}${detail}`);
53
+ const err = new Error(
54
+ `Anthropic OAuth API ${status} ${quota ? 'quota/rate limit' : 'request rejected'}${retry}${detail}`
55
+ );
54
56
  err.name = quota ? 'ProviderQuotaError' : 'ProviderRequestRejectedError';
55
57
  err.headers = headers;
56
58
  err.response = { status, headers };
@@ -8,6 +8,7 @@
8
8
  import { traceAgentSse, traceAgentUsage } from '../agent-trace.mjs';
9
9
  import {
10
10
  anthropicPrefixFingerprint,
11
+ anthropicPrefixSessionId,
11
12
  latestAnthropicPrefix,
12
13
  recordAnthropicPrefix,
13
14
  } from './lib/anthropic-prefix-trace.mjs';
@@ -43,16 +44,17 @@ import {
43
44
  } from './anthropic-oauth-credentials.mjs';
44
45
  import { claudeCliUserAgent, learnRequiredCliVersion, warmCliVersion } from './anthropic-oauth-client-version.mjs';
45
46
  import { createPassthroughSignal } from '../stall-policy.mjs';
46
- import { AnthropicFallbackTriggeredError } from './retry-classifier.mjs';
47
47
  import { ANTHROPIC_MAX_MIDSTREAM_RETRIES, parseSSEStream, _classifyMidstreamError } from './anthropic-sse.mjs';
48
48
  import { buildAnthropicBetaHeaders, supportsAnthropicFastMode } from './anthropic-betas.mjs';
49
49
  import { applyAnthropicServerFallback } from './anthropic-server-fallback.mjs';
50
50
  import { fastModeAvailable, fastModeDowngraded, noteFastModeCapacityError } from './anthropic-fast-mode.mjs';
51
51
  import { ANTHROPIC_VERSION, anthropicQuotaError, createAnthropicOAuthRequest } from './anthropic-oauth-request.mjs';
52
52
  import { isRefreshableAuthRejection } from './anthropic-oauth-request/initial-status.mjs';
53
+ import { postMessages } from './anthropic-oauth-request/gzip-post.mjs';
54
+ import { sendAnthropicCacheWarm } from './anthropic-cache-warm.mjs';
53
55
  import { applyAnthropicErrorContract } from './anthropic-error-contract.mjs';
54
56
  import { adjustMaxTokensForContextOverflow } from './anthropic-max-tokens-recovery.mjs';
55
- import { announceAnthropicModelFallback, createAnthropicOverloadTracker } from './anthropic-overload-fallback.mjs';
57
+ import { createAnthropicOverloadTracker, takeAnthropicModelFallback } from './anthropic-overload-fallback.mjs';
56
58
  import { createAnthropicOAuthRecovery } from './anthropic-oauth-recovery.mjs';
57
59
  import { createMidState, createMidstreamRecovery } from './anthropic-oauth-midstream.mjs';
58
60
  import { assertAnthropicStreamNotEmpty } from './anthropic-midstream-recovery.mjs';
@@ -302,6 +304,28 @@ function buildRequestBody(requestMessages, model, tools, sendOpts) {
302
304
  return markAnthropicEffortBody(body, effortProjection);
303
305
  }
304
306
 
307
+ // Known tool names for the leaked-tool-call guard in parseSSEStream:
308
+ // recovered leaked calls are only synthesized when they name a tool
309
+ // actually offered to this request (native + lowered). Derived from the
310
+ // final request body so it matches exactly what the model was given.
311
+ function requestToolNames(body) {
312
+ return new Set(
313
+ (Array.isArray(body.tools) ? body.tools : [])
314
+ .map((t) => (t && typeof t.name === 'string' ? t.name : null))
315
+ .filter(Boolean)
316
+ );
317
+ }
318
+
319
+ // The number of mid-stream retries a streamed turn took, as a hidden field of
320
+ // the result.
321
+ function tagMidstreamRetries(result, attemptIndex) {
322
+ try {
323
+ Object.defineProperty(result, '__midstreamRetries', { value: attemptIndex, enumerable: false });
324
+ } catch {
325
+ /* ignore non-extensible result */
326
+ }
327
+ }
328
+
305
329
  export function _buildRequestBodyForCacheSmoke(messages, model, tools = [], sendOpts = {}) {
306
330
  return buildRequestBody(messages, model, tools, sendOpts);
307
331
  }
@@ -466,6 +490,41 @@ export class AnthropicOAuthProvider {
466
490
  );
467
491
  }
468
492
 
493
+ /**
494
+ * Cache-warm mode (anthropic-cache-warm.mjs): the body `send` would build
495
+ * for these arguments, POSTed once — no retry, credential replay, fallback
496
+ * model or re-send — and cut at the first content block. `onUsage` receives
497
+ * the reported usage as it arrives; resolves the final usage.
498
+ */
499
+ async sendCacheWarm(messages, model, tools, sendOpts = {}, { onUsage, accountId = '' } = {}) {
500
+ await warmCliVersion();
501
+ const opts = sendOpts || {};
502
+ const creds = await this.ensureAuth();
503
+ const body = buildRequestBody(sanitizeToolPairs(messages), model, tools, opts);
504
+ body.messages = await prepareAnthropicImages(body.messages, { signal: opts.signal });
505
+ return sendAnthropicCacheWarm({
506
+ providerName: this.name,
507
+ instance: this,
508
+ accountId,
509
+ model,
510
+ opts,
511
+ onUsage,
512
+ post: (signal) =>
513
+ postMessages({
514
+ accessToken: creds.accessToken,
515
+ requestBody: body,
516
+ betaHeaders: buildOAuthBetaHeaders(body, {
517
+ fastMode: this.fastModeBetaHeaderLatched,
518
+ toolSearch: Array.isArray(body.tools) && body.tools.some((t) => t?.defer_loading === true),
519
+ model,
520
+ opts,
521
+ }),
522
+ signal,
523
+ plain: true,
524
+ }),
525
+ });
526
+ }
527
+
469
528
  async _sendOnce(messages, model, tools, sendOpts) {
470
529
  await warmCliVersion();
471
530
  // Re-warm the kept-alive socket before the turn. preconnect() is a
@@ -497,7 +556,7 @@ export class AnthropicOAuthProvider {
497
556
  const body = buildRequestBody(messages, useModel, tools, sendOpts);
498
557
  body.messages = await prepareAnthropicImages(body.messages, { signal: externalSignal });
499
558
  // Diagnostic: per-block prefix hashes of exactly what is sent.
500
- recordAnthropicPrefix(opts.sessionId || null, anthropicPrefixFingerprint(body));
559
+ recordAnthropicPrefix(anthropicPrefixSessionId(opts), anthropicPrefixFingerprint(body));
501
560
  if (body.speed === 'fast') {
502
561
  this.fastModeBetaHeaderLatched = true;
503
562
  }
@@ -505,15 +564,7 @@ export class AnthropicOAuthProvider {
505
564
  // actually carries deferred (defer_loading) tools — gate the header on
506
565
  // that instead of sending it unconditionally on every request.
507
566
  const hasDeferredTools = Array.isArray(body.tools) && body.tools.some((t) => t && t.defer_loading === true);
508
- // Known tool names for the leaked-tool-call guard in parseSSEStream:
509
- // recovered leaked calls are only synthesized when they name a tool
510
- // actually offered to this request (native + lowered). Derived from the
511
- // final request body so it matches exactly what the model was given.
512
- const knownToolNames = new Set(
513
- (Array.isArray(body.tools) ? body.tools : [])
514
- .map((t) => (t && typeof t.name === 'string' ? t.name : null))
515
- .filter(Boolean)
516
- );
567
+ const knownToolNames = requestToolNames(body);
517
568
  const sessionId = opts.sessionId || null;
518
569
  const iteration = Number.isFinite(Number(opts.iteration)) ? Number(opts.iteration) : null;
519
570
  // Option A: no absolute wall-clock cap on streaming generation. A stream
@@ -530,51 +581,17 @@ export class AnthropicOAuthProvider {
530
581
  // totalSignal is therefore a pure pass-through of externalSignal with no timer.
531
582
  const totalTimeout = createPassthroughSignal(externalSignal);
532
583
  const totalSignal = totalTimeout.signal;
533
- // Request-loop 529s and SSE overload events share one counter; at the
534
- // limit the configured fallback model takes over the whole send.
535
- const overload = createAnthropicOverloadTracker({
536
- model: useModel,
537
- fallbackModel: opts._fallbackTriggered ? undefined : opts.fallbackModel,
538
- });
539
- const { requestWithRetry, cleanupCancelHandler } = createAnthropicOAuthRequest({
540
- provider: this,
584
+ const { requestWithRetry, cleanupCancelHandler, midstream } = this._createSendRecovery({
541
585
  opts,
542
586
  body,
543
587
  useModel,
544
588
  sessionId,
545
- totalSignal,
546
- overload,
547
- betaHeadersFor: (requestBody) =>
548
- buildOAuthBetaHeaders(requestBody, {
549
- fastMode: this.fastModeBetaHeaderLatched,
550
- toolSearch: hasDeferredTools,
551
- model: useModel,
552
- opts,
553
- }),
554
- onStageChange,
555
- });
556
- const recovery = createAnthropicOAuthRecovery({
557
- provider: this,
558
- opts,
559
- body,
560
- useModel,
561
589
  auth,
562
590
  totalSignal,
563
- requestWithRetry,
564
- cleanupCancelHandler,
591
+ hasDeferredTools,
565
592
  onStageChange,
566
593
  onTextReset,
567
594
  });
568
- // Bounded mid-stream retries for transient stream loss; jittered backoff
569
- // between attempts (anthropic-oauth-midstream.mjs).
570
- const midstream = createMidstreamRecovery({
571
- maxRetries: ANTHROPIC_MAX_MIDSTREAM_RETRIES,
572
- totalSignal,
573
- recovery,
574
- onStageChange,
575
- retry529: opts.retry529 !== false,
576
- overload,
577
- });
578
595
 
579
596
  let maxTokensAdjusted = false;
580
597
  try {
@@ -605,7 +622,9 @@ export class AnthropicOAuthProvider {
605
622
  if (SSE_VERBOSE) process.stderr.write(`[anthropic-oauth] Response ${response.status}, parsing SSE...\n`);
606
623
  try {
607
624
  onStageChange?.('streaming');
608
- } catch {}
625
+ } catch {
626
+ // the stage observer is advisory
627
+ }
609
628
 
610
629
  const midState = createMidState(attemptIndex);
611
630
  try {
@@ -623,7 +642,9 @@ export class AnthropicOAuthProvider {
623
642
  );
624
643
  try {
625
644
  controller?.abort?.('Anthropic SSE complete');
626
- } catch {}
645
+ } catch {
646
+ // the stream is complete; the controller may already be aborted
647
+ }
627
648
  this._settleStreamedTurn({
628
649
  result,
629
650
  midState,
@@ -632,12 +653,9 @@ export class AnthropicOAuthProvider {
632
653
  iteration,
633
654
  useModel,
634
655
  requestKind: opts.requestKind || null,
656
+ prefixSessionId: anthropicPrefixSessionId(opts),
635
657
  });
636
- try {
637
- Object.defineProperty(result, '__midstreamRetries', { value: attemptIndex, enumerable: false });
638
- } catch {
639
- /* ignore non-extensible result */
640
- }
658
+ tagMidstreamRetries(result, attemptIndex);
641
659
  return result;
642
660
  } catch (err) {
643
661
  const decision = await midstream.onStreamError({ err, midState, controller, response, attemptIndex });
@@ -649,22 +667,81 @@ export class AnthropicOAuthProvider {
649
667
  }
650
668
  throw midstream.exhaustedError();
651
669
  } catch (err) {
652
- // The fallback trigger can surface from the request loop, a mid-stream
653
- // overload, or the non-streaming recovery: handle it around the whole
654
- // operation, not just the first request.
655
- if (!(err instanceof AnthropicFallbackTriggeredError)) throw err;
656
- process.stderr.write(`[anthropic-oauth] ${err.message}\n`);
657
- announceAnthropicModelFallback(onStageChange, _displayModel(useModel), _displayModel(err.fallbackModel));
658
- return await this.send(messages, err.fallbackModel, tools, {
659
- ...opts,
660
- fallbackModel: undefined,
661
- _fallbackTriggered: true,
670
+ const fallbackOpts = takeAnthropicModelFallback(err, {
671
+ tag: 'anthropic-oauth',
672
+ model: useModel,
673
+ opts,
674
+ onStageChange,
675
+ displayModel: _displayModel,
662
676
  });
677
+ return await this.send(messages, err.fallbackModel, tools, fallbackOpts);
663
678
  } finally {
664
679
  totalTimeout.cleanup();
665
680
  }
666
681
  }
667
682
 
683
+ // The request and recovery pipeline of one send over its fixed body: the
684
+ // shared overload counter, the retried request with its per-request beta
685
+ // headers, the non-streaming recovery and the bounded mid-stream retries.
686
+ _createSendRecovery({
687
+ opts,
688
+ body,
689
+ useModel,
690
+ sessionId,
691
+ auth,
692
+ totalSignal,
693
+ hasDeferredTools,
694
+ onStageChange,
695
+ onTextReset,
696
+ }) {
697
+ // Request-loop 529s and SSE overload events share one counter; at the
698
+ // limit the configured fallback model takes over the whole send.
699
+ const overload = createAnthropicOverloadTracker({
700
+ model: useModel,
701
+ fallbackModel: opts._fallbackTriggered ? undefined : opts.fallbackModel,
702
+ });
703
+ const { requestWithRetry, cleanupCancelHandler } = createAnthropicOAuthRequest({
704
+ provider: this,
705
+ opts,
706
+ body,
707
+ useModel,
708
+ sessionId,
709
+ totalSignal,
710
+ overload,
711
+ betaHeadersFor: (requestBody) =>
712
+ buildOAuthBetaHeaders(requestBody, {
713
+ fastMode: this.fastModeBetaHeaderLatched,
714
+ toolSearch: hasDeferredTools,
715
+ model: useModel,
716
+ opts,
717
+ }),
718
+ onStageChange,
719
+ });
720
+ const recovery = createAnthropicOAuthRecovery({
721
+ provider: this,
722
+ opts,
723
+ body,
724
+ useModel,
725
+ auth,
726
+ totalSignal,
727
+ requestWithRetry,
728
+ cleanupCancelHandler,
729
+ onStageChange,
730
+ onTextReset,
731
+ });
732
+ // Bounded mid-stream retries for transient stream loss; jittered backoff
733
+ // between attempts (anthropic-oauth-midstream.mjs).
734
+ const midstream = createMidstreamRecovery({
735
+ maxRetries: ANTHROPIC_MAX_MIDSTREAM_RETRIES,
736
+ totalSignal,
737
+ recovery,
738
+ onStageChange,
739
+ retry529: opts.retry529 !== false,
740
+ overload,
741
+ });
742
+ return { requestWithRetry, cleanupCancelHandler, midstream };
743
+ }
744
+
668
745
  // One attempt's initial response: a 401 (or Anthropic's exact revoked-token
669
746
  // 403) refreshes the credentials in `auth` and replays once; a context
670
747
  // overflow 400 shrinks `body.max_tokens` and replays once per send
@@ -687,7 +764,9 @@ export class AnthropicOAuthProvider {
687
764
  // resources before the credential-refresh replay.
688
765
  try {
689
766
  controller?.abort?.();
690
- } catch {}
767
+ } catch {
768
+ // the controller may already be aborted before the credential-refresh replay
769
+ }
691
770
  auth.creds = await this.ensureAuth({ forceRefresh: true, reason: String(response.status) });
692
771
  ({ response, controller, cancelHandler } = await requestWithRetry(auth.creds.accessToken));
693
772
  rejectedAuthBody = null;
@@ -702,7 +781,9 @@ export class AnthropicOAuthProvider {
702
781
  cleanupCancelHandler(cancelHandler);
703
782
  try {
704
783
  controller?.abort?.();
705
- } catch {}
784
+ } catch {
785
+ // the controller may already be aborted before the max-tokens replay
786
+ }
706
787
  ({ response, controller, cancelHandler } = await requestWithRetry(auth.creds.accessToken));
707
788
  rejectedAuthBody = null;
708
789
  }
@@ -808,7 +889,16 @@ export class AnthropicOAuthProvider {
808
889
  }
809
890
 
810
891
  // Traces + catalog upkeep for a streamed turn, then the empty-stream guard.
811
- _settleStreamedTurn({ result, midState, sseStartedAt, sessionId, iteration, useModel, requestKind }) {
892
+ _settleStreamedTurn({
893
+ result,
894
+ midState,
895
+ sseStartedAt,
896
+ sessionId,
897
+ iteration,
898
+ useModel,
899
+ requestKind,
900
+ prefixSessionId,
901
+ }) {
812
902
  const ttftMs = midState.ttftAt ? midState.ttftAt - sseStartedAt : null;
813
903
  const liveModel = result.model || useModel;
814
904
  traceAgentSse({
@@ -833,7 +923,7 @@ export class AnthropicOAuthProvider {
833
923
  rawUsage: result.usage?.raw || null,
834
924
  provider: 'anthropic-oauth',
835
925
  requestKind,
836
- prefixBlocks: latestAnthropicPrefix(sessionId),
926
+ prefixBlocks: latestAnthropicPrefix(prefixSessionId),
837
927
  });
838
928
 
839
929
  // Phase I: if the live response surfaced a model id we don't know
@@ -12,11 +12,15 @@
12
12
  import { ANTHROPIC_MAX_CONSECUTIVE_529 } from './retry-backoff.mjs';
13
13
  import { AnthropicFallbackTriggeredError } from './retry-classifier.mjs';
14
14
 
15
- export const OVERLOADED_ERROR_CODE = 'overloaded_error';
15
+ const OVERLOADED_ERROR_CODE = 'overloaded_error';
16
16
 
17
17
  /** Consecutive 529s end the request only for API-key (non-subscriber) first-party Opus. */
18
18
  export function isTerminalOverloadModel(model) {
19
- return /^claude-opus-/.test(String(model || '').trim().toLowerCase());
19
+ return /^claude-opus-/.test(
20
+ String(model || '')
21
+ .trim()
22
+ .toLowerCase()
23
+ );
20
24
  }
21
25
 
22
26
  export function isAnthropicOverloadError(err) {
@@ -56,8 +60,26 @@ export function createAnthropicOverloadTracker({ model, fallbackModel, terminalA
56
60
  };
57
61
  }
58
62
 
63
+ /**
64
+ * The catch around a whole Anthropic send. The fallback trigger can surface
65
+ * from the request loop, a mid-stream overload, or the non-streaming
66
+ * recovery; any other error is rethrown unchanged. For the trigger it logs,
67
+ * announces the model switch, and returns the options of the single re-send
68
+ * on `err.fallbackModel` (no second hop).
69
+ */
70
+ export function takeAnthropicModelFallback(err, { tag, model, opts, onStageChange, displayModel = (id) => id }) {
71
+ if (!(err instanceof AnthropicFallbackTriggeredError)) throw err;
72
+ process.stderr.write(`[${tag}] ${err.message}\n`);
73
+ announceAnthropicModelFallback(onStageChange, displayModel(model), displayModel(err.fallbackModel));
74
+ return {
75
+ ...opts,
76
+ fallbackModel: undefined,
77
+ _fallbackTriggered: true,
78
+ };
79
+ }
80
+
59
81
  /** Visible model-switch notice on the existing display-only stage channel. */
60
- export function announceAnthropicModelFallback(onStageChange, fromLabel, toLabel) {
82
+ function announceAnthropicModelFallback(onStageChange, fromLabel, toLabel) {
61
83
  if (typeof onStageChange !== 'function') return;
62
84
  try {
63
85
  onStageChange('reconnecting', {