mixdog 1.2.1 → 1.2.3

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 (557) hide show
  1. package/README.md +18 -0
  2. package/package.json +2 -1
  3. package/scripts/gate-local.mjs +19 -3
  4. package/scripts/model-catalog-audit.mjs +1 -15
  5. package/scripts/provider-pingpong-live.mjs +509 -0
  6. package/src/agents/advisor/AGENT.md +1 -1
  7. package/src/agents/advisor/agent.json +1 -1
  8. package/src/agents/reviewer/AGENT.md +3 -3
  9. package/src/agents/reviewer/agent.json +1 -1
  10. package/src/defaults/shipped-history.json +6 -0
  11. package/src/defaults/skills/setup/SKILL.md +6 -1
  12. package/src/defaults/skills/setup/references/actions.md +44 -22
  13. package/src/defaults/skills/setup/references/surfaces.md +10 -8
  14. package/src/headless-exec.mjs +15 -8
  15. package/src/lib/keychain-cjs.cjs +7 -4
  16. package/src/output-styles/common.md +11 -10
  17. package/src/repl/slash-commands.mjs +16 -1
  18. package/src/rules/agent/AGENT.md +5 -5
  19. package/src/rules/lead/LEAD.md +5 -5
  20. package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +29 -4
  21. package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +10 -0
  22. package/src/runtime/agent/orchestrator/agent-trace-io.mjs +92 -61
  23. package/src/runtime/agent/orchestrator/cache-mtime.mjs +10 -1
  24. package/src/runtime/agent/orchestrator/config-providers-merge.mjs +7 -0
  25. package/src/runtime/agent/orchestrator/config.mjs +5 -0
  26. package/src/runtime/agent/orchestrator/context/collect.mjs +1 -0
  27. package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +26 -7
  28. package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +112 -7
  29. package/src/runtime/agent/orchestrator/mcp/client-config.mjs +36 -7
  30. package/src/runtime/agent/orchestrator/mcp/client-handshake.mjs +49 -10
  31. package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +40 -3
  32. package/src/runtime/agent/orchestrator/mcp/client.mjs +230 -96
  33. package/src/runtime/agent/orchestrator/mcp/oauth-callback.mjs +103 -0
  34. package/src/runtime/agent/orchestrator/mcp/oauth-credentials.mjs +150 -0
  35. package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +111 -0
  36. package/src/runtime/agent/orchestrator/mcp/oauth-probe.mjs +87 -0
  37. package/src/runtime/agent/orchestrator/mcp/oauth-provider.mjs +95 -0
  38. package/src/runtime/agent/orchestrator/mcp/oauth-request.mjs +122 -0
  39. package/src/runtime/agent/orchestrator/mcp/oauth-shared.mjs +9 -0
  40. package/src/runtime/agent/orchestrator/mcp/oauth.mjs +229 -0
  41. package/src/runtime/agent/orchestrator/providers/account-pool.mjs +188 -29
  42. package/src/runtime/agent/orchestrator/providers/anthropic-api-recovery.mjs +2 -1
  43. package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +48 -20
  44. package/src/runtime/agent/orchestrator/providers/anthropic-api-transport.mjs +94 -31
  45. package/src/runtime/agent/orchestrator/providers/anthropic-error-contract.mjs +98 -0
  46. package/src/runtime/agent/orchestrator/providers/anthropic-fast-mode.mjs +39 -18
  47. package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens-recovery.mjs +55 -0
  48. package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens.mjs +48 -37
  49. package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +10 -7
  50. package/src/runtime/agent/orchestrator/providers/anthropic-midstream-recovery.mjs +18 -4
  51. package/src/runtime/agent/orchestrator/providers/anthropic-model-resolve.mjs +13 -1
  52. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
  53. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-midstream.mjs +10 -1
  54. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-recovery.mjs +23 -9
  55. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/initial-status.mjs +46 -20
  56. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request.mjs +14 -9
  57. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +102 -45
  58. package/src/runtime/agent/orchestrator/providers/anthropic-overload-fallback.mjs +69 -0
  59. package/src/runtime/agent/orchestrator/providers/anthropic-server-fallback.mjs +4 -0
  60. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-blocks.mjs +20 -1
  61. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-delta.mjs +15 -2
  62. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-start.mjs +11 -4
  63. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/message-events.mjs +3 -0
  64. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events.mjs +12 -5
  65. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-outcome.mjs +1 -0
  66. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-state.mjs +14 -0
  67. package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +10 -1
  68. package/src/runtime/agent/orchestrator/providers/anthropic-turn-result.mjs +9 -0
  69. package/src/runtime/agent/orchestrator/providers/anthropic.mjs +40 -7
  70. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-catalog.mjs +30 -9
  71. package/src/runtime/agent/orchestrator/providers/antigravity-oauth.mjs +7 -0
  72. package/src/runtime/agent/orchestrator/providers/antigravity-request.mjs +88 -21
  73. package/src/runtime/agent/orchestrator/providers/antigravity-response.mjs +30 -10
  74. package/src/runtime/agent/orchestrator/providers/antigravity-retry-policy.mjs +106 -0
  75. package/src/runtime/agent/orchestrator/providers/antigravity-stream.mjs +10 -61
  76. package/src/runtime/agent/orchestrator/providers/antigravity-transport.mjs +94 -15
  77. package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +1 -1
  78. package/src/runtime/agent/orchestrator/providers/command-code-oauth.mjs +117 -72
  79. package/src/runtime/agent/orchestrator/providers/compat-request-policy.mjs +78 -2
  80. package/src/runtime/agent/orchestrator/providers/cursor-auth.mjs +75 -10
  81. package/src/runtime/agent/orchestrator/providers/cursor-client-version.mjs +1 -1
  82. package/src/runtime/agent/orchestrator/providers/cursor-wire-guards.mjs +97 -2
  83. package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-bridge.mjs +103 -23
  84. package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-messages.mjs +43 -2
  85. package/src/runtime/agent/orchestrator/providers/cursor-wire-transport.mjs +103 -33
  86. package/src/runtime/agent/orchestrator/providers/cursor-wire.mjs +32 -6
  87. package/src/runtime/agent/orchestrator/providers/cursor.mjs +27 -3
  88. package/src/runtime/agent/orchestrator/providers/custom-provider-config.mjs +64 -1
  89. package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +70 -6
  90. package/src/runtime/agent/orchestrator/providers/custom-reasoning.mjs +34 -7
  91. package/src/runtime/agent/orchestrator/providers/custom-tool-wire.mjs +32 -6
  92. package/src/runtime/agent/orchestrator/providers/deepseek.mjs +67 -0
  93. package/src/runtime/agent/orchestrator/providers/effort-configuration.mjs +80 -18
  94. package/src/runtime/agent/orchestrator/providers/gemini-cache-policy.mjs +11 -4
  95. package/src/runtime/agent/orchestrator/providers/gemini-cache.mjs +46 -8
  96. package/src/runtime/agent/orchestrator/providers/gemini-error-contract.mjs +273 -0
  97. package/src/runtime/agent/orchestrator/providers/gemini-family.mjs +9 -0
  98. package/src/runtime/agent/orchestrator/providers/gemini-history-signatures.mjs +9 -4
  99. package/src/runtime/agent/orchestrator/providers/gemini-request-body.mjs +41 -5
  100. package/src/runtime/agent/orchestrator/providers/gemini-response.mjs +3 -1
  101. package/src/runtime/agent/orchestrator/providers/gemini-retry-policy.mjs +180 -0
  102. package/src/runtime/agent/orchestrator/providers/gemini-schema.mjs +369 -112
  103. package/src/runtime/agent/orchestrator/providers/gemini-sdk-request.mjs +3 -1
  104. package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +140 -35
  105. package/src/runtime/agent/orchestrator/providers/gemini-thinking.mjs +70 -24
  106. package/src/runtime/agent/orchestrator/providers/gemini.mjs +80 -29
  107. package/src/runtime/agent/orchestrator/providers/grok-client-version.mjs +1 -1
  108. package/src/runtime/agent/orchestrator/providers/grok-oauth-tokens.mjs +3 -0
  109. package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +69 -19
  110. package/src/runtime/agent/orchestrator/providers/lib/action-input-contract.mjs +60 -0
  111. package/src/runtime/agent/orchestrator/providers/lib/anthropic-native-blocks.mjs +1 -0
  112. package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +246 -42
  113. package/src/runtime/agent/orchestrator/providers/lib/anthropic-server-tool-usage.mjs +18 -0
  114. package/src/runtime/agent/orchestrator/providers/lib/anthropic-system-blocks.mjs +27 -6
  115. package/src/runtime/agent/orchestrator/providers/lib/claude-bridge-schema.mjs +388 -0
  116. package/src/runtime/agent/orchestrator/providers/lib/inclusive-usage.mjs +54 -0
  117. package/src/runtime/agent/orchestrator/providers/lib/origin-bound-fetch.mjs +16 -0
  118. package/src/runtime/agent/orchestrator/providers/lib/responses-terminal-fields.mjs +11 -0
  119. package/src/runtime/agent/orchestrator/providers/lib/usage-primitives.mjs +8 -0
  120. package/src/runtime/agent/orchestrator/providers/lib/wire-pairing.mjs +48 -22
  121. package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +119 -18
  122. package/src/runtime/agent/orchestrator/providers/mimo-oauth-profile.mjs +13 -15
  123. package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +3 -0
  124. package/src/runtime/agent/orchestrator/providers/model-list-sanitize.mjs +2 -1
  125. package/src/runtime/agent/orchestrator/providers/model-proxy-channel.d.mts +1 -1
  126. package/src/runtime/agent/orchestrator/providers/model-proxy-channel.mjs +1 -0
  127. package/src/runtime/agent/orchestrator/providers/model-proxy-provider.mjs +33 -1
  128. package/src/runtime/agent/orchestrator/providers/muse-code-oauth.mjs +4 -9
  129. package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +2 -0
  130. package/src/runtime/agent/orchestrator/providers/openai-codex-metadata.mjs +2 -0
  131. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +123 -61
  132. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/chunk-events.mjs +35 -14
  133. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-result.mjs +27 -2
  134. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +37 -7
  135. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/tool-call-acc.mjs +2 -9
  136. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +1 -0
  137. package/src/runtime/agent/orchestrator/providers/openai-compat-error-contract.mjs +50 -0
  138. package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +47 -2
  139. package/src/runtime/agent/orchestrator/providers/openai-compat-options.mjs +47 -25
  140. package/src/runtime/agent/orchestrator/providers/openai-compat-presets.mjs +5 -1
  141. package/src/runtime/agent/orchestrator/providers/openai-compat-reasoning-field.mjs +151 -0
  142. package/src/runtime/agent/orchestrator/providers/openai-compat-response-normalization.mjs +64 -23
  143. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-events.mjs +79 -33
  144. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-head-parity.json +2901 -0
  145. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-parity.fixtures.mjs +172 -0
  146. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-state.mjs +3 -2
  147. package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +144 -15
  148. package/src/runtime/agent/orchestrator/providers/openai-compat-retry-profile.mjs +193 -0
  149. package/src/runtime/agent/orchestrator/providers/openai-compat-stream-common.mjs +66 -2
  150. package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +9 -2
  151. package/src/runtime/agent/orchestrator/providers/openai-compat-trace.mjs +2 -0
  152. package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +109 -26
  153. package/src/runtime/agent/orchestrator/providers/openai-compat-xai-send.mjs +27 -6
  154. package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +34 -20
  155. package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +23 -4
  156. package/src/runtime/agent/orchestrator/providers/openai-direct-request.mjs +37 -28
  157. package/src/runtime/agent/orchestrator/providers/openai-error-contract.mjs +274 -0
  158. package/src/runtime/agent/orchestrator/providers/openai-http-sse-request.mjs +72 -32
  159. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/output-items.mjs +23 -10
  160. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/terminal-frames.mjs +43 -15
  161. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events.mjs +10 -0
  162. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-items.mjs +18 -7
  163. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-outcome.mjs +5 -2
  164. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-stamps.mjs +2 -2
  165. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-state.mjs +7 -3
  166. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/text-relay.mjs +9 -1
  167. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state.mjs +2 -2
  168. package/src/runtime/agent/orchestrator/providers/openai-http-sse-watchdogs.mjs +1 -3
  169. package/src/runtime/agent/orchestrator/providers/openai-model-capabilities.mjs +80 -0
  170. package/src/runtime/agent/orchestrator/providers/openai-oauth-dispatch.mjs +37 -4
  171. package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +12 -1
  172. package/src/runtime/agent/orchestrator/providers/openai-oauth-tokens.mjs +22 -2
  173. package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +12 -1
  174. package/src/runtime/agent/orchestrator/providers/openai-responses-input.mjs +76 -33
  175. package/src/runtime/agent/orchestrator/providers/openai-responses-payload-parity.fixture.json +323 -0
  176. package/src/runtime/agent/orchestrator/providers/openai-responses-payload.mjs +44 -16
  177. package/src/runtime/agent/orchestrator/providers/openai-retry-policy.mjs +9 -0
  178. package/src/runtime/agent/orchestrator/providers/openai-ws-delta.mjs +7 -16
  179. package/src/runtime/agent/orchestrator/providers/openai-ws-handshake.mjs +16 -8
  180. package/src/runtime/agent/orchestrator/providers/openai-ws-response-state/refusals.mjs +60 -0
  181. package/src/runtime/agent/orchestrator/providers/openai-ws-response-state/tool-calls.mjs +51 -35
  182. package/src/runtime/agent/orchestrator/providers/openai-ws-response-state.mjs +30 -0
  183. package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/attempt-context.mjs +1 -2
  184. package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/policy.mjs +25 -14
  185. package/src/runtime/agent/orchestrator/providers/openai-ws-stream/event-switch.mjs +12 -0
  186. package/src/runtime/agent/orchestrator/providers/openai-ws-stream/terminal-frames.mjs +25 -6
  187. package/src/runtime/agent/orchestrator/providers/openai-ws-terminal.mjs +18 -11
  188. package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +41 -22
  189. package/src/runtime/agent/orchestrator/providers/opencode-go-gemini.mjs +170 -0
  190. package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +75 -70
  191. package/src/runtime/agent/orchestrator/providers/openrouter.mjs +75 -0
  192. package/src/runtime/agent/orchestrator/providers/provider-error-kind.mjs +720 -0
  193. package/src/runtime/agent/orchestrator/providers/registry.mjs +4 -1
  194. package/src/runtime/agent/orchestrator/providers/retry-backoff.mjs +46 -7
  195. package/src/runtime/agent/orchestrator/providers/retry-classification.mjs +123 -219
  196. package/src/runtime/agent/orchestrator/providers/retry-classifier.mjs +2 -0
  197. package/src/runtime/agent/orchestrator/providers/retry-executor.mjs +148 -45
  198. package/src/runtime/agent/orchestrator/providers/retry-midstream.mjs +81 -16
  199. package/src/runtime/agent/orchestrator/providers/transport-scope.d.mts +6 -0
  200. package/src/runtime/agent/orchestrator/providers/transport-scope.mjs +28 -0
  201. package/src/runtime/agent/orchestrator/providers/wire-gateway.mjs +157 -0
  202. package/src/runtime/agent/orchestrator/providers/wire-route.mjs +512 -0
  203. package/src/runtime/agent/orchestrator/providers/xai-tool-search-head-parity.json +1131 -0
  204. package/src/runtime/agent/orchestrator/providers/xai-tool-search.fixtures.mjs +183 -0
  205. package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +100 -0
  206. package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +3 -0
  207. package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-availability.mjs +21 -0
  208. package/src/runtime/agent/orchestrator/runtime-core/effort.mjs +15 -0
  209. package/src/runtime/agent/orchestrator/runtime-core/goal-reminder.mjs +0 -18
  210. package/src/runtime/agent/orchestrator/runtime-core/model-capabilities.mjs +57 -28
  211. package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +19 -16
  212. package/src/runtime/agent/orchestrator/runtime-core/plugin-mcp.mjs +1 -97
  213. package/src/runtime/agent/orchestrator/runtime-core/provider-request-snapshot.mjs +7 -3
  214. package/src/runtime/agent/orchestrator/runtime-core/session-title.mjs +21 -1
  215. package/src/runtime/agent/orchestrator/runtime-core/skill-tool-loading.mjs +14 -3
  216. package/src/runtime/agent/orchestrator/runtime-core/tool-bridge.mjs +526 -0
  217. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-data.mjs +3 -0
  218. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-schema.mjs +10 -7
  219. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +176 -71
  220. package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +62 -10
  221. package/src/runtime/agent/orchestrator/runtime-core/tool-exposure.mjs +96 -0
  222. package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +5 -1
  223. package/src/runtime/agent/orchestrator/session/compact/constants.mjs +3 -2
  224. package/src/runtime/agent/orchestrator/session/compact/messages.mjs +14 -93
  225. package/src/runtime/agent/orchestrator/session/compact/summary-anchor.mjs +5 -0
  226. package/src/runtime/agent/orchestrator/session/compact/user-message-kind.mjs +120 -0
  227. package/src/runtime/agent/orchestrator/session/context-tool-schema.mjs +17 -2
  228. package/src/runtime/agent/orchestrator/session/context-utils.mjs +8 -4
  229. package/src/runtime/agent/orchestrator/session/eager-dispatch/admission.mjs +2 -1
  230. package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +6 -1
  231. package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +91 -1
  232. package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +1 -1
  233. package/src/runtime/agent/orchestrator/session/loop/context-overflow.mjs +56 -0
  234. package/src/runtime/agent/orchestrator/session/loop/deferred-call-through.mjs +18 -8
  235. package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +1 -0
  236. package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +21 -10
  237. package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +132 -0
  238. package/src/runtime/agent/orchestrator/session/loop/request-boundary.mjs +30 -0
  239. package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +67 -20
  240. package/src/runtime/agent/orchestrator/session/loop/step-auto-effort.mjs +104 -19
  241. package/src/runtime/agent/orchestrator/session/loop/tool-call-resolution.mjs +95 -0
  242. package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +30 -3
  243. package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +15 -4
  244. package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +15 -1
  245. package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +150 -0
  246. package/src/runtime/agent/orchestrator/session/loop/tool-phase.mjs +7 -2
  247. package/src/runtime/agent/orchestrator/session/manager/ask-queue.mjs +30 -2
  248. package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +11 -2
  249. package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +2 -1
  250. package/src/runtime/agent/orchestrator/session/manager/ask-turn-commit.mjs +34 -12
  251. package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +57 -21
  252. package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +57 -25
  253. package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +6 -0
  254. package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +4 -0
  255. package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +8 -0
  256. package/src/runtime/agent/orchestrator/session/manager/pending-message-entry.mjs +5 -10
  257. package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +208 -14
  258. package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +16 -4
  259. package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +25 -3
  260. package/src/runtime/agent/orchestrator/session/manager/session-fallback-title.mjs +82 -0
  261. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +19 -2
  262. package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +3 -0
  263. package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +4 -1
  264. package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +18 -7
  265. package/src/runtime/agent/orchestrator/session/manager.mjs +2 -1
  266. package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +6 -0
  267. package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +168 -29
  268. package/src/runtime/agent/orchestrator/session/side-question-store.mjs +96 -0
  269. package/src/runtime/agent/orchestrator/session/side-question.mjs +192 -0
  270. package/src/runtime/agent/orchestrator/session/store/lifecycle-barriers.mjs +17 -3
  271. package/src/runtime/agent/orchestrator/session/store/live-state.mjs +23 -0
  272. package/src/runtime/agent/orchestrator/session/store/paths-heartbeat.mjs +58 -2
  273. package/src/runtime/agent/orchestrator/session/store/save-worker.mjs +6 -3
  274. package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +41 -28
  275. package/src/runtime/agent/orchestrator/session/store/session-observers.mjs +4 -2
  276. package/src/runtime/agent/orchestrator/session/store/sweep/sweep-finish.mjs +12 -1
  277. package/src/runtime/agent/orchestrator/session/store/write-admission.mjs +3 -1
  278. package/src/runtime/agent/orchestrator/session/store/write-guards.mjs +16 -0
  279. package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +22 -10
  280. package/src/runtime/agent/orchestrator/session/store-summary-archived-agent.mjs +34 -15
  281. package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +6 -0
  282. package/src/runtime/agent/orchestrator/session/store-summary-fields.mjs +13 -0
  283. package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +13 -1
  284. package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +10 -2
  285. package/src/runtime/agent/orchestrator/session/store.mjs +19 -3
  286. package/src/runtime/agent/orchestrator/session/tool-batch/execute-call.mjs +1 -0
  287. package/src/runtime/agent/orchestrator/session/tool-batch/finalize.mjs +1 -1
  288. package/src/runtime/agent/orchestrator/session/tool-batch/record-outcome.mjs +1 -1
  289. package/src/runtime/agent/orchestrator/session/tool-batch/state.mjs +7 -1
  290. package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +4 -0
  291. package/src/runtime/agent/orchestrator/session/tool-schema-rejection.mjs +77 -0
  292. package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +20 -1
  293. package/src/runtime/agent/orchestrator/tools/bash-policy-scan.mjs +8 -2
  294. package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +2 -2
  295. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/command-preflight.mjs +3 -3
  296. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/deadline-plan.mjs +12 -15
  297. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +4 -1
  298. package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +5 -5
  299. package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.mjs +14 -10
  300. package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +49 -34
  301. package/src/runtime/agent/orchestrator/tools/builtin/runtime-capabilities.mjs +23 -1
  302. package/src/runtime/agent/orchestrator/tools/code-graph/dispatch/root-resolution.mjs +1 -1
  303. package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +1 -1
  304. package/src/runtime/agent/orchestrator/tools/patch/ui-diff.mjs +73 -39
  305. package/src/runtime/agent/orchestrator/tools/progress-message.mjs +18 -1
  306. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +7 -4
  307. package/src/runtime/agent/orchestrator/tools/shell-exec-policy.mjs +88 -12
  308. package/src/runtime/agent/orchestrator/tools/shell-policy.mjs +2 -0
  309. package/src/runtime/computer-bridge/action-schema.mjs +44 -21
  310. package/src/runtime/github/tool.mjs +92 -2
  311. package/src/runtime/memory/index.mjs +1 -0
  312. package/src/runtime/memory/lib/http-router/ingest-routes.mjs +22 -1
  313. package/src/runtime/memory/lib/ingest/transcript-offsets.mjs +2 -0
  314. package/src/runtime/memory/lib/pg/adapter.mjs +98 -1
  315. package/src/runtime/memory/lib/pg/process.mjs +65 -50
  316. package/src/runtime/memory/lib/pg/run-child.mjs +49 -0
  317. package/src/runtime/memory/lib/pg/supervisor.mjs +124 -16
  318. package/src/runtime/memory/lib/runtime-fetcher.mjs +12 -13
  319. package/src/runtime/memory/lib/transcript-ingest.mjs +14 -0
  320. package/src/runtime/office/README.md +2 -2
  321. package/src/runtime/office/authoring/html-document-author.mjs +2 -0
  322. package/src/runtime/office/authoring/pptx-contact-sheet.mjs +2 -0
  323. package/src/runtime/office/authoring/pptx-html-measure.mjs +2 -0
  324. package/src/runtime/office/authoring/pptx-html-runner.mjs +2 -0
  325. package/src/runtime/office/authoring/xlsx-html-runner.mjs +2 -0
  326. package/src/runtime/office/core/office-actions-read.mjs +3 -0
  327. package/src/runtime/office/core/office-render-preview.mjs +2 -0
  328. package/src/runtime/office/core/office-session-dispatch.mjs +7 -0
  329. package/src/runtime/office/core/office-sessionless-actions.mjs +8 -0
  330. package/src/runtime/office/core/office-sessions.mjs +5 -0
  331. package/src/runtime/office/core/office-transactions.mjs +3 -0
  332. package/src/runtime/office/core/office-write-ledger.mjs +98 -0
  333. package/src/runtime/office/design/library/templates/mixdog-executive.mixdog-edit.pptx +0 -0
  334. package/src/runtime/office/index.mjs +30 -0
  335. package/src/runtime/office/pdf/pdf-edit-document.mjs +2 -0
  336. package/src/runtime/office/pdf/pdf-render.mjs +23 -7
  337. package/src/runtime/office/pdf/pdf-security.mjs +2 -0
  338. package/src/runtime/office/portable/portable-opc.mjs +4 -1
  339. package/src/runtime/office/quality/visual-diff.mjs +2 -0
  340. package/src/runtime/office/shared/values.mjs +0 -5
  341. package/src/runtime/shared/background-tasks.mjs +92 -14
  342. package/src/runtime/shared/bounded-file-read.mjs +13 -0
  343. package/src/runtime/shared/bounded-line-diff.mjs +182 -0
  344. package/src/runtime/shared/buffered-appender.mjs +18 -0
  345. package/src/runtime/shared/config.mjs +78 -18
  346. package/src/runtime/shared/err-text.mjs +31 -0
  347. package/src/runtime/shared/error-presentation.mjs +159 -19
  348. package/src/runtime/shared/file-permissions.d.mts +6 -1
  349. package/src/runtime/shared/file-permissions.mjs +54 -6
  350. package/src/runtime/shared/llm/anthropic-betas.mjs +4 -3
  351. package/src/runtime/shared/llm/anthropic-effort.mjs +129 -134
  352. package/src/runtime/shared/llm/anthropic-thinking-contract.mjs +50 -14
  353. package/src/runtime/shared/llm/model-catalog.mjs +53 -40
  354. package/src/runtime/shared/llm/openai-daybreak.mjs +4 -16
  355. package/src/runtime/shared/llm/provider-catalog-registry.mjs +11 -0
  356. package/src/runtime/shared/llm/provider-model-identities.mjs +13 -4
  357. package/src/runtime/shared/llm/usage-accounting.mjs +5 -2
  358. package/src/runtime/shared/llm/usage-ledger-rollup.mjs +3 -0
  359. package/src/runtime/shared/llm/usage-rollup.mjs +0 -1
  360. package/src/runtime/shared/loopback-listener.mjs +9 -0
  361. package/src/runtime/shared/model-display.mjs +13 -0
  362. package/src/runtime/shared/provider-api-key.mjs +2 -0
  363. package/src/runtime/shared/quota-resume-store.mjs +11 -0
  364. package/src/runtime/shared/review-diff.mjs +52 -0
  365. package/src/runtime/shared/session-baseline-store.mjs +960 -0
  366. package/src/runtime/shared/session-sidebar-host.d.mts +4 -0
  367. package/src/runtime/shared/session-sidebar-host.mjs +38 -0
  368. package/src/runtime/shared/slow-span.mjs +114 -0
  369. package/src/runtime/shared/statusline/statusline-format.mjs +4 -4
  370. package/src/runtime/shared/statusline/statusline-segments.mjs +28 -4
  371. package/src/runtime/shared/task-notification-envelope.mjs +2 -2
  372. package/src/runtime/shared/tool-card-model/card-header.mjs +6 -1
  373. package/src/runtime/shared/tool-card-model/generic-detail.mjs +39 -5
  374. package/src/runtime/shared/tool-card-model.mjs +5 -2
  375. package/src/runtime/shared/tool-output-limit.mjs +4 -0
  376. package/src/runtime/shared/tool-primitives.mjs +13 -0
  377. package/src/runtime/shared/tool-result-summary.mjs +8 -1
  378. package/src/runtime/shared/tool-surface.mjs +18 -3
  379. package/src/runtime/shared/tool-work-units.mjs +40 -4
  380. package/src/runtime/shared/transcript-writer/purge.mjs +74 -0
  381. package/src/runtime/shared/transcript-writer.mjs +10 -2
  382. package/src/runtime/shared/turn-changes.mjs +670 -274
  383. package/src/runtime/shared/turn-review-reply.mjs +8 -39
  384. package/src/runtime/shared/turn-snapshot-store.mjs +94 -2
  385. package/src/runtime/shared/turn-snapshot.mjs +986 -690
  386. package/src/runtime/shared/turn-worktree-snapshot.mjs +279 -262
  387. package/src/runtime/shared/user-data-guard.mjs +262 -49
  388. package/src/runtime/shared/worktrees/carry.mjs +531 -0
  389. package/src/runtime/shared/worktrees/contract.mjs +34 -24
  390. package/src/runtime/shared/worktrees/file-recovery.mjs +68 -0
  391. package/src/runtime/shared/worktrees/git-head.mjs +205 -0
  392. package/src/runtime/shared/worktrees/git.mjs +8 -3
  393. package/src/runtime/shared/worktrees/maintenance.mjs +1 -1
  394. package/src/runtime/shared/worktrees/manager.mjs +156 -8
  395. package/src/runtime/shared/worktrees/merge.mjs +31 -21
  396. package/src/runtime/shared/worktrees/paths.d.mts +6 -0
  397. package/src/runtime/shared/worktrees/test-support.mjs +19 -4
  398. package/src/runtime/terminal-bridge/client.mjs +44 -11
  399. package/src/runtime/terminal-bridge/tool-defs.mjs +13 -6
  400. package/src/runtime/tidy/apply.mjs +47 -2
  401. package/src/runtime/tidy/run-engines.mjs +11 -5
  402. package/src/session-runtime/agent-tool-routing.mjs +19 -13
  403. package/src/session-runtime/boot/apis.mjs +19 -5
  404. package/src/session-runtime/boot/facade.mjs +1 -0
  405. package/src/session-runtime/boot/infrastructure.mjs +12 -1
  406. package/src/session-runtime/boot/session.mjs +0 -1
  407. package/src/session-runtime/boot/tools.mjs +4 -1
  408. package/src/session-runtime/cwd-plugins/cwd-apply.mjs +12 -5
  409. package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +65 -0
  410. package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +3 -1
  411. package/src/session-runtime/internal-tool-executor/knowledge-tools.mjs +11 -4
  412. package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +115 -18
  413. package/src/session-runtime/internal-tool-executor.mjs +6 -2
  414. package/src/session-runtime/lifecycle/cold-heir.mjs +188 -0
  415. package/src/session-runtime/lifecycle/inheritance.mjs +71 -27
  416. package/src/session-runtime/lifecycle/session-catalog.mjs +14 -3
  417. package/src/session-runtime/lifecycle/session-switch/resume.mjs +6 -0
  418. package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +29 -6
  419. package/src/session-runtime/lifecycle/teardown.mjs +73 -8
  420. package/src/session-runtime/lifecycle-api.mjs +1 -0
  421. package/src/session-runtime/mcp-glue/connect.mjs +46 -14
  422. package/src/session-runtime/mcp-glue/server-catalog.mjs +20 -3
  423. package/src/session-runtime/mcp-glue.mjs +3 -0
  424. package/src/session-runtime/mcp-oauth-login.mjs +174 -0
  425. package/src/session-runtime/model-route/model-switch-target.mjs +34 -0
  426. package/src/session-runtime/model-route/set-route.mjs +85 -17
  427. package/src/session-runtime/model-route/web-search-route.mjs +1 -1
  428. package/src/session-runtime/native-web-search/routes.mjs +22 -3
  429. package/src/session-runtime/native-web-search-usage.mjs +51 -0
  430. package/src/session-runtime/native-web-search.mjs +10 -1
  431. package/src/session-runtime/new-session-config.mjs +4 -2
  432. package/src/session-runtime/provider-auth/login.mjs +4 -0
  433. package/src/session-runtime/provider-models/model-meta.mjs +12 -3
  434. package/src/session-runtime/quick-model-rows/web-search-rows.mjs +13 -8
  435. package/src/session-runtime/quick-web-search-models.mjs +13 -38
  436. package/src/session-runtime/resource-extension-sync.mjs +4 -0
  437. package/src/session-runtime/resource-mcp-api.mjs +98 -2
  438. package/src/session-runtime/resource-scope-decorate.mjs +10 -3
  439. package/src/session-runtime/runtime-review-api.mjs +21 -2
  440. package/src/session-runtime/services/agent-tool/index-write-queue.mjs +81 -20
  441. package/src/session-runtime/services/agent-tool/job-task-reconcile.mjs +13 -1
  442. package/src/session-runtime/services/agent-tool/job-views/agent-list.mjs +7 -2
  443. package/src/session-runtime/services/agent-tool/lead-worker-index/forgotten-leads.mjs +29 -0
  444. package/src/session-runtime/services/agent-tool/lead-worker-index/index-file.mjs +1 -1
  445. package/src/session-runtime/services/agent-tool/lead-worker-index.mjs +73 -7
  446. package/src/session-runtime/services/agent-tool/send-flow.mjs +22 -4
  447. package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +2 -0
  448. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +22 -5
  449. package/src/session-runtime/services/agent-tool/tag-registry.mjs +15 -1
  450. package/src/session-runtime/services/agent-tool/worker-index/row-liveness.mjs +8 -1
  451. package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +2 -2
  452. package/src/session-runtime/services/agent-tool/worker-index/row-store.mjs +10 -1
  453. package/src/session-runtime/services/agent-tool/worker-index.mjs +46 -7
  454. package/src/session-runtime/services/agent-tool/worker-rows.mjs +17 -0
  455. package/src/session-runtime/services/agent-tool.mjs +3 -0
  456. package/src/session-runtime/services/channel-admin.mjs +19 -3
  457. package/src/session-runtime/services/memory-runtime-proxy/calls.mjs +4 -0
  458. package/src/session-runtime/services/memory-runtime-proxy.mjs +1 -0
  459. package/src/session-runtime/services/provider-admin.mjs +81 -15
  460. package/src/session-runtime/session-transcript-purge.mjs +32 -0
  461. package/src/session-runtime/session-turn-api.mjs +14 -5
  462. package/src/session-runtime/settings-builtin-tools-api.mjs +9 -0
  463. package/src/session-runtime/settings-compaction-api.mjs +1 -0
  464. package/src/session-runtime/setup-tool/executor.mjs +36 -6
  465. package/src/session-runtime/setup-tool/extended-actions.mjs +86 -6
  466. package/src/session-runtime/setup-tool/settings-contract.mjs +13 -3
  467. package/src/session-runtime/setup-tool/tool-defs.mjs +13 -4
  468. package/src/session-runtime/skills-api.mjs +3 -5
  469. package/src/session-runtime/tool-surface.mjs +5 -1
  470. package/src/session-runtime/turn/compaction-gate.mjs +25 -0
  471. package/src/session-runtime/turn/session-ops.mjs +7 -5
  472. package/src/session-runtime/turn/side-question-ops.mjs +22 -0
  473. package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +5 -1
  474. package/src/session-runtime/turn/turn-run/turn-prepare.mjs +8 -3
  475. package/src/session-runtime/turn/turn-run/turn-settle.mjs +10 -0
  476. package/src/session-runtime/turn/turn-run/turn-timing.mjs +4 -3
  477. package/src/session-runtime/turn/turn-run.mjs +25 -9
  478. package/src/session-runtime/usage-stats-api.mjs +43 -11
  479. package/src/session-runtime/workspace/project-branches.mjs +7 -5
  480. package/src/session-runtime/workspace/transition-steps.mjs +129 -31
  481. package/src/session-runtime/workspace/transitions.mjs +190 -15
  482. package/src/standalone/daemon-agent-control.mjs +9 -1
  483. package/src/standalone/daemon-drain-policy.mjs +8 -0
  484. package/src/standalone/daemon-local-session-bridge.mjs +14 -1
  485. package/src/standalone/daemon-owner.mjs +17 -4
  486. package/src/standalone/daemon-pg-stop.mjs +51 -0
  487. package/src/standalone/daemon-stop-budget.d.mts +2 -0
  488. package/src/standalone/daemon-stop-budget.mjs +18 -0
  489. package/src/standalone/daemon-stored-session-views.mjs +2 -0
  490. package/src/standalone/daemon-telemetry.mjs +74 -0
  491. package/src/standalone/daemon.mjs +64 -8
  492. package/src/standalone/desktop-service-registry.mjs +5 -0
  493. package/src/standalone/local-session-runtime.mjs +70 -19
  494. package/src/standalone/session-client.mjs +42 -0
  495. package/src/standalone/session-protocol.mjs +14 -0
  496. package/src/standalone/session-proxy/projection.mjs +41 -4
  497. package/src/standalone/session-runtime-inline-host/boot-loaders.mjs +15 -1
  498. package/src/standalone/session-runtime-inline-host.mjs +1 -0
  499. package/src/standalone/session-service/agent-tree/agent-cancel.mjs +33 -2
  500. package/src/standalone/session-service/agent-tree/agent-turns.mjs +26 -10
  501. package/src/standalone/session-service/agent-tree.mjs +12 -0
  502. package/src/standalone/session-service/quota-resume.mjs +8 -0
  503. package/src/standalone/session-service/retention/busy.mjs +15 -1
  504. package/src/standalone/session-service/session-calls/session-action.mjs +18 -3
  505. package/src/standalone/session-service-api.mjs +11 -1
  506. package/src/standalone/session-service.mjs +1 -0
  507. package/src/standalone/session-state-patch.d.mts +2 -1
  508. package/src/standalone/session-state-patch.mjs +41 -1
  509. package/src/tui/App.jsx +25 -0
  510. package/src/tui/app/app-view/floating-panel.jsx +26 -1
  511. package/src/tui/app/app-view.jsx +1 -0
  512. package/src/tui/app/btw-controller.mjs +118 -0
  513. package/src/tui/app/create-app-pickers.mjs +6 -0
  514. package/src/tui/app/extension-pickers/mcp-login.mjs +107 -0
  515. package/src/tui/app/extension-pickers/mcp-servers-picker.mjs +2 -1
  516. package/src/tui/app/extension-pickers.mjs +2 -1
  517. package/src/tui/app/model-options.mjs +11 -16
  518. package/src/tui/app/shell-layout/row-budgets.mjs +11 -1
  519. package/src/tui/app/shell-layout/surfaces.mjs +3 -1
  520. package/src/tui/app/slash-commands.mjs +20 -5
  521. package/src/tui/app/slash-dispatch/panel-commands.mjs +16 -1
  522. package/src/tui/app/slash-dispatch/session-commands.mjs +19 -6
  523. package/src/tui/app/use-global-key-input/approval-shortcut.mjs +12 -0
  524. package/src/tui/app/use-global-key-input.mjs +5 -12
  525. package/src/tui/app/use-prompt-handlers.mjs +11 -0
  526. package/src/tui/components/BtwPanel.jsx +53 -0
  527. package/src/tui/components/QuestionPanel.jsx +275 -0
  528. package/src/tui/components/StatusLine.jsx +2 -0
  529. package/src/tui/components/question-panel-model.mjs +156 -0
  530. package/src/tui/components/status-line/local-line.mjs +5 -2
  531. package/src/tui/components/status-line/use-statusline-text.mjs +7 -1
  532. package/src/tui/dist/index.mjs +3221 -1500
  533. package/src/tui/session/context-state.mjs +4 -2
  534. package/src/tui/session/quota-resume.mjs +46 -14
  535. package/src/tui/session/session-api/commands.mjs +43 -24
  536. package/src/tui/session/session-api/controls.mjs +2 -2
  537. package/src/tui/session/session-api/extensions.mjs +22 -0
  538. package/src/tui/session/session-api/integrations.mjs +16 -2
  539. package/src/tui/session/session-api/lifecycle/dispose.mjs +1 -0
  540. package/src/tui/session/session-api/lifecycle.mjs +7 -2
  541. package/src/tui/session/session-api/routes.mjs +71 -7
  542. package/src/tui/session/session-api/settings.mjs +11 -14
  543. package/src/tui/session/session-api.mjs +1 -0
  544. package/src/tui/session/session-flow/drain.mjs +7 -1
  545. package/src/tui/session/session-flow/failed-turn-rewind.mjs +10 -4
  546. package/src/tui/session/tool-approval.mjs +10 -7
  547. package/src/tui/session/transcript-spill.mjs +14 -7
  548. package/src/tui/session/turn-stream.mjs +174 -31
  549. package/src/tui/session/turn.mjs +46 -16
  550. package/src/tui/statusline-ansi-bridge.mjs +1 -1
  551. package/src/ui/statusline-agents.mjs +15 -4
  552. package/src/ui/statusline.mjs +7 -3
  553. package/src/ui/streaming-markdown-heal.mjs +34 -3
  554. package/src/vendor/statusline/src/gateway/claude-current.mjs +14 -4
  555. package/src/workflows/default/WORKFLOW.md +3 -1
  556. package/src/runtime/memory/lib/memory-session-merge.mjs +0 -32
  557. package/src/runtime/shared/llm/usage-session-history.mjs +0 -266
@@ -1,6 +1,11 @@
1
1
  import { reloadProviderApiKey, resolveProviderApiKey } from '../../../shared/provider-api-key.mjs';
2
2
  import { sanitizeToolPairs } from '../session/context-utils.mjs';
3
3
  import { AnthropicFallbackTriggeredError } from './retry-classifier.mjs';
4
+ import {
5
+ announceAnthropicModelFallback,
6
+ createAnthropicOverloadTracker,
7
+ isTerminalOverloadModel,
8
+ } from './anthropic-overload-fallback.mjs';
4
9
  import { readStreamOutcome } from './lib/stream-outcome.mjs';
5
10
  import { createPassthroughSignal } from '../stall-policy.mjs';
6
11
  import { createAbortController } from '../../../shared/abort-controller.mjs';
@@ -78,6 +83,11 @@ export class AnthropicProvider {
78
83
  maxRetries: 0,
79
84
  });
80
85
  }
86
+ // The model id capability lookups (output cap, thinking/effort shape) read;
87
+ // a gateway engine maps its routing slug to the Claude id it stands for.
88
+ _capabilityModel(model) {
89
+ return model;
90
+ }
81
91
  reloadApiKey() {
82
92
  try {
83
93
  const newKey = reloadProviderApiKey(this.name, this.config);
@@ -144,6 +154,7 @@ export class AnthropicProvider {
144
154
  fastModeLatched: this.fastModeBetaHeaderLatched,
145
155
  // Custom providers carry per-model reasoning settings on their own rows.
146
156
  modelInfo: isCustomProviderName(this.name) ? this.getCachedModelInfo?.(useModel) || null : null,
157
+ capabilityModel: this._capabilityModel(useModel),
147
158
  });
148
159
  this.fastModeBetaHeaderLatched = fastModeLatched;
149
160
 
@@ -166,6 +177,13 @@ export class AnthropicProvider {
166
177
  } catch {}
167
178
  };
168
179
 
180
+ // Request-loop 529s and SSE overload events share one counter; at the
181
+ // limit the configured fallback model takes over the whole send.
182
+ const overload = createAnthropicOverloadTracker({
183
+ model: useModel,
184
+ fallbackModel: opts._fallbackTriggered ? undefined : opts.fallbackModel,
185
+ terminalAtLimit: !isCustomProviderName(this.name) && isTerminalOverloadModel(useModel),
186
+ });
169
187
  // The SDK calls and their initial-response retry policy
170
188
  // (anthropic-api-transport.mjs).
171
189
  const transport = createAnthropicApiTransport({
@@ -176,6 +194,7 @@ export class AnthropicProvider {
176
194
  params,
177
195
  requestHeaders,
178
196
  totalSignal,
197
+ overload,
179
198
  });
180
199
  // Usage accounting + caller-visible projection, shared by the streaming
181
200
  // success path and the non-streaming fallback (anthropic-turn-result.mjs).
@@ -213,8 +232,10 @@ export class AnthropicProvider {
213
232
  recovery,
214
233
  onStageChange,
215
234
  retry529: opts.retry529 !== false,
235
+ overload,
216
236
  });
217
237
 
238
+ let streamingFallbackTried = false;
218
239
  try {
219
240
  for (let attemptIndex = 0; attemptIndex <= ANTHROPIC_MAX_MIDSTREAM_RETRIES; attemptIndex++) {
220
241
  const streamController = createAbortController();
@@ -274,13 +295,13 @@ export class AnthropicProvider {
274
295
 
275
296
  return buildTurnResult(parseResult);
276
297
  } catch (err) {
277
- if (err instanceof AnthropicFallbackTriggeredError) {
278
- process.stderr.write(`[${this.name}] ${err.message}\n`);
279
- return this._doSend(messages, err.fallbackModel, tools, {
280
- ...opts,
281
- fallbackModel: undefined,
282
- _fallbackTriggered: true,
283
- });
298
+ // The fallback trigger is handled around the whole send below.
299
+ if (err instanceof AnthropicFallbackTriggeredError) throw err;
300
+ // Gateways that 404 the streaming endpoint but serve non-streaming:
301
+ // one non-streaming replay (nothing was streamed yet).
302
+ if (err?.initialResponseError === true && Number(err.status) === 404 && !streamingFallbackTried) {
303
+ streamingFallbackTried = true;
304
+ return await recovery.issueNonStreamingFallback(streamController, err);
284
305
  }
285
306
  // Ordered recovery ladder: canonical outcome stamp, acknowledged
286
307
  // non-streaming replay for exposed output, bounded streaming
@@ -300,6 +321,18 @@ export class AnthropicProvider {
300
321
  }
301
322
  }
302
323
  throw midstream.exhaustedError();
324
+ } catch (err) {
325
+ // The fallback trigger can surface from the request loop, a mid-stream
326
+ // overload, or the non-streaming recovery: handle it around the whole
327
+ // operation, not just the first request.
328
+ if (!(err instanceof AnthropicFallbackTriggeredError)) throw err;
329
+ process.stderr.write(`[${this.name}] ${err.message}\n`);
330
+ announceAnthropicModelFallback(onStageChange, useModel, err.fallbackModel);
331
+ return await this._doSend(messages, err.fallbackModel, tools, {
332
+ ...opts,
333
+ fallbackModel: undefined,
334
+ _fallbackTriggered: true,
335
+ });
303
336
  } finally {
304
337
  totalTimeout.cleanup();
305
338
  }
@@ -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,14 +2,25 @@ 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
  }
12
17
 
18
+ // Claude declarations are validated for the gateway's Anthropic bridge in
19
+ // toGeminiTools (claudeBridge: true); a tool with an invalid schema is left
20
+ // out of the request and reported through `onToolExcluded` / console.warn.
21
+ const claudeRequestTools = (tools, nativeTools, onToolExcluded) =>
22
+ toGeminiRequestTools(tools, nativeTools, { claudeBridge: true, onToolExcluded });
23
+
13
24
  // Default function-calling mode when the caller sets no toolChoice. VALIDATED
14
25
  // (schema-constrained function calls) is what the Antigravity client sends;
15
26
  // MIXDOG_ANTIGRAVITY_FC_MODE=AUTO|ANY|VALIDATED overrides it for A/B runs.
@@ -30,14 +41,52 @@ function replayFamilyMatches(message, model) {
30
41
  return isAntigravityClaude(recorded) === isAntigravityClaude(model);
31
42
  }
32
43
 
44
+ // The stream records empty text parts around Claude tool calls; Cloud Code's
45
+ // Claude bridge rejects them on replay ("text.text: Field required").
46
+ const isEmptyPlainTextPart = (part) =>
47
+ part?.text === '' && part.thought !== true && typeof part.thoughtSignature !== 'string';
48
+
49
+ // Streamed Claude thinking arrives as many thought deltas with the signature
50
+ // on the closing (often empty) delta; the bridge turns every part into its own
51
+ // thinking block and rejects the unsigned ones ("thinking.signature: Field
52
+ // required"). Rejoin each run into one block that ends at its signature.
53
+ function coalesceClaudeThoughts(parts) {
54
+ const out = [];
55
+ let open = null;
56
+ for (const part of parts) {
57
+ if (part?.thought !== true) {
58
+ if (open) out.push(open);
59
+ open = null;
60
+ out.push(part);
61
+ continue;
62
+ }
63
+ open = open
64
+ ? { ...open, ...part, text: `${open.text}${typeof part.text === 'string' ? part.text : ''}` }
65
+ : { ...part, text: typeof part.text === 'string' ? part.text : '' };
66
+ if (typeof part.thoughtSignature === 'string') {
67
+ out.push(open);
68
+ open = null;
69
+ }
70
+ }
71
+ if (open) out.push(open);
72
+ return out;
73
+ }
74
+
33
75
  function signatureSafeMessages(messages, model) {
34
- return messages.map((message) => {
35
- if (message?.role !== 'assistant') return message;
76
+ const claude = isAntigravityClaude(model);
77
+ return messages.flatMap((message) => {
78
+ if (message?.role !== 'assistant') return [message];
36
79
  const ownParts = replayFamilyMatches(message, model) ? providerReplayItems(message, 'antigravity') : undefined;
37
80
  // Repair tool signatures only after the complete history establishes
38
81
  // the active turn, not while normalizing an isolated older message.
39
- const parts = ownParts || toGeminiContents([message], model, { repairToolSignatures: false })[0]?.parts;
40
- if (!parts?.length) return message;
82
+ const sourceParts = ownParts || toGeminiContents([message], model, { repairToolSignatures: false })[0]?.parts;
83
+ const parts =
84
+ claude && sourceParts
85
+ ? coalesceClaudeThoughts(sourceParts.filter((part) => !isEmptyPlainTextPart(part)))
86
+ : sourceParts;
87
+ // A turn that held only empty parts is omitted, not sent as parts:[].
88
+ if (sourceParts?.length && !parts.length) return [];
89
+ if (!parts?.length) return [message];
41
90
  for (const part of parts) {
42
91
  if (!part || typeof part !== 'object') continue;
43
92
  if (part.thought === true || typeof part.thoughtSignature === 'string') {
@@ -47,7 +96,7 @@ function signatureSafeMessages(messages, model) {
47
96
  if (!ownParts || !part.thoughtSignature) part.thoughtSignature = THOUGHT_SIGNATURE_SENTINEL;
48
97
  }
49
98
  }
50
- return { ...message, providerReplay: createProviderReplay('antigravity', parts) };
99
+ return [{ ...message, providerReplay: createProviderReplay('antigravity', parts) }];
51
100
  });
52
101
  }
53
102
 
@@ -59,33 +108,44 @@ function sessionId(contents) {
59
108
  return `-${digest.readBigUInt64BE(0) % 9223372036854775807n}`;
60
109
  }
61
110
 
111
+ // The gateway validates Claude's level against Google's ThinkingLevel enum,
112
+ // whose highest value is `high`; anything it does not name is left out.
113
+ const CLAUDE_GATEWAY_LEVELS = new Set(['low', 'medium', 'high']);
114
+ function claudeGatewayLevel(value) {
115
+ const level = String(value ?? '').toLowerCase();
116
+ if (level === 'xhigh' || level === 'max' || level === 'ultra') return 'high';
117
+ return CLAUDE_GATEWAY_LEVELS.has(level) ? level : null;
118
+ }
119
+
120
+ // An explicit token budget is sent as-is; otherwise the chosen effort rides
121
+ // on thinkingLevel with the wire id unchanged.
62
122
  function claudeThinkingConfig(opts) {
63
123
  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
124
  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;
125
+ if (budget == null) {
126
+ const level = claudeGatewayLevel(opts.thinkingLevel ?? opts.effort);
127
+ if (level) thinkingConfig.thinkingLevel = level;
128
+ return thinkingConfig;
129
+ }
130
+ const value = Number(budget);
131
+ if (!Number.isInteger(value) || value < 1024 || value >= CLAUDE_MAX_OUTPUT_TOKENS) {
132
+ throw new TypeError('Antigravity Claude thinkingBudget must be an integer from 1024 to 63999.');
76
133
  }
134
+ thinkingConfig.thinkingBudget = value;
77
135
  return thinkingConfig;
78
136
  }
79
137
 
80
138
  // Tiered wire ids (gemini-3.8-flash-high) already encode the thinking
81
139
  // level; the provider resolves them from the catalog and clears the
82
140
  // effort, so only bare ids reach this field.
83
- // Thought summaries on by default for every Gemini family, matching the
141
+ // Thought summaries on by default for every Gemini-family model, matching the
84
142
  // API-key provider. The gateway also serves GPT-OSS, which rejects the
85
- // thinking fields outright, so the flag stays Gemini-only.
143
+ // thinking fields outright and which the roster's thinking flag does not
144
+ // separate from Gemini, so the flag stays Gemini-only.
86
145
  function antigravityGeminiThinkingConfig(model, opts) {
87
146
  return geminiThinkingConfig(model, opts, {
88
- includeThoughts: /^gemini-/i.test(model) ? true : undefined,
147
+ provider: 'antigravity-oauth',
148
+ includeThoughts: isGeminiFamilyModel(model) ? true : undefined,
89
149
  });
90
150
  }
91
151
 
@@ -105,9 +165,16 @@ export function buildAntigravityRequest(messages, model, tools, opts = {}, proje
105
165
  };
106
166
  const request = { contents };
107
167
  if (systemText) request.systemInstruction = { role: 'user', parts: [{ text: systemText }] };
108
- const requestTools = toGeminiRequestTools(tools, opts.nativeTools);
168
+ const requestTools = claude
169
+ ? claudeRequestTools(tools, opts.nativeTools, opts.onToolExcluded)
170
+ : toGeminiRequestTools(tools, opts.nativeTools, {
171
+ onToolExcluded: opts.onToolExcluded,
172
+ // Other families (GPT-OSS) keep the plain conversion.
173
+ validate: isGeminiFamilyModel(model),
174
+ });
109
175
  if (requestTools.length) request.tools = requestTools;
110
- if (tools?.length) {
176
+ // Tool config only accompanies function declarations that were kept.
177
+ if (requestTools.some((entry) => entry.functionDeclarations?.length)) {
111
178
  request.toolConfig = toGeminiToolConfig(opts.toolChoice) || {
112
179
  functionCallingConfig: { mode: antigravityFunctionCallingMode() },
113
180
  };
@@ -8,12 +8,20 @@
8
8
  */
9
9
  import { traceAgentUsage } from '../agent-trace.mjs';
10
10
  import { createProviderReplay } from './lib/provider-replay.mjs';
11
- import { parseToolCalls, collectGeminiGroundingSources, parseGeminiTextPartMetadata } from './gemini-schema.mjs';
11
+ import {
12
+ parseToolCalls,
13
+ emitGeminiToolCalls,
14
+ collectGeminiGroundingSources,
15
+ parseGeminiTextPartMetadata,
16
+ } from './gemini-schema.mjs';
17
+ import { geminiFinishErrorFields, geminiPolicyFinishCode } from './gemini-error-contract.mjs';
12
18
 
13
19
  // Pure usageMetadata normalization shared by the success path and a failed
14
20
  // stream's partialUsage.
15
21
  export function normalizeAntigravityUsage(um) {
16
- const inputTokens = um.promptTokenCount || um.prompt_token_count || 0;
22
+ const inputTokens =
23
+ (um.promptTokenCount || um.prompt_token_count || 0) +
24
+ (um.toolUsePromptTokenCount || um.tool_use_prompt_token_count || 0);
17
25
  const cachedTokens = um.cachedContentTokenCount || um.cached_content_token_count || 0;
18
26
  const outputTokens =
19
27
  (um.candidatesTokenCount || um.candidates_token_count || 0) +
@@ -27,7 +35,7 @@ export function normalizeAntigravityUsage(um) {
27
35
  * @param {ReturnType<import('./antigravity-stream.mjs').createAntigravityStreamCollector>} deps.collector
28
36
  * @param {string} deps.useModel wire model id
29
37
  * @param {object} deps.opts send options (session/iteration/providerState)
30
- * @param {Function|null} deps.onToolCall set when calls were streamed live
38
+ * @param {Function|null} deps.onToolCall receives the turn's calls after a clean finish
31
39
  */
32
40
  export function finalizeAntigravityTurn({ response, collector, useModel, opts, onToolCall }) {
33
41
  const textLeakGuard = collector.leakGuard;
@@ -45,10 +53,8 @@ export function finalizeAntigravityTurn({ response, collector, useModel, opts, o
45
53
  // Thought signatures are only valid for the model family that minted
46
54
  // them; the request builder consults this when the route changes.
47
55
  if (providerReplay) providerReplay.requestContext = { model: useModel };
48
- let nativeToolCalls;
49
- if (!onToolCall) nativeToolCalls = parseToolCalls(responseParts);
50
- else if (collector.streamedNativeToolCalls.length) nativeToolCalls = collector.streamedNativeToolCalls;
51
- if (!onToolCall && textLeakGuard?.enabled) nativeToolCalls = textLeakGuard.filterNativeToolCalls(nativeToolCalls);
56
+ let nativeToolCalls = parseToolCalls(responseParts);
57
+ if (textLeakGuard?.enabled) nativeToolCalls = textLeakGuard.filterNativeToolCalls(nativeToolCalls);
52
58
  let toolCalls = nativeToolCalls;
53
59
  if (leakedToolCalls.length) {
54
60
  toolCalls = toolCalls?.length ? [...toolCalls, ...leakedToolCalls] : leakedToolCalls;
@@ -79,10 +85,20 @@ export function finalizeAntigravityTurn({ response, collector, useModel, opts, o
79
85
  });
80
86
  }
81
87
 
82
- if (finishReason && normalizedFinish !== 'STOP') {
88
+ // A MAX_TOKENS cut that still delivered whole native functionCall parts is
89
+ // a tool-use turn: the calls arrived intact, only trailing output was cut.
90
+ // Every other non-STOP finish fails the turn, and so does a cut whose text
91
+ // also leaked a call (that call may be as truncated as the text around it).
92
+ const completeNativeCalls =
93
+ normalizedFinish === 'MAX_TOKENS' &&
94
+ String(candidate?.finishReason || '').replace(/^FINISH_REASON_/, '') === 'MAX_TOKENS' &&
95
+ !leakedToolCalls.length &&
96
+ !!nativeToolCalls?.length &&
97
+ nativeToolCalls.every((call) => typeof call?.name === 'string' && call.name !== '');
98
+ if (finishReason && normalizedFinish !== 'STOP' && !completeNativeCalls) {
83
99
  throw Object.assign(new Error(`Antigravity response incomplete: finishReason=${finishReason}`), {
84
100
  name: 'ProviderIncompleteError',
85
- code: 'PROVIDER_INCOMPLETE',
101
+ code: geminiPolicyFinishCode(finishReason) || 'PROVIDER_INCOMPLETE',
86
102
  providerIncomplete: true,
87
103
  finishReason,
88
104
  partialContent: content,
@@ -92,10 +108,14 @@ export function finalizeAntigravityTurn({ response, collector, useModel, opts, o
92
108
  model: useModel,
93
109
  rawUsage: response.usageMetadata || null,
94
110
  ...(usage ? { partialUsage: usage, partialModel: useModel } : {}),
95
- ...(collector.emittedToolCount ? { emittedToolCall: true, unsafeToRetry: true } : {}),
111
+ ...geminiFinishErrorFields(response),
96
112
  });
97
113
  }
98
114
 
115
+ // Terminal status first: a failed turn never runs its tool calls.
116
+ textLeakGuard?.releaseDeferredToolCalls();
117
+ emitGeminiToolCalls(nativeToolCalls, onToolCall);
118
+
99
119
  return {
100
120
  content,
101
121
  model: useModel,
@@ -0,0 +1,106 @@
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, waiting at least the server's RetryInfo delay; advice that
8
+ * would push total waiting past 60s surfaces the error (with resetAt).
9
+ * Endpoint: the reference falls back to its next endpoint after a failure;
10
+ * generation here deliberately stays on the single daily host and never
11
+ * walks an endpoint list (a spent ladder surfaces to the account layer).
12
+ * RPM / unknown 429: ONE quick retry after 1s (or the server's advice, up to
13
+ * 60s), then the failure surfaces so the account layer can lock and
14
+ * rotate; advice beyond 60s surfaces at once.
15
+ * QUOTA_EXHAUSTED (and any day/plan window): never retried here.
16
+ *
17
+ * Replay stays gated by the stream-outcome contract: an attempt that exposed
18
+ * text or dispatched a tool is never re-issued.
19
+ */
20
+ import { readStreamOutcome } from './lib/stream-outcome.mjs';
21
+ import { DETERMINISTIC_KINDS, providerErrorKind } from './provider-error-kind.mjs';
22
+
23
+ export const ANTIGRAVITY_CAPACITY_RETRIES = 3;
24
+ export const ANTIGRAVITY_CAPACITY_BASE_MS = 1000;
25
+ export const ANTIGRAVITY_CAPACITY_MAX_MS = 8000;
26
+ export const ANTIGRAVITY_CAPACITY_JITTER_RATIO = 0.1;
27
+ // Total time capacity retries may spend waiting on server-advised delays.
28
+ export const ANTIGRAVITY_CAPACITY_BUDGET_MS = 60_000;
29
+ export const ANTIGRAVITY_QUICK_RETRY_MS = 1000;
30
+ export const ANTIGRAVITY_QUICK_RETRY_MAX_ADVICE_MS = 60_000;
31
+
32
+ // withRetry options for everything that is not a 429: transient transport and
33
+ // 5xx failures use the capacity schedule (the reference has no other same-host
34
+ // retry; the leading duplicate is the sleep-before-attempt index).
35
+ export const ANTIGRAVITY_RETRY = Object.freeze({
36
+ maxAttempts: ANTIGRAVITY_CAPACITY_RETRIES + 1,
37
+ backoffMs: Object.freeze([1000, 1000, 2000, 4000]),
38
+ retryJitterRatio: ANTIGRAVITY_CAPACITY_JITTER_RATIO,
39
+ // 429s are handled by antigravity429WaitMs, not the generic loop.
40
+ retry429: false,
41
+ });
42
+
43
+ /** Capacity wait for retry number `retryIndex` (0-based): 1s, 2s, 4s, 8s cap, ±10%. */
44
+ export function antigravityCapacityDelayMs(retryIndex) {
45
+ const base = Math.min(ANTIGRAVITY_CAPACITY_BASE_MS * 2 ** retryIndex, ANTIGRAVITY_CAPACITY_MAX_MS);
46
+ return Math.round(base * (1 - ANTIGRAVITY_CAPACITY_JITTER_RATIO + Math.random() * 2 * ANTIGRAVITY_CAPACITY_JITTER_RATIO));
47
+ }
48
+
49
+ export function isAntigravityCapacityError(err) {
50
+ return err?.code === 'model_capacity_exhausted' || providerErrorKind(err).kind === 'overloaded';
51
+ }
52
+
53
+ /**
54
+ * Wait before re-issuing a 429, or null when it must surface. `state` is the
55
+ * send's `{ capacityRetries, quickRetried }` record.
56
+ */
57
+ export function antigravity429WaitMs(err, state) {
58
+ const status = Number(err?.status || err?.httpStatus || 0);
59
+ const capacity = isAntigravityCapacityError(err);
60
+ if (status !== 429 && !(capacity && (status === 503 || status === 529))) return null;
61
+ if (readStreamOutcome(err).replaySafe !== true) return null;
62
+ const { kind, retryAfterMs } = providerErrorKind(err);
63
+ if (DETERMINISTIC_KINDS.has(kind) || err.code === 'quota_exhausted' || err.quotaScope === 'day' || err.quotaScope === 'plan') {
64
+ return null;
65
+ }
66
+ // Capacity waits at least the advised RetryInfo delay (the local schedule
67
+ // is the floor). Total advised waiting stays within the retry budget; an
68
+ // advice that does not fit surfaces with its reset time rather than
69
+ // retrying early.
70
+ if (capacity) {
71
+ if (state.capacityRetries >= ANTIGRAVITY_CAPACITY_RETRIES) return null;
72
+ const spent = state.capacityWaitedMs ?? 0;
73
+ if (retryAfterMs != null && spent + retryAfterMs > ANTIGRAVITY_CAPACITY_BUDGET_MS) {
74
+ err.resetAt ??= Date.now() + retryAfterMs;
75
+ return null;
76
+ }
77
+ const wait = Math.max(antigravityCapacityDelayMs(state.capacityRetries++), retryAfterMs ?? 0);
78
+ state.capacityWaitedMs = spent + wait;
79
+ return wait;
80
+ }
81
+ // An RPM hit gets one quick retry; advice up to a minute is honored in
82
+ // full, a longer wait surfaces so the account pool can rotate.
83
+ if (state.quickRetried || retryAfterMs > ANTIGRAVITY_QUICK_RETRY_MAX_ADVICE_MS) return null;
84
+ state.quickRetried = true;
85
+ return retryAfterMs ?? ANTIGRAVITY_QUICK_RETRY_MS;
86
+ }
87
+
88
+ // Account-pool roster cooldowns, read
89
+ // generically by the shared pool from the provider's `accountCooldownPolicy`
90
+ // when the server named no delay: a plain rate limit rotates the account for
91
+ // 30s; a spent quota escalates 60s → 5m → 30m → 2h per consecutive refusal of
92
+ // that account (a served answer resets it); anything else 60s; never under 2s.
93
+ // Capacity and server errors never block an account in the shared pool.
94
+ export const ANTIGRAVITY_ACCOUNT_COOLDOWN_POLICY = Object.freeze({
95
+ floorMs: 2_000,
96
+ rateLimitedMs: 30_000,
97
+ quotaStepsMs: Object.freeze([60_000, 5 * 60_000, 30 * 60_000, 2 * 60 * 60_000]),
98
+ unknownMs: 60_000,
99
+ rotateOnRateLimit: true,
100
+ // A roster that is only cooling down waits up to five minutes for its
101
+ // earliest cooldown instead of failing the send.
102
+ waitForCooldownMs: 300_000,
103
+ // An account that needs verification cools for ten minutes while the
104
+ // roster serves from the next account.
105
+ blockedMs: 600_000,
106
+ });