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
@@ -46,6 +46,62 @@ export function agentContextOverflowError(
46
46
  );
47
47
  }
48
48
 
49
+ export const TOOL_SURFACE_EXCEEDS_CONTEXT = 'TOOL_SURFACE_EXCEEDS_CONTEXT';
50
+
51
+ const tokens = (value) => `${Number(value || 0).toLocaleString('en-US')} tokens`;
52
+
53
+ // Distinct from AgentContextOverflowError: the request's FIXED overhead (tool
54
+ // definitions, protected system context, configured headroom) leaves no room
55
+ // for any history, so compacting the history cannot help and is not tried.
56
+ // The wording avoids provider context-overflow phrasing on purpose: this is
57
+ // not a "conversation too long" refusal and must not be routed as one.
58
+ export class ToolSurfaceExceedsContextError extends Error {
59
+ constructor({ sessionId, provider, model, overhead }) {
60
+ const target = [provider, model].filter(Boolean).join('/') || 'this model';
61
+ const reserve = overhead.kind === 'configured_reserve';
62
+ const headline = reserve
63
+ ? 'The configured compaction headroom leaves no room for conversation history'
64
+ : 'Tool definitions and system context leave no room for conversation history';
65
+ const remedy = reserve
66
+ ? 'Lower the configured headroom (compaction.reservedTokens or MIXDOG_AGENT_COMPACT_RESERVED_TOKENS), or use a model with a larger context window.'
67
+ : `Use a model with a larger context window, or send a smaller eager tool surface (disable MCP servers or custom tools this session does not need)${
68
+ overhead.configuredReserveTokens > 0 ? ', or configure fewer reserved tokens (compaction.reservedTokens)' : ''
69
+ }.`;
70
+ const largest = overhead.largestTools.map((tool) => `${tool.name} (${tokens(tool.tokens)})`).join(', ');
71
+ super(
72
+ [
73
+ `${headline} (${TOOL_SURFACE_EXCEEDS_CONTEXT}).`,
74
+ `${target}: context window ${tokens(overhead.contextWindowTokens)}, compaction boundary ${tokens(overhead.boundaryTokens)}.`,
75
+ `Fixed per-request overhead: tool definitions ${tokens(overhead.toolTokens)} (${overhead.toolCount} tools), ` +
76
+ `protected system context ${tokens(overhead.systemTokens)}, configured headroom ${tokens(overhead.configuredReserveTokens)}; ` +
77
+ 'nothing remains for conversation history.',
78
+ ...(overhead.measuredRequestTokens
79
+ ? [`The provider measured the last request at ${tokens(overhead.measuredRequestTokens)}.`]
80
+ : []),
81
+ 'Compacting the conversation history cannot reduce these.',
82
+ remedy,
83
+ ...(largest ? [`Largest tool definitions: ${largest}.`] : []),
84
+ ].join('\n')
85
+ );
86
+ this.name = 'ToolSurfaceExceedsContextError';
87
+ this.code = TOOL_SURFACE_EXCEEDS_CONTEXT;
88
+ this.sessionId = sessionId || null;
89
+ this.provider = provider || null;
90
+ this.model = model || null;
91
+ this.overheadKind = overhead.kind;
92
+ this.overhead = overhead;
93
+ }
94
+ }
95
+
96
+ export function toolSurfaceExceedsContextError({ sessionId, sessionRef, model, overhead }) {
97
+ return new ToolSurfaceExceedsContextError({
98
+ sessionId,
99
+ provider: sessionRef?.provider || null,
100
+ model: sessionRef?.model || model || null,
101
+ overhead,
102
+ });
103
+ }
104
+
49
105
  // Distinct from AgentContextOverflowError: the compaction pipeline itself
50
106
  // failed (handoff-summary error, dead Memory runtime,
51
107
  // etc.). This is NOT "latest turn cannot fit the context budget" — masking it
@@ -1,12 +1,10 @@
1
1
  // Deferred catalog call-through: inactive catalog tool_use → discovery bookkeeping
2
2
  // then normal executeTool routing (runtime errors only; no pre-dispatch schema).
3
3
  import { clean } from '../../runtime-core/session-text.mjs';
4
- import {
5
- deferredCatalogUnion,
6
- isReadonlySelectable,
7
- selectDeferredTools,
8
- } from '../../runtime-core/tool-catalog.mjs';
4
+ import { deferredCatalogUnion, isReadonlySelectable, selectDeferredTools } from '../../runtime-core/tool-catalog.mjs';
9
5
  import { isDeferredToolAvailable } from '../../runtime-core/deferred-tool-availability.mjs';
6
+ import { routeToolExclusionReason } from './provider-tool-exclusions.mjs';
7
+ import { isBridgeReadonlySession, isToolBridgeEnabled } from '../../runtime-core/tool-bridge.mjs';
10
8
 
11
9
  /** Skill-list plumbing only; mutation/MCP/builtins must use the catalog+mode gate. */
12
10
  const INACTIVE_INFRA_BYPASS = new Set(['skills_list', 'skill_view']);
@@ -41,7 +39,7 @@ function toolExecutesWhenInactive(name) {
41
39
  return INACTIVE_INFRA_BYPASS.has(name);
42
40
  }
43
41
 
44
- function resolveDeferredSelectMode(session) {
42
+ export function resolveDeferredSelectMode(session) {
45
43
  const spec = session?.toolSpec;
46
44
  if (spec == null || spec === '') return null;
47
45
  if (spec === 'readonly') return 'readonly';
@@ -89,20 +87,32 @@ export function prepareDeferredToolCallThrough(sessionRef, name) {
89
87
  }
90
88
  const tool = lookupDeferredCatalogTool(sessionRef, name);
91
89
  if (!tool) return null;
90
+ const routeExclusion = isToolBridgeEnabled(sessionRef) ? null : routeToolExclusionReason(sessionRef, tool);
91
+ if (routeExclusion) return denyDeferredCallThrough(`Error: ${routeExclusion}`);
92
92
  if (isActiveSessionTool(sessionRef, name)) return null;
93
93
  if (toolExecutesWhenInactive(name)) return null;
94
94
 
95
95
  const toolLabel = clean(tool.name) || clean(name) || 'tool';
96
+ const bridge = isToolBridgeEnabled(sessionRef);
96
97
  const resolvedMode = resolveDeferredSelectMode(sessionRef);
98
+ // Whatever the exposure, a deferred mutating tool never runs without a
99
+ // resolved tool mode, and never in a read-only one.
97
100
  if (resolvedMode === null) {
98
101
  if (!isReadonlySelectable(tool)) {
102
+ const remedy = bridge ? 'no call was sent.' : `load it with load_tool names:["${toolLabel}"].`;
99
103
  return denyDeferredCallThrough(
100
- `Error: tool "${toolLabel}" is deferred and cannot be auto-loaded without a resolved tool mode; load it with load_tool names:["${toolLabel}"].`
104
+ `Error: tool "${toolLabel}" is deferred and cannot be auto-loaded without a resolved tool mode; ${remedy}`
101
105
  );
102
106
  }
103
- } else if (resolvedMode === 'readonly' && !isReadonlySelectable(tool)) {
107
+ } else if (
108
+ (resolvedMode === 'readonly' || (bridge && isBridgeReadonlySession(sessionRef))) &&
109
+ !isReadonlySelectable(tool)
110
+ ) {
104
111
  return denyDeferredCallThrough(`Error: tool "${toolLabel}" is not available in readonly mode`);
105
112
  }
113
+ // Bridge sessions reach deferred tools through call_tool: the fixed
114
+ // provider surface is never extended.
115
+ if (bridge) return null;
106
116
 
107
117
  const selectMode = resolvedMode === null ? 'readonly' : resolvedMode;
108
118
  selectDeferredTools(sessionRef, [toolLabel], selectMode);
@@ -114,6 +114,7 @@ export function createLoopState({ provider, messages, model, tools, cwd, sendOpt
114
114
  // One-shot repair of an assistant turn whose stored reasoning replay the
115
115
  // API refuses to take back (see thinking-replay-recovery.mjs).
116
116
  thinkingReplayRepairUsed: false,
117
+ toolSchemaDropUsed: false,
117
118
  // Pending image-strip retry: identities of the images every attempt leaves
118
119
  // out until a send succeeds, and whether to heal them from history then.
119
120
  imageStrip: null,
@@ -13,8 +13,12 @@
13
13
  // registry knows its name.
14
14
  import { isAgentOwner } from '../../agent-owner.mjs';
15
15
  import { isOffReadonlySurface } from './deferred-call-through.mjs';
16
+ import { BRIDGE_CALL_TOOL_NAME, bridgeErrorText, isToolBridgeEnabled } from '../../runtime-core/tool-bridge.mjs';
17
+ import { sessionAllowlistExcludes, sessionDisallows } from '../../runtime-core/deferred-tool-availability.mjs';
18
+ import { providerToolExclusionReason } from './provider-tool-exclusions.mjs';
16
19
 
17
- const WORKER_DENIED_TOOLS = new Set(['agent']);
20
+ const WORKER_DENIED_TOOLS = new Set(['agent', 'ask_user', 'session']);
21
+ const BRIDGE_DISCOVERY_TOOL_NAMES = new Set(['load_tool']);
18
22
 
19
23
  const IMAGE_PATH_RE = /\.(?:png|jpe?g|gif|webp)(?:$|[?#])/i;
20
24
  const COMPACTED_PATCH_LINE_RE = /^\s*\[mixdog compacted\b[^\]\n]*\]/;
@@ -95,17 +99,24 @@ export function routeWebFetchCall(call) {
95
99
  export function preDispatchDenyForSession(sessionRef, call) {
96
100
  const name = call?.name;
97
101
  if (typeof name !== 'string' || !name) return null;
102
+ // A call_tool request that could not be projected onto its target answers
103
+ // its wire id with the projection error; call_tool itself never dispatches.
104
+ if (typeof call.bridgeError === 'string') return call.bridgeError;
105
+ if (name === BRIDGE_CALL_TOOL_NAME && isToolBridgeEnabled(sessionRef)) {
106
+ return bridgeErrorText('BRIDGE_RECURSION', 'call_tool runs one tool named in its arguments and cannot be dispatched itself.');
107
+ }
98
108
  const schemaName = String(call?.schemaName || name);
99
- if (Array.isArray(sessionRef?.schemaAllowedTools)) {
100
- const allowed = new Set(sessionRef.schemaAllowedTools.map((toolName) => String(toolName).toLowerCase()));
101
- if (!allowed.has(schemaName.toLowerCase())) {
102
- return `Error: tool "${name}" is not available on this session's schema allowlist.`;
103
- }
109
+ // A tool the provider left out of this request still exists in the session;
110
+ // a call to it is answered with why it is unavailable.
111
+ const excluded = providerToolExclusionReason(sessionRef, schemaName);
112
+ if (excluded) return `Error: ${excluded}`;
113
+ // The bridge's discovery tools grant no authority (every call_tool target
114
+ // is judged here under its own name), so an allowlist never strands them.
115
+ const bridgeDiscovery = isToolBridgeEnabled(sessionRef) && BRIDGE_DISCOVERY_TOOL_NAMES.has(schemaName);
116
+ if (!bridgeDiscovery && sessionAllowlistExcludes(sessionRef, schemaName)) {
117
+ return `Error: tool "${name}" is not available on this session's schema allowlist.`;
104
118
  }
105
- if (
106
- Array.isArray(sessionRef?.disallowedTools) &&
107
- sessionRef.disallowedTools.some((toolName) => String(toolName).toLowerCase() === schemaName.toLowerCase())
108
- ) {
119
+ if (sessionDisallows(sessionRef, schemaName)) {
109
120
  return `Error: tool "${name}" is not available in this session.`;
110
121
  }
111
122
  if (isOffReadonlySurface(sessionRef, schemaName)) {
@@ -0,0 +1,132 @@
1
+ // Tools a provider left out of a request because it cannot accept their input
2
+ // schema even after the wire's normalization (a schema with an unknown type
3
+ // name, an unresolvable $ref, a non-object root), or that the provider
4
+ // rejected with an HTTP 400 naming the schema (dropped for the session).
5
+ // The user is told once per session and tool on the turn's display-only stage
6
+ // channel (stage 'notice'); a call the model still makes to such a tool is
7
+ // answered with the reason instead of running it.
8
+ import { geminiToolExclusion } from '../../providers/gemini-schema.mjs';
9
+ import { isGeminiFamilyModel } from '../../providers/gemini-family.mjs';
10
+ import { anthropicToolExclusion } from '../../providers/lib/anthropic-request-utils.mjs';
11
+ import { claudeBridgeInputSchema, wireInputSchema } from '../../providers/lib/claude-bridge-schema.mjs';
12
+ import { actionInputUnionFor } from '../../providers/lib/action-input-contract.mjs';
13
+ import { isAntigravityClaude } from '../../providers/antigravity-request.mjs';
14
+ import { isResponsesFreeformTool } from '../../providers/custom-tool-wire.mjs';
15
+ import { ANTHROPIC_NATIVE_PROVIDERS } from '../../runtime-core/tool-catalog-schema.mjs';
16
+ import { finalizeProviderRequestTools, providerNativeToolPrefixCount } from '../../runtime-core/provider-request-tools.mjs';
17
+
18
+ const sessions = new WeakMap();
19
+
20
+ function exclusionsFor(sessionRef) {
21
+ let state = sessions.get(sessionRef);
22
+ if (!state) {
23
+ state = { noticed: new Set(), current: new Map(), dropped: new Map() };
24
+ sessions.set(sessionRef, state);
25
+ }
26
+ return state;
27
+ }
28
+
29
+ const isSessionRef = (value) => value !== null && typeof value === 'object';
30
+
31
+ /** A new provider request: exclusions describe the latest request only. */
32
+ export function beginProviderToolExclusions(sessionRef) {
33
+ if (isSessionRef(sessionRef)) sessions.get(sessionRef)?.current.clear();
34
+ }
35
+
36
+ export function excludedToolNoticeText({ name, pointer, reason }) {
37
+ return `Tool "${name}" was excluded from this session's requests: its input schema is invalid at ${pointer || '/'} (${reason}). Fix the tool's schema or disable the tool.`;
38
+ }
39
+
40
+ /** Record `exclusion` ({ name, pointer, reason }) for the session's current
41
+ * request and raise the user notice the first time this tool is excluded. */
42
+ export function recordProviderToolExclusion(sessionRef, exclusion, onStageChange) {
43
+ const name = String(exclusion?.name || '');
44
+ if (!name || !isSessionRef(sessionRef)) return;
45
+ const state = exclusionsFor(sessionRef);
46
+ state.current.set(name, exclusion);
47
+ if (state.noticed.has(name)) return;
48
+ state.noticed.add(name);
49
+ try {
50
+ onStageChange?.('notice', { tone: 'warn', message: excludedToolNoticeText(exclusion) });
51
+ } catch {
52
+ /* display-only */
53
+ }
54
+ }
55
+
56
+ const unavailableText = (exclusion) =>
57
+ `tool "${exclusion.name}" is unavailable with the current model: the provider rejected its input schema at ${exclusion.pointer || '/'} (${exclusion.reason}), so it was left out of the request; no call was sent. Use another tool, or ask the user to fix the tool's schema or disable it.`;
58
+
59
+ /** Why `name` cannot be called in the session's current request, or null. */
60
+ export function providerToolExclusionReason(sessionRef, name) {
61
+ if (!isSessionRef(sessionRef)) return null;
62
+ const state = sessions.get(sessionRef);
63
+ const key = String(name || '');
64
+ const exclusion = state?.current.get(key) || state?.dropped.get(key);
65
+ return exclusion ? unavailableText(exclusion) : null;
66
+ }
67
+
68
+ /** The provider rejected `exclusion.name`'s schema with an HTTP 400: leave the
69
+ * tool out of every later request of the session and tell the user once. */
70
+ export function dropSessionTool(sessionRef, exclusion, onStageChange) {
71
+ if (!isSessionRef(sessionRef)) return;
72
+ exclusionsFor(sessionRef).dropped.set(exclusion.name, exclusion);
73
+ recordProviderToolExclusion(sessionRef, exclusion, onStageChange);
74
+ }
75
+
76
+ /** The request's tool surface without the tools dropped for the session
77
+ * ({ sendTools, requestToolScope }, the same objects when none apply). */
78
+ export function withoutDroppedTools(sessionRef, { sendTools, requestToolScope }) {
79
+ const dropped = isSessionRef(sessionRef) ? sessions.get(sessionRef)?.dropped : null;
80
+ if (!dropped?.size) return { sendTools, requestToolScope };
81
+ const prefix = providerNativeToolPrefixCount(sendTools);
82
+ const kept = sendTools.filter((tool, index) => index < prefix || !dropped.has(tool?.name));
83
+ if (kept.length === sendTools.length) return { sendTools, requestToolScope };
84
+ const next = finalizeProviderRequestTools(kept, prefix);
85
+ return { sendTools: next, requestToolScope: { ...requestToolScope, requestTools: next } };
86
+ }
87
+
88
+ // The schema rule of the wire a session's requests use: 'gemini', 'anthropic'
89
+ // (Messages), 'antigravity-claude' (Anthropic bridge behind Antigravity) or
90
+ // 'openai' (Responses, Codex and every OpenAI-compatible chat route).
91
+ function routeSchemaFamily(session) {
92
+ const provider = String(session?.provider || '').toLowerCase();
93
+ const wire = session?.wireRoute?.wire;
94
+ if (provider === 'antigravity-oauth' && isAntigravityClaude(session?.model)) return 'antigravity-claude';
95
+ if (provider === 'gemini' || isGeminiFamilyModel(session?.model)) return 'gemini';
96
+ if (ANTHROPIC_NATIVE_PROVIDERS.has(provider) || wire === 'messages') return 'anthropic';
97
+ return 'openai';
98
+ }
99
+
100
+ function wireExclusion(tool, result) {
101
+ return result.schema ? null : { name: tool.name, pointer: result.pointer || '/', reason: result.reason };
102
+ }
103
+
104
+ // The same normalization + validation the wire applies to `tool`, as
105
+ // { name, pointer, reason } when the route leaves it out of its requests.
106
+ function schemaExclusion(session, family, tool) {
107
+ switch (family) {
108
+ case 'gemini':
109
+ return geminiToolExclusion(tool);
110
+ case 'anthropic':
111
+ return anthropicToolExclusion(tool, String(session?.provider || 'anthropic').toLowerCase());
112
+ case 'antigravity-claude':
113
+ return wireExclusion(tool, claudeBridgeInputSchema(actionInputUnionFor(tool.inputSchema)));
114
+ default:
115
+ if (tool.inputSchema == null) return null;
116
+ if (/^openai(-oauth)?$/.test(String(session?.provider || '')) && isResponsesFreeformTool(tool)) return null;
117
+ return wireExclusion(tool, wireInputSchema(tool.inputSchema, 'openai'));
118
+ }
119
+ }
120
+
121
+ /** Why `tool` is left out of every request on the session's route, or null.
122
+ * Validation is a pure function of the tool's schema and the route's wire, so
123
+ * this holds before the tool was ever sent and stays stable across turns; a
124
+ * tool the provider rejected with a 400 is dropped for the session. Built-in
125
+ * tools are never excluded by the schema rule. */
126
+ export function routeToolExclusionReason(session, tool) {
127
+ if (!tool) return null;
128
+ const dropped = isSessionRef(session) ? sessions.get(session)?.dropped.get(String(tool.name || '')) : null;
129
+ if (dropped) return unavailableText(dropped);
130
+ const exclusion = schemaExclusion(session, routeSchemaFamily(session), tool);
131
+ return exclusion ? unavailableText(exclusion) : null;
132
+ }
@@ -14,6 +14,10 @@ import {
14
14
  providerNativeToolPrefixCount,
15
15
  runWithProviderRequestToolsScope,
16
16
  } from '../../runtime-core/provider-request-tools.mjs';
17
+ import { TOOL_SURFACE_MIGRATION_INTENT } from '../../runtime-core/tool-exposure.mjs';
18
+ import { migrateToolExposureAtBoundary } from './tool-exposure-migration.mjs';
19
+ import { fixedRequestOverhead, fixedRequestOverheadInputs, resolveWorkerCompactPolicy } from './compact-policy.mjs';
20
+ import { toolSurfaceExceedsContextError } from './context-overflow.mjs';
17
21
 
18
22
  const isDynamicTool = (tool) =>
19
23
  tool.deferLoading === true || tool.defer_loading === true || String(tool.name || '').startsWith('mcp__');
@@ -61,6 +65,18 @@ export async function prepareProviderRequest(state) {
61
65
  let compactChanged;
62
66
  let sendTools;
63
67
  let requestToolScope;
68
+ // Fixed inputs of the last passing overhead verdict in this boundary.
69
+ let passedOverheadInputs;
70
+ // A session persisted with another tool exposure migrates here, once, at a
71
+ // boundary with no pending calls: new surface and fixed guidance, a fresh
72
+ // tool snapshot and provider state, and a tagged cache break.
73
+ if (migrateToolExposureAtBoundary(sessionRef, messages)) {
74
+ fixedProviderToolSurface = null;
75
+ providerState = undefined;
76
+ providerStateCleared = true;
77
+ delete sessionRef.pendingCacheBreakIntent;
78
+ opts.cacheBreakIntent = TOOL_SURFACE_MIGRATION_INTENT;
79
+ }
64
80
  refreshDeferredMcpToolCatalog(sessionRef);
65
81
  do {
66
82
  // Provider-history normalization is part of the request boundary:
@@ -90,6 +106,20 @@ export async function prepareProviderRequest(state) {
90
106
  requestTools: sendTools,
91
107
  nativePrefixCount: providerNativeToolPrefixCount(sendTools),
92
108
  };
109
+ // A request whose fixed overhead alone leaves no room for history fails
110
+ // here with an actionable error: no compaction could make it fit. A
111
+ // passing verdict holds while its fixed inputs (tool schemas, protected
112
+ // system context, headroom, boundary) are unchanged — a later pass whose
113
+ // compaction only removed history (and the provider reading with it) is
114
+ // not re-judged — but adopted MCP schema changes or a re-rooted system
115
+ // prompt are.
116
+ const overheadPolicy = resolveWorkerCompactPolicy(sessionRef, sendTools);
117
+ const overheadInputs = fixedRequestOverheadInputs(overheadPolicy, messages);
118
+ if (overheadInputs === null || overheadInputs !== passedOverheadInputs) {
119
+ const overhead = fixedRequestOverhead(overheadPolicy, messages, sendTools, sessionRef);
120
+ if (overhead) throw toolSurfaceExceedsContextError({ sessionId, sessionRef, model, overhead });
121
+ passedOverheadInputs = overheadInputs;
122
+ }
93
123
  const pass = await runWithProviderRequestToolsScope(requestToolScope, () =>
94
124
  runPreSendCompactPass({
95
125
  provider,
@@ -8,6 +8,7 @@ import { resolveLiveToolCwd } from './tool-exec.mjs';
8
8
  import { notifySkillsApplied, prepareExplicitSkills, recordAppliedSkills } from '../explicit-skills.mjs';
9
9
  import { addUsage, usageDeltaEvent } from './usage.mjs';
10
10
  import { prepareProviderRequest } from './request-boundary.mjs';
11
+ import { applyStepEffort } from './step-auto-effort.mjs';
11
12
  import { projectProviderRequest } from './request-projection.mjs';
12
13
  import { traceProviderSend, traceOutputTruncation } from './diagnostics.mjs';
13
14
  import { createEagerDispatcher } from '../eager-dispatch.mjs';
@@ -16,6 +17,13 @@ import { stripInlineImages } from '../image-strip-recovery.mjs';
16
17
  import { runWithProviderRequestToolsScope } from '../../runtime-core/provider-request-tools.mjs';
17
18
  import { REPEAT_FAIL_LIMIT } from './loop-state.mjs';
18
19
  import { createToolCallIdResolver } from './tool-call-ids.mjs';
20
+ import { captureSideQuestionRequest } from '../side-question-store.mjs';
21
+ import {
22
+ beginProviderToolExclusions,
23
+ dropSessionTool,
24
+ recordProviderToolExclusion,
25
+ withoutDroppedTools,
26
+ } from './provider-tool-exclusions.mjs';
19
27
 
20
28
  /**
21
29
  * Open an iteration: refresh the live cwd, drain queued steering after a
@@ -72,6 +80,8 @@ export async function beginIteration(state) {
72
80
  loopUsageMetricsTurnId: state.usageMetricsTurnId,
73
81
  loopUsageMetricsEpoch: state.usageMetricsEpoch,
74
82
  });
83
+ // A tool the provider rejected with a schema 400 stays out of the session.
84
+ Object.assign(boundary, withoutDroppedTools(sessionRef, boundary));
75
85
  state.iterations = boundary.iterations;
76
86
  state.lastUsage = boundary.lastUsage;
77
87
  state.firstTurnUsage = boundary.firstTurnUsage;
@@ -91,6 +101,10 @@ export async function beginIteration(state) {
91
101
  // callers omit the flag and retain legacy live deferred resolution.
92
102
  opts.providerToolSnapshotAuthoritative = true;
93
103
  opts.providerNativeToolPrefixCount = boundary.requestToolScope.nativePrefixCount;
104
+ // A tool the provider leaves out of this request (a schema it cannot
105
+ // accept) is noticed once per session and refused if the model calls it.
106
+ beginProviderToolExclusions(sessionRef);
107
+ opts.onToolExcluded = (exclusion) => recordProviderToolExclusion(sessionRef, exclusion, opts.onStageChange);
94
108
  state.lastSendTools = boundary.sendTools;
95
109
  // Eager-dispatch queue (see ../eager-dispatch.mjs): read-only tools start
96
110
  // the instant the provider streams a tool-call event; writes and unknown
@@ -132,6 +146,9 @@ export async function sendProviderRequest(state, round) {
132
146
  const sendStartedAt = Date.now();
133
147
  const preSendMs = sendStartedAt - round.iterT0;
134
148
  const toolResumeMs = state.lastToolBatchEndedAt ? sendStartedAt - state.lastToolBatchEndedAt : null;
149
+ // The step judgment ran beside opening the iteration; wait for it only up to
150
+ // its grace, then it rides on this request or on the next.
151
+ await applyStepEffort(state);
135
152
  // Every attempt is built from the live transcript, so a compaction between
136
153
  // attempts reaches the provider; a pending image strip only filters it.
137
154
  const messageSource = state.imageStrip
@@ -152,26 +169,46 @@ export async function sendProviderRequest(state, round) {
152
169
  try {
153
170
  opts.onProviderSendStarted?.();
154
171
  } catch {}
155
- const result = await runWithProviderRequestToolsScope(round.requestToolScope, () =>
156
- sendWithRecovery({
157
- provider,
158
- messages: providerMessages,
159
- recoveryMessages: messageSource,
160
- model,
161
- sendTools: round.sendTools,
162
- tools: round.sendTools,
163
- opts,
164
- sessionId,
165
- sessionRef,
166
- nextIteration: round.nextIteration,
167
- contextOverflowRetryUsed: state.contextOverflowRetryUsed,
168
- transportRetriesUsed: state.transportRetriesUsed,
169
- transportRetryMax: state.transportRetryMax,
170
- imageStripUsed: state.imageStripUsed,
171
- thinkingReplayRepairUsed: state.thinkingReplayRepairUsed,
172
- signal: state.signal,
173
- })
174
- );
172
+ // The request a /btw side question forks: kept while it is in flight, with
173
+ // its reply once it proceeds, and dropped again if it fails.
174
+ const sideQuestion = captureSideQuestionRequest({
175
+ sessionId,
176
+ sessionRef,
177
+ provider,
178
+ model,
179
+ messages: providerMessages,
180
+ tools: round.sendTools,
181
+ opts,
182
+ });
183
+ let result;
184
+ try {
185
+ result = await runWithProviderRequestToolsScope(round.requestToolScope, () =>
186
+ sendWithRecovery({
187
+ provider,
188
+ messages: providerMessages,
189
+ recoveryMessages: messageSource,
190
+ model,
191
+ sendTools: round.sendTools,
192
+ tools: round.sendTools,
193
+ opts,
194
+ sessionId,
195
+ sessionRef,
196
+ nextIteration: round.nextIteration,
197
+ contextOverflowRetryUsed: state.contextOverflowRetryUsed,
198
+ transportRetriesUsed: state.transportRetriesUsed,
199
+ transportRetryMax: state.transportRetryMax,
200
+ imageStripUsed: state.imageStripUsed,
201
+ thinkingReplayRepairUsed: state.thinkingReplayRepairUsed,
202
+ toolSchemaDropUsed: state.toolSchemaDropUsed,
203
+ signal: state.signal,
204
+ })
205
+ );
206
+ } catch (error) {
207
+ sideQuestion?.discard();
208
+ throw error;
209
+ }
210
+ if (result.action === 'proceed') sideQuestion?.settle(result.response);
211
+ else sideQuestion?.discard();
175
212
  return {
176
213
  result,
177
214
  providerMessages,
@@ -213,6 +250,16 @@ export function applyRetryAction(state, result) {
213
250
  // transport budget is consumed: nothing was generated.
214
251
  state.thinkingReplayRepairUsed = true;
215
252
  return true;
253
+ case 'retry_tool_schema_drop':
254
+ // The provider named a tool whose schema it rejects: the session drops
255
+ // it (with the notice) and the turn is rebuilt without it, once. The
256
+ // frozen tool surface and provider state are rebuilt around the change.
257
+ state.toolSchemaDropUsed = true;
258
+ dropSessionTool(state.sessionRef, result.exclusion, state.opts.onStageChange);
259
+ state.fixedProviderToolSurface = null;
260
+ state.providerState = undefined;
261
+ state.providerStateUpdated = true;
262
+ return true;
216
263
  case 'retry_image_strip':
217
264
  state.transportRetriesUsed += 1;
218
265
  state.imageStripUsed = true;