mixdog 1.3.4 → 1.4.0

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 (472) hide show
  1. package/LICENSES/oh-my-pi-MIT.txt +23 -0
  2. package/NOTICE.md +17 -2
  3. package/README.md +11 -0
  4. package/package.json +3 -11
  5. package/scripts/daemon-stub.mjs +1 -1
  6. package/scripts/embed-google-oauth-client.mjs +49 -0
  7. package/scripts/gate-local.mjs +4 -2
  8. package/scripts/lib/test-spawn-ledger.mjs +46 -1
  9. package/scripts/native-release-status.mjs +2 -2
  10. package/scripts/recall-history-cases.json +1 -1
  11. package/scripts/suite-health.mjs +10 -1
  12. package/scripts/test.mjs +12 -11
  13. package/src/agents/reviewer/AGENT.md +7 -11
  14. package/src/agents/reviewer/agent.json +1 -1
  15. package/src/defaults/shipped-history.json +25 -1
  16. package/src/defaults/skills/browser-use/SKILL.md +77 -17
  17. package/src/defaults/skills/code-tidy/SKILL.md +142 -270
  18. package/src/defaults/skills/code-tidy/references/agent-cleanup.md +4 -4
  19. package/src/defaults/skills/code-tidy/references/cleanup-report.md +31 -76
  20. package/src/defaults/skills/code-tidy/references/dead-code.md +6 -12
  21. package/src/defaults/skills/computer-use/SKILL.md +33 -9
  22. package/src/defaults/skills/setup/SKILL.md +29 -2
  23. package/src/defaults/skills/setup/references/actions.md +117 -28
  24. package/src/defaults/skills/setup/references/surfaces.md +77 -35
  25. package/src/defaults/skills/setup-guide/SKILL.md +3 -3
  26. package/src/defaults/skills/visualize/SKILL.md +2 -1
  27. package/src/lib/keychain-cjs.cjs +359 -29
  28. package/src/lib/rules-builder.cjs +10 -8
  29. package/src/rules/agent/AGENT.md +6 -6
  30. package/src/rules/agent-mode/AGENT_MODE.md +10 -2
  31. package/src/rules/agent-mode/MIXY.md +12 -0
  32. package/src/rules/lead/LEAD.md +18 -20
  33. package/src/rules/shared/05-tool-calls.md +5 -6
  34. package/src/rules/shared/10-tool-workflow.md +2 -0
  35. package/src/rules/shared/60-verification.md +7 -5
  36. package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +2 -3
  37. package/src/runtime/agent/orchestrator/agent-runtime/heartbeat-completion.mjs +193 -0
  38. package/src/runtime/agent/orchestrator/agent-runtime/title-completion.mjs +3 -1
  39. package/src/runtime/agent/orchestrator/agent-trace-format.mjs +3 -1
  40. package/src/runtime/agent/orchestrator/config.mjs +34 -0
  41. package/src/runtime/agent/orchestrator/context/collect.mjs +3 -0
  42. package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +72 -67
  43. package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +54 -1
  44. package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +3 -3
  45. package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +177 -73
  46. package/src/runtime/agent/orchestrator/mcp/client.mjs +25 -2
  47. package/src/runtime/agent/orchestrator/mcp/oauth-callback.mjs +31 -2
  48. package/src/runtime/agent/orchestrator/mcp/oauth-client.mjs +16 -3
  49. package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +42 -7
  50. package/src/runtime/agent/orchestrator/mcp/oauth-provider.mjs +21 -2
  51. package/src/runtime/agent/orchestrator/mcp/oauth-shared.mjs +23 -0
  52. package/src/runtime/agent/orchestrator/mcp/oauth.mjs +11 -1
  53. package/src/runtime/agent/orchestrator/providers/account-pool.mjs +230 -137
  54. package/src/runtime/agent/orchestrator/providers/admission-scheduler.mjs +64 -7
  55. package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +18 -5
  56. package/src/runtime/agent/orchestrator/providers/anthropic-cache-warm.mjs +165 -0
  57. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
  58. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +4 -1
  59. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/gzip-post.mjs +14 -14
  60. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +160 -69
  61. package/src/runtime/agent/orchestrator/providers/anthropic-overload-fallback.mjs +25 -3
  62. package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +64 -33
  63. package/src/runtime/agent/orchestrator/providers/anthropic.mjs +135 -87
  64. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-catalog.mjs +52 -8
  65. package/src/runtime/agent/orchestrator/providers/antigravity-oauth.mjs +10 -1
  66. package/src/runtime/agent/orchestrator/providers/antigravity-request.mjs +22 -6
  67. package/src/runtime/agent/orchestrator/providers/antigravity-response.mjs +15 -4
  68. package/src/runtime/agent/orchestrator/providers/antigravity-stream.mjs +17 -2
  69. package/src/runtime/agent/orchestrator/providers/antigravity-transport.mjs +142 -104
  70. package/src/runtime/agent/orchestrator/providers/cache-warm-admission.mjs +90 -0
  71. package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +1 -1
  72. package/src/runtime/agent/orchestrator/providers/cursor-wire-normalization.mjs +10 -4
  73. package/src/runtime/agent/orchestrator/providers/cursor-wire-protobuf.mjs +10 -217
  74. package/src/runtime/agent/orchestrator/providers/cursor-wire-transport.mjs +25 -9
  75. package/src/runtime/agent/orchestrator/providers/cursor.mjs +22 -6
  76. package/src/runtime/agent/orchestrator/providers/devin-auth.mjs +409 -0
  77. package/src/runtime/agent/orchestrator/providers/devin-wire-families.mjs +187 -0
  78. package/src/runtime/agent/orchestrator/providers/devin-wire-identity.mjs +342 -0
  79. package/src/runtime/agent/orchestrator/providers/devin-wire-models.mjs +541 -0
  80. package/src/runtime/agent/orchestrator/providers/devin-wire-protobuf.mjs +305 -0
  81. package/src/runtime/agent/orchestrator/providers/devin-wire-request.mjs +558 -0
  82. package/src/runtime/agent/orchestrator/providers/devin-wire-schema.mjs +880 -0
  83. package/src/runtime/agent/orchestrator/providers/devin-wire-session.mjs +190 -0
  84. package/src/runtime/agent/orchestrator/providers/devin-wire-tool-args.mjs +351 -0
  85. package/src/runtime/agent/orchestrator/providers/devin-wire-transport.mjs +560 -0
  86. package/src/runtime/agent/orchestrator/providers/devin.mjs +491 -0
  87. package/src/runtime/agent/orchestrator/providers/effort-configuration.mjs +3 -0
  88. package/src/runtime/agent/orchestrator/providers/gemini-output-limit.mjs +46 -0
  89. package/src/runtime/agent/orchestrator/providers/gemini-reasoning-relay.mjs +30 -0
  90. package/src/runtime/agent/orchestrator/providers/gemini-request-body.mjs +7 -11
  91. package/src/runtime/agent/orchestrator/providers/gemini-retry-policy.mjs +61 -22
  92. package/src/runtime/agent/orchestrator/providers/gemini-sdk-request.mjs +1 -0
  93. package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +71 -4
  94. package/src/runtime/agent/orchestrator/providers/gemini.mjs +25 -2
  95. package/src/runtime/agent/orchestrator/providers/grok-client-version.mjs +1 -1
  96. package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +96 -5
  97. package/src/runtime/agent/orchestrator/providers/lib/oauth-token-utils.mjs +17 -3
  98. package/src/runtime/agent/orchestrator/providers/lib/tail-reminder-split.mjs +23 -5
  99. package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +52 -10
  100. package/src/runtime/agent/orchestrator/providers/model-proxy-channel.d.mts +8 -1
  101. package/src/runtime/agent/orchestrator/providers/model-proxy-channel.mjs +1 -0
  102. package/src/runtime/agent/orchestrator/providers/npm-cli-version.mjs +11 -3
  103. package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +19 -1
  104. package/src/runtime/agent/orchestrator/providers/oauth-usage.mjs +39 -3
  105. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +3 -1
  106. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +2 -0
  107. package/src/runtime/agent/orchestrator/providers/openai-error-contract.mjs +6 -1
  108. package/src/runtime/agent/orchestrator/providers/openai-oauth-tokens.mjs +10 -9
  109. package/src/runtime/agent/orchestrator/providers/openai-ws-send/send-context.mjs +22 -3
  110. package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/attempt-context.mjs +43 -5
  111. package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/handshake-failure.mjs +3 -1
  112. package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/stream-failure.mjs +6 -3
  113. package/src/runtime/agent/orchestrator/providers/opencode-go-gemini.mjs +1 -0
  114. package/src/runtime/agent/orchestrator/providers/provider-availability.mjs +19 -0
  115. package/src/runtime/agent/orchestrator/providers/provider-error-kind.mjs +65 -1
  116. package/src/runtime/agent/orchestrator/providers/quota-reading.mjs +38 -12
  117. package/src/runtime/agent/orchestrator/providers/registry.mjs +43 -3
  118. package/src/runtime/agent/orchestrator/providers/retry-executor.mjs +39 -7
  119. package/src/runtime/agent/orchestrator/providers/statusline-route-meta.mjs +6 -0
  120. package/src/runtime/agent/orchestrator/providers/wire-protobuf-codec.mjs +368 -0
  121. package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +12 -7
  122. package/src/runtime/agent/orchestrator/runtime-core/builtin-features.mjs +2 -0
  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 +1 -1
  127. package/src/runtime/agent/orchestrator/runtime-core/reaction-tool-defs.mjs +133 -0
  128. package/src/runtime/agent/orchestrator/runtime-core/session-text.mjs +2 -0
  129. package/src/runtime/agent/orchestrator/runtime-core/tool-bridge.mjs +19 -4
  130. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-data.mjs +3 -0
  131. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +125 -30
  132. package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +23 -5
  133. package/src/runtime/agent/orchestrator/runtime-core/tool-profile.mjs +35 -10
  134. package/src/runtime/agent/orchestrator/runtime-core/workflow/agents.mjs +57 -10
  135. package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +9 -6
  136. package/src/runtime/agent/orchestrator/runtime-core/workflow-ids.mjs +1 -1
  137. package/src/runtime/agent/orchestrator/session/agent-loop.mjs +18 -0
  138. package/src/runtime/agent/orchestrator/session/agent-room.d.mts +0 -3
  139. package/src/runtime/agent/orchestrator/session/agent-room.mjs +10 -4
  140. package/src/runtime/agent/orchestrator/session/cache-warm.mjs +792 -0
  141. package/src/runtime/agent/orchestrator/session/compact/runner.mjs +148 -25
  142. package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +475 -58
  143. package/src/runtime/agent/orchestrator/session/compaction-archive.mjs +42 -17
  144. package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +8 -0
  145. package/src/runtime/agent/orchestrator/session/human-gate/gate.mjs +47 -9
  146. package/src/runtime/agent/orchestrator/session/human-gate/outbound-policy.mjs +6 -2
  147. package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +36 -4
  148. package/src/runtime/agent/orchestrator/session/human-gate/store.mjs +14 -2
  149. package/src/runtime/agent/orchestrator/session/loop/assistant-commit.mjs +8 -0
  150. package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +18 -22
  151. package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +32 -3
  152. package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +11 -2
  153. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/segments.mjs +4 -1
  154. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +51 -3
  155. package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +17 -3
  156. package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +10 -2
  157. package/src/runtime/agent/orchestrator/session/loop/tool-exec/after-hook.mjs +2 -1
  158. package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +14 -4
  159. package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +16 -2
  160. package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +16 -1
  161. package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +10 -0
  162. package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +3 -10
  163. package/src/runtime/agent/orchestrator/session/loop/tool-phase.mjs +23 -5
  164. package/src/runtime/agent/orchestrator/session/loop/turn-limits.mjs +60 -0
  165. package/src/runtime/agent/orchestrator/session/manager/ask-queue.mjs +12 -2
  166. package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +19 -1
  167. package/src/runtime/agent/orchestrator/session/manager/ask-turn-commit.mjs +2 -0
  168. package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +133 -90
  169. package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +14 -0
  170. package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +2 -1
  171. package/src/runtime/agent/orchestrator/session/manager/ask-turn-state.mjs +31 -4
  172. package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +30 -18
  173. package/src/runtime/agent/orchestrator/session/manager/owner-route-fallbacks.mjs +23 -13
  174. package/src/runtime/agent/orchestrator/session/manager/pending-message-entry.mjs +11 -2
  175. package/src/runtime/agent/orchestrator/session/manager/provider-replay.mjs +13 -0
  176. package/src/runtime/agent/orchestrator/session/manager/route-fallback-chain.mjs +129 -0
  177. package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +20 -2
  178. package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +2 -0
  179. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +8 -0
  180. package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +1 -1
  181. package/src/runtime/agent/orchestrator/session/manager/session-tool-surface.mjs +13 -0
  182. package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +7 -2
  183. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-journal.mjs +102 -15
  184. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint.mjs +18 -5
  185. package/src/runtime/agent/orchestrator/session/message-ids.mjs +5 -3
  186. package/src/runtime/agent/orchestrator/session/message-reactions.mjs +89 -0
  187. package/src/runtime/agent/orchestrator/session/message-reactions.test-support.mjs +75 -0
  188. package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +19 -8
  189. package/src/runtime/agent/orchestrator/session/prompt-cache-idle-gaps.mjs +113 -0
  190. package/src/runtime/agent/orchestrator/session/prompt-cache-touch-store.mjs +127 -0
  191. package/src/runtime/agent/orchestrator/session/routine-result.d.mts +0 -2
  192. package/src/runtime/agent/orchestrator/session/routine-result.mjs +47 -11
  193. package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +20 -2
  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-persistence-events.mjs +29 -0
  203. package/src/runtime/agent/orchestrator/session/store-agent-worker-header-cache.mjs +85 -0
  204. package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +133 -18
  205. package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +12 -2
  206. package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +44 -14
  207. package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +84 -3
  208. package/src/runtime/agent/orchestrator/session/stored-attachment-history.mjs +32 -0
  209. package/src/runtime/agent/orchestrator/session/tail-reminder-rules.mjs +11 -5
  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/tool-batch/state.mjs +4 -0
  214. package/src/runtime/agent/orchestrator/session/tool-batch.mjs +5 -0
  215. package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +25 -2
  216. package/src/runtime/agent/orchestrator/session/transcript-restore/tool-result-status.mjs +9 -7
  217. package/src/runtime/agent/orchestrator/session/transcript-restore/tool-result-text.mjs +2 -2
  218. package/src/runtime/agent/orchestrator/session/turn-failure.mjs +5 -1
  219. package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +5 -2
  220. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/backgrounded-result.mjs +12 -1
  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.mjs +25 -5
  225. package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +65 -7
  226. package/src/runtime/agent/orchestrator/tools/builtin/shell-runtime.mjs +7 -1
  227. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +36 -13
  228. package/src/runtime/browser-bridge/action-schema.mjs +13 -2
  229. package/src/runtime/browser-bridge/client.mjs +73 -8
  230. package/src/runtime/browser-bridge/input-fields.mjs +8 -9
  231. package/src/runtime/browser-bridge/mail-links.mjs +107 -0
  232. package/src/runtime/browser-bridge/tool-defs.mjs +1 -1
  233. package/src/runtime/channels/lib/config.mjs +6 -61
  234. package/src/runtime/channels/lib/crash-log.mjs +1 -1
  235. package/src/runtime/channels/lib/event-pipeline.mjs +4 -19
  236. package/src/runtime/channels/lib/event-queue.mjs +3 -18
  237. package/src/runtime/channels/lib/owned-runtime/automation-services.mjs +2 -2
  238. package/src/runtime/channels/lib/owned-runtime/automation-start.mjs +3 -4
  239. package/src/runtime/channels/lib/owned-runtime/config-reload.mjs +4 -59
  240. package/src/runtime/channels/lib/owned-runtime/owned-start.mjs +33 -115
  241. package/src/runtime/channels/lib/owned-runtime/owned-stop.mjs +5 -22
  242. package/src/runtime/channels/lib/owned-runtime/state.mjs +2 -8
  243. package/src/runtime/channels/lib/owned-runtime.mjs +6 -23
  244. package/src/runtime/channels/lib/parent-bridge.mjs +2 -2
  245. package/src/runtime/channels/lib/runtime-paths.mjs +4 -43
  246. package/src/runtime/channels/lib/schedule-errors.mjs +51 -0
  247. package/src/runtime/channels/lib/scheduler.mjs +135 -154
  248. package/src/runtime/channels/lib/schedules-db.mjs +83 -11
  249. package/src/runtime/channels/lib/status-snapshot.mjs +1 -1
  250. package/src/runtime/channels/lib/tool-dispatch.mjs +14 -2
  251. package/src/runtime/channels/lib/webhooks-db.mjs +5 -9
  252. package/src/runtime/channels/lib/worker-bootstrap.mjs +0 -1
  253. package/src/runtime/channels/lib/worker-ipc.mjs +0 -1
  254. package/src/runtime/channels/lib/worker-main.mjs +19 -34
  255. package/src/runtime/computer-bridge/action-schema.mjs +42 -1
  256. package/src/runtime/computer-bridge/actions.mjs +9 -1
  257. package/src/runtime/computer-bridge/client.mjs +180 -8
  258. package/src/runtime/computer-bridge/core-actions.mjs +2 -2
  259. package/src/runtime/computer-bridge/error-recovery.mjs +27 -2
  260. package/src/runtime/computer-bridge/linux-readiness.mjs +65 -23
  261. package/src/runtime/computer-bridge/pending-continuation.mjs +1 -1
  262. package/src/runtime/connectors/connector-accounts-mcp.mjs +230 -0
  263. package/src/runtime/connectors/gmail-app-password.mjs +172 -39
  264. package/src/runtime/connectors/google-mcp.mjs +10 -12
  265. package/src/runtime/memory/lib/pg/adapter.mjs +77 -70
  266. package/src/runtime/memory/lib/pg/supervisor.mjs +24 -12
  267. package/src/runtime/memory/lib/runtime-fetcher.mjs +23 -5
  268. package/src/runtime/office/com/com-adapter.mjs +17 -1
  269. package/src/runtime/office/com/office-com-host.ps1 +51 -1
  270. package/src/runtime/office/pdf/cfb-fixture.mjs +328 -0
  271. package/src/runtime/office/pdf/cfb-protection.mjs +311 -0
  272. package/src/runtime/office/pdf/document-preview.mjs +326 -8
  273. package/src/runtime/office/pdf/ooxml-crypto.mjs +469 -0
  274. package/src/runtime/office/pdf/ooxml-key-worker.mjs +14 -0
  275. package/src/runtime/office/portable/portable-soffice.mjs +45 -5
  276. package/src/runtime/session-search/session-search-db.mjs +73 -9
  277. package/src/runtime/session-search/session-search-ingest.mjs +110 -20
  278. package/src/runtime/shared/abort-race.mjs +89 -0
  279. package/src/runtime/shared/agent-avatar.d.mts +0 -1
  280. package/src/runtime/shared/agent-kind.mjs +4 -3
  281. package/src/runtime/shared/bot-hops.mjs +62 -2
  282. package/src/runtime/shared/bounded-download.mjs +8 -3
  283. package/src/runtime/shared/config.mjs +51 -35
  284. package/src/runtime/shared/connector-accounts.mjs +20 -10
  285. package/src/runtime/shared/connector-catalog.d.mts +33 -2
  286. package/src/runtime/shared/connector-catalog.mjs +166 -8
  287. package/src/runtime/shared/connector-triggers.mjs +22 -19
  288. package/src/runtime/shared/defaults-separation.mjs +2 -14
  289. package/src/runtime/shared/delegated-approval-host.mjs +103 -11
  290. package/src/runtime/shared/developer-options.mjs +32 -1
  291. package/src/runtime/shared/err-text.mjs +24 -15
  292. package/src/runtime/shared/file-permissions.d.mts +0 -8
  293. package/src/runtime/shared/file-permissions.mjs +0 -11
  294. package/src/runtime/shared/git-direct.test-support.mjs +19 -0
  295. package/src/runtime/shared/google-oauth-client.generated.json +4 -0
  296. package/src/runtime/shared/google-oauth-client.mjs +34 -9
  297. package/src/runtime/shared/heartbeat-interval.d.mts +4 -0
  298. package/src/runtime/shared/heartbeat-interval.mjs +19 -0
  299. package/src/runtime/shared/idle-auto-clear-gate.mjs +104 -0
  300. package/src/runtime/shared/llm/anthropic-betas.mjs +7 -0
  301. package/src/runtime/shared/llm/anthropic-thinking-contract.mjs +12 -0
  302. package/src/runtime/shared/llm/provider-catalog-registry.mjs +1 -0
  303. package/src/runtime/shared/llm/usage-rollup.mjs +1 -1
  304. package/src/runtime/shared/llm/well-formed.mjs +66 -0
  305. package/src/runtime/shared/mixy-presence.mjs +22 -0
  306. package/src/runtime/shared/orchestration.d.mts +2 -0
  307. package/src/runtime/shared/pg-schema-db.mjs +27 -16
  308. package/src/runtime/shared/profile-config.cjs +1 -1
  309. package/src/runtime/shared/prompt-origin.d.mts +4 -0
  310. package/src/runtime/shared/prompt-origin.mjs +21 -0
  311. package/src/runtime/shared/provider-accounts.mjs +231 -59
  312. package/src/runtime/shared/provider-api-key.mjs +19 -8
  313. package/src/runtime/shared/provider-display-name.mjs +29 -0
  314. package/src/runtime/shared/provider-timeout-phase.mjs +2 -0
  315. package/src/runtime/shared/routine-trigger.d.mts +2 -0
  316. package/src/runtime/shared/routine-trigger.mjs +52 -0
  317. package/src/runtime/shared/sensitive-path-rules.d.mts +2 -10
  318. package/src/runtime/shared/sensitive-path-rules.mjs +19 -41
  319. package/src/runtime/shared/session-activity-signal.mjs +34 -1
  320. package/src/runtime/shared/session-sidebar-host.d.mts +1 -1
  321. package/src/runtime/shared/session-sidebar-host.mjs +7 -3
  322. package/src/runtime/shared/session-turn-prelude.mjs +18 -0
  323. package/src/runtime/shared/tool-execution-contract.mjs +2 -0
  324. package/src/runtime/shared/tool-result-summary.mjs +1 -14
  325. package/src/runtime/shared/transcript-metadata.mjs +38 -0
  326. package/src/runtime/shared/user-data-guard.mjs +30 -2
  327. package/src/runtime/shared/worktrees/activity-gate.mjs +12 -5
  328. package/src/runtime/shared/worktrees/test-support.mjs +9 -4
  329. package/src/runtime/terminal-bridge/client.mjs +10 -1
  330. package/src/runtime/visualize-bridge/client.mjs +27 -8
  331. package/src/runtime/visualize-bridge/tool-defs.mjs +22 -8
  332. package/src/runtime/visualize-bridge/tool-meta.d.mts +5 -0
  333. package/src/runtime/visualize-bridge/tool-meta.mjs +22 -0
  334. package/src/runtime/web-search/lib/fetch-pipeline.mjs +2 -2
  335. package/src/session-runtime/agent-home-delivery.mjs +486 -179
  336. package/src/session-runtime/agent-room-delivery.mjs +28 -1
  337. package/src/session-runtime/agent-task-sessions.mjs +561 -199
  338. package/src/session-runtime/boot/apis.mjs +9 -0
  339. package/src/session-runtime/boot/begin.mjs +3 -2
  340. package/src/session-runtime/boot/infrastructure.mjs +4 -0
  341. package/src/session-runtime/boot/providers.mjs +3 -0
  342. package/src/session-runtime/boot/tools.mjs +8 -1
  343. package/src/session-runtime/bot-chain.mjs +32 -0
  344. package/src/session-runtime/bot-status.mjs +7 -4
  345. package/src/session-runtime/channel-config-api.mjs +63 -17
  346. package/src/session-runtime/config-lifecycle.mjs +6 -0
  347. package/src/session-runtime/connector-merge-migration.mjs +305 -0
  348. package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +132 -28
  349. package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +2 -0
  350. package/src/session-runtime/internal-tool-executor/reaction-tool.mjs +45 -0
  351. package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +72 -5
  352. package/src/session-runtime/internal-tool-executor.mjs +4 -0
  353. package/src/session-runtime/lifecycle/inheritance.mjs +16 -3
  354. package/src/session-runtime/lifecycle/session-catalog.mjs +3 -1
  355. package/src/session-runtime/lifecycle/teardown/runtime-stops.mjs +50 -4
  356. package/src/session-runtime/lifecycle/teardown.mjs +23 -5
  357. package/src/session-runtime/mcp-glue/server-catalog.mjs +61 -3
  358. package/src/session-runtime/mcp-oauth-login.mjs +5 -3
  359. package/src/session-runtime/mixy-heartbeat.mjs +927 -0
  360. package/src/session-runtime/model-route/route-tuning.mjs +10 -6
  361. package/src/session-runtime/notification-bus.mjs +31 -117
  362. package/src/session-runtime/notification-completion-queue.mjs +54 -0
  363. package/src/session-runtime/notification-listeners.mjs +76 -0
  364. package/src/session-runtime/owned-automation-run.mjs +35 -13
  365. package/src/session-runtime/prewarm/channel-start.mjs +3 -7
  366. package/src/session-runtime/provider-auth/login.mjs +7 -0
  367. package/src/session-runtime/provider-models/row-hydration.mjs +13 -2
  368. package/src/session-runtime/resource-mcp-api.mjs +143 -224
  369. package/src/session-runtime/resource-mcp-connector-accounts.mjs +163 -0
  370. package/src/session-runtime/resource-mcp-oauth-api.mjs +217 -0
  371. package/src/session-runtime/resource-mcp-secrets.mjs +82 -0
  372. package/src/session-runtime/resource-mcp-servers.mjs +78 -0
  373. package/src/session-runtime/resource-mcp-store.mjs +49 -0
  374. package/src/session-runtime/routine-home-turn.mjs +33 -6
  375. package/src/session-runtime/routine-owner.mjs +40 -9
  376. package/src/session-runtime/schedule-session-run.mjs +7 -3
  377. package/src/session-runtime/services/agent-tool/close-flow.mjs +3 -0
  378. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-plan.mjs +8 -12
  379. package/src/session-runtime/services/agent-tool/spawn-preset.mjs +7 -2
  380. package/src/session-runtime/services/agent-tool/tag-registry.mjs +1 -0
  381. package/src/session-runtime/services/agent-tool/worker-index/awaiting-user-sync.mjs +51 -0
  382. package/src/session-runtime/services/agent-tool/worker-index/disposal.mjs +55 -0
  383. package/src/session-runtime/services/agent-tool/worker-index/released-store.mjs +123 -0
  384. package/src/session-runtime/services/agent-tool/worker-index/restart-settlement.mjs +112 -0
  385. package/src/session-runtime/services/agent-tool/worker-index/row-reads.mjs +36 -0
  386. package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +2 -0
  387. package/src/session-runtime/services/agent-tool/worker-index/row-store.mjs +17 -4
  388. package/src/session-runtime/services/agent-tool/worker-index/row-writes.mjs +58 -0
  389. package/src/session-runtime/services/agent-tool/worker-index.mjs +41 -241
  390. package/src/session-runtime/services/agent-tool/worker-rows.mjs +3 -0
  391. package/src/session-runtime/services/channel-admin.mjs +73 -31
  392. package/src/session-runtime/services/channel-session-router.mjs +4 -2
  393. package/src/session-runtime/services/channel-worker.mjs +1 -1
  394. package/src/session-runtime/services/provider-admin.mjs +128 -25
  395. package/src/session-runtime/services/schedule-access.mjs +14 -0
  396. package/src/session-runtime/services/seeds.mjs +0 -28
  397. package/src/session-runtime/services/usage-dashboard-model.mjs +1 -0
  398. package/src/session-runtime/session-compaction-sync.mjs +27 -0
  399. package/src/session-runtime/session-create/session-options.mjs +8 -4
  400. package/src/session-runtime/settings-builtin-tools-api.mjs +11 -0
  401. package/src/session-runtime/settings-compaction-api.mjs +2 -40
  402. package/src/session-runtime/settings-system-api.mjs +28 -1
  403. package/src/session-runtime/setup-tool/agent-settings-actions.mjs +65 -0
  404. package/src/session-runtime/setup-tool/executor.mjs +187 -29
  405. package/src/session-runtime/setup-tool/extended-actions.mjs +33 -2
  406. package/src/session-runtime/setup-tool/session-route-actions.mjs +152 -0
  407. package/src/session-runtime/setup-tool/settings-contract.mjs +68 -6
  408. package/src/session-runtime/setup-tool/tool-defs.mjs +92 -6
  409. package/src/session-runtime/task-session-route.mjs +99 -0
  410. package/src/session-runtime/tool-policy/agent-profile-fold.mjs +17 -13
  411. package/src/session-runtime/tool-policy/policy-stage.mjs +21 -4
  412. package/src/session-runtime/tool-policy/surface-helpers.mjs +2 -3
  413. package/src/session-runtime/tool-surface.mjs +4 -0
  414. package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +1 -0
  415. package/src/session-runtime/workflow-agents-api/agent-editor.mjs +98 -21
  416. package/src/session-runtime/workflow-agents-api/style-and-mode.mjs +4 -0
  417. package/src/session-runtime/workflow-agents-api/workflow-packs.mjs +6 -1
  418. package/src/session-runtime/workspace/transitions.mjs +10 -2
  419. package/src/standalone/channel-transport/client-registry/client-records.mjs +65 -0
  420. package/src/standalone/channel-transport/client-registry/client-registration.mjs +118 -0
  421. package/src/standalone/channel-transport/client-registry.mjs +24 -163
  422. package/src/standalone/channel-transport.mjs +1 -1
  423. package/src/standalone/daemon-channels-loader.mjs +10 -8
  424. package/src/standalone/daemon-session-control/list-page.mjs +72 -0
  425. package/src/standalone/daemon-session-control/request.mjs +51 -0
  426. package/src/standalone/daemon-session-control/room-host.mjs +57 -0
  427. package/src/standalone/daemon-session-control/route-control.mjs +48 -0
  428. package/src/standalone/daemon-session-control/send-turn.mjs +60 -0
  429. package/src/standalone/daemon-session-control/worktree-control.mjs +40 -0
  430. package/src/standalone/daemon-session-control.mjs +161 -157
  431. package/src/standalone/daemon.mjs +33 -2
  432. package/src/standalone/session-client.mjs +7 -3
  433. package/src/standalone/session-protocol.mjs +10 -0
  434. package/src/standalone/session-service/agent-tree/agent-cancel.mjs +6 -2
  435. package/src/standalone/session-service/agent-tree/agent-child.mjs +1 -0
  436. package/src/standalone/session-service/quota-resume.mjs +3 -0
  437. package/src/standalone/session-service/retention/busy.mjs +65 -1
  438. package/src/standalone/session-service/session-calls/session-action.mjs +23 -2
  439. package/src/standalone/session-service/session-calls/session-turns.mjs +6 -0
  440. package/src/standalone/session-service/session-calls/session-views.mjs +8 -0
  441. package/src/standalone/session-service.mjs +13 -0
  442. package/src/standalone/session-tool-output.mjs +21 -10
  443. package/src/tui/app/model-options.mjs +4 -27
  444. package/src/tui/dist/index.mjs +81 -65
  445. package/src/tui/session/agent-job-feed/model-notification.mjs +3 -0
  446. package/src/tui/session/initial-state.mjs +3 -0
  447. package/src/tui/session/notice-surface.mjs +23 -1
  448. package/src/tui/session/queue-helpers.mjs +3 -42
  449. package/src/tui/session/session-api/integrations.mjs +1 -0
  450. package/src/tui/session/session-api/lifecycle.mjs +8 -0
  451. package/src/tui/session/session-api/routes-agent-definitions.mjs +14 -2
  452. package/src/tui/session/session-api/routes-write.mjs +5 -1
  453. package/src/tui/session/session-api/routes.mjs +1 -0
  454. package/src/tui/session/session-api/settings.mjs +30 -2
  455. package/src/tui/session/session-flow/auto-clear.mjs +4 -33
  456. package/src/tui/session/session-flow/drain-closed-queue.mjs +38 -0
  457. package/src/tui/session/session-flow/drain-enqueue.mjs +86 -0
  458. package/src/tui/session/session-flow/drain-retry.mjs +35 -0
  459. package/src/tui/session/session-flow/drain.mjs +118 -149
  460. package/src/tui/session/session-flow/queue/entry-shape.mjs +5 -0
  461. package/src/tui/session/session-flow/queue/take-entries.mjs +5 -2
  462. package/src/tui/session/tool-approval-delegation.mjs +64 -0
  463. package/src/tui/session/tool-approval-request.mjs +39 -0
  464. package/src/tui/session/tool-approval-settle.mjs +62 -0
  465. package/src/tui/session/tool-approval.mjs +69 -115
  466. package/src/tui/session/tui-steering-persist.mjs +8 -1
  467. package/src/tui/session/turn-stream.mjs +36 -3
  468. package/src/tui/session/turn.mjs +23 -2
  469. package/src/vendor/statusline/bin/statusline-route.mjs +1 -219
  470. package/src/vendor/statusline/src/gateway/route-meta.mjs +35 -13
  471. package/scripts/code-graph-description-contract.mjs +0 -188
  472. package/src/runtime/channels/lib/owned-runtime/ownership-refresh.mjs +0 -36
@@ -43,16 +43,17 @@ import {
43
43
  } from './anthropic-oauth-credentials.mjs';
44
44
  import { claudeCliUserAgent, learnRequiredCliVersion, warmCliVersion } from './anthropic-oauth-client-version.mjs';
45
45
  import { createPassthroughSignal } from '../stall-policy.mjs';
46
- import { AnthropicFallbackTriggeredError } from './retry-classifier.mjs';
47
46
  import { ANTHROPIC_MAX_MIDSTREAM_RETRIES, parseSSEStream, _classifyMidstreamError } from './anthropic-sse.mjs';
48
47
  import { buildAnthropicBetaHeaders, supportsAnthropicFastMode } from './anthropic-betas.mjs';
49
48
  import { applyAnthropicServerFallback } from './anthropic-server-fallback.mjs';
50
49
  import { fastModeAvailable, fastModeDowngraded, noteFastModeCapacityError } from './anthropic-fast-mode.mjs';
51
50
  import { ANTHROPIC_VERSION, anthropicQuotaError, createAnthropicOAuthRequest } from './anthropic-oauth-request.mjs';
52
51
  import { isRefreshableAuthRejection } from './anthropic-oauth-request/initial-status.mjs';
52
+ import { postMessages } from './anthropic-oauth-request/gzip-post.mjs';
53
+ import { sendAnthropicCacheWarm } from './anthropic-cache-warm.mjs';
53
54
  import { applyAnthropicErrorContract } from './anthropic-error-contract.mjs';
54
55
  import { adjustMaxTokensForContextOverflow } from './anthropic-max-tokens-recovery.mjs';
55
- import { announceAnthropicModelFallback, createAnthropicOverloadTracker } from './anthropic-overload-fallback.mjs';
56
+ import { createAnthropicOverloadTracker, takeAnthropicModelFallback } from './anthropic-overload-fallback.mjs';
56
57
  import { createAnthropicOAuthRecovery } from './anthropic-oauth-recovery.mjs';
57
58
  import { createMidState, createMidstreamRecovery } from './anthropic-oauth-midstream.mjs';
58
59
  import { assertAnthropicStreamNotEmpty } from './anthropic-midstream-recovery.mjs';
@@ -61,10 +62,13 @@ import { ANTHROPIC_EFFORT_LEVELS, withEffortRejectionFallback } from './effort-r
61
62
  import { getLlmDispatcher, preconnect } from '../../../shared/llm/http-agent.mjs';
62
63
  import {
63
64
  anthropicThinkingActive,
65
+ anthropicTurnScopedReminders,
64
66
  appendAnthropicTailReminder,
67
+ appendAnthropicTurnReminder,
65
68
  applyAnthropicCacheMarkers,
66
69
  clampAnthropicThinkingBudget as clampThinkingBudgetTokens,
67
70
  deferredAnthropicTools as sharedDeferredAnthropicTools,
71
+ hasAnthropicTurnScopedMessages,
68
72
  requestAnthropicTools as sharedRequestAnthropicTools,
69
73
  resolveAnthropicCacheTtls as resolveCacheTtls,
70
74
  resolveAnthropicMessageCacheSlots,
@@ -72,6 +76,7 @@ import {
72
76
  sharedCachePrefixBoundary,
73
77
  toAnthropicMessages,
74
78
  toAnthropicToolChoice,
79
+ withAnthropicTurnReminders,
75
80
  } from './lib/anthropic-request-utils.mjs';
76
81
  import { splitTailReminder } from './lib/tail-reminder-split.mjs';
77
82
  import {
@@ -111,6 +116,7 @@ function buildOAuthBetaHeaders(body, { fastMode = false, toolSearch = false, mod
111
116
  effort: shouldIncludeEffortBeta(model, opts),
112
117
  serverFallback: body?.fallbacks === 'default',
113
118
  thinkingDisplayUpdates: body?.thinking?.display === 'updates',
119
+ turnScopedSystem: hasAnthropicTurnScopedMessages(body?.messages),
114
120
  });
115
121
  }
116
122
 
@@ -223,12 +229,17 @@ function buildRequestBody(requestMessages, model, tools, sendOpts) {
223
229
  // applied to the FINAL sanitized array by invariant, so block drops /
224
230
  // inserts / reorders performed by the sanitizer can never move or delete a
225
231
  // marked block. NEVER sanitize again after this (see send path).
226
- const lowerHistory = (history, projection) =>
227
- lowerAnthropicEffortHistory(
232
+ // Turn-scoped tail reminders (tail-reminder-split.mjs): stored reminders are
233
+ // re-sent before their assistant turns, the current one ends the request.
234
+ const turnScoped = anthropicTurnScopedReminders('anthropic-oauth', model);
235
+ const lowerHistory = (history, projection) => {
236
+ const lowered = lowerAnthropicEffortHistory(
228
237
  history.filter((m) => m.role !== 'system'),
229
238
  (segment) => toAnthropicMessages(segment, requestTools),
230
239
  projection
231
240
  );
241
+ return turnScoped ? withAnthropicTurnReminders(lowered) : lowered;
242
+ };
232
243
  const anthropicMessages = applyAnthropicCacheMarkers(
233
244
  lowerHistory(chatMsgs, effortProjection),
234
245
  messageCacheSlots,
@@ -240,7 +251,9 @@ function buildRequestBody(requestMessages, model, tools, sendOpts) {
240
251
  const body = {
241
252
  model,
242
253
  max_tokens: maxTokens,
243
- messages: appendAnthropicTailReminder(anthropicMessages, reminder),
254
+ messages: turnScoped
255
+ ? appendAnthropicTurnReminder(anthropicMessages, reminder)
256
+ : appendAnthropicTailReminder(anthropicMessages, reminder),
244
257
  stream: true,
245
258
  };
246
259
  applyAnthropicServerFallback(body, model, {
@@ -290,6 +303,28 @@ function buildRequestBody(requestMessages, model, tools, sendOpts) {
290
303
  return markAnthropicEffortBody(body, effortProjection);
291
304
  }
292
305
 
306
+ // Known tool names for the leaked-tool-call guard in parseSSEStream:
307
+ // recovered leaked calls are only synthesized when they name a tool
308
+ // actually offered to this request (native + lowered). Derived from the
309
+ // final request body so it matches exactly what the model was given.
310
+ function requestToolNames(body) {
311
+ return new Set(
312
+ (Array.isArray(body.tools) ? body.tools : [])
313
+ .map((t) => (t && typeof t.name === 'string' ? t.name : null))
314
+ .filter(Boolean)
315
+ );
316
+ }
317
+
318
+ // The number of mid-stream retries a streamed turn took, as a hidden field of
319
+ // the result.
320
+ function tagMidstreamRetries(result, attemptIndex) {
321
+ try {
322
+ Object.defineProperty(result, '__midstreamRetries', { value: attemptIndex, enumerable: false });
323
+ } catch {
324
+ /* ignore non-extensible result */
325
+ }
326
+ }
327
+
293
328
  export function _buildRequestBodyForCacheSmoke(messages, model, tools = [], sendOpts = {}) {
294
329
  return buildRequestBody(messages, model, tools, sendOpts);
295
330
  }
@@ -454,6 +489,41 @@ export class AnthropicOAuthProvider {
454
489
  );
455
490
  }
456
491
 
492
+ /**
493
+ * Cache-warm mode (anthropic-cache-warm.mjs): the body `send` would build
494
+ * for these arguments, POSTed once — no retry, credential replay, fallback
495
+ * model or re-send — and cut at the first content block. `onUsage` receives
496
+ * the reported usage as it arrives; resolves the final usage.
497
+ */
498
+ async sendCacheWarm(messages, model, tools, sendOpts = {}, { onUsage, accountId = '' } = {}) {
499
+ await warmCliVersion();
500
+ const opts = sendOpts || {};
501
+ const creds = await this.ensureAuth();
502
+ const body = buildRequestBody(sanitizeToolPairs(messages), model, tools, opts);
503
+ body.messages = await prepareAnthropicImages(body.messages, { signal: opts.signal });
504
+ return sendAnthropicCacheWarm({
505
+ providerName: this.name,
506
+ instance: this,
507
+ accountId,
508
+ model,
509
+ opts,
510
+ onUsage,
511
+ post: (signal) =>
512
+ postMessages({
513
+ accessToken: creds.accessToken,
514
+ requestBody: body,
515
+ betaHeaders: buildOAuthBetaHeaders(body, {
516
+ fastMode: this.fastModeBetaHeaderLatched,
517
+ toolSearch: Array.isArray(body.tools) && body.tools.some((t) => t?.defer_loading === true),
518
+ model,
519
+ opts,
520
+ }),
521
+ signal,
522
+ plain: true,
523
+ }),
524
+ });
525
+ }
526
+
457
527
  async _sendOnce(messages, model, tools, sendOpts) {
458
528
  await warmCliVersion();
459
529
  // Re-warm the kept-alive socket before the turn. preconnect() is a
@@ -493,15 +563,7 @@ export class AnthropicOAuthProvider {
493
563
  // actually carries deferred (defer_loading) tools — gate the header on
494
564
  // that instead of sending it unconditionally on every request.
495
565
  const hasDeferredTools = Array.isArray(body.tools) && body.tools.some((t) => t && t.defer_loading === true);
496
- // Known tool names for the leaked-tool-call guard in parseSSEStream:
497
- // recovered leaked calls are only synthesized when they name a tool
498
- // actually offered to this request (native + lowered). Derived from the
499
- // final request body so it matches exactly what the model was given.
500
- const knownToolNames = new Set(
501
- (Array.isArray(body.tools) ? body.tools : [])
502
- .map((t) => (t && typeof t.name === 'string' ? t.name : null))
503
- .filter(Boolean)
504
- );
566
+ const knownToolNames = requestToolNames(body);
505
567
  const sessionId = opts.sessionId || null;
506
568
  const iteration = Number.isFinite(Number(opts.iteration)) ? Number(opts.iteration) : null;
507
569
  // Option A: no absolute wall-clock cap on streaming generation. A stream
@@ -518,51 +580,17 @@ export class AnthropicOAuthProvider {
518
580
  // totalSignal is therefore a pure pass-through of externalSignal with no timer.
519
581
  const totalTimeout = createPassthroughSignal(externalSignal);
520
582
  const totalSignal = totalTimeout.signal;
521
- // Request-loop 529s and SSE overload events share one counter; at the
522
- // limit the configured fallback model takes over the whole send.
523
- const overload = createAnthropicOverloadTracker({
524
- model: useModel,
525
- fallbackModel: opts._fallbackTriggered ? undefined : opts.fallbackModel,
526
- });
527
- const { requestWithRetry, cleanupCancelHandler } = createAnthropicOAuthRequest({
528
- provider: this,
583
+ const { requestWithRetry, cleanupCancelHandler, midstream } = this._createSendRecovery({
529
584
  opts,
530
585
  body,
531
586
  useModel,
532
587
  sessionId,
533
- totalSignal,
534
- overload,
535
- betaHeadersFor: (requestBody) =>
536
- buildOAuthBetaHeaders(requestBody, {
537
- fastMode: this.fastModeBetaHeaderLatched,
538
- toolSearch: hasDeferredTools,
539
- model: useModel,
540
- opts,
541
- }),
542
- onStageChange,
543
- });
544
- const recovery = createAnthropicOAuthRecovery({
545
- provider: this,
546
- opts,
547
- body,
548
- useModel,
549
588
  auth,
550
589
  totalSignal,
551
- requestWithRetry,
552
- cleanupCancelHandler,
590
+ hasDeferredTools,
553
591
  onStageChange,
554
592
  onTextReset,
555
593
  });
556
- // Bounded mid-stream retries for transient stream loss; jittered backoff
557
- // between attempts (anthropic-oauth-midstream.mjs).
558
- const midstream = createMidstreamRecovery({
559
- maxRetries: ANTHROPIC_MAX_MIDSTREAM_RETRIES,
560
- totalSignal,
561
- recovery,
562
- onStageChange,
563
- retry529: opts.retry529 !== false,
564
- overload,
565
- });
566
594
 
567
595
  let maxTokensAdjusted = false;
568
596
  try {
@@ -593,7 +621,9 @@ export class AnthropicOAuthProvider {
593
621
  if (SSE_VERBOSE) process.stderr.write(`[anthropic-oauth] Response ${response.status}, parsing SSE...\n`);
594
622
  try {
595
623
  onStageChange?.('streaming');
596
- } catch {}
624
+ } catch {
625
+ // the stage observer is advisory
626
+ }
597
627
 
598
628
  const midState = createMidState(attemptIndex);
599
629
  try {
@@ -611,7 +641,9 @@ export class AnthropicOAuthProvider {
611
641
  );
612
642
  try {
613
643
  controller?.abort?.('Anthropic SSE complete');
614
- } catch {}
644
+ } catch {
645
+ // the stream is complete; the controller may already be aborted
646
+ }
615
647
  this._settleStreamedTurn({
616
648
  result,
617
649
  midState,
@@ -621,11 +653,7 @@ export class AnthropicOAuthProvider {
621
653
  useModel,
622
654
  requestKind: opts.requestKind || null,
623
655
  });
624
- try {
625
- Object.defineProperty(result, '__midstreamRetries', { value: attemptIndex, enumerable: false });
626
- } catch {
627
- /* ignore non-extensible result */
628
- }
656
+ tagMidstreamRetries(result, attemptIndex);
629
657
  return result;
630
658
  } catch (err) {
631
659
  const decision = await midstream.onStreamError({ err, midState, controller, response, attemptIndex });
@@ -637,22 +665,81 @@ export class AnthropicOAuthProvider {
637
665
  }
638
666
  throw midstream.exhaustedError();
639
667
  } catch (err) {
640
- // The fallback trigger can surface from the request loop, a mid-stream
641
- // overload, or the non-streaming recovery: handle it around the whole
642
- // operation, not just the first request.
643
- if (!(err instanceof AnthropicFallbackTriggeredError)) throw err;
644
- process.stderr.write(`[anthropic-oauth] ${err.message}\n`);
645
- announceAnthropicModelFallback(onStageChange, _displayModel(useModel), _displayModel(err.fallbackModel));
646
- return await this.send(messages, err.fallbackModel, tools, {
647
- ...opts,
648
- fallbackModel: undefined,
649
- _fallbackTriggered: true,
668
+ const fallbackOpts = takeAnthropicModelFallback(err, {
669
+ tag: 'anthropic-oauth',
670
+ model: useModel,
671
+ opts,
672
+ onStageChange,
673
+ displayModel: _displayModel,
650
674
  });
675
+ return await this.send(messages, err.fallbackModel, tools, fallbackOpts);
651
676
  } finally {
652
677
  totalTimeout.cleanup();
653
678
  }
654
679
  }
655
680
 
681
+ // The request and recovery pipeline of one send over its fixed body: the
682
+ // shared overload counter, the retried request with its per-request beta
683
+ // headers, the non-streaming recovery and the bounded mid-stream retries.
684
+ _createSendRecovery({
685
+ opts,
686
+ body,
687
+ useModel,
688
+ sessionId,
689
+ auth,
690
+ totalSignal,
691
+ hasDeferredTools,
692
+ onStageChange,
693
+ onTextReset,
694
+ }) {
695
+ // Request-loop 529s and SSE overload events share one counter; at the
696
+ // limit the configured fallback model takes over the whole send.
697
+ const overload = createAnthropicOverloadTracker({
698
+ model: useModel,
699
+ fallbackModel: opts._fallbackTriggered ? undefined : opts.fallbackModel,
700
+ });
701
+ const { requestWithRetry, cleanupCancelHandler } = createAnthropicOAuthRequest({
702
+ provider: this,
703
+ opts,
704
+ body,
705
+ useModel,
706
+ sessionId,
707
+ totalSignal,
708
+ overload,
709
+ betaHeadersFor: (requestBody) =>
710
+ buildOAuthBetaHeaders(requestBody, {
711
+ fastMode: this.fastModeBetaHeaderLatched,
712
+ toolSearch: hasDeferredTools,
713
+ model: useModel,
714
+ opts,
715
+ }),
716
+ onStageChange,
717
+ });
718
+ const recovery = createAnthropicOAuthRecovery({
719
+ provider: this,
720
+ opts,
721
+ body,
722
+ useModel,
723
+ auth,
724
+ totalSignal,
725
+ requestWithRetry,
726
+ cleanupCancelHandler,
727
+ onStageChange,
728
+ onTextReset,
729
+ });
730
+ // Bounded mid-stream retries for transient stream loss; jittered backoff
731
+ // between attempts (anthropic-oauth-midstream.mjs).
732
+ const midstream = createMidstreamRecovery({
733
+ maxRetries: ANTHROPIC_MAX_MIDSTREAM_RETRIES,
734
+ totalSignal,
735
+ recovery,
736
+ onStageChange,
737
+ retry529: opts.retry529 !== false,
738
+ overload,
739
+ });
740
+ return { requestWithRetry, cleanupCancelHandler, midstream };
741
+ }
742
+
656
743
  // One attempt's initial response: a 401 (or Anthropic's exact revoked-token
657
744
  // 403) refreshes the credentials in `auth` and replays once; a context
658
745
  // overflow 400 shrinks `body.max_tokens` and replays once per send
@@ -675,7 +762,9 @@ export class AnthropicOAuthProvider {
675
762
  // resources before the credential-refresh replay.
676
763
  try {
677
764
  controller?.abort?.();
678
- } catch {}
765
+ } catch {
766
+ // the controller may already be aborted before the credential-refresh replay
767
+ }
679
768
  auth.creds = await this.ensureAuth({ forceRefresh: true, reason: String(response.status) });
680
769
  ({ response, controller, cancelHandler } = await requestWithRetry(auth.creds.accessToken));
681
770
  rejectedAuthBody = null;
@@ -690,7 +779,9 @@ export class AnthropicOAuthProvider {
690
779
  cleanupCancelHandler(cancelHandler);
691
780
  try {
692
781
  controller?.abort?.();
693
- } catch {}
782
+ } catch {
783
+ // the controller may already be aborted before the max-tokens replay
784
+ }
694
785
  ({ response, controller, cancelHandler } = await requestWithRetry(auth.creds.accessToken));
695
786
  rejectedAuthBody = null;
696
787
  }
@@ -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', {
@@ -97,7 +97,7 @@ function _statusForAnthropicSseError(event, payload) {
97
97
  return 0;
98
98
  }
99
99
 
100
- function _anthropicSseError(event, labels) {
100
+ export function _anthropicSseError(event, labels) {
101
101
  const payload = event?.error && typeof event.error === 'object' ? event.error : event;
102
102
  const type = payload?.type || event?.type || 'error';
103
103
  const message = payload?.message || 'Anthropic SSE error';
@@ -198,7 +198,9 @@ export async function parseSSEStream(
198
198
  const progress = (kind) => {
199
199
  try {
200
200
  onStreamDelta?.(kind);
201
- } catch {}
201
+ } catch {
202
+ // the stream-delta observer is advisory
203
+ }
202
204
  };
203
205
  const turn = createAnthropicSseTurn({
204
206
  state,
@@ -222,12 +224,7 @@ export async function parseSSEStream(
222
224
  _captureMidstreamAbort(state, signal.reason);
223
225
  return signal.reason instanceof Error ? signal.reason : new Error(`${labels.display} SSE stream aborted`);
224
226
  };
225
- const onAbort = () => {
226
- try {
227
- const _c = reader.cancel('SSE aborted');
228
- if (_c && typeof _c.catch === 'function') _c.catch(() => {});
229
- } catch {}
230
- };
227
+ const onAbort = () => cancelReaderOnAbort(reader);
231
228
  let buffer = '';
232
229
  let currentEvent = '';
233
230
  retainProviderSseStream(streamKey);
@@ -239,24 +236,12 @@ export async function parseSSEStream(
239
236
  signal.addEventListener('abort', onAbort, { once: true });
240
237
  }
241
238
  watchdogs.armFirstMessageTimer();
242
- streamLoop: while (true) {
239
+ while (true) {
243
240
  let chunk;
244
241
  try {
245
242
  chunk = await watchdogs.read();
246
243
  } catch (err) {
247
- const stopped = watchdogs.readFailure() ?? (signal?.aborted ? abortedError() : null);
248
- if (stopped) {
249
- // The caller's cancellation reason may be shared: never stamp this
250
- // request's usage on it; the usage reported so far goes to this send.
251
- if (signal?.aborted && state?.sawMessageStart) {
252
- const reported = turn.reportedUsage();
253
- noteAbandonedUsage(reported.usage, reported.model);
254
- }
255
- throw stopped;
256
- }
257
- // The connection dropped mid-body: carry what this turn completed so
258
- // the loop can continue from finished tool calls instead of failing.
259
- throw state?.sawMessageStart ? turn.attachTransportPartial(err) : err;
244
+ throw readFailureError(err, { watchdogs, signal, state, turn, abortedError });
260
245
  }
261
246
  const { done, value } = chunk;
262
247
  if (done) break;
@@ -277,10 +262,7 @@ export async function parseSSEStream(
277
262
  const framed = frameProviderSseChunk(region, { currentEvent, streamKey });
278
263
  const framedChunk = typeof framed?.then === 'function' ? await framed : framed;
279
264
  currentEvent = framedChunk.currentEvent;
280
- for (const framedEvent of framedChunk.events) {
281
- if (framedEvent.error) continue;
282
- if (applyAnthropicSseEvent(framedEvent, { turn, watchdogs, state, progress, labels })) break streamLoop;
283
- }
265
+ if (applyAnthropicSseChunk(framedChunk.events, { turn, watchdogs, state, progress, labels })) break;
284
266
  }
285
267
  turn.flushLeak();
286
268
  if (state?.sawMessageStart && !state?.sawCompleted) throw turn.truncatedError();
@@ -289,20 +271,69 @@ export async function parseSSEStream(
289
271
  watchdogs.dispose();
290
272
  try {
291
273
  releaseProviderSseStream(streamKey);
292
- } catch {}
274
+ } catch {
275
+ // releasing the stream registration is bookkeeping only
276
+ }
293
277
  if (signal) signal.removeEventListener('abort', onAbort);
294
278
  // message_stop deliberately exits before EOF because Anthropic may keep
295
279
  // sending pings. Cancel the reader so the successful response body and
296
280
  // underlying keep-alive connection are not stranded.
297
281
  try {
298
282
  await reader.cancel('Anthropic SSE complete');
299
- } catch {}
283
+ } catch {
284
+ // the reader may already be closed after the stream ended
285
+ }
286
+ releaseReaderLock(reader, labels);
287
+ }
288
+ }
289
+
290
+ // Caller cancellation of a live stream: cancel the reader without awaiting it.
291
+ function cancelReaderOnAbort(reader) {
292
+ try {
293
+ const _c = reader.cancel('SSE aborted');
294
+ if (_c && typeof _c.catch === 'function') _c.catch(() => {});
295
+ } catch {
296
+ // the reader may already be closed or released
297
+ }
298
+ }
299
+
300
+ // The error a failed reader.read() ends the stream with: a watchdog stop or the
301
+ // caller's abort as-is, otherwise the transport failure carrying the partial
302
+ // turn once the message started.
303
+ function readFailureError(err, { watchdogs, signal, state, turn, abortedError }) {
304
+ const stopped = watchdogs.readFailure() ?? (signal?.aborted ? abortedError() : null);
305
+ if (stopped) {
306
+ // The caller's cancellation reason may be shared: never stamp this
307
+ // request's usage on it; the usage reported so far goes to this send.
308
+ if (signal?.aborted && state?.sawMessageStart) {
309
+ const reported = turn.reportedUsage();
310
+ noteAbandonedUsage(reported.usage, reported.model);
311
+ }
312
+ return stopped;
313
+ }
314
+ // The connection dropped mid-body: carry what this turn completed so
315
+ // the loop can continue from finished tool calls instead of failing.
316
+ return state?.sawMessageStart ? turn.attachTransportPartial(err) : err;
317
+ }
318
+
319
+ // Fold one network chunk's framed records into the turn, in order. Returns true
320
+ // once a terminal record ends the stream; a framing error skips its record.
321
+ function applyAnthropicSseChunk(events, context) {
322
+ for (const framedEvent of events) {
323
+ if (framedEvent.error) continue;
324
+ if (applyAnthropicSseEvent(framedEvent, context)) return true;
325
+ }
326
+ return false;
327
+ }
328
+
329
+ function releaseReaderLock(reader, labels) {
330
+ try {
331
+ reader.releaseLock();
332
+ } catch (err) {
300
333
  try {
301
- reader.releaseLock();
302
- } catch (err) {
303
- try {
304
- process.stderr.write(`[${labels.tag}] reader releaseLock failed: ${err?.message ?? String(err)}\n`);
305
- } catch {}
334
+ process.stderr.write(`[${labels.tag}] reader releaseLock failed: ${err?.message ?? String(err)}\n`);
335
+ } catch {
336
+ // stderr may be closed; the releaseLock failure is only reported
306
337
  }
307
338
  }
308
339
  }