mixdog 1.2.2 → 1.2.4

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 (692) hide show
  1. package/README.md +18 -0
  2. package/package.json +2 -1
  3. package/scripts/gate-local.mjs +6 -4
  4. package/scripts/lib/gate-scheduler.mjs +29 -11
  5. package/scripts/probe-provider-catalog.mjs +31 -0
  6. package/scripts/provider-pingpong-live.mjs +599 -0
  7. package/scripts/session-sweep.mjs +5 -25
  8. package/src/agents/advisor/AGENT.md +1 -1
  9. package/src/agents/advisor/agent.json +1 -1
  10. package/src/agents/maintainer/AGENT.md +1 -1
  11. package/src/agents/maintainer/agent.json +1 -1
  12. package/src/agents/reviewer/AGENT.md +2 -4
  13. package/src/agents/security/AGENT.md +1 -2
  14. package/src/agents/writer/AGENT.md +2 -3
  15. package/src/defaults/shipped-history.json +11 -1
  16. package/src/defaults/skills/image/SKILL.md +21 -23
  17. package/src/defaults/skills/setup/SKILL.md +6 -1
  18. package/src/defaults/skills/setup/references/actions.md +44 -22
  19. package/src/defaults/skills/setup/references/surfaces.md +10 -8
  20. package/src/headless-exec.mjs +15 -8
  21. package/src/lib/keychain-cjs.cjs +20 -15
  22. package/src/output-styles/common.md +11 -10
  23. package/src/rules/agent/AGENT.md +6 -4
  24. package/src/rules/lead/LEAD.md +7 -9
  25. package/src/rules/shared/45-destructive.md +4 -0
  26. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/preset.mjs +1 -0
  27. package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +28 -7
  28. package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +2 -11
  29. package/src/runtime/agent/orchestrator/agent-trace-io.mjs +92 -61
  30. package/src/runtime/agent/orchestrator/cache-mtime.mjs +10 -1
  31. package/src/runtime/agent/orchestrator/config-providers-merge.mjs +7 -0
  32. package/src/runtime/agent/orchestrator/config.mjs +5 -0
  33. package/src/runtime/agent/orchestrator/context/collect.mjs +1 -0
  34. package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +26 -7
  35. package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +112 -7
  36. package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +101 -23
  37. package/src/runtime/agent/orchestrator/providers/account-pool.mjs +2 -0
  38. package/src/runtime/agent/orchestrator/providers/anthropic-api-key-fetch.mjs +36 -0
  39. package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +48 -20
  40. package/src/runtime/agent/orchestrator/providers/anthropic-error-contract.mjs +3 -1
  41. package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens.mjs +24 -17
  42. package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +9 -9
  43. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
  44. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/gzip-post.mjs +26 -44
  45. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +31 -15
  46. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-blocks.mjs +20 -1
  47. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-delta.mjs +15 -2
  48. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-start.mjs +11 -4
  49. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/message-events.mjs +3 -0
  50. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events.mjs +12 -5
  51. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-outcome.mjs +1 -0
  52. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-state.mjs +14 -0
  53. package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +2 -0
  54. package/src/runtime/agent/orchestrator/providers/anthropic-turn-result.mjs +9 -0
  55. package/src/runtime/agent/orchestrator/providers/anthropic.mjs +10 -0
  56. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-catalog.mjs +41 -12
  57. package/src/runtime/agent/orchestrator/providers/antigravity-oauth.mjs +13 -1
  58. package/src/runtime/agent/orchestrator/providers/antigravity-request.mjs +131 -9
  59. package/src/runtime/agent/orchestrator/providers/antigravity-response.mjs +29 -10
  60. package/src/runtime/agent/orchestrator/providers/antigravity-retry-policy.mjs +125 -8
  61. package/src/runtime/agent/orchestrator/providers/antigravity-stream.mjs +12 -62
  62. package/src/runtime/agent/orchestrator/providers/antigravity-transport.mjs +117 -41
  63. package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +1 -1
  64. package/src/runtime/agent/orchestrator/providers/command-code-oauth.mjs +117 -72
  65. package/src/runtime/agent/orchestrator/providers/compat-request-policy.mjs +78 -2
  66. package/src/runtime/agent/orchestrator/providers/cursor-auth.mjs +39 -5
  67. package/src/runtime/agent/orchestrator/providers/cursor-client-version.mjs +1 -1
  68. package/src/runtime/agent/orchestrator/providers/cursor-native-context.mjs +48 -0
  69. package/src/runtime/agent/orchestrator/providers/cursor-wire-exec.mjs +144 -34
  70. package/src/runtime/agent/orchestrator/providers/cursor-wire-protobuf.mjs +28 -4
  71. package/src/runtime/agent/orchestrator/providers/cursor-wire-request.mjs +8 -4
  72. package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-bridge.mjs +42 -11
  73. package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-messages.mjs +109 -6
  74. package/src/runtime/agent/orchestrator/providers/cursor-wire.mjs +17 -4
  75. package/src/runtime/agent/orchestrator/providers/cursor.mjs +22 -2
  76. package/src/runtime/agent/orchestrator/providers/custom-provider-config.mjs +73 -7
  77. package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +75 -6
  78. package/src/runtime/agent/orchestrator/providers/custom-reasoning.mjs +34 -7
  79. package/src/runtime/agent/orchestrator/providers/custom-tool-wire.mjs +32 -6
  80. package/src/runtime/agent/orchestrator/providers/deepseek.mjs +67 -0
  81. package/src/runtime/agent/orchestrator/providers/effort-configuration.mjs +29 -5
  82. package/src/runtime/agent/orchestrator/providers/gemini-cache-policy.mjs +11 -4
  83. package/src/runtime/agent/orchestrator/providers/gemini-cache.mjs +36 -13
  84. package/src/runtime/agent/orchestrator/providers/gemini-error-contract.mjs +101 -11
  85. package/src/runtime/agent/orchestrator/providers/gemini-request-body.mjs +41 -5
  86. package/src/runtime/agent/orchestrator/providers/gemini-response.mjs +1 -0
  87. package/src/runtime/agent/orchestrator/providers/gemini-rest-stream/watchdogs.mjs +16 -5
  88. package/src/runtime/agent/orchestrator/providers/gemini-retry-policy.mjs +19 -14
  89. package/src/runtime/agent/orchestrator/providers/gemini-schema.mjs +371 -41
  90. package/src/runtime/agent/orchestrator/providers/gemini-sdk-request.mjs +1 -2
  91. package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +97 -49
  92. package/src/runtime/agent/orchestrator/providers/gemini-thinking.mjs +81 -10
  93. package/src/runtime/agent/orchestrator/providers/gemini.mjs +35 -8
  94. package/src/runtime/agent/orchestrator/providers/grok-client-version.mjs +1 -1
  95. package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +1 -0
  96. package/src/runtime/agent/orchestrator/providers/lib/action-input-contract.mjs +60 -0
  97. package/src/runtime/agent/orchestrator/providers/lib/anthropic-native-blocks.mjs +1 -0
  98. package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +253 -42
  99. package/src/runtime/agent/orchestrator/providers/lib/anthropic-server-tool-usage.mjs +18 -0
  100. package/src/runtime/agent/orchestrator/providers/lib/anthropic-system-blocks.mjs +27 -6
  101. package/src/runtime/agent/orchestrator/providers/lib/claude-bridge-schema.mjs +392 -0
  102. package/src/runtime/agent/orchestrator/providers/lib/inclusive-usage.mjs +54 -0
  103. package/src/runtime/agent/orchestrator/providers/lib/origin-bound-fetch.mjs +16 -0
  104. package/src/runtime/agent/orchestrator/providers/lib/request-compression.mjs +86 -0
  105. package/src/runtime/agent/orchestrator/providers/lib/responses-terminal-fields.mjs +11 -0
  106. package/src/runtime/agent/orchestrator/providers/lib/usage-primitives.mjs +8 -0
  107. package/src/runtime/agent/orchestrator/providers/lib/wire-pairing.mjs +50 -22
  108. package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +133 -21
  109. package/src/runtime/agent/orchestrator/providers/mimo-oauth-profile.mjs +13 -15
  110. package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +7 -1
  111. package/src/runtime/agent/orchestrator/providers/model-proxy-channel.d.mts +1 -1
  112. package/src/runtime/agent/orchestrator/providers/model-proxy-channel.mjs +1 -0
  113. package/src/runtime/agent/orchestrator/providers/model-proxy-provider.mjs +92 -16
  114. package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +13 -13
  115. package/src/runtime/agent/orchestrator/providers/openai-codex-metadata.mjs +2 -0
  116. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +133 -62
  117. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/chunk-events.mjs +35 -14
  118. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-result.mjs +5 -2
  119. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +39 -7
  120. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/tool-call-acc.mjs +2 -9
  121. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +5 -0
  122. package/src/runtime/agent/orchestrator/providers/openai-compat-error-contract.mjs +1 -1
  123. package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +84 -2
  124. package/src/runtime/agent/orchestrator/providers/openai-compat-options.mjs +47 -25
  125. package/src/runtime/agent/orchestrator/providers/openai-compat-presets.mjs +5 -1
  126. package/src/runtime/agent/orchestrator/providers/openai-compat-reasoning-field.mjs +155 -0
  127. package/src/runtime/agent/orchestrator/providers/openai-compat-response-normalization.mjs +40 -24
  128. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-events.mjs +63 -25
  129. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-head-parity.json +2901 -0
  130. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-parity.fixtures.mjs +183 -0
  131. package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +87 -6
  132. package/src/runtime/agent/orchestrator/providers/openai-compat-retry-profile.mjs +51 -3
  133. package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +7 -1
  134. package/src/runtime/agent/orchestrator/providers/openai-compat-trace.mjs +2 -0
  135. package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +103 -26
  136. package/src/runtime/agent/orchestrator/providers/openai-compat-xai-send.mjs +23 -4
  137. package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +11 -6
  138. package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +17 -2
  139. package/src/runtime/agent/orchestrator/providers/openai-direct-request.mjs +15 -23
  140. package/src/runtime/agent/orchestrator/providers/openai-http-sse-request.mjs +64 -52
  141. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/output-items.mjs +23 -10
  142. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/terminal-frames.mjs +28 -5
  143. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events.mjs +10 -0
  144. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-items.mjs +18 -7
  145. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-outcome.mjs +4 -0
  146. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-state.mjs +5 -0
  147. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/text-relay.mjs +9 -1
  148. package/src/runtime/agent/orchestrator/providers/openai-model-capabilities.mjs +80 -0
  149. package/src/runtime/agent/orchestrator/providers/openai-oauth-dispatch.mjs +3 -1
  150. package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +7 -0
  151. package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +7 -1
  152. package/src/runtime/agent/orchestrator/providers/openai-responses-input.mjs +72 -24
  153. package/src/runtime/agent/orchestrator/providers/openai-responses-payload-parity.fixture.json +323 -0
  154. package/src/runtime/agent/orchestrator/providers/openai-responses-payload.mjs +50 -16
  155. package/src/runtime/agent/orchestrator/providers/openai-ws-delta.mjs +7 -19
  156. package/src/runtime/agent/orchestrator/providers/openai-ws-response-state/refusals.mjs +60 -0
  157. package/src/runtime/agent/orchestrator/providers/openai-ws-response-state/tool-calls.mjs +51 -36
  158. package/src/runtime/agent/orchestrator/providers/openai-ws-response-state.mjs +30 -0
  159. package/src/runtime/agent/orchestrator/providers/openai-ws-stream/event-switch.mjs +12 -0
  160. package/src/runtime/agent/orchestrator/providers/openai-ws-stream/terminal-frames.mjs +25 -6
  161. package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +18 -9
  162. package/src/runtime/agent/orchestrator/providers/opencode-go-gemini.mjs +181 -0
  163. package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +78 -70
  164. package/src/runtime/agent/orchestrator/providers/openrouter.mjs +74 -0
  165. package/src/runtime/agent/orchestrator/providers/provider-error-kind.mjs +150 -10
  166. package/src/runtime/agent/orchestrator/providers/registry.mjs +13 -2
  167. package/src/runtime/agent/orchestrator/providers/retry-classification.mjs +7 -1
  168. package/src/runtime/agent/orchestrator/providers/transport-scope.d.mts +6 -0
  169. package/src/runtime/agent/orchestrator/providers/transport-scope.mjs +28 -0
  170. package/src/runtime/agent/orchestrator/providers/wire-gateway.mjs +164 -0
  171. package/src/runtime/agent/orchestrator/providers/wire-route.mjs +522 -0
  172. package/src/runtime/agent/orchestrator/providers/xai-tool-search-head-parity.json +1131 -0
  173. package/src/runtime/agent/orchestrator/providers/xai-tool-search.fixtures.mjs +195 -0
  174. package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +104 -0
  175. package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +8 -6
  176. package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-availability.mjs +24 -0
  177. package/src/runtime/agent/orchestrator/runtime-core/effort.mjs +15 -0
  178. package/src/runtime/agent/orchestrator/runtime-core/goal-store.mjs +30 -2
  179. package/src/runtime/agent/orchestrator/runtime-core/goal-turns.mjs +3 -2
  180. package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +8 -3
  181. package/src/runtime/agent/orchestrator/runtime-core/provider-request-snapshot.mjs +7 -3
  182. package/src/runtime/agent/orchestrator/runtime-core/session-title.mjs +21 -1
  183. package/src/runtime/agent/orchestrator/runtime-core/skill-tool-loading.mjs +16 -3
  184. package/src/runtime/agent/orchestrator/runtime-core/tool-bridge-contract.mjs +6 -0
  185. package/src/runtime/agent/orchestrator/runtime-core/tool-bridge.mjs +526 -0
  186. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-data.mjs +3 -0
  187. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-schema.mjs +10 -7
  188. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +178 -71
  189. package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +102 -12
  190. package/src/runtime/agent/orchestrator/runtime-core/tool-exposure.mjs +96 -0
  191. package/src/runtime/agent/orchestrator/runtime-core/workflow.mjs +10 -8
  192. package/src/runtime/agent/orchestrator/session/agent-loop.mjs +1 -2
  193. package/src/runtime/agent/orchestrator/session/agent-pool-progress.mjs +24 -0
  194. package/src/runtime/agent/orchestrator/session/cache/tool-result-reuse.mjs +10 -2
  195. package/src/runtime/agent/orchestrator/session/catalog-db/index.mjs +2 -3
  196. package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +5 -11
  197. package/src/runtime/agent/orchestrator/session/catalog-db/worker.mjs +6 -22
  198. package/src/runtime/agent/orchestrator/session/compact/constants.mjs +3 -2
  199. package/src/runtime/agent/orchestrator/session/compact/messages.mjs +16 -93
  200. package/src/runtime/agent/orchestrator/session/compact/runner.mjs +16 -2
  201. package/src/runtime/agent/orchestrator/session/compact/summary-anchor.mjs +5 -0
  202. package/src/runtime/agent/orchestrator/session/compact/user-message-kind.mjs +148 -0
  203. package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +1 -1
  204. package/src/runtime/agent/orchestrator/session/context-tool-schema.mjs +17 -2
  205. package/src/runtime/agent/orchestrator/session/context-utils.mjs +8 -4
  206. package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +0 -6
  207. package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +0 -6
  208. package/src/runtime/agent/orchestrator/session/eager-dispatch/admission.mjs +3 -2
  209. package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +6 -1
  210. package/src/runtime/agent/orchestrator/session/historical-session-closure.mjs +10 -0
  211. package/src/runtime/agent/orchestrator/session/loop/assistant-commit.mjs +2 -5
  212. package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +89 -1
  213. package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +1 -1
  214. package/src/runtime/agent/orchestrator/session/loop/context-overflow.mjs +56 -0
  215. package/src/runtime/agent/orchestrator/session/loop/deferred-call-through.mjs +18 -8
  216. package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +1 -27
  217. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/output-limit.mjs +1 -1
  218. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/segments.mjs +4 -10
  219. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +2 -9
  220. package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +24 -10
  221. package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +135 -0
  222. package/src/runtime/agent/orchestrator/session/loop/request-boundary.mjs +31 -4
  223. package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +76 -0
  224. package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +67 -20
  225. package/src/runtime/agent/orchestrator/session/loop/step-auto-effort.mjs +10 -10
  226. package/src/runtime/agent/orchestrator/session/loop/tool-call-resolution.mjs +95 -0
  227. package/src/runtime/agent/orchestrator/session/loop/tool-classify.mjs +6 -0
  228. package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +30 -3
  229. package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +29 -5
  230. package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +15 -1
  231. package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +147 -0
  232. package/src/runtime/agent/orchestrator/session/loop/tool-phase.mjs +7 -5
  233. package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +33 -3
  234. package/src/runtime/agent/orchestrator/session/manager/ask-support.mjs +0 -4
  235. package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +23 -2
  236. package/src/runtime/agent/orchestrator/session/manager/ask-turn-commit.mjs +34 -12
  237. package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +54 -13
  238. package/src/runtime/agent/orchestrator/session/manager/ask-turn-failure.mjs +33 -0
  239. package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +57 -25
  240. package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +11 -0
  241. package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +22 -0
  242. package/src/runtime/agent/orchestrator/session/manager/ask-turn-state.mjs +57 -13
  243. package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +8 -0
  244. package/src/runtime/agent/orchestrator/session/manager/failed-turn-rewind.mjs +16 -0
  245. package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +6 -120
  246. package/src/runtime/agent/orchestrator/session/manager/pending-persist-queue.mjs +1 -1
  247. package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +231 -16
  248. package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +42 -49
  249. package/src/runtime/agent/orchestrator/session/manager/runtime-state.mjs +50 -0
  250. package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +47 -17
  251. package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +26 -4
  252. package/src/runtime/agent/orchestrator/session/manager/session-fallback-title.mjs +82 -0
  253. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +36 -35
  254. package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +29 -13
  255. package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +6 -3
  256. package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +4 -1
  257. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-recovery.mjs +45 -0
  258. package/src/runtime/agent/orchestrator/session/manager.mjs +4 -10
  259. package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +6 -0
  260. package/src/runtime/agent/orchestrator/session/send-instrumentation.mjs +2 -1
  261. package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +17 -1
  262. package/src/runtime/agent/orchestrator/session/side-question-store.mjs +96 -0
  263. package/src/runtime/agent/orchestrator/session/side-question.mjs +197 -0
  264. package/src/runtime/agent/orchestrator/session/store/lifecycle-barriers.mjs +22 -15
  265. package/src/runtime/agent/orchestrator/session/store/lifecycle-read.mjs +1 -1
  266. package/src/runtime/agent/orchestrator/session/store/listing.mjs +2 -6
  267. package/src/runtime/agent/orchestrator/session/store/live-cache-eviction.mjs +1 -1
  268. package/src/runtime/agent/orchestrator/session/store/live-state.mjs +23 -0
  269. package/src/runtime/agent/orchestrator/session/store/liveness-veto.mjs +46 -37
  270. package/src/runtime/agent/orchestrator/session/store/load-cache.mjs +1 -1
  271. package/src/runtime/agent/orchestrator/session/store/load-session.mjs +1 -1
  272. package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +44 -37
  273. package/src/runtime/agent/orchestrator/session/store/session-observers.mjs +4 -2
  274. package/src/runtime/agent/orchestrator/session/store/session-paths.mjs +59 -0
  275. package/src/runtime/agent/orchestrator/session/store/summary-cache.mjs +1 -1
  276. package/src/runtime/agent/orchestrator/session/store/sweep/stale-sweep.mjs +1 -1
  277. package/src/runtime/agent/orchestrator/session/store/sweep/sweep-finish.mjs +27 -21
  278. package/src/runtime/agent/orchestrator/session/store/sweep/sweep-plan.mjs +0 -8
  279. package/src/runtime/agent/orchestrator/session/store/sweep/sweep-record.mjs +6 -18
  280. package/src/runtime/agent/orchestrator/session/store/sweep/sweep-row.mjs +33 -106
  281. package/src/runtime/agent/orchestrator/session/store/write-admission.mjs +4 -2
  282. package/src/runtime/agent/orchestrator/session/store-agent-worker-pool.mjs +5 -8
  283. package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +136 -196
  284. package/src/runtime/agent/orchestrator/session/store-summary-archived-agent.mjs +34 -15
  285. package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +53 -115
  286. package/src/runtime/agent/orchestrator/session/store-summary-fields.mjs +8 -0
  287. package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +10 -1
  288. package/src/runtime/agent/orchestrator/session/store-summary-locations.mjs +3 -29
  289. package/src/runtime/agent/orchestrator/session/store-summary-reader-catalog-fixture.mjs +1 -1
  290. package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +17 -10
  291. package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +9 -20
  292. package/src/runtime/agent/orchestrator/session/store.mjs +22 -19
  293. package/src/runtime/agent/orchestrator/session/tool-batch/execute-call.mjs +12 -12
  294. package/src/runtime/agent/orchestrator/session/tool-batch/finalize.mjs +38 -14
  295. package/src/runtime/agent/orchestrator/session/tool-batch/pre-dispatch.mjs +15 -4
  296. package/src/runtime/agent/orchestrator/session/tool-batch/record-outcome.mjs +1 -1
  297. package/src/runtime/agent/orchestrator/session/tool-batch/state.mjs +7 -1
  298. package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +4 -0
  299. package/src/runtime/agent/orchestrator/session/tool-schema-rejection.mjs +79 -0
  300. package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +72 -15
  301. package/src/runtime/agent/orchestrator/session/turn-failure.mjs +45 -0
  302. package/src/runtime/agent/orchestrator/stall-policy.mjs +50 -0
  303. package/src/runtime/agent/orchestrator/tools/bash-policy-scan.mjs +8 -2
  304. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/command-preflight.mjs +3 -3
  305. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/completed-result.mjs +5 -1
  306. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/inline-hoist.mjs +6 -2
  307. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +4 -1
  308. package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.mjs +218 -20
  309. package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +160 -39
  310. package/src/runtime/agent/orchestrator/tools/builtin/git-partial-stage.mjs +7 -5
  311. package/src/runtime/agent/orchestrator/tools/builtin/grep-formatting.mjs +14 -5
  312. package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-context-expander.mjs +4 -3
  313. package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-output.mjs +2 -1
  314. package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-path-fanout.mjs +48 -44
  315. package/src/runtime/agent/orchestrator/tools/builtin/lib/search-input-helpers.mjs +10 -3
  316. package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +247 -49
  317. package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-task-output.mjs +5 -4
  318. package/src/runtime/agent/orchestrator/tools/builtin/read-formatting.mjs +6 -1
  319. package/src/runtime/agent/orchestrator/tools/builtin/runtime-capabilities.mjs +23 -1
  320. package/src/runtime/agent/orchestrator/tools/builtin/shell-analysis.mjs +20 -0
  321. package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +101 -2
  322. package/src/runtime/agent/orchestrator/tools/code-graph/dispatch/root-resolution.mjs +1 -1
  323. package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +1 -1
  324. package/src/runtime/agent/orchestrator/tools/code-graph-prewarm-worker.mjs +1 -1
  325. package/src/runtime/agent/orchestrator/tools/lib/owned-shell-trees.mjs +67 -0
  326. package/src/runtime/agent/orchestrator/tools/lib/process-table-fixture.mjs +50 -0
  327. package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +303 -63
  328. package/src/runtime/agent/orchestrator/tools/lib/shell-run-background/promote-job.mjs +2 -0
  329. package/src/runtime/agent/orchestrator/tools/lib/shell-run-settle.mjs +108 -18
  330. package/src/runtime/agent/orchestrator/tools/lib/shell-run-spawn.mjs +77 -11
  331. package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +81 -5
  332. package/src/runtime/agent/orchestrator/tools/patch/ui-diff.mjs +73 -39
  333. package/src/runtime/agent/orchestrator/tools/progress-message.mjs +18 -1
  334. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +7 -4
  335. package/src/runtime/agent/orchestrator/tools/shell-exec-policy.mjs +88 -12
  336. package/src/runtime/agent/orchestrator/tools/shell-policy.mjs +2 -0
  337. package/src/runtime/attachments/store.d.mts +9 -0
  338. package/src/runtime/attachments/store.mjs +80 -9
  339. package/src/runtime/browser-bridge/browser-action-contract.d.mts +0 -1
  340. package/src/runtime/browser-bridge/browser-action-contract.mjs +0 -2
  341. package/src/runtime/computer-bridge/action-schema.mjs +219 -196
  342. package/src/runtime/computer-bridge/linux-readiness.d.mts +0 -2
  343. package/src/runtime/computer-bridge/linux-readiness.mjs +0 -16
  344. package/src/runtime/effort-judge/judge-client.mjs +21 -4
  345. package/src/runtime/effort-judge/judge-worker.mjs +4 -1
  346. package/src/runtime/github/tool.mjs +208 -17
  347. package/src/runtime/media/adapters/codex-image.mjs +140 -21
  348. package/src/runtime/media/catalog.mjs +4 -4
  349. package/src/runtime/media/chatgpt-usage.mjs +55 -0
  350. package/src/runtime/media/defaults.mjs +37 -0
  351. package/src/runtime/media/jobs.mjs +12 -2
  352. package/src/runtime/media/lanes.mjs +12 -0
  353. package/src/runtime/media/tool-defs.mjs +15 -4
  354. package/src/runtime/media/tool.mjs +41 -12
  355. package/src/runtime/media/upstream-error.mjs +72 -6
  356. package/src/runtime/memory/index.mjs +1 -0
  357. package/src/runtime/memory/lib/http-router/ingest-routes.mjs +22 -1
  358. package/src/runtime/memory/lib/ingest/transcript-offsets.mjs +2 -0
  359. package/src/runtime/memory/lib/ingest/transcript-rows.mjs +1 -0
  360. package/src/runtime/memory/lib/pg/adapter.mjs +98 -1
  361. package/src/runtime/memory/lib/pg/process.mjs +36 -33
  362. package/src/runtime/memory/lib/pg/run-child.mjs +49 -0
  363. package/src/runtime/memory/lib/pg/supervisor.mjs +112 -4
  364. package/src/runtime/memory/lib/runtime-fetcher.mjs +12 -13
  365. package/src/runtime/memory/lib/transcript-ingest.mjs +14 -0
  366. package/src/runtime/office/README.md +1 -1
  367. package/src/runtime/office/authoring/docx-html-runner.mjs +1 -1
  368. package/src/runtime/office/authoring/html-browser.mjs +18 -8
  369. package/src/runtime/office/authoring/html-document-author.mjs +2 -0
  370. package/src/runtime/office/authoring/pdf-html-runner.mjs +1 -1
  371. package/src/runtime/office/authoring/pptx-contact-sheet.mjs +2 -0
  372. package/src/runtime/office/authoring/pptx-html-measure.mjs +3 -1
  373. package/src/runtime/office/authoring/pptx-html-runner.mjs +2 -0
  374. package/src/runtime/office/authoring/xlsx-html-runner.mjs +3 -1
  375. package/src/runtime/office/core/office-actions-read.mjs +3 -0
  376. package/src/runtime/office/core/office-render-preview.mjs +2 -0
  377. package/src/runtime/office/core/office-session-dispatch.mjs +7 -0
  378. package/src/runtime/office/core/office-sessionless-actions.mjs +8 -0
  379. package/src/runtime/office/core/office-sessions.mjs +5 -0
  380. package/src/runtime/office/core/office-transactions.mjs +3 -0
  381. package/src/runtime/office/core/office-write-ledger.mjs +94 -0
  382. package/src/runtime/office/design/library/templates/mixdog-executive.mixdog-edit.pptx +0 -0
  383. package/src/runtime/office/index.mjs +29 -0
  384. package/src/runtime/office/pdf/pdf-analysis.mjs +0 -68
  385. package/src/runtime/office/pdf/pdf-edit-document.mjs +2 -0
  386. package/src/runtime/office/pdf/pdf-render.mjs +23 -7
  387. package/src/runtime/office/pdf/pdf-security.mjs +2 -0
  388. package/src/runtime/office/portable/portable-opc.mjs +4 -1
  389. package/src/runtime/office/quality/visual-diff.mjs +2 -0
  390. package/src/runtime/session-search/session-search-ingest.mjs +1 -1
  391. package/src/runtime/shared/agent-reap-state.mjs +13 -0
  392. package/src/runtime/shared/atomic-file.d.mts +1 -1
  393. package/src/runtime/shared/background-tasks.mjs +6 -1
  394. package/src/runtime/shared/bounded-file-read.mjs +13 -0
  395. package/src/runtime/shared/bounded-line-diff.mjs +191 -0
  396. package/src/runtime/shared/browser-launch.mjs +15 -0
  397. package/src/runtime/shared/buffered-appender.mjs +18 -0
  398. package/src/runtime/shared/config.mjs +78 -18
  399. package/src/runtime/shared/err-text.mjs +48 -4
  400. package/src/runtime/shared/file-lock.mjs +6 -5
  401. package/src/runtime/shared/file-permissions.d.mts +6 -1
  402. package/src/runtime/shared/file-permissions.mjs +54 -6
  403. package/src/runtime/shared/llm/anthropic-betas.mjs +1 -2
  404. package/src/runtime/shared/llm/anthropic-effort.mjs +6 -0
  405. package/src/runtime/shared/llm/provider-model-identities.mjs +1 -0
  406. package/src/runtime/shared/llm/usage-accounting.mjs +5 -2
  407. package/src/runtime/shared/llm/usage-ledger-rollup.mjs +3 -0
  408. package/src/runtime/shared/loopback-listener.mjs +9 -0
  409. package/src/runtime/shared/model-route-chain.d.mts +8 -0
  410. package/src/runtime/shared/model-route-chain.mjs +48 -0
  411. package/src/runtime/shared/model-route-fallback.mjs +22 -0
  412. package/src/runtime/shared/pid-liveness.mjs +12 -0
  413. package/src/runtime/shared/provider-api-key.mjs +8 -0
  414. package/src/runtime/shared/provider-timeout-phase.mjs +17 -0
  415. package/src/runtime/shared/quiet-progress.d.mts +35 -0
  416. package/src/runtime/shared/quiet-progress.mjs +101 -0
  417. package/src/runtime/shared/quota-resume-store.mjs +32 -1
  418. package/src/runtime/shared/read-row-numbers.mjs +44 -0
  419. package/src/runtime/shared/remote-intent.mjs +2 -42
  420. package/src/runtime/shared/review-diff.mjs +52 -0
  421. package/src/runtime/shared/session-sidebar-host.d.mts +4 -0
  422. package/src/runtime/shared/session-sidebar-host.mjs +38 -0
  423. package/src/runtime/shared/slow-span.mjs +121 -0
  424. package/src/runtime/shared/statusline/statusline-segments.mjs +52 -6
  425. package/src/runtime/shared/tool-card-model/card-header.mjs +7 -1
  426. package/src/runtime/shared/tool-card-model/generic-detail.mjs +39 -5
  427. package/src/runtime/shared/tool-card-model.mjs +5 -2
  428. package/src/runtime/shared/tool-output-budget.mjs +2 -0
  429. package/src/runtime/shared/tool-output-limit.mjs +4 -0
  430. package/src/runtime/shared/tool-primitives.mjs +13 -0
  431. package/src/runtime/shared/tool-result-summary.mjs +22 -1
  432. package/src/runtime/shared/tool-status.mjs +3 -2
  433. package/src/runtime/shared/tool-surface.mjs +20 -6
  434. package/src/runtime/shared/tool-work-units.mjs +54 -11
  435. package/src/runtime/shared/transcript-metadata.mjs +49 -1
  436. package/src/runtime/shared/transcript-turn-keys.mjs +33 -0
  437. package/src/runtime/shared/transcript-writer/purge.mjs +74 -0
  438. package/src/runtime/shared/transcript-writer/transcript-file.mjs +10 -1
  439. package/src/runtime/shared/transcript-writer.mjs +24 -6
  440. package/src/runtime/shared/turn-changes.mjs +269 -100
  441. package/src/runtime/shared/turn-review-reply.mjs +8 -39
  442. package/src/runtime/shared/turn-snapshot-store.mjs +19 -108
  443. package/src/runtime/shared/turn-snapshot.mjs +865 -683
  444. package/src/runtime/shared/turn-worktree-snapshot.mjs +183 -255
  445. package/src/runtime/shared/user-data-guard.mjs +262 -49
  446. package/src/runtime/shared/worktrees/activity-gate.mjs +175 -0
  447. package/src/runtime/shared/worktrees/branch-management.mjs +179 -0
  448. package/src/runtime/shared/worktrees/carry.mjs +533 -0
  449. package/src/runtime/shared/worktrees/contract.mjs +60 -0
  450. package/src/runtime/shared/worktrees/dependencies.mjs +456 -0
  451. package/src/runtime/shared/worktrees/file-recovery.mjs +84 -0
  452. package/src/runtime/shared/worktrees/git-head.mjs +214 -0
  453. package/src/runtime/shared/worktrees/git.mjs +8 -3
  454. package/src/runtime/shared/worktrees/include.mjs +125 -7
  455. package/src/runtime/shared/worktrees/lock.mjs +1 -1
  456. package/src/runtime/shared/worktrees/maintenance.mjs +20 -2
  457. package/src/runtime/shared/worktrees/manager.mjs +525 -31
  458. package/src/runtime/shared/worktrees/merge.mjs +31 -21
  459. package/src/runtime/shared/worktrees/owner.mjs +2 -1
  460. package/src/runtime/shared/worktrees/paths.d.mts +6 -0
  461. package/src/runtime/shared/worktrees/preparation-report.mjs +79 -0
  462. package/src/runtime/shared/worktrees/setup-commands.mjs +232 -0
  463. package/src/runtime/shared/worktrees/workspace-visibility.mjs +17 -0
  464. package/src/runtime/terminal-bridge/client.mjs +57 -20
  465. package/src/runtime/terminal-bridge/tool-defs.mjs +13 -6
  466. package/src/runtime/tidy/apply.mjs +47 -2
  467. package/src/runtime/tidy/run-engines.mjs +11 -5
  468. package/src/session-runtime/agent-tool-routing.mjs +19 -13
  469. package/src/session-runtime/boot/apis.mjs +20 -6
  470. package/src/session-runtime/boot/config.mjs +2 -0
  471. package/src/session-runtime/boot/facade.mjs +4 -0
  472. package/src/session-runtime/boot/infrastructure.mjs +6 -1
  473. package/src/session-runtime/boot/session.mjs +3 -3
  474. package/src/session-runtime/boot/tools.mjs +7 -1
  475. package/src/session-runtime/conversation-import/service.mjs +1 -1
  476. package/src/session-runtime/cwd-plugins/cwd-apply.mjs +12 -5
  477. package/src/session-runtime/goal-facade-api.mjs +2 -2
  478. package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +91 -0
  479. package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +3 -1
  480. package/src/session-runtime/internal-tool-executor/knowledge-tools.mjs +15 -5
  481. package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +137 -26
  482. package/src/session-runtime/internal-tool-executor.mjs +8 -2
  483. package/src/session-runtime/lifecycle/cold-heir.mjs +187 -0
  484. package/src/session-runtime/lifecycle/inheritance.mjs +71 -27
  485. package/src/session-runtime/lifecycle/session-catalog.mjs +25 -18
  486. package/src/session-runtime/lifecycle/session-switch/resume.mjs +6 -0
  487. package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +36 -48
  488. package/src/session-runtime/lifecycle/session-switch.mjs +1 -1
  489. package/src/session-runtime/lifecycle/shared.mjs +5 -6
  490. package/src/session-runtime/lifecycle/teardown/session-close.mjs +6 -5
  491. package/src/session-runtime/lifecycle/teardown.mjs +70 -14
  492. package/src/session-runtime/lifecycle-api.mjs +1 -0
  493. package/src/session-runtime/mcp-glue/connect.mjs +17 -5
  494. package/src/session-runtime/media-api.mjs +8 -0
  495. package/src/session-runtime/model-route/route-ownership.mjs +60 -0
  496. package/src/session-runtime/model-route/route-persist.mjs +3 -2
  497. package/src/session-runtime/model-route/set-route.mjs +116 -36
  498. package/src/session-runtime/model-route/web-search-route.mjs +7 -2
  499. package/src/session-runtime/model-route-api.mjs +4 -2
  500. package/src/session-runtime/native-web-search/routes.mjs +37 -24
  501. package/src/session-runtime/native-web-search-usage.mjs +51 -0
  502. package/src/session-runtime/native-web-search.mjs +19 -9
  503. package/src/session-runtime/new-session-config.mjs +4 -2
  504. package/src/session-runtime/provider-auth/login.mjs +4 -0
  505. package/src/session-runtime/provider-auth/setup.mjs +4 -0
  506. package/src/session-runtime/provider-models/catalog-load.mjs +9 -0
  507. package/src/session-runtime/provider-models/web-search-catalog.mjs +23 -3
  508. package/src/session-runtime/provider-models.mjs +1 -0
  509. package/src/session-runtime/provider-usage.mjs +4 -0
  510. package/src/session-runtime/resource-scope-decorate.mjs +10 -3
  511. package/src/session-runtime/route-resolution.mjs +3 -1
  512. package/src/session-runtime/runtime-core.mjs +4 -0
  513. package/src/session-runtime/runtime-facade.mjs +6 -0
  514. package/src/session-runtime/runtime-review-api.mjs +8 -2
  515. package/src/session-runtime/services/agent-task-status.mjs +2 -0
  516. package/src/session-runtime/services/agent-tool/close-flow/close-all.mjs +0 -3
  517. package/src/session-runtime/services/agent-tool/close-flow.mjs +6 -7
  518. package/src/session-runtime/services/agent-tool/execute-send.mjs +2 -2
  519. package/src/session-runtime/services/agent-tool/execute-spawn.mjs +36 -3
  520. package/src/session-runtime/services/agent-tool/execute.mjs +9 -1
  521. package/src/session-runtime/services/agent-tool/helpers.mjs +30 -7
  522. package/src/session-runtime/services/agent-tool/index-write-queue.mjs +81 -20
  523. package/src/session-runtime/services/agent-tool/job-task-reconcile.mjs +7 -2
  524. package/src/session-runtime/services/agent-tool/job-views/session-progress.mjs +6 -3
  525. package/src/session-runtime/services/agent-tool/lead-worker-index/forgotten-leads.mjs +29 -0
  526. package/src/session-runtime/services/agent-tool/lead-worker-index/index-file.mjs +1 -1
  527. package/src/session-runtime/services/agent-tool/lead-worker-index/lead-rows.mjs +3 -4
  528. package/src/session-runtime/services/agent-tool/lead-worker-index/reap-timers.mjs +9 -3
  529. package/src/session-runtime/services/agent-tool/lead-worker-index/row-settlement.mjs +7 -18
  530. package/src/session-runtime/services/agent-tool/lead-worker-index.mjs +82 -13
  531. package/src/session-runtime/services/agent-tool/model-select.mjs +82 -0
  532. package/src/session-runtime/services/agent-tool/send-flow.mjs +24 -6
  533. package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +3 -1
  534. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +19 -5
  535. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +5 -4
  536. package/src/session-runtime/services/agent-tool/spawn-flow.mjs +2 -1
  537. package/src/session-runtime/services/agent-tool/spawn-preset.mjs +3 -0
  538. package/src/session-runtime/services/agent-tool/tag-registry/tag-lookup.mjs +1 -3
  539. package/src/session-runtime/services/agent-tool/tag-registry/tag-refresh.mjs +1 -3
  540. package/src/session-runtime/services/agent-tool/tag-registry.mjs +18 -10
  541. package/src/session-runtime/services/agent-tool/terminal-reaper/scan-admission.mjs +8 -41
  542. package/src/session-runtime/services/agent-tool/terminal-reaper/stale-rows.mjs +3 -3
  543. package/src/session-runtime/services/agent-tool/terminal-reaper.mjs +6 -23
  544. package/src/session-runtime/services/agent-tool/terminal-trace.mjs +0 -1
  545. package/src/session-runtime/services/agent-tool/tool-def.mjs +7 -0
  546. package/src/session-runtime/services/agent-tool/worker-index/row-liveness.mjs +32 -20
  547. package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +5 -2
  548. package/src/session-runtime/services/agent-tool/worker-index/row-store.mjs +10 -1
  549. package/src/session-runtime/services/agent-tool/worker-index.mjs +74 -15
  550. package/src/session-runtime/services/agent-tool.mjs +7 -0
  551. package/src/session-runtime/services/agent-watchdog-registry.mjs +2 -0
  552. package/src/session-runtime/services/channel-admin.mjs +19 -3
  553. package/src/session-runtime/services/memory-runtime-proxy/calls.mjs +4 -0
  554. package/src/session-runtime/services/memory-runtime-proxy.mjs +1 -0
  555. package/src/session-runtime/services/provider-admin.mjs +158 -15
  556. package/src/session-runtime/session-create/session-options.mjs +7 -5
  557. package/src/session-runtime/session-create/session-start-hook.mjs +2 -1
  558. package/src/session-runtime/session-transcript-purge.mjs +32 -0
  559. package/src/session-runtime/session-transcript.mjs +4 -5
  560. package/src/session-runtime/session-turn-api.mjs +17 -14
  561. package/src/session-runtime/settings-builtin-tools-api.mjs +18 -6
  562. package/src/session-runtime/setup-tool/executor.mjs +57 -9
  563. package/src/session-runtime/setup-tool/extended-actions.mjs +86 -6
  564. package/src/session-runtime/setup-tool/settings-contract.mjs +18 -3
  565. package/src/session-runtime/setup-tool/tool-defs.mjs +25 -4
  566. package/src/session-runtime/skills-api.mjs +3 -5
  567. package/src/session-runtime/tool-policy-refresh.mjs +83 -32
  568. package/src/session-runtime/tool-surface.mjs +5 -1
  569. package/src/session-runtime/turn/agent-ops.mjs +49 -2
  570. package/src/session-runtime/turn/compaction-gate.mjs +25 -0
  571. package/src/session-runtime/turn/session-ops.mjs +7 -5
  572. package/src/session-runtime/turn/side-question-ops.mjs +19 -0
  573. package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +7 -1
  574. package/src/session-runtime/turn/turn-run/turn-prepare.mjs +12 -3
  575. package/src/session-runtime/turn/turn-run/turn-settle.mjs +18 -2
  576. package/src/session-runtime/turn/turn-run/turn-timing.mjs +4 -3
  577. package/src/session-runtime/turn/turn-run.mjs +26 -45
  578. package/src/session-runtime/usage-stats-api.mjs +46 -11
  579. package/src/session-runtime/workflow-agents-api/agent-route.mjs +16 -1
  580. package/src/session-runtime/workspace/admission-gate.mjs +44 -15
  581. package/src/session-runtime/workspace/project-branches.mjs +35 -41
  582. package/src/session-runtime/workspace/transition-steps.mjs +215 -116
  583. package/src/session-runtime/workspace/transitions.mjs +428 -73
  584. package/src/standalone/channel-transport.mjs +3 -4
  585. package/src/standalone/daemon-agent-control.mjs +9 -1
  586. package/src/standalone/daemon-desktop-runtime.mjs +32 -1
  587. package/src/standalone/daemon-local-session-bridge.mjs +14 -1
  588. package/src/standalone/daemon-owner.mjs +17 -4
  589. package/src/standalone/daemon-pg-stop.mjs +49 -0
  590. package/src/standalone/daemon-session-control.mjs +88 -0
  591. package/src/standalone/daemon-stop-budget.d.mts +2 -0
  592. package/src/standalone/daemon-stop-budget.mjs +18 -0
  593. package/src/standalone/daemon-stored-session-views.mjs +25 -3
  594. package/src/standalone/daemon-telemetry.mjs +19 -0
  595. package/src/standalone/daemon.mjs +63 -1
  596. package/src/standalone/desktop-service-registry.mjs +5 -0
  597. package/src/standalone/local-session-runtime.mjs +80 -30
  598. package/src/standalone/session-client.mjs +42 -0
  599. package/src/standalone/session-protocol.mjs +14 -0
  600. package/src/standalone/session-proxy/projection.mjs +41 -4
  601. package/src/standalone/session-runtime-inline-host/boot-loaders.mjs +15 -1
  602. package/src/standalone/session-runtime-inline-host.mjs +3 -0
  603. package/src/standalone/session-service/agent-tree/agent-cancel.mjs +91 -49
  604. package/src/standalone/session-service/agent-tree/agent-child.mjs +19 -1
  605. package/src/standalone/session-service/agent-tree/agent-registry.mjs +25 -0
  606. package/src/standalone/session-service/agent-tree/agent-turns.mjs +9 -1
  607. package/src/standalone/session-service/agent-tree.mjs +28 -2
  608. package/src/standalone/session-service/entries/session-loads.mjs +16 -5
  609. package/src/standalone/session-service/entries.mjs +1 -0
  610. package/src/standalone/session-service/projection/transcript-window.mjs +39 -0
  611. package/src/standalone/session-service/quota-resume.mjs +28 -13
  612. package/src/standalone/session-service/session-calls/session-action.mjs +18 -3
  613. package/src/standalone/session-service/session-calls/session-turns.mjs +17 -6
  614. package/src/standalone/session-service/session-calls/session-views.mjs +6 -0
  615. package/src/standalone/session-service-api.mjs +6 -1
  616. package/src/standalone/session-state-patch.d.mts +2 -1
  617. package/src/standalone/session-state-patch.mjs +41 -1
  618. package/src/standalone/session-tool-output.mjs +82 -0
  619. package/src/tui/App.jsx +25 -0
  620. package/src/tui/app/app-view/floating-panel.jsx +26 -1
  621. package/src/tui/app/app-view.jsx +2 -1
  622. package/src/tui/app/btw-controller.mjs +118 -0
  623. package/src/tui/app/create-app-pickers.mjs +2 -0
  624. package/src/tui/app/provider-setup/provider-items.mjs +8 -0
  625. package/src/tui/app/provider-setup-picker.mjs +15 -3
  626. package/src/tui/app/shell-layout/row-budgets.mjs +11 -1
  627. package/src/tui/app/shell-layout/surfaces.mjs +3 -1
  628. package/src/tui/app/slash-commands.mjs +19 -3
  629. package/src/tui/app/slash-dispatch/session-commands.mjs +68 -6
  630. package/src/tui/app/use-global-key-input/approval-shortcut.mjs +12 -0
  631. package/src/tui/app/use-global-key-input.mjs +5 -12
  632. package/src/tui/app/use-prompt-handlers.mjs +11 -0
  633. package/src/tui/components/BtwPanel.jsx +53 -0
  634. package/src/tui/components/QuestionPanel.jsx +275 -0
  635. package/src/tui/components/Spinner.jsx +4 -0
  636. package/src/tui/components/SpinnerByline.jsx +21 -2
  637. package/src/tui/components/question-panel-model.mjs +156 -0
  638. package/src/tui/components/status-line/local-line.mjs +10 -2
  639. package/src/tui/dist/index.mjs +2897 -1722
  640. package/src/tui/session/active-tool-summary.mjs +1 -1
  641. package/src/tui/session/context-state.mjs +4 -5
  642. package/src/tui/session/goal-continuation/continuation-queue.mjs +2 -3
  643. package/src/tui/session/goal-continuation/deadline-delivery.mjs +4 -2
  644. package/src/tui/session/goal-continuation/session-boundary.mjs +21 -0
  645. package/src/tui/session/quota-resume.mjs +140 -61
  646. package/src/tui/session/session-api/commands.mjs +14 -10
  647. package/src/tui/session/session-api/controls.mjs +14 -2
  648. package/src/tui/session/session-api/integrations.mjs +9 -2
  649. package/src/tui/session/session-api/lifecycle/dispose.mjs +3 -9
  650. package/src/tui/session/session-api/lifecycle/resume.mjs +2 -7
  651. package/src/tui/session/session-api/lifecycle.mjs +14 -11
  652. package/src/tui/session/session-api/media.mjs +2 -0
  653. package/src/tui/session/session-api/routes.mjs +81 -57
  654. package/src/tui/session/session-api/settings.mjs +9 -3
  655. package/src/tui/session/session-api/worktree.mjs +3 -2
  656. package/src/tui/session/session-api.mjs +1 -0
  657. package/src/tui/session/session-flow/auto-clear.mjs +1 -3
  658. package/src/tui/session/session-flow/drain.mjs +6 -4
  659. package/src/tui/session/session-flow/queue/entry-shape.mjs +2 -0
  660. package/src/tui/session/session-flow/queue/take-entries.mjs +2 -1
  661. package/src/tui/session/session-flow/queue.mjs +1 -1
  662. package/src/tui/session/tool-approval.mjs +20 -8
  663. package/src/tui/session/transcript-spill.mjs +14 -7
  664. package/src/tui/session/transcript-store/streaming-tail.mjs +1 -1
  665. package/src/tui/session/tui-steering-persist.mjs +3 -5
  666. package/src/tui/session/turn-quiet.mjs +53 -0
  667. package/src/tui/session/turn-stream.mjs +179 -32
  668. package/src/tui/session/turn.mjs +50 -36
  669. package/src/tui/session/worktree-setup-notice.mjs +38 -0
  670. package/src/tui/spinner-meta.mjs +10 -0
  671. package/src/tui/spinner-verbs.mjs +3 -0
  672. package/src/ui/statusline.mjs +13 -3
  673. package/src/workflows/default/WORKFLOW.md +3 -1
  674. package/src/runtime/agent/orchestrator/providers/model-pricing-rates.mjs +0 -1
  675. package/src/runtime/agent/orchestrator/session/manager/foreign-pending-messages.mjs +0 -346
  676. package/src/runtime/agent/orchestrator/session/manager/session-owner-liveness.mjs +0 -117
  677. package/src/runtime/agent/orchestrator/session/store/paths-heartbeat.mjs +0 -246
  678. package/src/session-runtime/services/agent-tool/terminal-reaper/reap-timers.mjs +0 -142
  679. package/src/session-runtime/turn/share-ops.mjs +0 -77
  680. package/src/tui/session/cross-surface-share.mjs +0 -406
  681. package/src/tui/session/live-share/delta.mjs +0 -153
  682. package/src/tui/session/live-share/mirror.mjs +0 -106
  683. package/src/tui/session/live-share/owner.mjs +0 -254
  684. package/src/tui/session/live-share/retry.mjs +0 -54
  685. package/src/tui/session/live-share/viewer/frame-router.mjs +0 -32
  686. package/src/tui/session/live-share/viewer/pipe-client.mjs +0 -108
  687. package/src/tui/session/live-share/viewer/submit-acks.mjs +0 -65
  688. package/src/tui/session/live-share/viewer/sync-waiters.mjs +0 -53
  689. package/src/tui/session/live-share/viewer.mjs +0 -99
  690. package/src/tui/session/live-share/wire.mjs +0 -44
  691. package/src/tui/session/live-share.mjs +0 -154
  692. package/src/tui/session/shared-dir-watch.mjs +0 -69
@@ -15,6 +15,12 @@ export function isAntigravityClaude(model) {
15
15
  return /^claude-/i.test(String(model || ''));
16
16
  }
17
17
 
18
+ // Claude declarations are validated for the gateway's Anthropic bridge in
19
+ // toGeminiTools (claudeBridge: true); a tool with an invalid schema is left
20
+ // out of the request and reported through `onToolExcluded` / console.warn.
21
+ const claudeRequestTools = (tools, nativeTools, onToolExcluded) =>
22
+ toGeminiRequestTools(tools, nativeTools, { claudeBridge: true, onToolExcluded });
23
+
18
24
  // Default function-calling mode when the caller sets no toolChoice. VALIDATED
19
25
  // (schema-constrained function calls) is what the Antigravity client sends;
20
26
  // MIXDOG_ANTIGRAVITY_FC_MODE=AUTO|ANY|VALIDATED overrides it for A/B runs.
@@ -35,14 +41,72 @@ function replayFamilyMatches(message, model) {
35
41
  return isAntigravityClaude(recorded) === isAntigravityClaude(model);
36
42
  }
37
43
 
44
+ // The stream records empty text parts around Claude tool calls; Cloud Code's
45
+ // Claude bridge rejects them on replay ("text.text: Field required").
46
+ const isEmptyPlainTextPart = (part) =>
47
+ part?.text === '' && part.thought !== true && typeof part.thoughtSignature !== 'string';
48
+
49
+ // Streamed Claude thinking arrives as many thought deltas with the signature
50
+ // on the closing (often empty) delta; the bridge turns every part into its own
51
+ // thinking block and rejects the unsigned ones ("thinking.signature: Field
52
+ // required"). Rejoin each run into one block that ends at its signature.
53
+ function coalesceClaudeThoughts(parts) {
54
+ const out = [];
55
+ let open = null;
56
+ for (const part of parts) {
57
+ if (part?.thought !== true) {
58
+ if (open) out.push(open);
59
+ open = null;
60
+ out.push(part);
61
+ continue;
62
+ }
63
+ const partText = typeof part.text === 'string' ? part.text : '';
64
+ open = open ? { ...open, ...part, text: `${open.text}${partText}` } : { ...part, text: partText };
65
+ if (typeof part.thoughtSignature === 'string') {
66
+ out.push(open);
67
+ open = null;
68
+ }
69
+ }
70
+ if (open) out.push(open);
71
+ return out;
72
+ }
73
+
74
+ // The validator-bypass sentinel is a Gemini wire token: the Claude bridge
75
+ // sends a thinking block carrying it (or no signature at all) without a
76
+ // signature and Anthropic rejects the request ("thinking.signature: Field
77
+ // required"). Only a signature this route recorded is replayed to Claude;
78
+ // any other signature is removed, and a thinking block left without one (an
79
+ // interrupted run, another model's or provider's turn, legacy metadata) is
80
+ // dropped rather than turned into visible text.
81
+ const hasOwnClaudeSignature = (part) =>
82
+ typeof part.thoughtSignature === 'string' &&
83
+ part.thoughtSignature !== '' &&
84
+ part.thoughtSignature !== THOUGHT_SIGNATURE_SENTINEL;
85
+
86
+ function claudeReplayParts(parts, own) {
87
+ const signed = parts.map((part) => {
88
+ if (!part || typeof part !== 'object' || !('thoughtSignature' in part)) return part;
89
+ if (own && hasOwnClaudeSignature(part)) return part;
90
+ const { thoughtSignature: _foreign, ...unsigned } = part;
91
+ return unsigned;
92
+ });
93
+ return coalesceClaudeThoughts(signed.filter((part) => !isEmptyPlainTextPart(part))).filter(
94
+ (part) => part?.thought !== true || hasOwnClaudeSignature(part)
95
+ );
96
+ }
97
+
38
98
  function signatureSafeMessages(messages, model) {
39
- return messages.map((message) => {
40
- if (message?.role !== 'assistant') return message;
99
+ const claude = isAntigravityClaude(model);
100
+ return messages.flatMap((message) => {
101
+ if (message?.role !== 'assistant') return [message];
41
102
  const ownParts = replayFamilyMatches(message, model) ? providerReplayItems(message, 'antigravity') : undefined;
42
103
  // Repair tool signatures only after the complete history establishes
43
104
  // the active turn, not while normalizing an isolated older message.
44
- const parts = ownParts || toGeminiContents([message], model, { repairToolSignatures: false })[0]?.parts;
45
- if (!parts?.length) return message;
105
+ const sourceParts = ownParts || toGeminiContents([message], model, { repairToolSignatures: false })[0]?.parts;
106
+ const parts = claude && sourceParts ? claudeReplayParts(sourceParts, !!ownParts) : sourceParts;
107
+ // A turn that held only empty or dropped parts is omitted, not sent as parts:[].
108
+ if (sourceParts?.length && !parts.length) return [];
109
+ if (!parts?.length) return [message];
46
110
  for (const part of parts) {
47
111
  if (!part || typeof part !== 'object') continue;
48
112
  if (part.thought === true || typeof part.thoughtSignature === 'string') {
@@ -52,10 +116,60 @@ function signatureSafeMessages(messages, model) {
52
116
  if (!ownParts || !part.thoughtSignature) part.thoughtSignature = THOUGHT_SIGNATURE_SENTINEL;
53
117
  }
54
118
  }
55
- return { ...message, providerReplay: createProviderReplay('antigravity', parts) };
119
+ return [{ ...message, providerReplay: createProviderReplay('antigravity', parts) }];
56
120
  });
57
121
  }
58
122
 
123
+ const isToolResultTurn = (content) =>
124
+ content?.role === 'user' && !!content.parts?.some((part) => part?.functionResponse);
125
+ const isPromptTurn = (content) => content?.role === 'user' && !isToolResultTurn(content);
126
+ const hasSignedThinking = (content) =>
127
+ !!content?.parts?.some((part) => part?.thought === true && hasOwnClaudeSignature(part));
128
+
129
+ // With thinking on, Claude rejects a tool loop whose turn did not open with a
130
+ // signed thinking block, and a block that was dropped (unsigned, foreign or
131
+ // compacted away) cannot be restored. The outgoing request closes that loop
132
+ // instead: the closed part loses its thinking, a short model reply
133
+ // acknowledges the tool results, and a user nudge opens a fresh turn that
134
+ // Claude starts with new thinking. The closure sits after the results of the
135
+ // turn's last unthought model message, so later steps keep the signed
136
+ // thinking that the fresh turn produced. Wire-only: the caller's messages and
137
+ // recorded replays are never touched.
138
+ function closeUnthoughtToolLoop(contents) {
139
+ if (!isToolResultTurn(contents.at(-1))) return contents;
140
+ const promptIndex = contents.findLastIndex(isPromptTurn);
141
+ const modelIndexes = [];
142
+ for (let index = promptIndex + 1; index < contents.length; index += 1) {
143
+ if (contents[index]?.role === 'model') modelIndexes.push(index);
144
+ }
145
+ if (!modelIndexes.length || hasSignedThinking(contents[modelIndexes[0]])) return contents;
146
+ const unthought = modelIndexes.findLast((index) => !hasSignedThinking(contents[index]));
147
+ let cut = unthought + 1;
148
+ let results = 0;
149
+ while (isToolResultTurn(contents[cut])) {
150
+ results += contents[cut].parts.filter((part) => part?.functionResponse).length;
151
+ cut += 1;
152
+ }
153
+ if (!results) return contents;
154
+ const closed = contents.slice(0, cut).flatMap((content) => {
155
+ if (content?.role !== 'model') return [content];
156
+ const parts = content.parts.filter((part) => part?.thought !== true);
157
+ return parts.length ? [{ ...content, parts }] : [];
158
+ });
159
+ const ack = results === 1 ? '[Tool result received.]' : `[${results} tool results received.]`;
160
+ return [
161
+ ...closed,
162
+ { role: 'model', parts: [{ text: ack }] },
163
+ { role: 'user', parts: [{ text: '[Continue.]' }] },
164
+ ...contents.slice(cut),
165
+ ];
166
+ }
167
+
168
+ // The request turns Claude thinking on through an effort level or token
169
+ // budget; a `-thinking` wire id thinks without either.
170
+ const claudeThinkingEnabled = (model, thinkingConfig) =>
171
+ !!(thinkingConfig.thinkingLevel || thinkingConfig.thinkingBudget) || /-thinking$/i.test(String(model));
172
+
59
173
  function sessionId(contents) {
60
174
  const first = contents.find((content) => content?.role === 'user');
61
175
  const text = first?.parts?.map((part) => (typeof part?.text === 'string' ? part.text : '')).join('') || '';
@@ -111,19 +225,27 @@ export function buildAntigravityRequest(messages, model, tools, opts = {}, proje
111
225
  .map((message) => message.content)
112
226
  .join('\n\n');
113
227
  const chatMessages = messages.filter((message) => message.role !== 'system');
114
- const contents = toGeminiContents(signatureSafeMessages(chatMessages, model), model);
115
- if (!contents.length) throw new Error('No messages to send');
228
+ const history = toGeminiContents(signatureSafeMessages(chatMessages, model), model);
229
+ if (!history.length) throw new Error('No messages to send');
116
230
  const claude = isAntigravityClaude(model);
117
231
  const thinkingConfig = claude ? claudeThinkingConfig(opts) : antigravityGeminiThinkingConfig(model, opts);
232
+ const contents = claude && claudeThinkingEnabled(model, thinkingConfig) ? closeUnthoughtToolLoop(history) : history;
118
233
  const generationConfig = {
119
234
  ...(claude ? { maxOutputTokens: CLAUDE_MAX_OUTPUT_TOKENS } : {}),
120
235
  ...(thinkingConfig ? { thinkingConfig } : {}),
121
236
  };
122
237
  const request = { contents };
123
238
  if (systemText) request.systemInstruction = { role: 'user', parts: [{ text: systemText }] };
124
- const requestTools = toGeminiRequestTools(tools, opts.nativeTools);
239
+ const requestTools = claude
240
+ ? claudeRequestTools(tools, opts.nativeTools, opts.onToolExcluded)
241
+ : toGeminiRequestTools(tools, opts.nativeTools, {
242
+ onToolExcluded: opts.onToolExcluded,
243
+ // Other families (GPT-OSS) keep the plain conversion.
244
+ validate: isGeminiFamilyModel(model),
245
+ });
125
246
  if (requestTools.length) request.tools = requestTools;
126
- if (tools?.length) {
247
+ // Tool config only accompanies function declarations that were kept.
248
+ if (requestTools.some((entry) => entry.functionDeclarations?.length)) {
127
249
  request.toolConfig = toGeminiToolConfig(opts.toolChoice) || {
128
250
  functionCallingConfig: { mode: antigravityFunctionCallingMode() },
129
251
  };
@@ -8,13 +8,20 @@
8
8
  */
9
9
  import { traceAgentUsage } from '../agent-trace.mjs';
10
10
  import { createProviderReplay } from './lib/provider-replay.mjs';
11
- import { parseToolCalls, collectGeminiGroundingSources, parseGeminiTextPartMetadata } from './gemini-schema.mjs';
12
- import { geminiPolicyFinishCode } from './gemini-error-contract.mjs';
11
+ import {
12
+ parseToolCalls,
13
+ emitGeminiToolCalls,
14
+ collectGeminiGroundingSources,
15
+ parseGeminiTextPartMetadata,
16
+ } from './gemini-schema.mjs';
17
+ import { geminiFinishErrorFields, geminiPolicyFinishCode } from './gemini-error-contract.mjs';
13
18
 
14
19
  // Pure usageMetadata normalization shared by the success path and a failed
15
20
  // stream's partialUsage.
16
21
  export function normalizeAntigravityUsage(um) {
17
- const inputTokens = um.promptTokenCount || um.prompt_token_count || 0;
22
+ const inputTokens =
23
+ (um.promptTokenCount || um.prompt_token_count || 0) +
24
+ (um.toolUsePromptTokenCount || um.tool_use_prompt_token_count || 0);
18
25
  const cachedTokens = um.cachedContentTokenCount || um.cached_content_token_count || 0;
19
26
  const outputTokens =
20
27
  (um.candidatesTokenCount || um.candidates_token_count || 0) +
@@ -28,7 +35,7 @@ export function normalizeAntigravityUsage(um) {
28
35
  * @param {ReturnType<import('./antigravity-stream.mjs').createAntigravityStreamCollector>} deps.collector
29
36
  * @param {string} deps.useModel wire model id
30
37
  * @param {object} deps.opts send options (session/iteration/providerState)
31
- * @param {Function|null} deps.onToolCall set when calls were streamed live
38
+ * @param {Function|null} deps.onToolCall receives the turn's calls after a clean finish
32
39
  */
33
40
  export function finalizeAntigravityTurn({ response, collector, useModel, opts, onToolCall }) {
34
41
  const textLeakGuard = collector.leakGuard;
@@ -46,10 +53,8 @@ export function finalizeAntigravityTurn({ response, collector, useModel, opts, o
46
53
  // Thought signatures are only valid for the model family that minted
47
54
  // them; the request builder consults this when the route changes.
48
55
  if (providerReplay) providerReplay.requestContext = { model: useModel };
49
- let nativeToolCalls;
50
- if (!onToolCall) nativeToolCalls = parseToolCalls(responseParts);
51
- else if (collector.streamedNativeToolCalls.length) nativeToolCalls = collector.streamedNativeToolCalls;
52
- if (!onToolCall && textLeakGuard?.enabled) nativeToolCalls = textLeakGuard.filterNativeToolCalls(nativeToolCalls);
56
+ let nativeToolCalls = parseToolCalls(responseParts);
57
+ if (textLeakGuard?.enabled) nativeToolCalls = textLeakGuard.filterNativeToolCalls(nativeToolCalls);
53
58
  let toolCalls = nativeToolCalls;
54
59
  if (leakedToolCalls.length) {
55
60
  toolCalls = toolCalls?.length ? [...toolCalls, ...leakedToolCalls] : leakedToolCalls;
@@ -80,7 +85,17 @@ export function finalizeAntigravityTurn({ response, collector, useModel, opts, o
80
85
  });
81
86
  }
82
87
 
83
- if (finishReason && normalizedFinish !== 'STOP') {
88
+ // A MAX_TOKENS cut that still delivered whole native functionCall parts is
89
+ // a tool-use turn: the calls arrived intact, only trailing output was cut.
90
+ // Every other non-STOP finish fails the turn, and so does a cut whose text
91
+ // also leaked a call (that call may be as truncated as the text around it).
92
+ const completeNativeCalls =
93
+ normalizedFinish === 'MAX_TOKENS' &&
94
+ String(candidate?.finishReason || '').replace(/^FINISH_REASON_/, '') === 'MAX_TOKENS' &&
95
+ !leakedToolCalls.length &&
96
+ !!nativeToolCalls?.length &&
97
+ nativeToolCalls.every((call) => typeof call?.name === 'string' && call.name !== '');
98
+ if (finishReason && normalizedFinish !== 'STOP' && !completeNativeCalls) {
84
99
  throw Object.assign(new Error(`Antigravity response incomplete: finishReason=${finishReason}`), {
85
100
  name: 'ProviderIncompleteError',
86
101
  code: geminiPolicyFinishCode(finishReason) || 'PROVIDER_INCOMPLETE',
@@ -93,10 +108,14 @@ export function finalizeAntigravityTurn({ response, collector, useModel, opts, o
93
108
  model: useModel,
94
109
  rawUsage: response.usageMetadata || null,
95
110
  ...(usage ? { partialUsage: usage, partialModel: useModel } : {}),
96
- ...(collector.emittedToolCount ? { emittedToolCall: true, unsafeToRetry: true } : {}),
111
+ ...geminiFinishErrorFields(response),
97
112
  });
98
113
  }
99
114
 
115
+ // Terminal status first: a failed turn never runs its tool calls.
116
+ textLeakGuard?.releaseDeferredToolCalls();
117
+ emitGeminiToolCalls(nativeToolCalls, onToolCall);
118
+
100
119
  return {
101
120
  content,
102
121
  model: useModel,
@@ -4,7 +4,8 @@
4
4
  *
5
5
  * capacity (429/503/529, MODEL_CAPACITY_EXHAUSTED, "server busy"): retried on
6
6
  * the SAME account and host with 1s → 2s → 4s (8s cap) ±10% jitter, three
7
- * retries, whatever wait the server names, then the failure surfaces.
7
+ * retries, waiting at least the server's RetryInfo delay; advice that
8
+ * would push total waiting past 60s surfaces the error (with resetAt).
8
9
  * Endpoint: the reference falls back to its next endpoint after a failure;
9
10
  * generation here deliberately stays on the single daily host and never
10
11
  * walks an endpoint list (a spent ladder surfaces to the account layer).
@@ -13,34 +14,135 @@
13
14
  * rotate; advice beyond 60s surfaces at once.
14
15
  * QUOTA_EXHAUSTED (and any day/plan window): never retried here.
15
16
  *
17
+ * First byte: the gateway queues or thinks server-side and sends the
18
+ * response headers together with the first chunk, so the window is chosen
19
+ * per model class from the catalog `family`: Pro-class Gemini (Pro tiers,
20
+ * Argon) waits MIXDOG_ANTIGRAVITY_FIRST_BYTE_TIMEOUT_MS (300s, clamped to
21
+ * the provider ceiling PROVIDER_MAX_BEFORE_WARN_MS, 285s by default),
22
+ * Flash-class Gemini the shared Gemini window (60s); both apply to the
23
+ * headers and again to the first chunk. A header or first-chunk timeout is
24
+ * retried at most MIXDOG_ANTIGRAVITY_FIRST_BYTE_RETRIES times (1), each
25
+ * retry doubling the window up to that ceiling; connect, 5xx and drop
26
+ * failures keep the full ladder (MIXDOG_ANTIGRAVITY_RETRY_MAX_ATTEMPTS, 4
27
+ * attempts, at MIXDOG_ANTIGRAVITY_RETRY_BACKOFF_MS 1s / 2s / 4s). Models
28
+ * without a Gemini family (Claude, GPT-OSS, unlisted ids) keep the shared
29
+ * Gemini window on that ladder.
30
+ *
16
31
  * Replay stays gated by the stream-outcome contract: an attempt that exposed
17
32
  * text or dispatched a tool is never re-issued.
18
33
  */
19
34
  import { readStreamOutcome } from './lib/stream-outcome.mjs';
20
35
  import { DETERMINISTIC_KINDS, providerErrorKind } from './provider-error-kind.mjs';
36
+ import { PROVIDER_MAX_BEFORE_WARN_MS, firstBytePolicyBudget, resolveTimeoutMs } from '../stall-policy.mjs';
37
+ import { GEMINI_FIRST_BYTE_TIMEOUT_MS } from './gemini-stream.mjs';
38
+ import { antigravityModelFamily } from './antigravity-oauth-catalog.mjs';
21
39
 
22
40
  export const ANTIGRAVITY_CAPACITY_RETRIES = 3;
23
41
  export const ANTIGRAVITY_CAPACITY_BASE_MS = 1000;
24
42
  export const ANTIGRAVITY_CAPACITY_MAX_MS = 8000;
25
43
  export const ANTIGRAVITY_CAPACITY_JITTER_RATIO = 0.1;
44
+ // Total time capacity retries may spend waiting on server-advised delays.
45
+ export const ANTIGRAVITY_CAPACITY_BUDGET_MS = 60_000;
26
46
  export const ANTIGRAVITY_QUICK_RETRY_MS = 1000;
27
47
  export const ANTIGRAVITY_QUICK_RETRY_MAX_ADVICE_MS = 60_000;
28
48
 
49
+ const DEFAULT_RETRY_BACKOFF_MS = Object.freeze([1000, 1000, 2000, 4000]);
50
+
51
+ function envInt(env, name, fallback, min, max) {
52
+ const raw = env?.[name];
53
+ if (raw == null || String(raw).trim() === '') return fallback;
54
+ const n = Number(raw);
55
+ if (!Number.isInteger(n)) return fallback;
56
+ return Math.min(Math.max(n, min), max);
57
+ }
58
+
59
+ function envBackoffMs(env, name) {
60
+ const raw = String(env?.[name] ?? '').trim();
61
+ if (!raw) return DEFAULT_RETRY_BACKOFF_MS;
62
+ const steps = raw.split(',').map((step) => Number(step.trim()));
63
+ if (!steps.every((step) => Number.isInteger(step) && step >= 0)) return DEFAULT_RETRY_BACKOFF_MS;
64
+ return Object.freeze(steps);
65
+ }
66
+
67
+ /**
68
+ * The same-host ladder for everything that is not a 429, read from the
69
+ * environment: attempts (1–6), the backoff list (index n is the wait before
70
+ * attempt n) and how many first-byte timeouts a thinking model may retry.
71
+ */
72
+ export function resolveAntigravityRetryConfig(env = process.env) {
73
+ return {
74
+ maxAttempts: envInt(env, 'MIXDOG_ANTIGRAVITY_RETRY_MAX_ATTEMPTS', ANTIGRAVITY_CAPACITY_RETRIES + 1, 1, 6),
75
+ backoffMs: envBackoffMs(env, 'MIXDOG_ANTIGRAVITY_RETRY_BACKOFF_MS'),
76
+ firstByteRetries: envInt(env, 'MIXDOG_ANTIGRAVITY_FIRST_BYTE_RETRIES', 1, 0, 5),
77
+ };
78
+ }
79
+
80
+ const RETRY_CONFIG = resolveAntigravityRetryConfig();
81
+
29
82
  // withRetry options for everything that is not a 429: transient transport and
30
83
  // 5xx failures use the capacity schedule (the reference has no other same-host
31
84
  // retry; the leading duplicate is the sleep-before-attempt index).
32
85
  export const ANTIGRAVITY_RETRY = Object.freeze({
33
- maxAttempts: ANTIGRAVITY_CAPACITY_RETRIES + 1,
34
- backoffMs: Object.freeze([1000, 1000, 2000, 4000]),
86
+ maxAttempts: RETRY_CONFIG.maxAttempts,
87
+ backoffMs: RETRY_CONFIG.backoffMs,
35
88
  retryJitterRatio: ANTIGRAVITY_CAPACITY_JITTER_RATIO,
36
89
  // 429s are handled by antigravity429WaitMs, not the generic loop.
37
90
  retry429: false,
38
91
  });
39
92
 
93
+ export const ANTIGRAVITY_FIRST_BYTE_RETRIES = RETRY_CONFIG.firstByteRetries;
94
+
95
+ // Pro-class window: 300s requested, clamped to the provider ceiling.
96
+ export const ANTIGRAVITY_FIRST_BYTE_TIMEOUT_MS = resolveTimeoutMs('MIXDOG_ANTIGRAVITY_FIRST_BYTE_TIMEOUT_MS', 300_000, {
97
+ minMs: 30_000,
98
+ maxMs: PROVIDER_MAX_BEFORE_WARN_MS,
99
+ });
100
+
101
+ // First-attempt window per catalog family.
102
+ const FAMILY_FIRST_BYTE_MS = Object.freeze({
103
+ 'gemini-pro': ANTIGRAVITY_FIRST_BYTE_TIMEOUT_MS,
104
+ 'gemini-flash': GEMINI_FIRST_BYTE_TIMEOUT_MS,
105
+ });
106
+
107
+ // Models without a Gemini family: the shared Gemini window on the ordinary ladder.
108
+ export const ANTIGRAVITY_UNCLASSED_FIRST_BYTE = Object.freeze({
109
+ timeoutMs: GEMINI_FIRST_BYTE_TIMEOUT_MS,
110
+ maxMs: GEMINI_FIRST_BYTE_TIMEOUT_MS,
111
+ retries: null,
112
+ });
113
+
114
+ /**
115
+ * First-byte policy (see firstByteWindowMs) for one model, picker or wire id.
116
+ * The class comes from the catalog record's `family`.
117
+ */
118
+ export function antigravityFirstBytePolicy(model, models) {
119
+ const timeoutMs = FAMILY_FIRST_BYTE_MS[antigravityModelFamily(model, models)];
120
+ if (!timeoutMs) return ANTIGRAVITY_UNCLASSED_FIRST_BYTE;
121
+ return {
122
+ timeoutMs,
123
+ maxMs: PROVIDER_MAX_BEFORE_WARN_MS,
124
+ retries: Math.min(ANTIGRAVITY_FIRST_BYTE_RETRIES, ANTIGRAVITY_RETRY.maxAttempts - 1),
125
+ };
126
+ }
127
+
128
+ /**
129
+ * Longest a send may wait before its first output across the whole transport
130
+ * ladder ({ transportMs, semanticMs }, see firstBytePolicyBudget): the agent
131
+ * watchdog must not fire inside it. Drops and 5xx share the ladder with
132
+ * first-byte timeouts, so the budget is every backoff step of the ladder plus
133
+ * the windows of the first-byte timeouts the policy permits (all attempts for
134
+ * a policy without its own retry cap).
135
+ */
136
+ export function antigravityFirstResponseBudget(policy, backoffMs = ANTIGRAVITY_RETRY.backoffMs) {
137
+ return firstBytePolicyBudget(policy, { attempts: ANTIGRAVITY_RETRY.maxAttempts, backoffMs });
138
+ }
139
+
40
140
  /** Capacity wait for retry number `retryIndex` (0-based): 1s, 2s, 4s, 8s cap, ±10%. */
41
- export function antigravityCapacityDelayMs(retryIndex) {
141
+ function antigravityCapacityDelayMs(retryIndex) {
42
142
  const base = Math.min(ANTIGRAVITY_CAPACITY_BASE_MS * 2 ** retryIndex, ANTIGRAVITY_CAPACITY_MAX_MS);
43
- return Math.round(base * (1 - ANTIGRAVITY_CAPACITY_JITTER_RATIO + Math.random() * 2 * ANTIGRAVITY_CAPACITY_JITTER_RATIO));
143
+ return Math.round(
144
+ base * (1 - ANTIGRAVITY_CAPACITY_JITTER_RATIO + Math.random() * 2 * ANTIGRAVITY_CAPACITY_JITTER_RATIO)
145
+ );
44
146
  }
45
147
 
46
148
  export function isAntigravityCapacityError(err) {
@@ -57,13 +159,28 @@ export function antigravity429WaitMs(err, state) {
57
159
  if (status !== 429 && !(capacity && (status === 503 || status === 529))) return null;
58
160
  if (readStreamOutcome(err).replaySafe !== true) return null;
59
161
  const { kind, retryAfterMs } = providerErrorKind(err);
60
- if (DETERMINISTIC_KINDS.has(kind) || err.code === 'quota_exhausted' || err.quotaScope === 'day' || err.quotaScope === 'plan') {
162
+ if (
163
+ DETERMINISTIC_KINDS.has(kind) ||
164
+ err.code === 'quota_exhausted' ||
165
+ err.quotaScope === 'day' ||
166
+ err.quotaScope === 'plan'
167
+ ) {
61
168
  return null;
62
169
  }
63
- // Capacity follows the local schedule whatever wait the server names.
170
+ // Capacity waits at least the advised RetryInfo delay (the local schedule
171
+ // is the floor). Total advised waiting stays within the retry budget; an
172
+ // advice that does not fit surfaces with its reset time rather than
173
+ // retrying early.
64
174
  if (capacity) {
65
175
  if (state.capacityRetries >= ANTIGRAVITY_CAPACITY_RETRIES) return null;
66
- return antigravityCapacityDelayMs(state.capacityRetries++);
176
+ const spent = state.capacityWaitedMs ?? 0;
177
+ if (retryAfterMs != null && spent + retryAfterMs > ANTIGRAVITY_CAPACITY_BUDGET_MS) {
178
+ err.resetAt ??= Date.now() + retryAfterMs;
179
+ return null;
180
+ }
181
+ const wait = Math.max(antigravityCapacityDelayMs(state.capacityRetries++), retryAfterMs ?? 0);
182
+ state.capacityWaitedMs = spent + wait;
183
+ return wait;
67
184
  }
68
185
  // An RPM hit gets one quick retry; advice up to a minute is honored in
69
186
  // full, a longer wait surfaces so the account pool can rotate.
@@ -1,18 +1,15 @@
1
1
  /**
2
2
  * antigravity-stream.mjs — what one Antigravity SSE turn accumulates while it
3
3
  * streams: the live text mirror a retirement notice is recognised from, the
4
- * ordered parts of every chunk, the native tool calls parsed per chunk with
5
- * their id dedup, the leak guard that recovers calls the model wrote as text,
6
- * the first terminal finishReason, and the exposure marks a failed stream must
7
- * carry (emittedToolCall / unsafeToRetry / partial calls + partial replay).
4
+ * leak guard that recovers calls the model wrote as text (held back, like the
5
+ * native calls, until the turn finishes cleanly), and the first terminal
6
+ * finishReason. Nothing is dispatched while streaming.
8
7
  *
9
8
  * The transport (antigravity-transport.mjs) owns the socket and the retry
10
9
  * policy; the projection (antigravity-response.mjs) reads this record after
11
10
  * the turn settles.
12
11
  */
13
- import { createProviderReplay } from './lib/provider-replay.mjs';
14
12
  import { createGeminiTextLeakGuard, consumeGeminiRestStreamResponse } from './gemini-stream.mjs';
15
- import { parseToolCalls, emitGeminiToolCalls } from './gemini-schema.mjs';
16
13
  import { normalizeAntigravityUsage } from './antigravity-response.mjs';
17
14
 
18
15
  // A retired wire id answers with one plain-text notice and no finishReason.
@@ -46,10 +43,6 @@ export function createAntigravityStreamCollector({ tools, useModel, onToolCall,
46
43
  // Streamed text is kept so a retirement notice can be told apart from
47
44
  // a truncated stream when the gateway omits the finishReason.
48
45
  let streamedText = '';
49
- let streamedParts = [];
50
- let streamedNativeToolCalls = [];
51
- const seenNativeToolIds = new Set();
52
- const emittedToolIds = new Set();
53
46
 
54
47
  const relayText = onTextDelta
55
48
  ? (text) => {
@@ -57,15 +50,9 @@ export function createAntigravityStreamCollector({ tools, useModel, onToolCall,
57
50
  onTextDelta(text);
58
51
  }
59
52
  : null;
60
- const dispatchToolCall = onToolCall
61
- ? (call) => {
62
- // A failure already observed in this chunk must win over both
63
- // native calls and calls recovered from its text.
64
- if (terminalFailure || emittedToolIds.has(call.id)) return;
65
- emittedToolIds.add(call.id);
66
- onToolCall(call);
67
- }
68
- : null;
53
+ // Tool calls (native and text-recovered) are never dispatched while the
54
+ // stream runs: the turn's terminal verdict decides, and
55
+ // finalizeAntigravityTurn releases them only after a clean finish.
69
56
  const onChunk = (chunk) => {
70
57
  const candidate = chunk?.candidates?.[0];
71
58
  const finishReason =
@@ -74,46 +61,30 @@ export function createAntigravityStreamCollector({ tools, useModel, onToolCall,
74
61
  if (finishReason && String(finishReason).replace(/^FINISH_REASON_/, '') !== 'STOP') {
75
62
  terminalFailure ||= finishReason;
76
63
  }
77
- if (!onToolCall) return;
78
- const parts = candidate?.content?.parts ?? [];
79
- streamedParts.push(...parts);
80
- if (terminalFailure || !parts.some((part) => part?.functionCall)) return;
81
- // Parse against the turn's parts so anonymous call IDs keep the
82
- // same ordinal as final parsing, even across separate SSE chunks.
83
- const fresh = (parseToolCalls(streamedParts) || []).filter((call) => {
84
- if (seenNativeToolIds.has(call.id)) return false;
85
- seenNativeToolIds.add(call.id);
86
- return true;
87
- });
88
- const calls = textLeakGuard?.enabled ? textLeakGuard.filterNativeToolCalls(fresh) : fresh;
89
- if (calls?.length) streamedNativeToolCalls.push(...calls);
90
- emitGeminiToolCalls(calls, dispatchToolCall);
91
64
  };
92
65
 
93
66
  // Each attempt starts from an empty record: a replayed request must not
94
- // inherit the dead attempt's text, parts or dispatched-call ids.
67
+ // inherit the dead attempt's text or failure.
95
68
  const beginAttempt = () => {
96
69
  textLeakGuard = createGeminiTextLeakGuard({
97
70
  knownToolNames: tools?.map((t) => t.name).filter(Boolean) ?? [],
98
71
  onTextDelta: relayText,
99
- onToolCall: dispatchToolCall,
72
+ onToolCall,
100
73
  onStreamDelta,
74
+ deferToolCalls: true,
101
75
  });
102
76
  streamedText = '';
103
77
  terminalFailure = null;
104
- streamedParts = [];
105
- streamedNativeToolCalls = [];
106
- seenNativeToolIds.clear();
107
- emittedToolIds.clear();
108
78
  };
109
79
  const releaseGuard = () => {
110
80
  textLeakGuard = null;
111
81
  };
112
82
 
113
- const consume = async (res, attemptSignal) => {
83
+ const consume = async (res, attemptSignal, { firstByteTimeoutMs } = {}) => {
114
84
  try {
115
85
  return await consumeGeminiRestStreamResponse(res, {
116
86
  signal: attemptSignal,
87
+ firstByteTimeoutMs,
117
88
  onStreamDelta,
118
89
  onTextDelta: relayText,
119
90
  onChunk,
@@ -125,22 +96,7 @@ export function createAntigravityStreamCollector({ tools, useModel, onToolCall,
125
96
  unwrapChunk: (chunk) => (chunk && typeof chunk === 'object' && chunk.response ? chunk.response : chunk),
126
97
  });
127
98
  } catch (streamErr) {
128
- const error = retiredModelError(streamErr, streamedText, useModel) || streamErr;
129
- // Native calls now run before EOF. Preserve
130
- // their history and prohibit resampling after
131
- // a tool callback.
132
- if (emittedToolIds.size) {
133
- error.emittedToolCall = true;
134
- error.unsafeToRetry = true;
135
- const leaked = textLeakGuard.getLeakedToolCalls();
136
- error.partialToolCalls = [...streamedNativeToolCalls, ...leaked];
137
- const replay = createProviderReplay('antigravity', leaked.length ? [] : streamedParts);
138
- if (replay) {
139
- replay.requestContext = { model: useModel };
140
- error.partialProviderReplay = replay;
141
- }
142
- }
143
- throw error;
99
+ throw retiredModelError(streamErr, streamedText, useModel) || streamErr;
144
100
  }
145
101
  };
146
102
 
@@ -155,11 +111,5 @@ export function createAntigravityStreamCollector({ tools, useModel, onToolCall,
155
111
  get terminalFailure() {
156
112
  return terminalFailure;
157
113
  },
158
- get streamedNativeToolCalls() {
159
- return streamedNativeToolCalls;
160
- },
161
- get emittedToolCount() {
162
- return emittedToolIds.size;
163
- },
164
114
  };
165
115
  }