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,18 +1,15 @@
1
1
  /**
2
2
  * antigravity-stream.mjs — what one Antigravity SSE turn accumulates while it
3
3
  * streams: the live text mirror a retirement notice is recognised from, the
4
- * ordered parts of every chunk, the native tool calls parsed per chunk with
5
- * their id dedup, the leak guard that recovers calls the model wrote as text,
6
- * the first terminal finishReason, and the exposure marks a failed stream must
7
- * carry (emittedToolCall / unsafeToRetry / partial calls + partial replay).
4
+ * leak guard that recovers calls the model wrote as text (held back, like the
5
+ * native calls, until the turn finishes cleanly), and the first terminal
6
+ * finishReason. Nothing is dispatched while streaming.
8
7
  *
9
8
  * The transport (antigravity-transport.mjs) owns the socket and the retry
10
9
  * policy; the projection (antigravity-response.mjs) reads this record after
11
10
  * the turn settles.
12
11
  */
13
- import { createProviderReplay } from './lib/provider-replay.mjs';
14
12
  import { createGeminiTextLeakGuard, consumeGeminiRestStreamResponse } from './gemini-stream.mjs';
15
- import { parseToolCalls, emitGeminiToolCalls } from './gemini-schema.mjs';
16
13
  import { normalizeAntigravityUsage } from './antigravity-response.mjs';
17
14
 
18
15
  // A retired wire id answers with one plain-text notice and no finishReason.
@@ -46,10 +43,6 @@ export function createAntigravityStreamCollector({ tools, useModel, onToolCall,
46
43
  // Streamed text is kept so a retirement notice can be told apart from
47
44
  // a truncated stream when the gateway omits the finishReason.
48
45
  let streamedText = '';
49
- let streamedParts = [];
50
- let streamedNativeToolCalls = [];
51
- const seenNativeToolIds = new Set();
52
- const emittedToolIds = new Set();
53
46
 
54
47
  const relayText = onTextDelta
55
48
  ? (text) => {
@@ -57,15 +50,9 @@ export function createAntigravityStreamCollector({ tools, useModel, onToolCall,
57
50
  onTextDelta(text);
58
51
  }
59
52
  : null;
60
- const dispatchToolCall = onToolCall
61
- ? (call) => {
62
- // A failure already observed in this chunk must win over both
63
- // native calls and calls recovered from its text.
64
- if (terminalFailure || emittedToolIds.has(call.id)) return;
65
- emittedToolIds.add(call.id);
66
- onToolCall(call);
67
- }
68
- : null;
53
+ // Tool calls (native and text-recovered) are never dispatched while the
54
+ // stream runs: the turn's terminal verdict decides, and
55
+ // finalizeAntigravityTurn releases them only after a clean finish.
69
56
  const onChunk = (chunk) => {
70
57
  const candidate = chunk?.candidates?.[0];
71
58
  const finishReason =
@@ -74,37 +61,20 @@ export function createAntigravityStreamCollector({ tools, useModel, onToolCall,
74
61
  if (finishReason && String(finishReason).replace(/^FINISH_REASON_/, '') !== 'STOP') {
75
62
  terminalFailure ||= finishReason;
76
63
  }
77
- if (!onToolCall) return;
78
- const parts = candidate?.content?.parts ?? [];
79
- streamedParts.push(...parts);
80
- if (terminalFailure || !parts.some((part) => part?.functionCall)) return;
81
- // Parse against the turn's parts so anonymous call IDs keep the
82
- // same ordinal as final parsing, even across separate SSE chunks.
83
- const fresh = (parseToolCalls(streamedParts) || []).filter((call) => {
84
- if (seenNativeToolIds.has(call.id)) return false;
85
- seenNativeToolIds.add(call.id);
86
- return true;
87
- });
88
- const calls = textLeakGuard?.enabled ? textLeakGuard.filterNativeToolCalls(fresh) : fresh;
89
- if (calls?.length) streamedNativeToolCalls.push(...calls);
90
- emitGeminiToolCalls(calls, dispatchToolCall);
91
64
  };
92
65
 
93
66
  // Each attempt starts from an empty record: a replayed request must not
94
- // inherit the dead attempt's text, parts or dispatched-call ids.
67
+ // inherit the dead attempt's text or failure.
95
68
  const beginAttempt = () => {
96
69
  textLeakGuard = createGeminiTextLeakGuard({
97
70
  knownToolNames: tools?.map((t) => t.name).filter(Boolean) ?? [],
98
71
  onTextDelta: relayText,
99
- onToolCall: dispatchToolCall,
72
+ onToolCall,
100
73
  onStreamDelta,
74
+ deferToolCalls: true,
101
75
  });
102
76
  streamedText = '';
103
77
  terminalFailure = null;
104
- streamedParts = [];
105
- streamedNativeToolCalls = [];
106
- seenNativeToolIds.clear();
107
- emittedToolIds.clear();
108
78
  };
109
79
  const releaseGuard = () => {
110
80
  textLeakGuard = null;
@@ -125,22 +95,7 @@ export function createAntigravityStreamCollector({ tools, useModel, onToolCall,
125
95
  unwrapChunk: (chunk) => (chunk && typeof chunk === 'object' && chunk.response ? chunk.response : chunk),
126
96
  });
127
97
  } catch (streamErr) {
128
- const error = retiredModelError(streamErr, streamedText, useModel) || streamErr;
129
- // Native calls now run before EOF. Preserve
130
- // their history and prohibit resampling after
131
- // a tool callback.
132
- if (emittedToolIds.size) {
133
- error.emittedToolCall = true;
134
- error.unsafeToRetry = true;
135
- const leaked = textLeakGuard.getLeakedToolCalls();
136
- error.partialToolCalls = [...streamedNativeToolCalls, ...leaked];
137
- const replay = createProviderReplay('antigravity', leaked.length ? [] : streamedParts);
138
- if (replay) {
139
- replay.requestContext = { model: useModel };
140
- error.partialProviderReplay = replay;
141
- }
142
- }
143
- throw error;
98
+ throw retiredModelError(streamErr, streamedText, useModel) || streamErr;
144
99
  }
145
100
  };
146
101
 
@@ -155,11 +110,5 @@ export function createAntigravityStreamCollector({ tools, useModel, onToolCall,
155
110
  get terminalFailure() {
156
111
  return terminalFailure;
157
112
  },
158
- get streamedNativeToolCalls() {
159
- return streamedNativeToolCalls;
160
- },
161
- get emittedToolCount() {
162
- return emittedToolIds.size;
163
- },
164
113
  };
165
114
  }
@@ -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,23 +62,36 @@ 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.
37
- const validationDetail = Array.isArray(detail?.details)
38
- ? detail.details.find(
39
- (entry) => entry?.reason === 'VALIDATION_REQUIRED' && typeof entry.metadata?.validation_url === 'string'
40
- )
41
- : null;
73
+ // Order: google.rpc.Help.links, metadata.validation_url, metadata.validation_link.
74
+ const detailEntries = Array.isArray(detail?.details) ? detail.details : [];
75
+ const helpUrl = detailEntries
76
+ .flatMap((entry) => (Array.isArray(entry?.links) ? entry.links : []))
77
+ .map((link) => link?.url)
78
+ .find((url) => typeof url === 'string' && url.length > 0);
79
+ const metadataUrl = (key) =>
80
+ detailEntries.find((entry) => entry?.reason === 'VALIDATION_REQUIRED' && typeof entry.metadata?.[key] === 'string' && entry.metadata[key])
81
+ ?.metadata[key];
42
82
  const validationUrl =
43
- validationDetail?.metadata.validation_url ||
83
+ helpUrl ||
84
+ metadataUrl('validation_url') ||
85
+ metadataUrl('validation_link') ||
44
86
  /https:\/\/\S*(?:accounts|console)\.google\.com\/\S+/.exec(message || '')?.[0] ||
45
87
  '';
46
88
  if (res.status === 403 && /VALIDATION_REQUIRED/i.test(text || '')) {
47
89
  err.message = `Antigravity requires account verification${validationUrl ? `: open ${validationUrl} , complete the check, then retry` : ''}`;
48
90
  err.validationUrl = validationUrl || undefined;
49
91
  err.unsafeToRetry = true;
92
+ // This account needs verification; another account may still serve.
93
+ err.code ||= 'validation_required';
94
+ err.accountBlocked = true;
50
95
  }
51
96
  return err;
52
97
  }
@@ -62,8 +107,17 @@ function antigravityError(res, text, endpoint) {
62
107
  * @param {{ beginAttempt: Function, consume: Function }} deps.collector
63
108
  * @returns {() => Promise<object>} one retried request that resolves the final payload
64
109
  */
65
- export function createAntigravityRequest({ fetchFn, endpoint, headers, body, opts, signal, collector }) {
66
- return () =>
110
+ export function createAntigravityRequest({ fetchFn, endpoint, headers, body, opts, signal, collector, sleepFn }) {
111
+ const log = (attempt, lastErr, delayMs) => {
112
+ emitProviderRetryStage(opts.onStageChange, {
113
+ attempt: attempt + 1,
114
+ maxAttempts: ANTIGRAVITY_RETRY.maxAttempts,
115
+ lastErr,
116
+ delayMs,
117
+ });
118
+ process.stderr.write(`[antigravity] retry ${attempt + 1} after ${lastErr?.message || 'transient error'}\n`);
119
+ };
120
+ const attemptOnce = () =>
67
121
  withRetry(
68
122
  async ({ signal: attemptSignal }) => {
69
123
  try {
@@ -94,17 +148,42 @@ export function createAntigravityRequest({ fetchFn, endpoint, headers, body, opt
94
148
  }
95
149
  if (!res.ok) {
96
150
  const text = await res.text().catch(() => '');
97
- throw antigravityError(res, text, endpoint);
151
+ const failure = antigravityError(res, text, endpoint);
152
+ // Capacity is paced by the local schedule below; the generic loop
153
+ // would sleep whatever wait the server names.
154
+ if (isCapacityFailure(failure)) markProviderRecoveryExhausted(failure, { owner: 'antigravity-capacity' });
155
+ throw failure;
98
156
  }
99
157
  collector.beginAttempt();
100
158
  return collector.consume(res, attemptSignal);
101
159
  },
102
160
  {
161
+ ...ANTIGRAVITY_RETRY,
162
+ finalOnExhaust: true,
103
163
  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
- },
164
+ sleepFn,
165
+ onRetry: ({ attempt, lastErr: retryErr, delayMs }) => log(attempt, retryErr, delayMs),
108
166
  }
109
167
  );
168
+ // A 429 comes back from withRetry untouched (retry429:false) and is paced by
169
+ // the retry schedule: capacity backs off on this host, an RPM hit
170
+ // gets one quick retry, a spent quota surfaces.
171
+ return async () => {
172
+ const state = { capacityRetries: 0, quickRetried: false };
173
+ for (let tried = 1; ; tried++) {
174
+ try {
175
+ return await attemptOnce();
176
+ } catch (err) {
177
+ const waitMs = antigravity429WaitMs(err, state);
178
+ if (waitMs == null) {
179
+ if (isCapacityFailure(err)) {
180
+ markProviderRecoveryExhausted(err, { owner: 'antigravity-capacity', attempts: tried });
181
+ }
182
+ throw err;
183
+ }
184
+ log(tried, err, waitMs);
185
+ await sleepWithAbort(waitMs, signal, sleepFn, 'Antigravity retry wait aborted');
186
+ }
187
+ }
188
+ };
110
189
  }
@@ -20,7 +20,7 @@ import { createNpmVersionSource, maxSemver } from './npm-cli-version.mjs';
20
20
  // version (gpt-6.1-sol requires >= 0.159.0, measured 2026-10-09), so the
21
21
  // release workflow raises this to the published CLI version on every release
22
22
  // (scripts/sync-client-version-floors.mjs).
23
- export const CODEX_CLIENT_VERSION_FLOOR = '0.162.1';
23
+ export const CODEX_CLIENT_VERSION_FLOOR = '0.163.0';
24
24
  export const CODEX_CLI_NPM_PACKAGE = '@openai/codex';
25
25
  const live = createNpmVersionSource(CODEX_CLI_NPM_PACKAGE, { persistKey: 'codex-cli' });
26
26
 
@@ -2,22 +2,25 @@
2
2
  * Command Code provider (commandcode.ai Provider API).
3
3
  *
4
4
  * Credentials are a Studio-issued API key (command-code-oauth-tokens.mjs).
5
- * Each model is served on the endpoint its /models row declares: Chat
6
- * Completions through the OpenAI-compatible engine, Messages-only models
7
- * (Claude) through the Anthropic engine. Both clients are pinned to the
8
- * Command Code API host. The key never expires and has no refresh grant: a
9
- * 401 means the user must sign in again.
5
+ * Each model is served on a wire its /models row declares (wire-route.mjs
6
+ * picks among them): Chat Completions and Responses through the
7
+ * OpenAI-compatible engine, Messages through the Anthropic engine. Both
8
+ * clients are pinned to the Command Code API host. The key never expires and
9
+ * has no refresh grant: a 401 means the user must sign in again.
10
10
  */
11
11
  import { noteErrorUsage } from './lib/note-error-usage.mjs';
12
12
  import { fileMtimeMs, normalizeExpiresAtMs, scrubOAuthSecrets } from './lib/oauth-token-utils.mjs';
13
+ import { originBoundFetch } from './lib/origin-bound-fetch.mjs';
14
+ import { withInclusiveUsage } from './lib/inclusive-usage.mjs';
13
15
  import { OpenAICompatProvider, preloadOpenAICompatRuntime } from './openai-compat.mjs';
16
+ import { COMPAT_RETRY_POLICY } from './openai-compat-retry-profile.mjs';
14
17
  import { listCompatModels } from './openai-compat-models.mjs';
15
18
  import { AnthropicProvider } from './anthropic.mjs';
16
- import { toInclusiveOpenCodeGoUsage as toInclusiveUsage } from './opencode-go.mjs';
17
19
  import { sanitizeToolPairs } from '../session/context-utils.mjs';
18
20
  import { preparePdfTextForProvider } from './media-normalization.mjs';
19
- import { currentUsageContext } from '../../../shared/llm/usage-context.mjs';
20
21
  import { makeModelCache } from './model-cache.mjs';
22
+ import { resolveWireRoute, sendOnRoute } from './wire-route.mjs';
23
+ import { gatewayMessagesOpts } from './wire-gateway.mjs';
21
24
  import {
22
25
  API_ORIGIN,
23
26
  CREDITS_URL,
@@ -37,8 +40,11 @@ export {
37
40
  export { beginOAuthLogin, loginOAuth } from './command-code-oauth-login.mjs';
38
41
 
39
42
  export const DEFAULT_MODEL = 'deepseek/deepseek-v4-flash';
40
- const CHAT_ENDPOINT = '/chat/completions';
41
- const MESSAGES_ENDPOINT = '/messages';
43
+ const ENDPOINT_WIRES = Object.freeze({
44
+ '/chat/completions': 'chat',
45
+ '/messages': 'messages',
46
+ '/responses': 'responses',
47
+ });
42
48
  // The Anthropic SDK appends /v1/messages itself.
43
49
  const MESSAGES_BASE_URL = `${API_ORIGIN}/provider`;
44
50
  const FIVE_HOURS_MS = 5 * 60 * 60 * 1000;
@@ -55,35 +61,42 @@ const commandCodeModelCache = makeModelCache({
55
61
  });
56
62
 
57
63
  /**
58
- * The wire a /models row is served on: 'chat' when it declares Chat
59
- * Completions or declares no endpoints at all, 'messages' when it declares
60
- * only Messages, null when it declares neither.
64
+ * The wires a /models row declares (`supported_endpoints`), or null when it
65
+ * declares none — such a row is served on Chat Completions by convention.
66
+ */
67
+ export function modelEndpoints(item) {
68
+ const declared = item?.supported_endpoints;
69
+ if (!Array.isArray(declared)) return null;
70
+ const wires = [];
71
+ for (const endpoint of declared) {
72
+ const path = String(endpoint).replace(/^\/?(?:provider\/)?(?:v1\/)?/, '/');
73
+ const wire = Object.hasOwn(ENDPOINT_WIRES, path) ? ENDPOINT_WIRES[path] : null;
74
+ if (wire && !wires.includes(wire)) wires.push(wire);
75
+ }
76
+ return wires;
77
+ }
78
+
79
+ // The route for a model with these declared endpoints (null: undeclared, Chat).
80
+ // `undefined`: nothing describes the model, so no wire is ruled out.
81
+ function commandCodeRoute(model, endpoints, ctx = {}) {
82
+ return resolveWireRoute(PROVIDER_ID, model, { ...ctx, endpoints: endpoints === undefined ? null : (endpoints ?? ['chat']) });
83
+ }
84
+
85
+ /**
86
+ * The wire a /models row is served on (wire-route.mjs over its declared
87
+ * endpoints): Responses for GPT / Muse / Grok when advertised, otherwise Chat
88
+ * when declared or undeclared, Messages when it is the only one, Responses
89
+ * for a Responses-only row; null when it declares none of them.
61
90
  */
62
91
  export function modelWire(item) {
63
92
  if (typeof item?.id !== 'string' || !item.id) return null;
64
- const endpoints = item.supported_endpoints;
65
- if (!Array.isArray(endpoints)) return 'chat';
66
- const declared = endpoints.map((endpoint) => String(endpoint).replace(/^\/?(?:provider\/)?(?:v1\/)?/, '/'));
67
- if (declared.includes(CHAT_ENDPOINT)) return 'chat';
68
- if (declared.includes(MESSAGES_ENDPOINT)) return 'messages';
69
- return null;
93
+ return commandCodeRoute(item.id, modelEndpoints(item))?.wire || null;
70
94
  }
71
95
 
72
- // Every request either engine makes goes through this fetch: anything outside
73
- // the Command Code API origin is refused before the key leaves the process,
74
- // and redirects are never followed (any 3xx is an error).
96
+ // Every request either engine makes goes through this fetch: only the Command
97
+ // Code API origin, never a redirect.
75
98
  function apiOnlyFetch(fetchImpl) {
76
- return async (input, init) => {
77
- const url = new URL(String(input?.url ?? input));
78
- if (url.origin !== API_ORIGIN) {
79
- throw new Error(`[command-code-oauth] refusing to send the API key to ${url.host}`);
80
- }
81
- const res = await (fetchImpl || globalThis.fetch)(input, { ...init, redirect: 'manual' });
82
- if (res.status >= 300 && res.status < 400) {
83
- throw new Error(`[command-code-oauth] refusing to follow a redirect from ${url.host}`);
84
- }
85
- return res;
86
- };
99
+ return originBoundFetch(API_ORIGIN, fetchImpl, PROVIDER_ID);
87
100
  }
88
101
 
89
102
  // Anthropic engine bound to this credential: only the Command Code key is
@@ -97,15 +110,11 @@ class CommandCodeMessagesEngine extends AnthropicProvider {
97
110
  client.fetch = apiOnlyFetch(this.config.fetchImpl);
98
111
  return client;
99
112
  }
100
- }
101
-
102
- const normalizeUsageError = (err) => {
103
- if (err && typeof err === 'object') {
104
- if (err.usage) err.usage = toInclusiveUsage(err.usage);
105
- if (err.partialUsage) err.partialUsage = toInclusiveUsage(err.partialUsage);
113
+ // The roster's output ceiling reaches the shared request builder.
114
+ _sendOnce(messages, model, tools, opts) {
115
+ return super._sendOnce(messages, model, tools, gatewayMessagesOpts(this.config, model, messages, opts));
106
116
  }
107
- return err;
108
- };
117
+ }
109
118
 
110
119
  function rosterRow(item) {
111
120
  const contextWindow = Number(item.context_window ?? item.max_context_window ?? item.context_length ?? 0);
@@ -117,6 +126,11 @@ function rosterRow(item) {
117
126
  ...(name ? { name: name.trim() } : {}),
118
127
  ...(contextWindow > 0 ? { contextWindow } : {}),
119
128
  ...(outputTokens > 0 ? { outputTokens } : {}),
129
+ // The full declared endpoint set: the cached route metadata a later
130
+ // send falls back on when the live roster cannot be read.
131
+ ...(Array.isArray(item.supported_endpoints)
132
+ ? { supportedEndpoints: item.supported_endpoints.map((endpoint) => String(endpoint)) }
133
+ : {}),
120
134
  };
121
135
  }
122
136
 
@@ -146,11 +160,16 @@ function scrubErrorSecrets(err, apiKey) {
146
160
  }
147
161
 
148
162
  // Redact where the transport first surfaces errors (request open and stream
149
- // iteration), so the shared retry reporter never logs the key.
163
+ // iteration) on the Chat and Responses endpoints, so the shared retry
164
+ // reporter never logs the key.
150
165
  function redactClientErrors(client, apiKey) {
151
- const completions = client?.chat?.completions;
152
- if (!completions || !apiKey || completions.create?.commandCodeRedacting === apiKey) return;
153
- const create = completions.create.bind(completions);
166
+ redactCreateErrors(client?.chat?.completions, apiKey);
167
+ redactCreateErrors(client?.responses, apiKey);
168
+ }
169
+
170
+ function redactCreateErrors(endpoint, apiKey) {
171
+ if (!endpoint || !apiKey || endpoint.create?.commandCodeRedacting === apiKey) return;
172
+ const create = endpoint.create.bind(endpoint);
154
173
  const wrapped = async (...args) => {
155
174
  try {
156
175
  const stream = await create(...args);
@@ -176,7 +195,7 @@ function redactClientErrors(client, apiKey) {
176
195
  }
177
196
  };
178
197
  wrapped.commandCodeRedacting = apiKey;
179
- completions.create = wrapped;
198
+ endpoint.create = wrapped;
180
199
  }
181
200
 
182
201
  // Same for the Anthropic client's streaming request (read through
@@ -242,6 +261,8 @@ export class CommandCodeOAuthProvider {
242
261
  // OpenAI-compatible usage: prompt_tokens includes cached. See registry.mjs.
243
262
  static inputExcludesCache = false;
244
263
  name = PROVIDER_ID;
264
+ // The retry profile's limits are final: no loop-level recovery cycles on top.
265
+ retryPolicy = COMPAT_RETRY_POLICY;
245
266
  config;
246
267
  tokens = null;
247
268
  _inner = null;
@@ -250,8 +271,9 @@ export class CommandCodeOAuthProvider {
250
271
  _defaultModelKey = null;
251
272
  _messages = null;
252
273
  _messagesKey = null;
253
- // Model id → wire ('chat' | 'messages') from the roster fetched with `_wiresKey`.
254
- _wires = new Map();
274
+ // Model id → declared endpoint wires (null: undeclared) from the roster
275
+ // fetched with `_wiresKey`.
276
+ _endpoints = new Map();
255
277
  _wiresKey = null;
256
278
 
257
279
  constructor(config) {
@@ -312,6 +334,8 @@ export class CommandCodeOAuthProvider {
312
334
  apiKey,
313
335
  baseURL: MESSAGES_BASE_URL,
314
336
  disableBetaHeaders: true,
337
+ modelMaxOutputTokens: (model) =>
338
+ commandCodeModelCache.loadSync({ allowStale: true })?.find((row) => row?.id === model)?.outputTokens,
315
339
  // x-api-key from the SDK plus the bearer form of the same key.
316
340
  extraHeaders: { Authorization: `Bearer ${apiKey}` },
317
341
  });
@@ -321,8 +345,9 @@ export class CommandCodeOAuthProvider {
321
345
  return engine;
322
346
  }
323
347
 
324
- // Servable rows from /models; only the latest fetch with the still-active
325
- // key publishes the roster and the per-model wire map.
348
+ // Servable rows from /models (any declared Chat, Messages or Responses
349
+ // endpoint, or none declared); only the latest fetch with the still-active
350
+ // key publishes the roster and the per-model endpoint map.
326
351
  async _fetchRoster(apiKey, signal = null) {
327
352
  const publish = commandCodeModelCache.beginSave(() => loadTokens()?.apiKey === apiKey);
328
353
  const body = await requestCommandCodeJson(`${PROVIDER_BASE_URL}/models`, apiKey, {
@@ -335,16 +360,30 @@ export class CommandCodeOAuthProvider {
335
360
  const items = list.filter((item) => modelWire(item));
336
361
  publish(items.map(rosterRow));
337
362
  if (this.tokens?.apiKey === apiKey) {
338
- this._wires = new Map(items.map((item) => [item.id, modelWire(item)]));
363
+ // Rows accumulate for one key: a later roster that misses a model
364
+ // leaves the endpoints it was last listed with.
365
+ const known = this._wiresKey === apiKey ? this._endpoints : new Map();
366
+ for (const item of items) known.set(item.id, modelEndpoints(item));
367
+ this._endpoints = known;
339
368
  this._wiresKey = apiKey;
340
369
  }
341
370
  return items;
342
371
  }
343
372
 
344
- // The wire for a model, from this credential's roster (fetched once when
345
- // missing). A model the roster does not know, or a roster that cannot be
346
- // read right now, stays on Chat Completions; a rejected key is surfaced.
347
- async _wireFor(inner, model) {
373
+ // A model's declared endpoints: what this credential's rosters listed,
374
+ // then the persisted roster (a roster miss or a roster that cannot be read
375
+ // right now must not move a known Messages-only model to Chat). null is a
376
+ // row declaring none (Chat); undefined is a model nothing describes.
377
+ _endpointsFor(apiKey, model) {
378
+ if (this._wiresKey === apiKey && this._endpoints.has(model)) return this._endpoints.get(model);
379
+ const cached = commandCodeModelCache.loadSync({ allowStale: true })?.find((row) => row?.id === model);
380
+ return cached ? modelEndpoints({ supported_endpoints: cached.supportedEndpoints }) : undefined;
381
+ }
382
+
383
+ // This credential's route for a model (the roster is fetched once when
384
+ // missing; a roster that cannot be read falls back on the persisted rows);
385
+ // a rejected key is surfaced.
386
+ async _routeFor(inner, model, ctx = {}) {
348
387
  if (this._wiresKey !== inner.apiKey) {
349
388
  try {
350
389
  await listCompatModels(inner, { throwOnError: true });
@@ -352,7 +391,16 @@ export class CommandCodeOAuthProvider {
352
391
  if (isUnauthorized(err)) throw err;
353
392
  }
354
393
  }
355
- return (this._wiresKey === inner.apiKey && this._wires.get(model)) || 'chat';
394
+ const endpoints = this._endpointsFor(inner.apiKey, model);
395
+ return commandCodeRoute(model, endpoints, {
396
+ ...ctx,
397
+ override: this.config?.modelWires?.[model] ?? null,
398
+ known: endpoints !== undefined,
399
+ });
400
+ }
401
+
402
+ resolveWireRoute(model, ctx = {}) {
403
+ return this._routeFor(this._ensureInner(), model, ctx);
356
404
  }
357
405
 
358
406
  // A rejected key needs a fresh sign-in; the gateway's own detail stays attached.
@@ -379,17 +427,21 @@ export class CommandCodeOAuthProvider {
379
427
  throw this._shapeError(err, this.tokens?.apiKey);
380
428
  }
381
429
  const apiKey = this._innerKey;
382
- // The model's declared endpoint picks the wire; a caller cannot move a
383
- // model to Responses.
384
- const { compatWireApi: _wire, responsesTransport: _transport, ...opts } = sendOpts || {};
430
+ // The model's route (the session's pinned one, else its declared
431
+ // endpoints) picks the wire; a caller's compat wire flag cannot move it.
432
+ const { compatWireApi: _wire, responsesTransport: _transport, ...callerOpts } = sendOpts || {};
385
433
  try {
386
434
  const useModel = model || (await this._pickDefaultModel(inner));
387
- if ((await this._wireFor(inner, useModel)) === 'messages') {
388
- return await this._sendMessages(apiKey, messages, useModel, tools, opts);
389
- }
390
- // _doSend directly: the compat wrapper's 401 handler reloads a static
391
- // config key, which does not apply to this credential.
392
- return await inner._doSend(messages, useModel, tools, opts);
435
+ // One clear "unsupported" refusal moves the send to the next wire once.
436
+ return await sendOnRoute(this, useModel, tools, callerOpts, messages, (wire, history, opts) => {
437
+ if (wire === 'messages') return this._sendMessages(apiKey, history, useModel, tools, opts);
438
+ // _doSend directly: the compat wrapper's 401 handler reloads a static
439
+ // config key, which does not apply to this credential.
440
+ if (wire === 'responses') {
441
+ return inner._doSend(history, useModel, tools, { ...opts, compatWireApi: 'responses' });
442
+ }
443
+ return inner._doSend(history, useModel, tools, opts);
444
+ });
393
445
  } catch (err) {
394
446
  throw this._shapeError(err, apiKey);
395
447
  }
@@ -402,14 +454,7 @@ export class CommandCodeOAuthProvider {
402
454
  async _sendMessages(apiKey, messages, model, tools, opts) {
403
455
  const engine = this._ensureMessages(apiKey);
404
456
  const prepared = await preparePdfTextForProvider(sanitizeToolPairs(messages), engine);
405
- const identity = currentUsageContext();
406
- if (identity) identity.normalizeAbandonedUsage = toInclusiveUsage;
407
- try {
408
- const result = await engine._doSend(prepared, model, tools, opts);
409
- return result?.usage ? { ...result, usage: toInclusiveUsage(result.usage) } : result;
410
- } catch (err) {
411
- throw normalizeUsageError(err);
412
- }
457
+ return withInclusiveUsage(() => engine._doSend(prepared, model, tools, opts));
413
458
  }
414
459
 
415
460
  async listModels() {