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
@@ -11,6 +11,9 @@
11
11
  * comes from `retrieveUserQuotaSummary`, not the per-model catalog counters.
12
12
  */
13
13
  import { makeModelCache } from './model-cache.mjs';
14
+ import { isGeminiFamilyModel } from './gemini-family.mjs';
15
+ import { isAntigravityClaude } from './antigravity-request.mjs';
16
+ import { getModelMetadataSync } from '../../../shared/llm/model-catalog.mjs';
14
17
  import {
15
18
  ANTIGRAVITY_MODELS,
16
19
  PROJECT_ENDPOINT,
@@ -27,8 +30,9 @@ const TIER_EFFORTS = { 'extra low': 'minimal', minimal: 'minimal', low: 'low', m
27
30
  const EFFORT_ORDER = ['minimal', 'low', 'medium', 'high'];
28
31
  // IDE-internal completion/chat models are listed without a display name.
29
32
  const INTERNAL_ID = /^(?:chat|tab)_/;
30
- // Bare Gemini 3 ids take the ordinary thinkingLevel field instead of a tier id.
31
- const BARE_GEMINI3_LEVELS = Object.freeze(['low', 'medium', 'high']);
33
+ // The thinkingLevel values the gateway accepts on a single wire id; `minimal`
34
+ // is an error there, so it is never offered even when a catalog lists it.
35
+ const GATEWAY_THINKING_LEVELS = Object.freeze(['low', 'medium', 'high']);
32
36
 
33
37
  let _mirror = null;
34
38
  export const antigravityModelCache = makeModelCache({
@@ -116,6 +120,23 @@ function chatEntries(rawModels) {
116
120
  return out;
117
121
  }
118
122
 
123
+ // A Gemini wire id without tier siblings takes the ordinary thinkingLevel field.
124
+ // The ladder comes from the catalogs' row for the same Gemini id (models.dev /
125
+ // LiteLLM) narrows what the gateway accepts; when no catalog declares a ladder
126
+ // the gateway-accepted levels are offered and the server judges the value.
127
+ // Only a model the gateway does not flag as thinking-capable has no levels.
128
+ function bareThinkingLevels(wire, supportsReasoning) {
129
+ if (!supportsReasoning) return [];
130
+ // Claude behind the gateway takes the same thinkingLevel enum; no catalog
131
+ // describes these wire ids, so the gateway-accepted levels are offered.
132
+ if (isAntigravityClaude(wire)) return [...GATEWAY_THINKING_LEVELS];
133
+ if (!isGeminiFamilyModel(wire)) return [];
134
+ const effort = getModelMetadataSync(wire, 'gemini')?.reasoningOptions?.find((option) => option?.type === 'effort');
135
+ if (!Array.isArray(effort?.values) || !effort.values.length) return [...GATEWAY_THINKING_LEVELS];
136
+ const declared = new Set(effort.values.map((value) => String(value).toLowerCase()));
137
+ return GATEWAY_THINKING_LEVELS.filter((level) => declared.has(level));
138
+ }
139
+
119
140
  /** Collapse the gateway's per-tier wire ids into picker records. */
120
141
  export function normalizeAntigravityCatalog(rawModels) {
121
142
  const families = new Map();
@@ -142,13 +163,13 @@ export function normalizeAntigravityCatalog(rawModels) {
142
163
  ? Object.fromEntries(efforts.map((effort) => [effort, pickWire(family.wires.get(effort), family.base)]))
143
164
  : pickWire(family.wires.get(efforts[0] ?? ''), family.base);
144
165
  const id = tiered ? key : wire;
145
- const bareGemini3 = !tiered && /^gemini-3(?:\.\d+)?-(?:flash|pro)$/.test(wire);
146
166
  const display =
147
167
  tiered || !efforts.length ? family.base : `${family.base} (${efforts[0][0].toUpperCase()}${efforts[0].slice(1)})`;
148
168
  const kind = familyKind(family.base);
149
- let reasoningLevels = [];
150
- if (tiered) reasoningLevels = efforts;
151
- else if (bareGemini3) reasoningLevels = [...BARE_GEMINI3_LEVELS];
169
+ // A lone labelled tier already names its effort in the wire id.
170
+ let reasoningLevels = efforts;
171
+ if (!efforts.length) reasoningLevels = bareThinkingLevels(wire, family.supportsReasoning);
172
+ else if (!tiered) reasoningLevels = [];
152
173
  models.push({
153
174
  id,
154
175
  name: display,
@@ -174,9 +195,9 @@ function antigravityCatalogModels() {
174
195
 
175
196
  /**
176
197
  * Turn a picker model + effort into the wire id the gateway accepts. Tiered
177
- * families consume the effort (the id encodes it); a bare Gemini 3 id keeps it
178
- * for thinkingLevel; every other record drops it because the model has no
179
- * effort surface. Unknown ids pass through unchanged.
198
+ * families consume the effort (the id encodes it); a bare id whose record
199
+ * lists levels keeps it for thinkingLevel; every other record drops it
200
+ * because the gateway does not flag the model as thinking-capable. Unknown ids pass through unchanged.
180
201
  */
181
202
  export function resolveAntigravityWireModel(model, effort, models = antigravityCatalogModels()) {
182
203
  const id = String(model || '');
@@ -20,6 +20,7 @@ import { preconnect } from '../../../shared/llm/http-agent.mjs';
20
20
  import { createAntigravityStreamCollector } from './antigravity-stream.mjs';
21
21
  import { createAntigravityRequest } from './antigravity-transport.mjs';
22
22
  import { finalizeAntigravityTurn } from './antigravity-response.mjs';
23
+ import { ANTIGRAVITY_ACCOUNT_COOLDOWN_POLICY } from './antigravity-retry-policy.mjs';
23
24
  import {
24
25
  CONTENT_ENDPOINT,
25
26
  ANTIGRAVITY_MODELS,
@@ -69,6 +70,11 @@ export class AntigravityOAuthProvider {
69
70
  // usageMetadata.promptTokenCount is the total, cached tokens included.
70
71
  static inputExcludesCache = false;
71
72
  name = 'antigravity-oauth';
73
+ // Roster cooldowns the shared account pool applies when the server names no delay.
74
+ accountCooldownPolicy = ANTIGRAVITY_ACCOUNT_COOLDOWN_POLICY;
75
+ // The capacity / quick-retry ladder is the whole recovery: a spent ladder
76
+ // surfaces instead of parking on loop recovery cycles.
77
+ retryPolicy = Object.freeze({ recoveryCycles: false });
72
78
 
73
79
  constructor(config = {}) {
74
80
  this.config = config || {};
@@ -162,6 +168,7 @@ export class AntigravityOAuthProvider {
162
168
  opts,
163
169
  signal: passthrough.signal,
164
170
  collector,
171
+ sleepFn: this.config.sleepFn,
165
172
  });
166
173
  try {
167
174
  try {
@@ -2,10 +2,15 @@ import { randomUUID, createHash } from 'node:crypto';
2
2
  import { createProviderReplay, providerReplayItems } from './lib/provider-replay.mjs';
3
3
  import { toGeminiContents, toGeminiRequestTools, toGeminiToolConfig } from './gemini-schema.mjs';
4
4
  import { geminiThinkingConfig } from './gemini-thinking.mjs';
5
+ import { isGeminiFamilyModel } from './gemini-family.mjs';
5
6
 
6
7
  const THOUGHT_SIGNATURE_SENTINEL = 'skip_thought_signature_validator';
7
8
  const CLAUDE_MAX_OUTPUT_TOKENS = 64000;
8
9
 
10
+ // Claude models behind the gateway speak a different thinking/replay dialect
11
+ // (token budgets, anthropic-beta header, their own signatures). The roster
12
+ // carries no protocol marker, and a wrong guess is rejected upstream, so the
13
+ // vendor prefix of the wire id decides.
9
14
  export function isAntigravityClaude(model) {
10
15
  return /^claude-/i.test(String(model || ''));
11
16
  }
@@ -59,33 +64,44 @@ function sessionId(contents) {
59
64
  return `-${digest.readBigUInt64BE(0) % 9223372036854775807n}`;
60
65
  }
61
66
 
67
+ // The gateway validates Claude's level against Google's ThinkingLevel enum,
68
+ // whose highest value is `high`; anything it does not name is left out.
69
+ const CLAUDE_GATEWAY_LEVELS = new Set(['low', 'medium', 'high']);
70
+ function claudeGatewayLevel(value) {
71
+ const level = String(value ?? '').toLowerCase();
72
+ if (level === 'xhigh' || level === 'max' || level === 'ultra') return 'high';
73
+ return CLAUDE_GATEWAY_LEVELS.has(level) ? level : null;
74
+ }
75
+
76
+ // An explicit token budget is sent as-is; otherwise the chosen effort rides
77
+ // on thinkingLevel with the wire id unchanged.
62
78
  function claudeThinkingConfig(opts) {
63
79
  const budget = opts.thinkingBudget ?? opts.thinkingBudgetTokens;
64
- if (opts.thinkingLevel != null || (budget == null && opts.effort != null)) {
65
- throw new TypeError(
66
- 'Antigravity Claude uses thinkingBudget; effort levels cannot be converted to a token budget automatically.'
67
- );
68
- }
69
80
  const thinkingConfig = { includeThoughts: true };
70
- if (budget != null) {
71
- const value = Number(budget);
72
- if (!Number.isInteger(value) || value < 1024 || value >= CLAUDE_MAX_OUTPUT_TOKENS) {
73
- throw new TypeError('Antigravity Claude thinkingBudget must be an integer from 1024 to 63999.');
74
- }
75
- thinkingConfig.thinkingBudget = value;
81
+ if (budget == null) {
82
+ const level = claudeGatewayLevel(opts.thinkingLevel ?? opts.effort);
83
+ if (level) thinkingConfig.thinkingLevel = level;
84
+ return thinkingConfig;
85
+ }
86
+ const value = Number(budget);
87
+ if (!Number.isInteger(value) || value < 1024 || value >= CLAUDE_MAX_OUTPUT_TOKENS) {
88
+ throw new TypeError('Antigravity Claude thinkingBudget must be an integer from 1024 to 63999.');
76
89
  }
90
+ thinkingConfig.thinkingBudget = value;
77
91
  return thinkingConfig;
78
92
  }
79
93
 
80
94
  // Tiered wire ids (gemini-3.8-flash-high) already encode the thinking
81
95
  // level; the provider resolves them from the catalog and clears the
82
96
  // effort, so only bare ids reach this field.
83
- // Thought summaries on by default for every Gemini family, matching the
97
+ // Thought summaries on by default for every Gemini-family model, matching the
84
98
  // API-key provider. The gateway also serves GPT-OSS, which rejects the
85
- // thinking fields outright, so the flag stays Gemini-only.
99
+ // thinking fields outright and which the roster's thinking flag does not
100
+ // separate from Gemini, so the flag stays Gemini-only.
86
101
  function antigravityGeminiThinkingConfig(model, opts) {
87
102
  return geminiThinkingConfig(model, opts, {
88
- includeThoughts: /^gemini-/i.test(model) ? true : undefined,
103
+ provider: 'antigravity-oauth',
104
+ includeThoughts: isGeminiFamilyModel(model) ? true : undefined,
89
105
  });
90
106
  }
91
107
 
@@ -9,6 +9,7 @@
9
9
  import { traceAgentUsage } from '../agent-trace.mjs';
10
10
  import { createProviderReplay } from './lib/provider-replay.mjs';
11
11
  import { parseToolCalls, collectGeminiGroundingSources, parseGeminiTextPartMetadata } from './gemini-schema.mjs';
12
+ import { geminiPolicyFinishCode } from './gemini-error-contract.mjs';
12
13
 
13
14
  // Pure usageMetadata normalization shared by the success path and a failed
14
15
  // stream's partialUsage.
@@ -82,7 +83,7 @@ export function finalizeAntigravityTurn({ response, collector, useModel, opts, o
82
83
  if (finishReason && normalizedFinish !== 'STOP') {
83
84
  throw Object.assign(new Error(`Antigravity response incomplete: finishReason=${finishReason}`), {
84
85
  name: 'ProviderIncompleteError',
85
- code: 'PROVIDER_INCOMPLETE',
86
+ code: geminiPolicyFinishCode(finishReason) || 'PROVIDER_INCOMPLETE',
86
87
  providerIncomplete: true,
87
88
  finishReason,
88
89
  partialContent: content,
@@ -0,0 +1,93 @@
1
+ /**
2
+ * antigravity-retry-policy.mjs — Antigravity retry constants and the verdict
3
+ * for a 429:
4
+ *
5
+ * capacity (429/503/529, MODEL_CAPACITY_EXHAUSTED, "server busy"): retried on
6
+ * the SAME account and host with 1s → 2s → 4s (8s cap) ±10% jitter, three
7
+ * retries, whatever wait the server names, then the failure surfaces.
8
+ * Endpoint: the reference falls back to its next endpoint after a failure;
9
+ * generation here deliberately stays on the single daily host and never
10
+ * walks an endpoint list (a spent ladder surfaces to the account layer).
11
+ * RPM / unknown 429: ONE quick retry after 1s (or the server's advice, up to
12
+ * 60s), then the failure surfaces so the account layer can lock and
13
+ * rotate; advice beyond 60s surfaces at once.
14
+ * QUOTA_EXHAUSTED (and any day/plan window): never retried here.
15
+ *
16
+ * Replay stays gated by the stream-outcome contract: an attempt that exposed
17
+ * text or dispatched a tool is never re-issued.
18
+ */
19
+ import { readStreamOutcome } from './lib/stream-outcome.mjs';
20
+ import { DETERMINISTIC_KINDS, providerErrorKind } from './provider-error-kind.mjs';
21
+
22
+ export const ANTIGRAVITY_CAPACITY_RETRIES = 3;
23
+ export const ANTIGRAVITY_CAPACITY_BASE_MS = 1000;
24
+ export const ANTIGRAVITY_CAPACITY_MAX_MS = 8000;
25
+ export const ANTIGRAVITY_CAPACITY_JITTER_RATIO = 0.1;
26
+ export const ANTIGRAVITY_QUICK_RETRY_MS = 1000;
27
+ export const ANTIGRAVITY_QUICK_RETRY_MAX_ADVICE_MS = 60_000;
28
+
29
+ // withRetry options for everything that is not a 429: transient transport and
30
+ // 5xx failures use the capacity schedule (the reference has no other same-host
31
+ // retry; the leading duplicate is the sleep-before-attempt index).
32
+ export const ANTIGRAVITY_RETRY = Object.freeze({
33
+ maxAttempts: ANTIGRAVITY_CAPACITY_RETRIES + 1,
34
+ backoffMs: Object.freeze([1000, 1000, 2000, 4000]),
35
+ retryJitterRatio: ANTIGRAVITY_CAPACITY_JITTER_RATIO,
36
+ // 429s are handled by antigravity429WaitMs, not the generic loop.
37
+ retry429: false,
38
+ });
39
+
40
+ /** Capacity wait for retry number `retryIndex` (0-based): 1s, 2s, 4s, 8s cap, ±10%. */
41
+ export function antigravityCapacityDelayMs(retryIndex) {
42
+ const base = Math.min(ANTIGRAVITY_CAPACITY_BASE_MS * 2 ** retryIndex, ANTIGRAVITY_CAPACITY_MAX_MS);
43
+ return Math.round(base * (1 - ANTIGRAVITY_CAPACITY_JITTER_RATIO + Math.random() * 2 * ANTIGRAVITY_CAPACITY_JITTER_RATIO));
44
+ }
45
+
46
+ export function isAntigravityCapacityError(err) {
47
+ return err?.code === 'model_capacity_exhausted' || providerErrorKind(err).kind === 'overloaded';
48
+ }
49
+
50
+ /**
51
+ * Wait before re-issuing a 429, or null when it must surface. `state` is the
52
+ * send's `{ capacityRetries, quickRetried }` record.
53
+ */
54
+ export function antigravity429WaitMs(err, state) {
55
+ const status = Number(err?.status || err?.httpStatus || 0);
56
+ const capacity = isAntigravityCapacityError(err);
57
+ if (status !== 429 && !(capacity && (status === 503 || status === 529))) return null;
58
+ if (readStreamOutcome(err).replaySafe !== true) return null;
59
+ const { kind, retryAfterMs } = providerErrorKind(err);
60
+ if (DETERMINISTIC_KINDS.has(kind) || err.code === 'quota_exhausted' || err.quotaScope === 'day' || err.quotaScope === 'plan') {
61
+ return null;
62
+ }
63
+ // Capacity follows the local schedule whatever wait the server names.
64
+ if (capacity) {
65
+ if (state.capacityRetries >= ANTIGRAVITY_CAPACITY_RETRIES) return null;
66
+ return antigravityCapacityDelayMs(state.capacityRetries++);
67
+ }
68
+ // An RPM hit gets one quick retry; advice up to a minute is honored in
69
+ // full, a longer wait surfaces so the account pool can rotate.
70
+ if (state.quickRetried || retryAfterMs > ANTIGRAVITY_QUICK_RETRY_MAX_ADVICE_MS) return null;
71
+ state.quickRetried = true;
72
+ return retryAfterMs ?? ANTIGRAVITY_QUICK_RETRY_MS;
73
+ }
74
+
75
+ // Account-pool roster cooldowns, read
76
+ // generically by the shared pool from the provider's `accountCooldownPolicy`
77
+ // when the server named no delay: a plain rate limit rotates the account for
78
+ // 30s; a spent quota escalates 60s → 5m → 30m → 2h per consecutive refusal of
79
+ // that account (a served answer resets it); anything else 60s; never under 2s.
80
+ // Capacity and server errors never block an account in the shared pool.
81
+ export const ANTIGRAVITY_ACCOUNT_COOLDOWN_POLICY = Object.freeze({
82
+ floorMs: 2_000,
83
+ rateLimitedMs: 30_000,
84
+ quotaStepsMs: Object.freeze([60_000, 5 * 60_000, 30 * 60_000, 2 * 60 * 60_000]),
85
+ unknownMs: 60_000,
86
+ rotateOnRateLimit: true,
87
+ // A roster that is only cooling down waits up to five minutes for its
88
+ // earliest cooldown instead of failing the send.
89
+ waitForCooldownMs: 300_000,
90
+ // An account that needs verification cools for ten minutes while the
91
+ // roster serves from the next account.
92
+ blockedMs: 600_000,
93
+ });
@@ -6,13 +6,45 @@
6
6
  * account-verification URL Google hides in the error details), and the
7
7
  * per-attempt hand-off of the live stream to the turn collector.
8
8
  */
9
- import { emitProviderRetryStage, withRetry } from './retry-classifier.mjs';
9
+ import { emitProviderRetryStage, markProviderRecoveryExhausted, sleepWithAbort, withRetry } from './retry-classifier.mjs';
10
+ import {
11
+ ANTIGRAVITY_RETRY,
12
+ antigravity429WaitMs,
13
+ isAntigravityCapacityError,
14
+ } from './antigravity-retry-policy.mjs';
10
15
  import { createTimeoutSignal } from '../stall-policy.mjs';
11
16
  import { getLlmDispatcher } from '../../../shared/llm/http-agent.mjs';
12
17
  import { GEMINI_FIRST_BYTE_TIMEOUT_MS } from './gemini-stream.mjs';
13
18
  import { _scrubTokens } from './antigravity-oauth-tokens.mjs';
19
+ import { applyGeminiErrorContract } from './gemini-error-contract.mjs';
20
+ import { DETERMINISTIC_KINDS, providerErrorKind } from './provider-error-kind.mjs';
14
21
 
15
- function antigravityError(res, text, endpoint) {
22
+ // Rate-limit reason: 503/529 are capacity by status; a
23
+ // typed ErrorInfo reason decides next; wording is the last resort for a 429.
24
+ const CAPACITY_MESSAGE_RE = /capacity|overloaded|resource exhausted|server (?:is )?(?:currently )?busy/i;
25
+ const RATE_LIMIT_MESSAGE_RE = /per minute|rate limit|too many requests/i;
26
+ const TYPED_REASONS = new Set(['quota_exhausted', 'rate_limit_exceeded', 'model_capacity_exhausted']);
27
+
28
+ function applyAntigravityRateLimitReason(err, status, message) {
29
+ if (status === 503 || status === 529) {
30
+ // A typed refusal of this request (bad argument, policy, auth, quota) is
31
+ // not an overload whatever the status says.
32
+ if (DETERMINISTIC_KINDS.has(providerErrorKind(err).kind)) return;
33
+ err.code = 'model_capacity_exhausted';
34
+ return;
35
+ }
36
+ if (status !== 429 || TYPED_REASONS.has(err.code)) return;
37
+ if (CAPACITY_MESSAGE_RE.test(message)) err.code = 'model_capacity_exhausted';
38
+ else if (RATE_LIMIT_MESSAGE_RE.test(message)) err.code = 'rate_limit_exceeded';
39
+ }
40
+
41
+ const CAPACITY_STATUSES = new Set([429, 503, 529]);
42
+
43
+ function isCapacityFailure(err) {
44
+ return CAPACITY_STATUSES.has(Number(err?.status)) && isAntigravityCapacityError(err);
45
+ }
46
+
47
+ export function antigravityError(res, text, endpoint) {
16
48
  let payload = null;
17
49
  try {
18
50
  payload = text ? JSON.parse(text) : null;
@@ -30,7 +62,11 @@ function antigravityError(res, text, endpoint) {
30
62
  err.error = detail;
31
63
  err.data = payload;
32
64
  if (detail.status) err.geminiStatus = detail.status;
65
+ const details = detail.details ?? detail.errorDetails;
66
+ applyGeminiErrorContract(err, { details, googleStatus: detail.status, message });
33
67
  }
68
+ // Capacity is overload of the shared model pool, not this account's quota.
69
+ applyAntigravityRateLimitReason(err, res.status, message);
34
70
  // Account verification is terminal and actionable: surface the URL Google
35
71
  // returns instead of a raw API body the user cannot act on.
36
72
  // Google puts the link in the error details, not the message text.
@@ -47,6 +83,9 @@ function antigravityError(res, text, endpoint) {
47
83
  err.message = `Antigravity requires account verification${validationUrl ? `: open ${validationUrl} , complete the check, then retry` : ''}`;
48
84
  err.validationUrl = validationUrl || undefined;
49
85
  err.unsafeToRetry = true;
86
+ // This account needs verification; another account may still serve.
87
+ err.code ||= 'validation_required';
88
+ err.accountBlocked = true;
50
89
  }
51
90
  return err;
52
91
  }
@@ -62,8 +101,17 @@ function antigravityError(res, text, endpoint) {
62
101
  * @param {{ beginAttempt: Function, consume: Function }} deps.collector
63
102
  * @returns {() => Promise<object>} one retried request that resolves the final payload
64
103
  */
65
- export function createAntigravityRequest({ fetchFn, endpoint, headers, body, opts, signal, collector }) {
66
- return () =>
104
+ export function createAntigravityRequest({ fetchFn, endpoint, headers, body, opts, signal, collector, sleepFn }) {
105
+ const log = (attempt, lastErr, delayMs) => {
106
+ emitProviderRetryStage(opts.onStageChange, {
107
+ attempt: attempt + 1,
108
+ maxAttempts: ANTIGRAVITY_RETRY.maxAttempts,
109
+ lastErr,
110
+ delayMs,
111
+ });
112
+ process.stderr.write(`[antigravity] retry ${attempt + 1} after ${lastErr?.message || 'transient error'}\n`);
113
+ };
114
+ const attemptOnce = () =>
67
115
  withRetry(
68
116
  async ({ signal: attemptSignal }) => {
69
117
  try {
@@ -94,17 +142,42 @@ export function createAntigravityRequest({ fetchFn, endpoint, headers, body, opt
94
142
  }
95
143
  if (!res.ok) {
96
144
  const text = await res.text().catch(() => '');
97
- throw antigravityError(res, text, endpoint);
145
+ const failure = antigravityError(res, text, endpoint);
146
+ // Capacity is paced by the local schedule below; the generic loop
147
+ // would sleep whatever wait the server names.
148
+ if (isCapacityFailure(failure)) markProviderRecoveryExhausted(failure, { owner: 'antigravity-capacity' });
149
+ throw failure;
98
150
  }
99
151
  collector.beginAttempt();
100
152
  return collector.consume(res, attemptSignal);
101
153
  },
102
154
  {
155
+ ...ANTIGRAVITY_RETRY,
156
+ finalOnExhaust: true,
103
157
  signal,
104
- onRetry: ({ attempt, maxAttempts, lastErr: retryErr, delayMs }) => {
105
- emitProviderRetryStage(opts.onStageChange, { attempt: attempt + 1, maxAttempts, lastErr: retryErr, delayMs });
106
- process.stderr.write(`[antigravity] retry ${attempt + 1} after ${retryErr?.message || 'transient error'}\n`);
107
- },
158
+ sleepFn,
159
+ onRetry: ({ attempt, lastErr: retryErr, delayMs }) => log(attempt, retryErr, delayMs),
108
160
  }
109
161
  );
162
+ // A 429 comes back from withRetry untouched (retry429:false) and is paced by
163
+ // the retry schedule: capacity backs off on this host, an RPM hit
164
+ // gets one quick retry, a spent quota surfaces.
165
+ return async () => {
166
+ const state = { capacityRetries: 0, quickRetried: false };
167
+ for (let tried = 1; ; tried++) {
168
+ try {
169
+ return await attemptOnce();
170
+ } catch (err) {
171
+ const waitMs = antigravity429WaitMs(err, state);
172
+ if (waitMs == null) {
173
+ if (isCapacityFailure(err)) {
174
+ markProviderRecoveryExhausted(err, { owner: 'antigravity-capacity', attempts: tried });
175
+ }
176
+ throw err;
177
+ }
178
+ log(tried, err, waitMs);
179
+ await sleepWithAbort(waitMs, signal, sleepFn, 'Antigravity retry wait aborted');
180
+ }
181
+ }
182
+ };
110
183
  }
@@ -89,6 +89,15 @@ export function resolveAutoEffort({ base, options, probs }) {
89
89
  const ladder = autoEffortLadder(options);
90
90
  const at = ladder.indexOf(String(base ?? '').toLowerCase());
91
91
  if (at < 0) return null;
92
+ return resolveOnLadder(ladder, at, probs);
93
+ }
94
+
95
+ /** True when some judged outcome could apply: the base lies on the model's ladder. */
96
+ export function autoEffortApplicable({ base, options }) {
97
+ return autoEffortLadder(options).includes(String(base ?? '').toLowerCase());
98
+ }
99
+
100
+ function resolveOnLadder(ladder, at, probs) {
92
101
  const { step, level, confidence } = judgedStep(probs);
93
102
  const effort = ladder[Math.max(0, Math.min(ladder.length - 1, at + step))];
94
103
  return { base: ladder[at], effort, step, level, confidence: Number(confidence.toFixed(3)) };