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
@@ -338,6 +338,24 @@ export function degradeMediaParts(parts) {
338
338
  return changed ? next : parts;
339
339
  }
340
340
 
341
+ // The text of a document whose source is not base64 bytes: a text source is
342
+ // its data, a content source its text blocks. A url / file-id source has no
343
+ // bytes to read, so the request is rejected rather than silently dropped.
344
+ function documentSourceText(part) {
345
+ const source = part.source;
346
+ let text = null;
347
+ if (part.type === 'document' && source?.type === 'text' && typeof source.data === 'string') text = source.data;
348
+ else if (part.type === 'document' && source?.type === 'content') {
349
+ text = contentToText(source.content, '');
350
+ }
351
+ if (text === null) {
352
+ const kind = part.type === 'document' ? `${source?.type || 'unknown'} source` : 'format';
353
+ throw new TypeError(`This provider accepts no document blocks and cannot read a document with a ${kind}.`);
354
+ }
355
+ const title = typeof part.title === 'string' && part.title ? part.title : '';
356
+ return title ? `--- ${title} ---\n${text}` : text;
357
+ }
358
+
341
359
  function replacePdfParts(content, texts) {
342
360
  if (Array.isArray(content)) {
343
361
  let changed = false;
@@ -368,8 +386,12 @@ function replacePdfParts(content, texts) {
368
386
  * read error or a pdf.js environment failure propagates and nothing is cached.
369
387
  */
370
388
  export async function preparePdfTextForProvider(messages, provider) {
371
- if (providerTakesNativePdf(provider) || !Array.isArray(messages)) return messages;
389
+ // A provider that declares `nativeDocuments === false` takes no document
390
+ // block of any kind: every document variant becomes text (or is rejected).
391
+ const noDocuments = provider?.nativeDocuments === false;
392
+ if ((providerTakesNativePdf(provider) && !noDocuments) || !Array.isArray(messages)) return messages;
372
393
  const found = [];
394
+ const texts = new Map();
373
395
  for (const message of messages) {
374
396
  for (const part of walkContentParts(message?.content)) {
375
397
  if (part.type !== 'file' && part.type !== 'document') continue;
@@ -381,11 +403,12 @@ export async function preparePdfTextForProvider(messages, provider) {
381
403
  continue;
382
404
  }
383
405
  if (file && fileKind(file) === 'pdf') found.push({ part, file });
406
+ else if (noDocuments && (file || part.type === 'document')) texts.set(part, file ? textFormOfFilePart(part) : documentSourceText(part));
384
407
  }
385
408
  }
386
- if (!found.length) return messages;
409
+ if (!found.length && !texts.size) return messages;
387
410
  const extracted = await Promise.all(found.map(({ file }) => pdfTextFor(file)));
388
- const texts = new Map(found.map(({ part, file }, i) => [part, `--- ${fileLabel(file)} ---\n${extracted[i]}`]));
411
+ found.forEach(({ part, file }, i) => texts.set(part, `--- ${fileLabel(file)} ---\n${extracted[i]}`));
389
412
  return messages.map((message) => {
390
413
  // A message whose content is one bare part becomes a one-part array.
391
414
  if (texts.has(message?.content)) return { ...message, content: [{ type: 'text', text: texts.get(message.content) }] };
@@ -882,6 +905,11 @@ function normalizeAnthropicPart(part) {
882
905
  } else {
883
906
  out = { type: 'text', text: fileFallbackText(file, kind) };
884
907
  }
908
+ // Citation settings and the model-only context belong to the document block.
909
+ if (out.type === 'document') {
910
+ if (part.citations) out.citations = part.citations;
911
+ if (part.context) out.context = part.context;
912
+ }
885
913
  if (part.cache_control) out.cache_control = part.cache_control;
886
914
  return out;
887
915
  }
@@ -941,7 +969,12 @@ function normalizeAnthropicPart(part) {
941
969
  // `nativePdf: false` marks a provider that takes a PDF as text: its PDFs were
942
970
  // converted by preparePdfTextForProvider, so a PDF part reaching these
943
971
  // normalizers is an error rather than a file block the provider cannot read.
944
- export function normalizeContentForOpenAIChat(content, { role = 'user', nativePdf = true } = {}) {
972
+ //
973
+ // `cacheControl: true` is a capability the caller grants to a gateway that
974
+ // accepts Anthropic-style cache directives on text blocks (OpenRouter): text
975
+ // parts keep their `cache_control`, and multipart system content stays an
976
+ // array instead of being flattened. Off by default.
977
+ export function normalizeContentForOpenAIChat(content, { role = 'user', nativePdf = true, cacheControl = false } = {}) {
945
978
  const parts = contentParts(content);
946
979
  if (!parts) return content;
947
980
  const out = [];
@@ -968,22 +1001,29 @@ export function normalizeContentForOpenAIChat(content, { role = 'user', nativePd
968
1001
  }
969
1002
  const fileUri = imageFileUriFromPart(part);
970
1003
  if (fileUri) {
971
- out.push({ type: 'image_url', image_url: { url: fileUri.fileUri } });
1004
+ out.push({ type: 'image_url', image_url: { url: fileUri.fileUri, ...imageDetailField(part) } });
972
1005
  continue;
973
1006
  }
974
1007
  const url = imageUrlFromPart(part);
975
1008
  if (url) {
976
- out.push({ type: 'image_url', image_url: { url } });
1009
+ out.push({ type: 'image_url', image_url: { url, ...imageDetailField(part) } });
977
1010
  continue;
978
1011
  }
979
1012
  const text = jsonFallbackFromPart(part, nativePdf);
980
- if (text) out.push({ type: 'text', text });
1013
+ if (text) {
1014
+ const cache = cacheControl && part?.cache_control ? { cache_control: part.cache_control } : {};
1015
+ out.push({ type: 'text', text, ...cache });
1016
+ }
981
1017
  } catch (error) {
982
1018
  const unavailable = unavailableAttachmentText(part, error);
983
1019
  if (unavailable === null) throw error;
984
1020
  out.push({ type: 'text', text: unavailable });
985
1021
  }
986
1022
  }
1023
+ if (cacheControl && role === 'system') {
1024
+ const blocks = out.filter((part) => part.type === 'text' && part.text);
1025
+ if (blocks.length > 1 || blocks.some((part) => part.cache_control)) return blocks;
1026
+ }
987
1027
  if (role !== 'user')
988
1028
  return out
989
1029
  .map((part) => part.text || '')
@@ -992,6 +1032,15 @@ export function normalizeContentForOpenAIChat(content, { role = 'user', nativePd
992
1032
  return out.length ? out : contentToText(content, '');
993
1033
  }
994
1034
 
1035
+ const RESPONSES_IMAGE_DETAILS = new Set(['low', 'high', 'auto', 'original']);
1036
+
1037
+ // A caller-supplied image detail rides through; an unknown value is left out.
1038
+ function imageDetailField(part) {
1039
+ const raw = part.detail ?? part.image_url?.detail ?? part.source?.detail;
1040
+ const detail = typeof raw === 'string' ? raw.trim().toLowerCase() : '';
1041
+ return RESPONSES_IMAGE_DETAILS.has(detail) ? { detail } : {};
1042
+ }
1043
+
995
1044
  export function normalizeContentForOpenAIResponses(content, { role = 'user', nativePdf = true } = {}) {
996
1045
  const textType = role === 'assistant' ? 'output_text' : 'input_text';
997
1046
  if (typeof content === 'string') return content ? [{ type: textType, text: content }] : [];
@@ -1020,17 +1069,17 @@ export function normalizeContentForOpenAIResponses(content, { role = 'user', nat
1020
1069
  }
1021
1070
  const fileId = imageFileIdFromPart(part);
1022
1071
  if (fileId) {
1023
- out.push({ type: 'input_image', file_id: fileId });
1072
+ out.push({ type: 'input_image', file_id: fileId, ...imageDetailField(part) });
1024
1073
  continue;
1025
1074
  }
1026
1075
  const fileUri = imageFileUriFromPart(part);
1027
1076
  if (fileUri) {
1028
- out.push({ type: 'input_image', image_url: fileUri.fileUri });
1077
+ out.push({ type: 'input_image', image_url: fileUri.fileUri, ...imageDetailField(part) });
1029
1078
  continue;
1030
1079
  }
1031
1080
  const url = imageUrlFromPart(part);
1032
1081
  if (url) {
1033
- out.push({ type: 'input_image', image_url: url });
1082
+ out.push({ type: 'input_image', image_url: url, ...imageDetailField(part) });
1034
1083
  continue;
1035
1084
  }
1036
1085
  const text = jsonFallbackFromPart(part, nativePdf);
@@ -1044,6 +1093,58 @@ export function normalizeContentForOpenAIResponses(content, { role = 'user', nat
1044
1093
  return out;
1045
1094
  }
1046
1095
 
1096
+ // Image types the Gemini API documents; an extension outside this map yields
1097
+ // no MIME type at all (FileData.mimeType is optional) instead of a guess.
1098
+ const GEMINI_IMAGE_EXTENSION_MIME = {
1099
+ png: 'image/png',
1100
+ jpg: 'image/jpeg',
1101
+ jpeg: 'image/jpeg',
1102
+ webp: 'image/webp',
1103
+ heic: 'image/heic',
1104
+ heif: 'image/heif',
1105
+ };
1106
+
1107
+ function mimeFromImageUrl(url) {
1108
+ let pathname = '';
1109
+ try {
1110
+ pathname = new URL(url).pathname;
1111
+ } catch {
1112
+ return undefined;
1113
+ }
1114
+ const ext = /\.([a-z0-9]+)$/i.exec(pathname)?.[1]?.toLowerCase();
1115
+ return ext ? GEMINI_IMAGE_EXTENSION_MIME[ext] : undefined;
1116
+ }
1117
+
1118
+ function trimmedMime(value) {
1119
+ const mime = typeof value === 'string' ? value.trim().toLowerCase() : '';
1120
+ return mime || undefined;
1121
+ }
1122
+
1123
+ // Part-level metadata the Gemini API accepts beside inlineData/fileData.
1124
+ /** Supported Gemini part metadata (mediaResolution, videoMetadata) a caller put on `part`, camelCased. */
1125
+ export function geminiPartMetadata(part) {
1126
+ const out = {};
1127
+ if (!part || typeof part !== 'object') return out;
1128
+ const mediaResolution = part.mediaResolution ?? part.media_resolution;
1129
+ if (mediaResolution !== undefined && mediaResolution !== null) out.mediaResolution = mediaResolution;
1130
+ const videoMetadata = part.videoMetadata ?? part.video_metadata;
1131
+ if (videoMetadata !== undefined && videoMetadata !== null) out.videoMetadata = videoMetadata;
1132
+ return out;
1133
+ }
1134
+
1135
+ // FileData for an external URI: the MIME type comes from the part's own
1136
+ // declaration, else the URL's extension, else it is omitted.
1137
+ function geminiFileDataInfo(part, url) {
1138
+ const fileData = part?.fileData || part?.file_data;
1139
+ const declared = fileData
1140
+ ? fileData.mimeType || fileData.mime_type || fileData.mediaType || fileData.media_type
1141
+ : part?.mime_type || part?.mimeType || part?.media_type || part?.mediaType;
1142
+ const fileUri = fileData?.fileUri || fileData?.file_uri || (part?.type === 'image' && part.uri) || url;
1143
+ if (typeof fileUri !== 'string' || !fileUri) return null;
1144
+ const mimeType = trimmedMime(declared) || trimmedMime(part?.image_url?.mime_type) || mimeFromImageUrl(fileUri);
1145
+ return { fileUri, ...(mimeType ? { mimeType } : {}) };
1146
+ }
1147
+
1047
1148
  export function normalizeContentForGeminiParts(content) {
1048
1149
  if (typeof content === 'string') return content ? [{ text: content }] : [];
1049
1150
  const parts = contentParts(content);
@@ -1054,21 +1155,21 @@ export function normalizeContentForGeminiParts(content) {
1054
1155
  const out = [];
1055
1156
  for (const part of parts) {
1056
1157
  try {
1158
+ const meta = geminiPartMetadata(part);
1057
1159
  const file = fileInfo(part);
1058
1160
  if (file) {
1059
1161
  const kind = fileKind(file);
1060
- if (kind === 'pdf') out.push({ inlineData: { mimeType: 'application/pdf', data: file.data } });
1162
+ if (kind === 'pdf') out.push({ inlineData: { mimeType: 'application/pdf', data: file.data }, ...meta });
1061
1163
  else out.push({ text: fileFallbackText(file, kind) });
1062
1164
  continue;
1063
1165
  }
1064
1166
  const inlineInfo = geminiInlineInfo(part);
1065
1167
  if (inlineInfo) {
1066
- out.push({ inlineData: { mimeType: inlineInfo.mimeType, data: inlineInfo.data } });
1168
+ out.push({ inlineData: { mimeType: inlineInfo.mimeType, data: inlineInfo.data }, ...meta });
1067
1169
  continue;
1068
1170
  }
1069
- const fileUri = imageFileUriFromPart(part);
1070
- if (fileUri) {
1071
- out.push({ fileData: { mimeType: fileUri.mimeType, fileUri: fileUri.fileUri } });
1171
+ if (imageFileUriFromPart(part)) {
1172
+ out.push({ fileData: geminiFileDataInfo(part), ...meta });
1072
1173
  continue;
1073
1174
  }
1074
1175
  const fileId = imageFileIdFromPart(part);
@@ -1078,17 +1179,17 @@ export function normalizeContentForGeminiParts(content) {
1078
1179
  }
1079
1180
  const info = imageInfo(part);
1080
1181
  if (info) {
1081
- out.push({ inlineData: { mimeType: info.mimeType, data: info.data } });
1182
+ out.push({ inlineData: { mimeType: info.mimeType, data: info.data }, ...meta });
1082
1183
  continue;
1083
1184
  }
1084
1185
  const url = imageUrlFromPart(part);
1085
1186
  const dataUrlInfo = imageInfoFromDataUrl(url);
1086
1187
  if (dataUrlInfo) {
1087
- out.push({ inlineData: { mimeType: dataUrlInfo.mimeType, data: dataUrlInfo.data } });
1188
+ out.push({ inlineData: { mimeType: dataUrlInfo.mimeType, data: dataUrlInfo.data }, ...meta });
1088
1189
  continue;
1089
1190
  }
1090
1191
  if (url && !url.startsWith('data:')) {
1091
- out.push({ fileData: { mimeType: DEFAULT_IMAGE_MIME, fileUri: url } });
1192
+ out.push({ fileData: geminiFileDataInfo(part, url), ...meta });
1092
1193
  continue;
1093
1194
  }
1094
1195
  const text = jsonFallbackFromPart(part);
@@ -11,6 +11,7 @@ import { MIMO_SEED_MODELS, mimoSeedRow as seedRow } from '../../../shared/llm/pr
11
11
  const MIMO_EFFORT_LEVELS = Object.freeze(['minimal', 'low', 'medium', 'high']);
12
12
  const MIMO_DEFAULT_TEMPERATURE = 1.0;
13
13
  const MIMO_DEFAULT_MAX_OUTPUT_TOKENS = 128_000;
14
+ const MIMO_MAX_OUTPUT_TOKENS = 131_072;
14
15
  // Slow reasoning can stay silent for minutes: wait for the first byte as long
15
16
  // as the agent stall watchdog allows, and tolerate long gaps between events.
16
17
  export const MIMO_FIRST_BYTE_TIMEOUT_MS = Math.min(300_000, PROVIDER_MAX_BEFORE_WARN_MS);
@@ -79,12 +80,6 @@ function thinkingDisabled(thinking, effort) {
79
80
  return thinking === false || mode === 'disabled' || mode === 'off' || mode === 'none' || effort === 'none';
80
81
  }
81
82
 
82
- function namedToolChoice(choice) {
83
- if (!choice || typeof choice !== 'object') return null;
84
- const name = choice.function?.name || choice.name;
85
- return typeof name === 'string' && name ? name : null;
86
- }
87
-
88
83
  function applyMimoParams(params, { opts = {}, config = {}, modelInfo = null } = {}) {
89
84
  const temperature = Number(opts.temperature);
90
85
  params.temperature = Number.isFinite(temperature) && temperature >= 0 ? temperature : MIMO_DEFAULT_TEMPERATURE;
@@ -97,9 +92,12 @@ function applyMimoParams(params, { opts = {}, config = {}, modelInfo = null } =
97
92
  if ((opts[key] ?? config?.[key]) != null && Number.isFinite(value) && value >= 0) params[wire] = value;
98
93
  }
99
94
 
95
+ // MiMo's output limit is `max_completion_tokens` (visible + reasoning
96
+ // tokens, 1..131072); it documents no `max_tokens`.
100
97
  const limit = Number(modelInfo?.outputTokens);
101
- const requested = params.max_tokens || MIMO_DEFAULT_MAX_OUTPUT_TOKENS;
102
- params.max_tokens = Number.isFinite(limit) && limit > 0 ? Math.min(requested, limit) : requested;
98
+ const requested = Math.min(params.max_tokens || MIMO_DEFAULT_MAX_OUTPUT_TOKENS, MIMO_MAX_OUTPUT_TOKENS);
99
+ delete params.max_tokens;
100
+ params.max_completion_tokens = Number.isFinite(limit) && limit > 0 ? Math.min(requested, limit) : requested;
103
101
 
104
102
  const thinking = opts.thinking ?? config?.thinking;
105
103
  const rawEffort = opts.effort ?? config?.reasoningEffort;
@@ -114,13 +112,11 @@ function applyMimoParams(params, { opts = {}, config = {}, modelInfo = null } =
114
112
  if (level) params.reasoning_effort = level;
115
113
  }
116
114
 
117
- if (params.tools?.length) {
118
- if (opts.toolChoice === 'required') params.tool_choice = 'required';
119
- else {
120
- const name = namedToolChoice(opts.toolChoice);
121
- if (name) params.tool_choice = { type: 'function', function: { name } };
122
- }
123
- }
115
+ // MiMo documents `tool_choice: auto` only: any other value is dropped by the
116
+ // backend and the call behaves as auto. `none` is honored by sending no tools
117
+ // at all; `required` / a named tool cannot be forced, so nothing is sent.
118
+ if (params.tool_choice === 'none') delete params.tools;
119
+ delete params.tool_choice;
124
120
  return params;
125
121
  }
126
122
 
@@ -178,6 +174,8 @@ function refineMimoError(err) {
178
174
 
179
175
  export const MIMO_CHAT_PROFILE = Object.freeze({
180
176
  replaysReasoningContent: true,
177
+ // MiMo documents the `developer` role next to system.
178
+ developerRole: true,
181
179
  firstByteTimeoutMs: MIMO_FIRST_BYTE_TIMEOUT_MS,
182
180
  semanticIdleTimeoutMs: MIMO_SEMANTIC_IDLE_TIMEOUT_MS,
183
181
  resolveModelInfo: (provider, model) => provider.getCachedModelInfo(model) || seedRow(model),
@@ -9,6 +9,7 @@
9
9
  import { noteErrorUsage } from './lib/note-error-usage.mjs';
10
10
  import { fileMtimeMs, scrubOAuthSecrets } from './lib/oauth-token-utils.mjs';
11
11
  import { OpenAICompatProvider, preloadOpenAICompatRuntime } from './openai-compat.mjs';
12
+ import { COMPAT_RETRY_POLICY } from './openai-compat-retry-profile.mjs';
12
13
  import { fetchCompatModelItems, listCompatModels } from './openai-compat-models.mjs';
13
14
  import { makeModelCache } from './model-cache.mjs';
14
15
  import {
@@ -114,6 +115,8 @@ export class MimoOAuthProvider {
114
115
  // OpenAI-compatible usage: prompt_tokens includes cached. See registry.mjs.
115
116
  static inputExcludesCache = false;
116
117
  name = 'mimo-oauth';
118
+ // The retry profile's limits are final: no loop-level recovery cycles on top.
119
+ retryPolicy = COMPAT_RETRY_POLICY;
117
120
  config;
118
121
  tokens = null;
119
122
  _inner = null;
@@ -208,7 +208,8 @@ function _stalenessFamily(row, id) {
208
208
  const modelId = String(id || row?.id || row?.name || '')
209
209
  .trim()
210
210
  .toLowerCase();
211
- const claude = modelId.match(/(?:^|\/)claude-(opus|sonnet|haiku|fable)(?:-|$)/);
211
+ // Claude ids name their family right after the brand (`claude-<family>-<version>`).
212
+ const claude = modelId.match(/(?:^|\/)claude-([a-z]+)(?:-|$)/);
212
213
  if (claude) return `claude-${claude[1]}`;
213
214
  const family = row && typeof row.family === 'string' ? row.family.trim().toLowerCase() : '';
214
215
  return family || null;
@@ -5,7 +5,7 @@ export const MODEL_PROXY_OPERATIONS: Readonly<{
5
5
  resolve: 'modelProxyResolve';
6
6
  heartbeat: 'modelProxyHeartbeat';
7
7
  }>;
8
- export type ModelProxyMethod = 'send' | 'listModels' | 'refreshModels' | 'isAvailable' | 'providerConfig';
8
+ export type ModelProxyMethod = 'send' | 'listModels' | 'refreshModels' | 'isAvailable' | 'resolveWireRoute' | 'providerConfig';
9
9
  export const MODEL_PROXY_METHODS: ReadonlyArray<ModelProxyMethod>;
10
10
  export const MODEL_PROXY_HEARTBEAT_MS: number;
11
11
  export const MODEL_PROXY_LEASE_MS: number;
@@ -34,6 +34,7 @@ export const MODEL_PROXY_METHODS = Object.freeze([
34
34
  'listModels',
35
35
  'refreshModels',
36
36
  'isAvailable',
37
+ 'resolveWireRoute',
37
38
  'providerConfig',
38
39
  ]);
39
40
  /** PC heartbeat cadence while it runs calls; well inside the lease. */
@@ -93,6 +93,7 @@ export function inlineModelProxyAttachments(messages, { maxBytes = MODEL_PROXY_I
93
93
  export class ModelProxyProvider {
94
94
  #channel;
95
95
  #modelInfo = new Map();
96
+ #noWireRoute = new Set();
96
97
 
97
98
  constructor(name, config = {}, channel = getModelProxyChannel()) {
98
99
  this.name = name;
@@ -109,7 +110,7 @@ export class ModelProxyProvider {
109
110
  async send(messages, model, tools, sendOpts) {
110
111
  const { options, callbacks } = splitModelProxySendOptions(sendOpts);
111
112
  const finalized = isFinalizedProviderRequestTools(tools);
112
- return this.#call(
113
+ const result = await this.#call(
113
114
  'send',
114
115
  {
115
116
  model: model ?? null,
@@ -121,6 +122,22 @@ export class ModelProxyProvider {
121
122
  },
122
123
  { signal: sendOpts?.signal || null, callbacks }
123
124
  );
125
+ // The PC rerouted the wire (a clear "unsupported" refusal) and reports the
126
+ // route it used: the daemon's own session adopts it, so the next proxied
127
+ // turn starts on the new wire instead of repeating the refusal.
128
+ const rerouted = result?.wireReroute;
129
+ const session = sendOpts?.session;
130
+ if (
131
+ rerouted?.source === 'reroute' &&
132
+ session?.wireRoute &&
133
+ session.wireRoute.provider === this.name &&
134
+ session.wireRoute.model === (model ?? null) &&
135
+ rerouted.provider === this.name &&
136
+ rerouted.model === session.wireRoute.model
137
+ ) {
138
+ session.wireRoute = rerouted;
139
+ }
140
+ return result;
124
141
  }
125
142
 
126
143
  #adoptCatalog(catalog) {
@@ -145,6 +162,21 @@ export class ModelProxyProvider {
145
162
  getCachedModelInfo(model) {
146
163
  return this.#modelInfo.get(String(model ?? '')) ?? null;
147
164
  }
165
+
166
+ /** The PC adapter's wire route for `model` (its config and roster decide);
167
+ * null for a single-wire adapter, which is remembered so every later turn
168
+ * skips the round trip. */
169
+ async resolveWireRoute(model, ctx = {}) {
170
+ const key = String(model ?? '');
171
+ if (this.#noWireRoute.has(key)) return null;
172
+ const route = await this.#call('resolveWireRoute', {
173
+ model: model ?? null,
174
+ context: { agent: ctx.agent === true, legacy: ctx.legacy === true },
175
+ });
176
+ if (route && typeof route === 'object') return route;
177
+ this.#noWireRoute.add(key);
178
+ return null;
179
+ }
148
180
  }
149
181
 
150
182
  /** A proxy instance whose class carries the PC adapter's usage convention. */
@@ -10,8 +10,10 @@ import { createHash } from 'node:crypto';
10
10
  import { noteErrorUsage } from './lib/note-error-usage.mjs';
11
11
  import { fileMtimeMs } from './lib/oauth-token-utils.mjs';
12
12
  import { OpenAICompatProvider, preloadOpenAICompatRuntime } from './openai-compat.mjs';
13
+ import { COMPAT_RETRY_POLICY } from './openai-compat-retry-profile.mjs';
13
14
  import { getModelMetadataSync } from './model-catalog.mjs';
14
15
  import { makeModelCache } from './model-cache.mjs';
16
+ import { normalizeCacheKey } from '../agent-runtime/cache-strategy.mjs';
15
17
  import { PRICING_RATE_KEYS } from '../../../shared/llm/model-pricing-rates.mjs';
16
18
  import {
17
19
  MUSE_DEFAULT_EFFORT_LEVELS as FIVE_LEVELS,
@@ -100,15 +102,6 @@ function museRow(id, discovered = null) {
100
102
  const EFFORT_DOWNGRADE = { max: 'xhigh' };
101
103
  const SUMMARY_MODES = new Set(['auto', 'detailed', 'concise']);
102
104
 
103
- // Cache identities beyond the wire limit become a bounded hash identity.
104
- function normalizeCacheKey(value) {
105
- const text = String(value ?? '').trim();
106
- if (!text) return '';
107
- const wellFormed = text.toWellFormed();
108
- if (wellFormed.length <= 64) return wellFormed;
109
- return `pc_${createHash('sha256').update(wellFormed).digest('hex').slice(0, 32)}`;
110
- }
111
-
112
105
  // Final request shaping on the Responses wire (installed through the shared
113
106
  // transport's opt-in params hook).
114
107
  function shapeResponsesParams(params, { opts, modelInfo }, config = {}) {
@@ -321,6 +314,8 @@ export class MuseCodeOAuthProvider {
321
314
  nativePdf = false;
322
315
  static inputExcludesCache = false;
323
316
  name = 'muse-code-oauth';
317
+ // The retry profile's limits are final: no loop-level recovery cycles on top.
318
+ retryPolicy = COMPAT_RETRY_POLICY;
324
319
  config;
325
320
  tokens = null;
326
321
  _inner = null;
@@ -252,6 +252,8 @@ function cursorOAuthState() {
252
252
  return resolveProbeState(paths, (docs) =>
253
253
  docs.some((own) => {
254
254
  if (!own?.access_token) return false;
255
+ // Cursor permanently rejected the refresh token: signed out until a new login.
256
+ if (own.reauth_required === true) return false;
255
257
  const expiresAt = Number(own.expires_at) || 0;
256
258
  return expiresAt === 0 || expiresAt > Date.now() || Boolean(own.refresh_token);
257
259
  })
@@ -101,6 +101,8 @@ function _codexMetadataBase({ poolKey, cacheKey, sendOpts, handshake = false } =
101
101
  sendOpts?.codexSessionId ||
102
102
  sendOpts?.session?.codexWireSessionId ||
103
103
  sendOpts?.session?.codexSessionId ||
104
+ // A forked transport scope keeps its session's wire identity.
105
+ (sendOpts?.transportScope ? sendOpts?.sessionId : '') ||
104
106
  poolKey ||
105
107
  cacheKey
106
108
  ) || 'mixdog-session';