mixdog 1.2.0 → 1.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (386) hide show
  1. package/README.md +7 -5
  2. package/package.json +1 -1
  3. package/scripts/gate-local.mjs +19 -3
  4. package/scripts/model-catalog-audit.mjs +1 -15
  5. package/src/agents/reviewer/AGENT.md +3 -3
  6. package/src/agents/reviewer/agent.json +1 -1
  7. package/src/defaults/shipped-history.json +5 -0
  8. package/src/defaults/skills/pptx/SKILL.md +6 -6
  9. package/src/defaults/skills/pptx/references/review.md +6 -4
  10. package/src/defaults/skills/pptx/scripts/source-extract.mjs +1 -1
  11. package/src/defaults/skills/setup/references/actions.md +13 -3
  12. package/src/defaults/skills/visualize/SKILL.md +12 -9
  13. package/src/repl/slash-commands.mjs +16 -1
  14. package/src/rules/shared/60-verification.md +3 -1
  15. package/src/rules/shared/70-delivery.md +4 -2
  16. package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +29 -4
  17. package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +10 -0
  18. package/src/runtime/agent/orchestrator/cache-mtime.mjs +26 -5
  19. package/src/runtime/agent/orchestrator/config.mjs +10 -4
  20. package/src/runtime/agent/orchestrator/context/collect.mjs +2 -1
  21. package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +11 -5
  22. package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +74 -21
  23. package/src/runtime/agent/orchestrator/mcp/client-config.mjs +122 -15
  24. package/src/runtime/agent/orchestrator/mcp/client-handshake.mjs +54 -11
  25. package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +104 -9
  26. package/src/runtime/agent/orchestrator/mcp/client.mjs +358 -140
  27. package/src/runtime/agent/orchestrator/mcp/lazy-output-validator.mjs +25 -0
  28. package/src/runtime/agent/orchestrator/mcp/oauth-callback.mjs +103 -0
  29. package/src/runtime/agent/orchestrator/mcp/oauth-credentials.mjs +150 -0
  30. package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +111 -0
  31. package/src/runtime/agent/orchestrator/mcp/oauth-probe.mjs +87 -0
  32. package/src/runtime/agent/orchestrator/mcp/oauth-provider.mjs +95 -0
  33. package/src/runtime/agent/orchestrator/mcp/oauth-request.mjs +122 -0
  34. package/src/runtime/agent/orchestrator/mcp/oauth-shared.mjs +9 -0
  35. package/src/runtime/agent/orchestrator/mcp/oauth.mjs +229 -0
  36. package/src/runtime/agent/orchestrator/mcp/plugin-placeholders.mjs +54 -0
  37. package/src/runtime/agent/orchestrator/providers/account-pool.mjs +294 -44
  38. package/src/runtime/agent/orchestrator/providers/anthropic-api-recovery.mjs +2 -1
  39. package/src/runtime/agent/orchestrator/providers/anthropic-api-transport.mjs +94 -31
  40. package/src/runtime/agent/orchestrator/providers/anthropic-error-contract.mjs +96 -0
  41. package/src/runtime/agent/orchestrator/providers/anthropic-fast-mode.mjs +39 -18
  42. package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens-recovery.mjs +55 -0
  43. package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens.mjs +25 -21
  44. package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +3 -1
  45. package/src/runtime/agent/orchestrator/providers/anthropic-midstream-recovery.mjs +18 -4
  46. package/src/runtime/agent/orchestrator/providers/anthropic-model-resolve.mjs +13 -1
  47. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
  48. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-midstream.mjs +10 -1
  49. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-recovery.mjs +23 -9
  50. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/initial-status.mjs +46 -20
  51. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request.mjs +14 -9
  52. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +73 -35
  53. package/src/runtime/agent/orchestrator/providers/anthropic-overload-fallback.mjs +69 -0
  54. package/src/runtime/agent/orchestrator/providers/anthropic-server-fallback.mjs +4 -0
  55. package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +8 -1
  56. package/src/runtime/agent/orchestrator/providers/anthropic.mjs +53 -18
  57. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-catalog.mjs +30 -9
  58. package/src/runtime/agent/orchestrator/providers/antigravity-oauth.mjs +7 -0
  59. package/src/runtime/agent/orchestrator/providers/antigravity-request.mjs +30 -14
  60. package/src/runtime/agent/orchestrator/providers/antigravity-response.mjs +2 -1
  61. package/src/runtime/agent/orchestrator/providers/antigravity-retry-policy.mjs +93 -0
  62. package/src/runtime/agent/orchestrator/providers/antigravity-transport.mjs +82 -9
  63. package/src/runtime/agent/orchestrator/providers/auto-effort.mjs +9 -0
  64. package/src/runtime/agent/orchestrator/providers/command-code-oauth-login.mjs +337 -0
  65. package/src/runtime/agent/orchestrator/providers/command-code-oauth-tokens.mjs +159 -0
  66. package/src/runtime/agent/orchestrator/providers/command-code-oauth.mjs +447 -0
  67. package/src/runtime/agent/orchestrator/providers/cursor-auth.mjs +38 -5
  68. package/src/runtime/agent/orchestrator/providers/cursor-client-version.mjs +1 -1
  69. package/src/runtime/agent/orchestrator/providers/cursor-wire-guards.mjs +97 -2
  70. package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-bridge.mjs +102 -23
  71. package/src/runtime/agent/orchestrator/providers/cursor-wire-transport.mjs +103 -33
  72. package/src/runtime/agent/orchestrator/providers/cursor-wire.mjs +29 -6
  73. package/src/runtime/agent/orchestrator/providers/cursor.mjs +18 -1
  74. package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +7 -4
  75. package/src/runtime/agent/orchestrator/providers/effort-configuration.mjs +86 -19
  76. package/src/runtime/agent/orchestrator/providers/gemini-cache-policy.mjs +1 -1
  77. package/src/runtime/agent/orchestrator/providers/gemini-cache.mjs +29 -8
  78. package/src/runtime/agent/orchestrator/providers/gemini-error-contract.mjs +191 -0
  79. package/src/runtime/agent/orchestrator/providers/gemini-family.mjs +9 -0
  80. package/src/runtime/agent/orchestrator/providers/gemini-history-signatures.mjs +9 -4
  81. package/src/runtime/agent/orchestrator/providers/gemini-response.mjs +3 -1
  82. package/src/runtime/agent/orchestrator/providers/gemini-retry-policy.mjs +180 -0
  83. package/src/runtime/agent/orchestrator/providers/gemini-schema.mjs +21 -82
  84. package/src/runtime/agent/orchestrator/providers/gemini-sdk-request.mjs +4 -1
  85. package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +71 -12
  86. package/src/runtime/agent/orchestrator/providers/gemini-thinking.mjs +21 -20
  87. package/src/runtime/agent/orchestrator/providers/gemini.mjs +97 -51
  88. package/src/runtime/agent/orchestrator/providers/grok-oauth-tokens.mjs +3 -0
  89. package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +68 -19
  90. package/src/runtime/agent/orchestrator/providers/lib/gemini-model-catalog.mjs +7 -1
  91. package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +3 -0
  92. package/src/runtime/agent/orchestrator/providers/model-list-sanitize.mjs +2 -1
  93. package/src/runtime/agent/orchestrator/providers/model-proxy-bridge.mjs +1080 -0
  94. package/src/runtime/agent/orchestrator/providers/model-proxy-channel.d.mts +15 -0
  95. package/src/runtime/agent/orchestrator/providers/model-proxy-channel.mjs +35 -0
  96. package/src/runtime/agent/orchestrator/providers/muse-code-oauth.mjs +4 -9
  97. package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +12 -0
  98. package/src/runtime/agent/orchestrator/providers/oauth-usage.mjs +6 -5
  99. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +5 -3
  100. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-result.mjs +22 -0
  101. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +1 -0
  102. package/src/runtime/agent/orchestrator/providers/openai-compat-error-contract.mjs +50 -0
  103. package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +6 -2
  104. package/src/runtime/agent/orchestrator/providers/openai-compat-options.mjs +11 -0
  105. package/src/runtime/agent/orchestrator/providers/openai-compat-response-normalization.mjs +23 -0
  106. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-events.mjs +16 -8
  107. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-state.mjs +3 -2
  108. package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +94 -13
  109. package/src/runtime/agent/orchestrator/providers/openai-compat-retry-profile.mjs +193 -0
  110. package/src/runtime/agent/orchestrator/providers/openai-compat-stream-common.mjs +66 -2
  111. package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +2 -1
  112. package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +6 -0
  113. package/src/runtime/agent/orchestrator/providers/openai-compat-xai-send.mjs +6 -3
  114. package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +23 -14
  115. package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +26 -6
  116. package/src/runtime/agent/orchestrator/providers/openai-direct-request.mjs +42 -25
  117. package/src/runtime/agent/orchestrator/providers/openai-error-contract.mjs +274 -0
  118. package/src/runtime/agent/orchestrator/providers/openai-http-sse-request.mjs +72 -32
  119. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/terminal-frames.mjs +18 -11
  120. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-outcome.mjs +1 -2
  121. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-stamps.mjs +2 -2
  122. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-state.mjs +2 -3
  123. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state.mjs +2 -2
  124. package/src/runtime/agent/orchestrator/providers/openai-http-sse-watchdogs.mjs +1 -3
  125. package/src/runtime/agent/orchestrator/providers/openai-oauth-dispatch.mjs +34 -3
  126. package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +5 -1
  127. package/src/runtime/agent/orchestrator/providers/openai-oauth-tokens.mjs +22 -2
  128. package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +5 -0
  129. package/src/runtime/agent/orchestrator/providers/openai-responses-input.mjs +5 -9
  130. package/src/runtime/agent/orchestrator/providers/openai-retry-policy.mjs +9 -0
  131. package/src/runtime/agent/orchestrator/providers/openai-ws-handshake.mjs +16 -8
  132. package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/attempt-context.mjs +1 -2
  133. package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/policy.mjs +25 -14
  134. package/src/runtime/agent/orchestrator/providers/openai-ws-terminal.mjs +18 -11
  135. package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +35 -24
  136. package/src/runtime/agent/orchestrator/providers/provider-error-kind.mjs +581 -0
  137. package/src/runtime/agent/orchestrator/providers/registry.mjs +35 -9
  138. package/src/runtime/agent/orchestrator/providers/retry-backoff.mjs +46 -7
  139. package/src/runtime/agent/orchestrator/providers/retry-classification.mjs +118 -219
  140. package/src/runtime/agent/orchestrator/providers/retry-classifier.mjs +2 -0
  141. package/src/runtime/agent/orchestrator/providers/retry-executor.mjs +148 -45
  142. package/src/runtime/agent/orchestrator/providers/retry-midstream.mjs +81 -16
  143. package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +3 -0
  144. package/src/runtime/agent/orchestrator/runtime-core/effort.mjs +3 -0
  145. package/src/runtime/agent/orchestrator/runtime-core/extension-scopes.mjs +15 -55
  146. package/src/runtime/agent/orchestrator/runtime-core/goal-control.mjs +15 -2
  147. package/src/runtime/agent/orchestrator/runtime-core/goal-reminder.mjs +0 -18
  148. package/src/runtime/agent/orchestrator/runtime-core/model-capabilities.mjs +57 -28
  149. package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +19 -16
  150. package/src/runtime/agent/orchestrator/runtime-core/plugin-mcp.mjs +268 -181
  151. package/src/runtime/agent/orchestrator/runtime-core/skill-tool-loading.mjs +4 -1
  152. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-schema.mjs +21 -0
  153. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +54 -3
  154. package/src/runtime/agent/orchestrator/session/catalog-db/index.mjs +284 -0
  155. package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +270 -0
  156. package/src/runtime/agent/orchestrator/session/catalog-db/sqlite-gate.mjs +27 -0
  157. package/src/runtime/agent/orchestrator/session/catalog-db/worker.mjs +628 -0
  158. package/src/runtime/agent/orchestrator/session/compact/messages.mjs +6 -2
  159. package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +184 -0
  160. package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +136 -0
  161. package/src/runtime/agent/orchestrator/session/conversation-import/convert.mjs +128 -0
  162. package/src/runtime/agent/orchestrator/session/conversation-import/imported-session.mjs +127 -0
  163. package/src/runtime/agent/orchestrator/session/conversation-import/turns.mjs +101 -0
  164. package/src/runtime/agent/orchestrator/session/explicit-skills.mjs +83 -5
  165. package/src/runtime/agent/orchestrator/session/imported-message.mjs +11 -0
  166. package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +2 -1
  167. package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +1 -1
  168. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +3 -2
  169. package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +10 -4
  170. package/src/runtime/agent/orchestrator/session/loop/steering.mjs +4 -3
  171. package/src/runtime/agent/orchestrator/session/loop/step-auto-effort.mjs +102 -18
  172. package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +3 -0
  173. package/src/runtime/agent/orchestrator/session/loop/tool-phase.mjs +3 -1
  174. package/src/runtime/agent/orchestrator/session/manager/ask-queue.mjs +42 -5
  175. package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +14 -3
  176. package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +20 -12
  177. package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +50 -23
  178. package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +4 -0
  179. package/src/runtime/agent/orchestrator/session/manager/pending-message-entry.mjs +22 -14
  180. package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +1 -1
  181. package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +18 -7
  182. package/src/runtime/agent/orchestrator/session/manager.mjs +0 -1
  183. package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +4 -3
  184. package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +155 -29
  185. package/src/runtime/agent/orchestrator/session/store/listing.mjs +6 -2
  186. package/src/runtime/agent/orchestrator/session/store/save-worker.mjs +6 -3
  187. package/src/runtime/agent/orchestrator/session/store/summary-cache.mjs +6 -0
  188. package/src/runtime/agent/orchestrator/session/store/write-guards.mjs +16 -0
  189. package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +22 -10
  190. package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +819 -0
  191. package/src/runtime/agent/orchestrator/session/store-summary-fields.mjs +12 -0
  192. package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +22 -12
  193. package/src/runtime/agent/orchestrator/session/store-summary-reader-catalog-fixture.mjs +158 -0
  194. package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +183 -374
  195. package/src/runtime/agent/orchestrator/session/synthetic-user-envelope.mjs +3 -1
  196. package/src/runtime/agent/orchestrator/session/tool-batch/pre-dispatch.mjs +1 -1
  197. package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +41 -3
  198. package/src/runtime/agent/orchestrator/session/transcript-restore/user-text.mjs +38 -17
  199. package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +2 -2
  200. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/deadline-plan.mjs +12 -15
  201. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/invocation-plan.mjs +17 -1
  202. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/spawn-env.mjs +4 -0
  203. package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +5 -5
  204. package/src/runtime/agent/orchestrator/tools/builtin/lib/list-helpers.mjs +2 -2
  205. package/src/runtime/agent/orchestrator/tools/builtin/path-diagnostics.mjs +6 -6
  206. package/src/runtime/agent/orchestrator/tools/builtin/read-range-index.mjs +173 -22
  207. package/src/runtime/agent/orchestrator/tools/builtin/read-single-guards.mjs +8 -4
  208. package/src/runtime/agent/orchestrator/tools/builtin/read-single-tool.mjs +5 -4
  209. package/src/runtime/agent/orchestrator/tools/builtin/read-source-windows.mjs +15 -2
  210. package/src/runtime/agent/orchestrator/tools/builtin/search-glob-tool.mjs +13 -10
  211. package/src/runtime/agent/orchestrator/tools/builtin/search-grep-tool.mjs +1 -1
  212. package/src/runtime/agent/orchestrator/tools/builtin/search-path-diagnostics.mjs +17 -12
  213. package/src/runtime/agent/orchestrator/tools/code-graph/dispatch/root-resolution.mjs +2 -2
  214. package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.mjs +1 -1
  215. package/src/runtime/agent/orchestrator/tools/patch/apply-patch/codex-batch.mjs +4 -4
  216. package/src/runtime/agent/orchestrator/tools/patch/apply-patch/route.mjs +2 -2
  217. package/src/runtime/agent/orchestrator/tools/patch/orchestrator.mjs +1 -1
  218. package/src/runtime/agent/orchestrator/tools/patch/read-redirects.mjs +34 -30
  219. package/src/runtime/agent/orchestrator/tools/patch/sequence/units.mjs +7 -7
  220. package/src/runtime/agent/orchestrator/tools/patch/sequence.mjs +1 -1
  221. package/src/runtime/agent/orchestrator/tools/shell-snapshot.mjs +4 -0
  222. package/src/runtime/attachments/store.d.mts +3 -0
  223. package/src/runtime/channels/lib/owned-runtime/owned-start.mjs +1 -1
  224. package/src/runtime/channels/lib/webhook/session-dispatch.mjs +16 -4
  225. package/src/runtime/channels/lib/worker-main.mjs +17 -14
  226. package/src/runtime/computer-bridge/linux-readiness.mjs +0 -2
  227. package/src/runtime/effort-judge/judge-client.mjs +56 -18
  228. package/src/runtime/memory/lib/memory.mjs +1 -1
  229. package/src/runtime/memory/lib/pg/process.mjs +34 -24
  230. package/src/runtime/memory/lib/pg/supervisor.mjs +16 -13
  231. package/src/runtime/memory/lib/session-ingest.mjs +2 -2
  232. package/src/runtime/office/README.md +1 -1
  233. package/src/runtime/office/shared/values.mjs +0 -5
  234. package/src/runtime/shared/atomic-file.mjs +25 -4
  235. package/src/runtime/shared/background-tasks.mjs +92 -14
  236. package/src/runtime/shared/err-text.mjs +25 -0
  237. package/src/runtime/shared/error-presentation.mjs +159 -19
  238. package/src/runtime/shared/extension-scopes.mjs +5 -3
  239. package/src/runtime/shared/file-lock.mjs +37 -11
  240. package/src/runtime/shared/llm/anthropic-betas.mjs +4 -3
  241. package/src/runtime/shared/llm/anthropic-effort.mjs +134 -131
  242. package/src/runtime/shared/llm/anthropic-thinking-contract.mjs +50 -14
  243. package/src/runtime/shared/llm/model-catalog.mjs +53 -52
  244. package/src/runtime/shared/llm/openai-daybreak.mjs +4 -16
  245. package/src/runtime/shared/llm/provider-catalog-registry.mjs +17 -0
  246. package/src/runtime/shared/llm/provider-model-identities.mjs +13 -4
  247. package/src/runtime/shared/llm/usage-rollup.mjs +0 -1
  248. package/src/runtime/shared/model-display.mjs +13 -0
  249. package/src/runtime/shared/plugin-manifest.mjs +18 -9
  250. package/src/runtime/shared/pristine-execution-contract.json +9 -2
  251. package/src/runtime/shared/pristine-execution.mjs +28 -4
  252. package/src/runtime/shared/provider-accounts.mjs +124 -20
  253. package/src/runtime/shared/provider-api-key.mjs +12 -0
  254. package/src/runtime/shared/quota-resume-store.mjs +11 -0
  255. package/src/runtime/shared/session-baseline-store.mjs +960 -0
  256. package/src/runtime/shared/shell-display.mjs +9 -3
  257. package/src/runtime/shared/skill-mentions.d.mts +10 -0
  258. package/src/runtime/shared/skill-mentions.mjs +133 -0
  259. package/src/runtime/shared/skill-script-runtime.mjs +264 -0
  260. package/src/runtime/shared/statusline/statusline-format.mjs +4 -4
  261. package/src/runtime/shared/task-notification-envelope.mjs +2 -2
  262. package/src/runtime/shared/tool-primitives.mjs +35 -2
  263. package/src/runtime/shared/turn-changes.mjs +447 -219
  264. package/src/runtime/shared/turn-snapshot-store.mjs +182 -1
  265. package/src/runtime/shared/turn-snapshot.mjs +170 -48
  266. package/src/runtime/shared/turn-worktree-snapshot.mjs +160 -51
  267. package/src/runtime/shared/worker-requests.mjs +15 -2
  268. package/src/runtime/shared/worktrees/contract.mjs +0 -24
  269. package/src/runtime/shared/worktrees/test-support.mjs +19 -4
  270. package/src/session-runtime/automation-agents.mjs +8 -2
  271. package/src/session-runtime/boot/apis.mjs +61 -0
  272. package/src/session-runtime/boot/config.mjs +5 -2
  273. package/src/session-runtime/boot/facade.mjs +1 -0
  274. package/src/session-runtime/boot/infrastructure.mjs +35 -18
  275. package/src/session-runtime/conversation-import/discovery.mjs +698 -0
  276. package/src/session-runtime/conversation-import/service.mjs +369 -0
  277. package/src/session-runtime/cwd-plugins/cwd-apply.mjs +10 -5
  278. package/src/session-runtime/cwd-plugins/plugin-status.mjs +47 -42
  279. package/src/session-runtime/lifecycle/session-catalog.mjs +2 -0
  280. package/src/session-runtime/lifecycle/teardown.mjs +1 -1
  281. package/src/session-runtime/mcp-glue/connect.mjs +83 -16
  282. package/src/session-runtime/mcp-glue/plugin-servers.mjs +499 -0
  283. package/src/session-runtime/mcp-glue/server-catalog.mjs +135 -33
  284. package/src/session-runtime/mcp-glue.mjs +25 -2
  285. package/src/session-runtime/mcp-oauth-login.mjs +174 -0
  286. package/src/session-runtime/model-route/model-switch-target.mjs +34 -0
  287. package/src/session-runtime/model-route/set-route.mjs +83 -15
  288. package/src/session-runtime/model-route/web-search-route.mjs +1 -1
  289. package/src/session-runtime/native-web-search/routes.mjs +22 -3
  290. package/src/session-runtime/new-session-config.mjs +3 -2
  291. package/src/session-runtime/notification-bus.mjs +9 -2
  292. package/src/session-runtime/provider-auth/accounts.mjs +33 -15
  293. package/src/session-runtime/provider-models/model-meta.mjs +12 -3
  294. package/src/session-runtime/provider-models/web-search-catalog.mjs +5 -1
  295. package/src/session-runtime/provider-readiness.mjs +16 -10
  296. package/src/session-runtime/quick-model-rows/web-search-rows.mjs +13 -8
  297. package/src/session-runtime/quick-web-search-models.mjs +13 -38
  298. package/src/session-runtime/resource-extension-sync.mjs +24 -5
  299. package/src/session-runtime/resource-mcp-api.mjs +198 -78
  300. package/src/session-runtime/resource-plugins-api.mjs +29 -41
  301. package/src/session-runtime/resource-scope-decorate.mjs +6 -8
  302. package/src/session-runtime/resource-skills-api.mjs +23 -2
  303. package/src/session-runtime/runtime-review-api.mjs +13 -0
  304. package/src/session-runtime/schedule-session-run.mjs +1 -1
  305. package/src/session-runtime/services/agent-tool/job-task-reconcile.mjs +13 -1
  306. package/src/session-runtime/services/agent-tool/job-views/agent-list.mjs +7 -2
  307. package/src/session-runtime/services/agent-tool/send-flow.mjs +22 -4
  308. package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +2 -0
  309. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +22 -5
  310. package/src/session-runtime/services/agent-tool/worker-index/row-liveness.mjs +8 -1
  311. package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +2 -2
  312. package/src/session-runtime/services/agent-tool/worker-rows.mjs +17 -0
  313. package/src/session-runtime/services/channel-session-router.mjs +4 -1
  314. package/src/session-runtime/services/hook-bus/command-handler.mjs +4 -1
  315. package/src/session-runtime/services/hook-bus/handlers.mjs +7 -3
  316. package/src/session-runtime/services/provider-admin.mjs +64 -18
  317. package/src/session-runtime/services/usage-dashboard-model.mjs +3 -0
  318. package/src/session-runtime/settings-compaction-api.mjs +1 -0
  319. package/src/session-runtime/setup-tool/executor.mjs +12 -1
  320. package/src/session-runtime/setup-tool/extended-actions.mjs +1 -0
  321. package/src/session-runtime/setup-tool/settings-contract.mjs +1 -0
  322. package/src/session-runtime/setup-tool/tool-defs.mjs +7 -1
  323. package/src/session-runtime/skills-api.mjs +7 -3
  324. package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +1 -0
  325. package/src/session-runtime/webhook-session-run.mjs +16 -4
  326. package/src/skill-script-entry.mjs +36 -0
  327. package/src/standalone/daemon-drain-policy.mjs +8 -0
  328. package/src/standalone/daemon-stored-session-views.mjs +11 -3
  329. package/src/standalone/daemon-telemetry.mjs +55 -0
  330. package/src/standalone/daemon.mjs +44 -11
  331. package/src/standalone/session-protocol.mjs +12 -0
  332. package/src/standalone/session-service/agent-tree/agent-cancel.mjs +33 -2
  333. package/src/standalone/session-service/agent-tree/agent-turns.mjs +26 -10
  334. package/src/standalone/session-service/agent-tree.mjs +12 -0
  335. package/src/standalone/session-service/quota-resume.mjs +8 -0
  336. package/src/standalone/session-service/retention/busy.mjs +15 -1
  337. package/src/standalone/session-service/session-calls/session-action.mjs +6 -1
  338. package/src/standalone/session-service-api.mjs +5 -0
  339. package/src/standalone/session-service.mjs +1 -0
  340. package/src/tui/App.jsx +9 -1
  341. package/src/tui/app/app-view/floating-panel.jsx +9 -1
  342. package/src/tui/app/app-view.jsx +7 -0
  343. package/src/tui/app/create-app-pickers.mjs +4 -0
  344. package/src/tui/app/extension-pickers/mcp-login.mjs +107 -0
  345. package/src/tui/app/extension-pickers/mcp-servers-picker.mjs +2 -1
  346. package/src/tui/app/extension-pickers/plugins-pickers.mjs +35 -16
  347. package/src/tui/app/extension-pickers.mjs +2 -1
  348. package/src/tui/app/model-options.mjs +13 -16
  349. package/src/tui/app/skill-mention-palette.mjs +88 -0
  350. package/src/tui/app/slash-commands.mjs +7 -2
  351. package/src/tui/app/slash-dispatch/panel-commands.mjs +16 -1
  352. package/src/tui/app/slash-palette.mjs +23 -7
  353. package/src/tui/app/transcript-row-estimate.mjs +11 -3
  354. package/src/tui/app/use-prompt-draft-flow.mjs +7 -2
  355. package/src/tui/app/use-prompt-state.mjs +5 -0
  356. package/src/tui/components/Message.jsx +22 -1
  357. package/src/tui/components/PromptInput.jsx +21 -3
  358. package/src/tui/components/SlashCommandPalette.jsx +12 -3
  359. package/src/tui/components/StatusLine.jsx +2 -0
  360. package/src/tui/components/TranscriptItem.jsx +9 -1
  361. package/src/tui/components/prompt-input/key-handler.mjs +21 -8
  362. package/src/tui/components/status-line/local-line.mjs +5 -2
  363. package/src/tui/components/status-line/use-statusline-text.mjs +7 -1
  364. package/src/tui/components/user-message-skills.mjs +38 -0
  365. package/src/tui/dist/index.mjs +1323 -214
  366. package/src/tui/session/queue-helpers.mjs +7 -2
  367. package/src/tui/session/quota-resume.mjs +46 -14
  368. package/src/tui/session/session-api/commands.mjs +33 -24
  369. package/src/tui/session/session-api/extensions.mjs +26 -2
  370. package/src/tui/session/session-api/integrations.mjs +7 -0
  371. package/src/tui/session/session-api/lifecycle.mjs +5 -1
  372. package/src/tui/session/session-api/routes.mjs +71 -7
  373. package/src/tui/session/session-api/settings.mjs +12 -14
  374. package/src/tui/session/session-flow/drain.mjs +21 -5
  375. package/src/tui/session/session-flow/failed-turn-rewind.mjs +10 -4
  376. package/src/tui/session/tui-steering-persist.mjs +25 -9
  377. package/src/tui/session/turn.mjs +55 -15
  378. package/src/tui/statusline-ansi-bridge.mjs +1 -1
  379. package/src/ui/statusline-agents.mjs +15 -4
  380. package/src/ui/statusline.mjs +7 -3
  381. package/src/ui/streaming-markdown-heal.mjs +34 -3
  382. package/src/vendor/statusline/src/gateway/claude-current.mjs +14 -4
  383. package/src/runtime/effort-judge/previous-human-request.mjs +0 -162
  384. package/src/runtime/effort-judge/verified-context-input.mjs +0 -10
  385. package/src/runtime/memory/lib/memory-session-merge.mjs +0 -32
  386. package/src/runtime/shared/llm/usage-session-history.mjs +0 -266
@@ -0,0 +1,96 @@
1
+ /**
2
+ * anthropic-error-contract.mjs — the fields every error thrown at an Anthropic
3
+ * provider boundary carries, so the shared core never has to re-derive them
4
+ * from message text:
5
+ *
6
+ * status / httpStatus the HTTP status
7
+ * code the lowercased Anthropic error type (`rate_limit_error`,
8
+ * `overloaded_error`, ...); a 413 is always
9
+ * `request_too_large` (a byte/media size refusal), which
10
+ * stays distinct from a 400 `invalid_request_error`
11
+ * "prompt is too long" (a token-count refusal)
12
+ * headers the response headers, preserved as received
13
+ * retryAfterMs the server's Retry-After / retry-after-ms window, uncapped
14
+ * resetAt epoch ms of anthropic-ratelimit-unified-reset, uncapped
15
+ */
16
+ import { headerValue, retryAfterMsFromError } from './retry-classification.mjs';
17
+
18
+ const RESET_HEADER = 'anthropic-ratelimit-unified-reset';
19
+ const REQUEST_TOO_LARGE = 'request_too_large';
20
+
21
+ // Anthropic's documented error-type enumeration by status, used only when the
22
+ // body names no type of its own.
23
+ const STATUS_ERROR_TYPE = new Map([
24
+ [400, 'invalid_request_error'],
25
+ [401, 'authentication_error'],
26
+ [403, 'permission_error'],
27
+ [404, 'not_found_error'],
28
+ [413, REQUEST_TOO_LARGE],
29
+ [429, 'rate_limit_error'],
30
+ [500, 'api_error'],
31
+ [529, 'overloaded_error'],
32
+ ]);
33
+
34
+ const BODY_TYPE_RE = /"error"\s*:\s*\{\s*"type"\s*:\s*"([A-Za-z_]+)"/;
35
+
36
+ function present(value) {
37
+ return value != null && value !== '';
38
+ }
39
+
40
+ function lowered(value) {
41
+ return typeof value === 'string' && value.trim() && value.trim() !== 'error' ? value.trim().toLowerCase() : '';
42
+ }
43
+
44
+ /** The lowercased error type named by an Anthropic error body (JSON text or parsed object). */
45
+ export function anthropicErrorTypeFromBody(body) {
46
+ if (body && typeof body === 'object') return lowered((body.error && body.error.type) || body.type);
47
+ const match = BODY_TYPE_RE.exec(String(body || ''));
48
+ return match ? lowered(match[1]) : '';
49
+ }
50
+
51
+ /** Retry-After / retry-after-ms in ms, uncapped; null when the server sent neither. */
52
+ export function retryAfterMsFromHeaders(headers) {
53
+ if (!present(headerValue(headers, 'retry-after-ms')) && !present(headerValue(headers, 'retry-after'))) return null;
54
+ return retryAfterMsFromError({ headers });
55
+ }
56
+
57
+ /** Epoch ms of the unified rate-limit reset header, uncapped; null when absent or past. */
58
+ export function resetAtFromHeaders(headers) {
59
+ const raw = headerValue(headers, RESET_HEADER);
60
+ if (!present(raw)) return null;
61
+ const seconds = Number(raw);
62
+ return Number.isFinite(seconds) && seconds > 0 ? Math.ceil(seconds * 1000) : null;
63
+ }
64
+
65
+ /**
66
+ * Stamp the contract onto `err`. Existing `headers` and a finite
67
+ * `retryAfterMs` are preserved. `type` is the wire error type when the caller
68
+ * already parsed one; otherwise it is read from `bodyText` (or err.error, the
69
+ * SDK's parsed body, or err.message) and finally from the status.
70
+ */
71
+ export function applyAnthropicErrorContract(err, { status, headers, type = '', bodyText = '' } = {}) {
72
+ if (!err || typeof err !== 'object') return err;
73
+ const httpStatus = Number(status || err.httpStatus || err.status || 0) || 0;
74
+ if (httpStatus) {
75
+ err.status = httpStatus;
76
+ err.httpStatus = httpStatus;
77
+ const wireType =
78
+ lowered(type) ||
79
+ anthropicErrorTypeFromBody(bodyText) ||
80
+ anthropicErrorTypeFromBody(err.error) ||
81
+ anthropicErrorTypeFromBody(err.message) ||
82
+ STATUS_ERROR_TYPE.get(httpStatus) ||
83
+ '';
84
+ const code = httpStatus === 413 ? REQUEST_TOO_LARGE : wireType;
85
+ if (code) err.code = code;
86
+ }
87
+ if (!err.headers && headers) err.headers = headers;
88
+ const effectiveHeaders = err.headers || headers || null;
89
+ if (!(err.retryAfterMs != null && Number.isFinite(Number(err.retryAfterMs)))) {
90
+ const retryAfterMs = retryAfterMsFromHeaders(effectiveHeaders);
91
+ if (retryAfterMs != null) err.retryAfterMs = retryAfterMs;
92
+ }
93
+ const resetAt = resetAtFromHeaders(effectiveHeaders);
94
+ if (resetAt != null) err.resetAt = resetAt;
95
+ return err;
96
+ }
@@ -6,7 +6,7 @@
6
6
  // cache, because the retry after the wait carries a different speed anyway.
7
7
  // The reference client's rule: a SHORT server window is worth waiting for at
8
8
  // fast speed (the cache prefix survives), anything longer drops to standard
9
- // speed for a cooldown. An explicit "overage billing unavailable" header is
9
+ // speed for a cooldown (reference thresholds: <20s keeps fast; otherwise\n// max(Retry-After ?? 30min, 10min)). An explicit "overage billing unavailable" header is
10
10
  // terminal for the process — no cooldown can make paid overage appear.
11
11
  //
12
12
  // State is process-wide because the capacity pool is per-account, not per
@@ -14,23 +14,28 @@
14
14
  // sessions hammering it.
15
15
 
16
16
  import { headerValue } from './retry-classification.mjs';
17
+ import { retryAfterMsFromHeaders } from './anthropic-error-contract.mjs';
17
18
 
18
19
  // Server-declared reason header for a fast-mode rejection caused by missing
19
20
  // overage billing (matches the reference client's header name).
20
21
  const OVERAGE_DISABLED_HEADER = 'anthropic-ratelimit-unified-overage-disabled-reason';
21
- // Body-only form of the same rejection ("Usage credits are required for fast
22
- // mode."), sent as a 429 rate_limit_error without the header above.
23
- const CREDITS_REQUIRED_PATTERN = /usage credits are required for fast mode/i;
24
- const CREDITS_REQUIRED_REASON = 'usage_credits_required';
22
+ // Reasons that mean the wallet is empty / capped for now rather than that
23
+ // overage can never exist: the request drops to standard speed, but fast mode
24
+ // is not switched off (the reference client keeps its setting for these).
25
+ const TRANSIENT_OVERAGE_REASONS = new Set(['org_level_disabled_until', 'out_of_credits']);
26
+ // A 400 from an account/endpoint that cannot serve fast mode at all. The same
27
+ // request succeeds at standard speed, and no cooldown makes it succeed fast.
28
+ const NOT_ENABLED_PATTERN = /fast mode is not enabled/i;
29
+ const NOT_ENABLED_REASON = 'fast_mode_not_enabled';
25
30
 
26
31
  // A Retry-After under this bound is short enough that waiting keeps fast mode
27
32
  // (and its cache prefix) worthwhile.
28
- const SHORT_RETRY_THRESHOLD_MS = 10_000;
33
+ const SHORT_RETRY_THRESHOLD_MS = 20_000;
29
34
  // Cooldown floor: without it a 1s window would flip fast mode on and off every
30
35
  // turn, which costs more in cache misses than the downgrade saves.
31
- const MIN_COOLDOWN_MS = 60_000;
36
+ const MIN_COOLDOWN_MS = 600_000;
32
37
  // Applied when the server gives no window at all.
33
- const DEFAULT_COOLDOWN_MS = 300_000;
38
+ const DEFAULT_COOLDOWN_MS = 1_800_000;
34
39
 
35
40
  let _cooldownUntilMs = 0;
36
41
  let _disabledReason = null;
@@ -62,23 +67,23 @@ export function fastModeDisabledReason() {
62
67
  export function noteFastModeCapacityError(err, { fast = false, now = Date.now() } = {}) {
63
68
  if (!fast) return 'ignored';
64
69
  const status = Number(err?.httpStatus || err?.status || err?.response?.status || 0);
70
+ if (status === 400 && NOT_ENABLED_PATTERN.test(String(err?.message || ''))) {
71
+ _disabledReason = NOT_ENABLED_REASON;
72
+ return 'disabled';
73
+ }
65
74
  if (status !== 429 && status !== 529) return 'ignored';
66
75
 
67
76
  const headers = err?.headers || err?.response?.headers || err?.data?.responseHeaders || null;
68
77
  const overageReason = headerValue(headers, OVERAGE_DISABLED_HEADER);
69
- if (overageReason != null && String(overageReason) !== '') {
70
- _disabledReason = String(overageReason);
71
- return 'disabled';
72
- }
73
- // Same terminal condition reported only in the error body: the account has
74
- // no usage credits for fast mode, so no cooldown can make it succeed.
75
- if (CREDITS_REQUIRED_PATTERN.test(String(err?.message || ''))) {
76
- _disabledReason = CREDITS_REQUIRED_REASON;
78
+ // The header's presence (even empty) is the signal, as in the reference client.
79
+ if (overageReason != null) {
80
+ if (TRANSIENT_OVERAGE_REASONS.has(String(overageReason))) return 'downgrade';
81
+ _disabledReason = String(overageReason) || 'overage_unavailable';
77
82
  return 'disabled';
78
83
  }
79
84
 
80
- const retryAfterMs = Number(err?.retryAfterMs);
81
- const hasWindow = Number.isFinite(retryAfterMs) && retryAfterMs >= 0;
85
+ const retryAfterMs = serverWindowMs(err);
86
+ const hasWindow = retryAfterMs != null;
82
87
  if (hasWindow && retryAfterMs < SHORT_RETRY_THRESHOLD_MS) return 'retry-fast';
83
88
 
84
89
  const cooldownMs = Math.max(hasWindow ? retryAfterMs : DEFAULT_COOLDOWN_MS, MIN_COOLDOWN_MS);
@@ -86,6 +91,22 @@ export function noteFastModeCapacityError(err, { fast = false, now = Date.now()
86
91
  return 'downgrade';
87
92
  }
88
93
 
94
+ /** True when the decision means the caller must drop `speed` before replaying. */
95
+ export function fastModeDowngraded(decision) {
96
+ return decision === 'downgrade' || decision === 'disabled';
97
+ }
98
+
99
+ // The server's Retry-After window: an explicit err.retryAfterMs, else the
100
+ // Retry-After headers. The unified-reset header is deliberately not a window
101
+ // here (the reference client reads Retry-After only). null when none.
102
+ function serverWindowMs(err) {
103
+ const explicit = err?.retryAfterMs;
104
+ if (explicit != null && explicit !== '' && Number.isFinite(Number(explicit)) && Number(explicit) >= 0) {
105
+ return Number(explicit);
106
+ }
107
+ return retryAfterMsFromHeaders(err?.headers || err?.response?.headers || err?.data?.responseHeaders || null);
108
+ }
109
+
89
110
  /** Manual re-enable (user action) and test seam. */
90
111
  export function clearFastModeCooldown() {
91
112
  _cooldownUntilMs = 0;
@@ -0,0 +1,55 @@
1
+ /**
2
+ * anthropic-max-tokens-recovery.mjs — the two max_tokens adjustments the
3
+ * reference client makes (withRetry.ts / claude.ts):
4
+ *
5
+ * - a 400 "input length and `max_tokens` exceed context limit: A + B > C" is
6
+ * answered by shrinking max_tokens to what the context still has room for
7
+ * (1000-token safety buffer, 3000-token floor, thinking budget + 1 minimum)
8
+ * and replaying; with less than the floor available the error surfaces.
9
+ * - the non-streaming replay caps max_tokens at 64000 (the API's long-request
10
+ * boundary) and keeps thinking.budget_tokens below it.
11
+ */
12
+
13
+ export const FLOOR_OUTPUT_TOKENS = 3000;
14
+ export const CONTEXT_SAFETY_BUFFER_TOKENS = 1000;
15
+ export const MAX_NON_STREAMING_TOKENS = 64_000;
16
+
17
+ const OVERFLOW_RE = /input length and `max_tokens` exceed context limit: (\d+) \+ (\d+) > (\d+)/;
18
+
19
+ /** `{ inputTokens, maxTokens, contextLimit }` for the exact 400, else null. */
20
+ export function parseMaxTokensContextOverflow(status, message) {
21
+ if (Number(status) !== 400) return null;
22
+ const match = OVERFLOW_RE.exec(String(message || ''));
23
+ if (!match) return null;
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;
26
+ }
27
+
28
+ const thinkingBudget = (body) =>
29
+ body?.thinking?.type === 'enabled' && Number(body.thinking.budget_tokens) > 0 ? Number(body.thinking.budget_tokens) : 0;
30
+
31
+ /**
32
+ * Shrink `body.max_tokens` to fit the reported context. Returns true when the
33
+ * body was adjusted and is worth replaying.
34
+ */
35
+ export function adjustMaxTokensForContextOverflow(body, status, message) {
36
+ const overflow = parseMaxTokensContextOverflow(status, message);
37
+ if (!overflow || !body) return false;
38
+ const available = Math.max(0, overflow.contextLimit - overflow.inputTokens - CONTEXT_SAFETY_BUFFER_TOKENS);
39
+ if (available < FLOOR_OUTPUT_TOKENS) return false;
40
+ body.max_tokens = Math.max(FLOOR_OUTPUT_TOKENS, available, thinkingBudget(body) + 1);
41
+ return true;
42
+ }
43
+
44
+ /** Cap a non-streaming body in place (max_tokens and the thinking budget). */
45
+ export function capForNonStreaming(body) {
46
+ if (!body || !(Number(body.max_tokens) > MAX_NON_STREAMING_TOKENS)) return body;
47
+ body.max_tokens = MAX_NON_STREAMING_TOKENS;
48
+ if (thinkingBudget(body)) {
49
+ body.thinking = {
50
+ ...body.thinking,
51
+ budget_tokens: Math.min(body.thinking.budget_tokens, MAX_NON_STREAMING_TOKENS - 1),
52
+ };
53
+ }
54
+ return body;
55
+ }
@@ -8,25 +8,17 @@
8
8
  // 2. Catalog outputTokens for the model id (trusted over hardcoded
9
9
  // heuristics when present — the API reports real per-model limits),
10
10
  // clamped to [MAX_TOKENS_FLOOR, safetyCap].
11
- // 3. Static per-model table / family heuristic fallback when the catalog
12
- // has no entry for this model, also capped at the safety cap.
11
+ // 3. The shared model catalog's outputTokens for the model (cached roster /
12
+ // LiteLLM / models.dev), same clamp.
13
+ // 4. The pre-catalog family limits for a model no catalog describes, else
14
+ // the floor.
15
+
16
+ import { getModelMetadataSync } from './model-catalog.mjs';
13
17
 
14
18
  const MAX_TOKENS_FLOOR = 8192;
15
19
  const DEFAULT_SAFETY_CAP = 65536;
16
20
  const ENV_VAR = 'MIXDOG_ANTHROPIC_MAX_OUTPUT_TOKENS';
17
21
 
18
- // Per-model max_tokens when the model id is explicitly listed. New models
19
- // (e.g., Sonnet 4.7) won't match a specific entry and fall through to the
20
- // family-based heuristic below. Conservative defaults — model may support
21
- // more but we'd rather stay within safe bounds.
22
- const MAX_TOKENS = {
23
- 'claude-opus-4-8': 65536,
24
- 'claude-opus-4-7': 65536,
25
- 'claude-opus-4-6': 65536,
26
- 'claude-sonnet-4-6': 16384,
27
- 'claude-haiku-4-5-20251001': 8192,
28
- };
29
-
30
22
  // Strict-positive env override parsing. Invalid values ("0", negatives,
31
23
  // garbage, whitespace) are treated as UNSET — not as "use the default cap
32
24
  // outright" — so catalog/fallback still decide for low-cap models. Raw env
@@ -39,11 +31,18 @@ function envAnthropicMaxOutputOverride() {
39
31
  return Math.floor(n);
40
32
  }
41
33
 
42
- // Static per-model table + family heuristic, used when the catalog has no
43
- // entry for this model id. Sonnet 5+ ships a much larger output budget than
44
- // the legacy 4.x line (this is the claude-sonnet-5 fix: 16384 was starving
45
- // visible output once extended thinking ate into the same hard cap). Keep
46
- // sonnet-4-x conservative at 16384; only bump 5+.
34
+ // Last resort when no catalog describes the model: the limits known before
35
+ // the catalogs existed. Sonnet 5+ ships a much larger output budget than the
36
+ // legacy 4.x line (16384 starved visible output once extended thinking ate
37
+ // into the same hard cap). Unknown families stay at the floor.
38
+ const MAX_TOKENS = {
39
+ 'claude-opus-4-8': 65536,
40
+ 'claude-opus-4-7': 65536,
41
+ 'claude-opus-4-6': 65536,
42
+ 'claude-sonnet-4-6': 16384,
43
+ 'claude-haiku-4-5-20251001': 8192,
44
+ };
45
+
47
46
  function fallbackAnthropicMaxTokens(model) {
48
47
  if (MAX_TOKENS[model]) return MAX_TOKENS[model];
49
48
  const id = String(model || '').toLowerCase();
@@ -52,8 +51,12 @@ function fallbackAnthropicMaxTokens(model) {
52
51
  const sonnetVersion = id.match(/^claude-sonnet-(\d+)/);
53
52
  if (sonnetVersion) return Number(sonnetVersion[1]) >= 5 ? 65536 : 16384;
54
53
  if (id.includes('sonnet')) return 16384;
55
- if (id.includes('haiku')) return 8192;
56
- return 8192;
54
+ return MAX_TOKENS_FLOOR;
55
+ }
56
+
57
+ function sharedCatalogOutputTokens(model) {
58
+ const declared = Number(getModelMetadataSync(String(model || ''), 'anthropic')?.outputTokens);
59
+ return Number.isFinite(declared) && declared > 0 ? declared : null;
57
60
  }
58
61
 
59
62
  // catalogLookup(model) -> number|null. Providers supply their own strategy
@@ -71,6 +74,7 @@ export function resolveAnthropicMaxTokens(model, { catalogLookup } = {}) {
71
74
  catalogValue = null;
72
75
  }
73
76
  }
77
+ if (!(Number.isFinite(catalogValue) && catalogValue > 0)) catalogValue = sharedCatalogOutputTokens(model);
74
78
  if (Number.isFinite(catalogValue) && catalogValue > 0) {
75
79
  return Math.max(MAX_TOKENS_FLOOR, Math.min(catalogValue, safetyCap));
76
80
  }
@@ -1,6 +1,6 @@
1
1
  // Anthropic model catalog + message conversion helpers.
2
2
  import { createRequire } from 'node:module';
3
- import { effortValuesForModel } from './anthropic-effort.mjs';
3
+ import { effortValuesForModel, thinkingTypesFromCapabilities } from './anthropic-effort.mjs';
4
4
  import { makeModelCache } from './model-cache.mjs';
5
5
  import { resolveAnthropicMaxTokens } from './anthropic-max-tokens.mjs';
6
6
  import {
@@ -73,6 +73,7 @@ export function _normalizeAnthropicModel(raw, provider = 'anthropic') {
73
73
  const dated = /-\d{8}$/.test(String(id));
74
74
  const versioned = !dated && /^claude-[a-z]+-\d+(?:-\d+)?$/i.test(String(id));
75
75
  const effortValues = effortValuesForModel(raw?.capabilities, id);
76
+ const thinkingTypes = thinkingTypesFromCapabilities(raw?.capabilities);
76
77
  return {
77
78
  id,
78
79
  display: raw?.display_name || raw?.displayName || raw?.display || _prettyName(id, family),
@@ -90,6 +91,7 @@ export function _normalizeAnthropicModel(raw, provider = 'anthropic') {
90
91
  latest: false,
91
92
  supportsReasoning: effortValues.length > 0 || _capabilitySupported(raw?.capabilities?.thinking),
92
93
  reasoningOptions: effortValues.length ? [{ type: 'effort', values: effortValues }] : [],
94
+ ...(thinkingTypes ? { thinkingTypes } : {}),
93
95
  };
94
96
  }
95
97
  // The API-key provider has no catalog cache of its own — it reads the same
@@ -24,6 +24,8 @@ import {
24
24
  } from './retry-classifier.mjs';
25
25
  import { _classifyMidstreamError, _midstreamSleepWithAbort, stampAnthropicStreamOutcome } from './anthropic-sse.mjs';
26
26
  import { notifyCurrentAnthropicRateLimit } from './admission-scheduler.mjs';
27
+ import { applyAnthropicErrorContract } from './anthropic-error-contract.mjs';
28
+ import { isAnthropicOverloadError } from './anthropic-overload-fallback.mjs';
27
29
  import { noteAbandonedUsage } from '../../../shared/llm/usage-context.mjs';
28
30
 
29
31
  export function createAnthropicMidState(attemptIndex) {
@@ -88,6 +90,8 @@ export function assertAnthropicStreamNotEmpty(midState, result, label) {
88
90
  * @param {{ recoverNonStreaming: Function, issueNonStreamingFallback: Function, requireTransportRecoveryBudget: Function }} deps.recovery
89
91
  * @param {Function|null} [deps.onStageChange] receives the display-only 'reconnecting' stage per retry
90
92
  * @param {boolean} [deps.retry529] false for a background call: an overload mid-stream is not retried
93
+ * @param {ReturnType<typeof import('./anthropic-overload-fallback.mjs').createAnthropicOverloadTracker>|null} [deps.overload]
94
+ * the send's shared overload counter (SSE overloads feed it)
91
95
  */
92
96
  export function createAnthropicMidstreamRecovery({
93
97
  label,
@@ -101,6 +105,7 @@ export function createAnthropicMidstreamRecovery({
101
105
  recovery,
102
106
  onStageChange = null,
103
107
  retry529 = true,
108
+ overload = null,
104
109
  }) {
105
110
  const log = (line) => {
106
111
  try {
@@ -128,7 +133,7 @@ export function createAnthropicMidstreamRecovery({
128
133
  firstAttemptClassifier = classifier;
129
134
  abortStream(controller, err);
130
135
  log(message);
131
- const waitMs = delayMs ?? midstreamBackoffFor(attemptIndex + 1);
136
+ const waitMs = delayMs ?? midstreamBackoffFor(attemptIndex + 1, undefined, err);
132
137
  emitProviderRetryStage(onStageChange, {
133
138
  attempt: attemptIndex + 1,
134
139
  maxAttempts: maxRetries,
@@ -192,6 +197,16 @@ export function createAnthropicMidstreamRecovery({
192
197
  abortStream(controller, err);
193
198
  throw err;
194
199
  }
200
+ // An SSE overload counts toward the same limit as a request-loop 529; at
201
+ // the limit the configured fallback model takes over (the provider's
202
+ // send loop catches the trigger around this whole recovery).
203
+ if (overload && isAnthropicOverloadError(err)) {
204
+ const trigger = overload.noteStreamOverload(err);
205
+ if (trigger) {
206
+ abortStream(controller, err);
207
+ throw trigger;
208
+ }
209
+ }
195
210
  const canRetry = attemptIndex < maxRetries;
196
211
  const attemptLabel = `${attemptIndex + 1}/${maxRetries}`;
197
212
  // Empty/dropped stream (no message_start): safe to retry once —
@@ -270,10 +285,9 @@ export function createAnthropicMidstreamRecovery({
270
285
  const status = Number(err?.httpStatus || err?.status || 0);
271
286
  let retryDelayMs = null;
272
287
  if (status === 429) {
273
- if (!err.headers && response?.headers) err.headers = response.headers;
274
288
  if (!err.response && response) err.response = { status, headers: response.headers };
289
+ applyAnthropicErrorContract(err, { status, headers: response?.headers });
275
290
  retryDelayMs = retryAfterMsFromError(err);
276
- if (retryDelayMs != null) err.retryAfterMs = retryDelayMs;
277
291
  notifyCurrentAnthropicRateLimit(err);
278
292
  }
279
293
  try {
@@ -283,7 +297,7 @@ export function createAnthropicMidstreamRecovery({
283
297
  log(`abort on stream error failed: ${abortErr?.message ?? String(abortErr)}`);
284
298
  }
285
299
  log(`mid-stream recovered: retry ${attemptLabel} (cause: ${classifier})`);
286
- const waitMs = retryDelayMs ?? midstreamBackoffFor(attemptIndex + 1);
300
+ const waitMs = retryDelayMs ?? midstreamBackoffFor(attemptIndex + 1, undefined, err);
287
301
  emitProviderRetryStage(onStageChange, {
288
302
  attempt: attemptIndex + 1,
289
303
  maxAttempts: maxRetries,
@@ -8,7 +8,12 @@
8
8
  import { enrichModels } from './model-catalog.mjs';
9
9
  import { sanitizeModelList } from './model-list-sanitize.mjs';
10
10
  import { makeModelCache } from './model-cache.mjs';
11
- import { effortValuesForModel, setModelEffortCapabilities } from './anthropic-effort.mjs';
11
+ import {
12
+ effortValuesForModel,
13
+ setModelEffortCapabilities,
14
+ thinkingTypesFromCapabilities,
15
+ } from './anthropic-effort.mjs';
16
+ import { getModelMetadataSync } from './model-catalog.mjs';
12
17
 
13
18
  // Disk-backed cache so repeated process starts (cron, tool calls) don't
14
19
  // hammer /v1/models. 24h TTL matches the upstream client cadence.
@@ -85,6 +90,7 @@ export function _normalizeAnthropicModel(raw) {
85
90
  const tier = modelTier(dated, versioned);
86
91
  const releaseDate = dated ? id.match(/-(\d{4})(\d{2})(\d{2})$/) : null;
87
92
  const effortValues = effortValuesForModel(raw?.capabilities, id);
93
+ const thinkingTypes = thinkingTypesFromCapabilities(raw?.capabilities);
88
94
  return {
89
95
  id,
90
96
  display: raw?.display_name || _prettyName(id, family),
@@ -98,6 +104,7 @@ export function _normalizeAnthropicModel(raw) {
98
104
  releaseDate: releaseDate ? `${releaseDate[1]}-${releaseDate[2]}-${releaseDate[3]}` : null,
99
105
  supportsReasoning: effortValues.length > 0 || _capabilitySupported(raw?.capabilities?.thinking),
100
106
  reasoningOptions: effortValues.length ? [{ type: 'effort', values: effortValues }] : [],
107
+ ...(thinkingTypes ? { thinkingTypes } : {}),
101
108
  };
102
109
  }
103
110
 
@@ -115,7 +122,12 @@ export function _prettyName(id, family) {
115
122
  return `${base} ${v[1]}${minor}`;
116
123
  }
117
124
 
125
+ // Context window for a roster row that reports none: the shared model catalog
126
+ // (cached roster / LiteLLM / models.dev) first, else the pre-catalog family
127
+ // windows.
118
128
  export function _defaultContextForModel(id) {
129
+ const declared = Number(getModelMetadataSync(id, 'anthropic')?.contextWindow);
130
+ if (Number.isFinite(declared) && declared > 0) return declared;
119
131
  const text = String(id || '');
120
132
  const version = text.match(/^claude-[a-z]+-(\d+)(?:-(\d+))?/i);
121
133
  if (Number(version?.[1] || 0) >= 5) return 1000000;
@@ -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.296';
13
+ export const DEFAULT_CLI_VERSION = '2.1.300';
14
14
  export const CLAUDE_CLI_NPM_PACKAGE = '@anthropic-ai/claude-code';
15
15
 
16
16
  const CACHE_SCHEMA_VERSION = 1;
@@ -21,8 +21,16 @@ export function createMidState(attemptIndex) {
21
21
  * @param {ReturnType<import('./anthropic-oauth-recovery.mjs').createAnthropicOAuthRecovery>} deps.recovery
22
22
  * @param {Function|null} [deps.onStageChange]
23
23
  * @param {boolean} [deps.retry529]
24
+ * @param {object|null} [deps.overload] the send's shared overload counter
24
25
  */
25
- export function createMidstreamRecovery({ maxRetries, totalSignal, recovery, onStageChange = null, retry529 = true }) {
26
+ export function createMidstreamRecovery({
27
+ maxRetries,
28
+ totalSignal,
29
+ recovery,
30
+ onStageChange = null,
31
+ retry529 = true,
32
+ overload = null,
33
+ }) {
26
34
  return createAnthropicMidstreamRecovery({
27
35
  label: 'anthropic-oauth',
28
36
  outcomeProvider: 'anthropic-oauth',
@@ -33,5 +41,6 @@ export function createMidstreamRecovery({ maxRetries, totalSignal, recovery, onS
33
41
  recovery,
34
42
  onStageChange,
35
43
  retry529,
44
+ overload,
36
45
  });
37
46
  }
@@ -8,7 +8,10 @@ import { PROVIDER_NONSTREAM_TOTAL_TIMEOUT_MS, createTimeoutSignal } from '../sta
8
8
  import { AnthropicFallbackTriggeredError, markProviderRecoveryExhausted } from './retry-classifier.mjs';
9
9
  import { cloneAnthropicEffortBody } from './effort-configuration.mjs';
10
10
  import { normalizeAnthropicNonStreamingResponse } from './lib/anthropic-request-utils.mjs';
11
+ import { capForNonStreaming } from './anthropic-max-tokens-recovery.mjs';
11
12
  import { createAnthropicRecoveryGuards } from './anthropic-recovery-guards.mjs';
13
+ import { applyAnthropicErrorContract } from './anthropic-error-contract.mjs';
14
+ import { isRefreshableAuthRejection } from './anthropic-oauth-request/initial-status.mjs';
12
15
 
13
16
  /**
14
17
  * @param {object} deps
@@ -70,7 +73,7 @@ export function createAnthropicOAuthRecovery({
70
73
  const requestFallback = async (accessToken) => {
71
74
  const result = await requestWithRetry(
72
75
  accessToken,
73
- cloneAnthropicEffortBody(body, { stream: false }),
76
+ capForNonStreaming(cloneAnthropicEffortBody(body, { stream: false })),
74
77
  lifetime.signal
75
78
  );
76
79
  fallback = result;
@@ -89,19 +92,30 @@ export function createAnthropicOAuthRecovery({
89
92
  };
90
93
  try {
91
94
  fallback = await requestFallback(auth.creds.accessToken);
92
- if (fallback.response.status === 401) {
93
- releaseFallback('Anthropic OAuth non-streaming fallback refreshing auth');
94
- auth.creds = await provider.ensureAuth({ forceRefresh: true, reason: '401' });
95
- fallback = await requestFallback(auth.creds.accessToken);
95
+ // Same refresh rule as the streaming request: every 401 and only the
96
+ // exact revoked-token 403 are refreshed and replayed once; an ordinary
97
+ // 403 stays terminal. A rejected body is drained once and reused below.
98
+ let rejectedBody = null;
99
+ if (fallback.response.status === 401 || fallback.response.status === 403) {
100
+ rejectedBody = await fallback.response.text().catch(() => '');
101
+ if (isRefreshableAuthRejection(fallback.response.status, rejectedBody)) {
102
+ const rejectedStatus = fallback.response.status;
103
+ releaseFallback('Anthropic OAuth non-streaming fallback refreshing auth');
104
+ auth.creds = await provider.ensureAuth({ forceRefresh: true, reason: String(rejectedStatus) });
105
+ fallback = await requestFallback(auth.creds.accessToken);
106
+ rejectedBody = null;
107
+ }
96
108
  }
97
109
  if (!fallback.response.ok) {
98
- const text = await fallback.response.text().catch(() => '');
110
+ const text = rejectedBody ?? (await fallback.response.text().catch(() => ''));
99
111
  const fallbackError = new Error(
100
112
  `Anthropic OAuth API ${fallback.response.status}: ${provider.scrubTokens(text).slice(0, 200)}`
101
113
  );
102
- fallbackError.status = fallback.response.status;
103
- fallbackError.httpStatus = fallback.response.status;
104
- throw fallbackError;
114
+ throw applyAnthropicErrorContract(fallbackError, {
115
+ status: fallback.response.status,
116
+ headers: fallback.response.headers,
117
+ bodyText: provider.scrubTokens(text),
118
+ });
105
119
  }
106
120
  const message = await fallback.response.json();
107
121
  return normalizeAnthropicNonStreamingResponse(message, useModel);