mixdog 1.3.4 → 1.4.0

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 (472) hide show
  1. package/LICENSES/oh-my-pi-MIT.txt +23 -0
  2. package/NOTICE.md +17 -2
  3. package/README.md +11 -0
  4. package/package.json +3 -11
  5. package/scripts/daemon-stub.mjs +1 -1
  6. package/scripts/embed-google-oauth-client.mjs +49 -0
  7. package/scripts/gate-local.mjs +4 -2
  8. package/scripts/lib/test-spawn-ledger.mjs +46 -1
  9. package/scripts/native-release-status.mjs +2 -2
  10. package/scripts/recall-history-cases.json +1 -1
  11. package/scripts/suite-health.mjs +10 -1
  12. package/scripts/test.mjs +12 -11
  13. package/src/agents/reviewer/AGENT.md +7 -11
  14. package/src/agents/reviewer/agent.json +1 -1
  15. package/src/defaults/shipped-history.json +25 -1
  16. package/src/defaults/skills/browser-use/SKILL.md +77 -17
  17. package/src/defaults/skills/code-tidy/SKILL.md +142 -270
  18. package/src/defaults/skills/code-tidy/references/agent-cleanup.md +4 -4
  19. package/src/defaults/skills/code-tidy/references/cleanup-report.md +31 -76
  20. package/src/defaults/skills/code-tidy/references/dead-code.md +6 -12
  21. package/src/defaults/skills/computer-use/SKILL.md +33 -9
  22. package/src/defaults/skills/setup/SKILL.md +29 -2
  23. package/src/defaults/skills/setup/references/actions.md +117 -28
  24. package/src/defaults/skills/setup/references/surfaces.md +77 -35
  25. package/src/defaults/skills/setup-guide/SKILL.md +3 -3
  26. package/src/defaults/skills/visualize/SKILL.md +2 -1
  27. package/src/lib/keychain-cjs.cjs +359 -29
  28. package/src/lib/rules-builder.cjs +10 -8
  29. package/src/rules/agent/AGENT.md +6 -6
  30. package/src/rules/agent-mode/AGENT_MODE.md +10 -2
  31. package/src/rules/agent-mode/MIXY.md +12 -0
  32. package/src/rules/lead/LEAD.md +18 -20
  33. package/src/rules/shared/05-tool-calls.md +5 -6
  34. package/src/rules/shared/10-tool-workflow.md +2 -0
  35. package/src/rules/shared/60-verification.md +7 -5
  36. package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +2 -3
  37. package/src/runtime/agent/orchestrator/agent-runtime/heartbeat-completion.mjs +193 -0
  38. package/src/runtime/agent/orchestrator/agent-runtime/title-completion.mjs +3 -1
  39. package/src/runtime/agent/orchestrator/agent-trace-format.mjs +3 -1
  40. package/src/runtime/agent/orchestrator/config.mjs +34 -0
  41. package/src/runtime/agent/orchestrator/context/collect.mjs +3 -0
  42. package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +72 -67
  43. package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +54 -1
  44. package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +3 -3
  45. package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +177 -73
  46. package/src/runtime/agent/orchestrator/mcp/client.mjs +25 -2
  47. package/src/runtime/agent/orchestrator/mcp/oauth-callback.mjs +31 -2
  48. package/src/runtime/agent/orchestrator/mcp/oauth-client.mjs +16 -3
  49. package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +42 -7
  50. package/src/runtime/agent/orchestrator/mcp/oauth-provider.mjs +21 -2
  51. package/src/runtime/agent/orchestrator/mcp/oauth-shared.mjs +23 -0
  52. package/src/runtime/agent/orchestrator/mcp/oauth.mjs +11 -1
  53. package/src/runtime/agent/orchestrator/providers/account-pool.mjs +230 -137
  54. package/src/runtime/agent/orchestrator/providers/admission-scheduler.mjs +64 -7
  55. package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +18 -5
  56. package/src/runtime/agent/orchestrator/providers/anthropic-cache-warm.mjs +165 -0
  57. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
  58. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +4 -1
  59. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/gzip-post.mjs +14 -14
  60. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +160 -69
  61. package/src/runtime/agent/orchestrator/providers/anthropic-overload-fallback.mjs +25 -3
  62. package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +64 -33
  63. package/src/runtime/agent/orchestrator/providers/anthropic.mjs +135 -87
  64. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-catalog.mjs +52 -8
  65. package/src/runtime/agent/orchestrator/providers/antigravity-oauth.mjs +10 -1
  66. package/src/runtime/agent/orchestrator/providers/antigravity-request.mjs +22 -6
  67. package/src/runtime/agent/orchestrator/providers/antigravity-response.mjs +15 -4
  68. package/src/runtime/agent/orchestrator/providers/antigravity-stream.mjs +17 -2
  69. package/src/runtime/agent/orchestrator/providers/antigravity-transport.mjs +142 -104
  70. package/src/runtime/agent/orchestrator/providers/cache-warm-admission.mjs +90 -0
  71. package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +1 -1
  72. package/src/runtime/agent/orchestrator/providers/cursor-wire-normalization.mjs +10 -4
  73. package/src/runtime/agent/orchestrator/providers/cursor-wire-protobuf.mjs +10 -217
  74. package/src/runtime/agent/orchestrator/providers/cursor-wire-transport.mjs +25 -9
  75. package/src/runtime/agent/orchestrator/providers/cursor.mjs +22 -6
  76. package/src/runtime/agent/orchestrator/providers/devin-auth.mjs +409 -0
  77. package/src/runtime/agent/orchestrator/providers/devin-wire-families.mjs +187 -0
  78. package/src/runtime/agent/orchestrator/providers/devin-wire-identity.mjs +342 -0
  79. package/src/runtime/agent/orchestrator/providers/devin-wire-models.mjs +541 -0
  80. package/src/runtime/agent/orchestrator/providers/devin-wire-protobuf.mjs +305 -0
  81. package/src/runtime/agent/orchestrator/providers/devin-wire-request.mjs +558 -0
  82. package/src/runtime/agent/orchestrator/providers/devin-wire-schema.mjs +880 -0
  83. package/src/runtime/agent/orchestrator/providers/devin-wire-session.mjs +190 -0
  84. package/src/runtime/agent/orchestrator/providers/devin-wire-tool-args.mjs +351 -0
  85. package/src/runtime/agent/orchestrator/providers/devin-wire-transport.mjs +560 -0
  86. package/src/runtime/agent/orchestrator/providers/devin.mjs +491 -0
  87. package/src/runtime/agent/orchestrator/providers/effort-configuration.mjs +3 -0
  88. package/src/runtime/agent/orchestrator/providers/gemini-output-limit.mjs +46 -0
  89. package/src/runtime/agent/orchestrator/providers/gemini-reasoning-relay.mjs +30 -0
  90. package/src/runtime/agent/orchestrator/providers/gemini-request-body.mjs +7 -11
  91. package/src/runtime/agent/orchestrator/providers/gemini-retry-policy.mjs +61 -22
  92. package/src/runtime/agent/orchestrator/providers/gemini-sdk-request.mjs +1 -0
  93. package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +71 -4
  94. package/src/runtime/agent/orchestrator/providers/gemini.mjs +25 -2
  95. package/src/runtime/agent/orchestrator/providers/grok-client-version.mjs +1 -1
  96. package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +96 -5
  97. package/src/runtime/agent/orchestrator/providers/lib/oauth-token-utils.mjs +17 -3
  98. package/src/runtime/agent/orchestrator/providers/lib/tail-reminder-split.mjs +23 -5
  99. package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +52 -10
  100. package/src/runtime/agent/orchestrator/providers/model-proxy-channel.d.mts +8 -1
  101. package/src/runtime/agent/orchestrator/providers/model-proxy-channel.mjs +1 -0
  102. package/src/runtime/agent/orchestrator/providers/npm-cli-version.mjs +11 -3
  103. package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +19 -1
  104. package/src/runtime/agent/orchestrator/providers/oauth-usage.mjs +39 -3
  105. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +3 -1
  106. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +2 -0
  107. package/src/runtime/agent/orchestrator/providers/openai-error-contract.mjs +6 -1
  108. package/src/runtime/agent/orchestrator/providers/openai-oauth-tokens.mjs +10 -9
  109. package/src/runtime/agent/orchestrator/providers/openai-ws-send/send-context.mjs +22 -3
  110. package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/attempt-context.mjs +43 -5
  111. package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/handshake-failure.mjs +3 -1
  112. package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/stream-failure.mjs +6 -3
  113. package/src/runtime/agent/orchestrator/providers/opencode-go-gemini.mjs +1 -0
  114. package/src/runtime/agent/orchestrator/providers/provider-availability.mjs +19 -0
  115. package/src/runtime/agent/orchestrator/providers/provider-error-kind.mjs +65 -1
  116. package/src/runtime/agent/orchestrator/providers/quota-reading.mjs +38 -12
  117. package/src/runtime/agent/orchestrator/providers/registry.mjs +43 -3
  118. package/src/runtime/agent/orchestrator/providers/retry-executor.mjs +39 -7
  119. package/src/runtime/agent/orchestrator/providers/statusline-route-meta.mjs +6 -0
  120. package/src/runtime/agent/orchestrator/providers/wire-protobuf-codec.mjs +368 -0
  121. package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +12 -7
  122. package/src/runtime/agent/orchestrator/runtime-core/builtin-features.mjs +2 -0
  123. package/src/runtime/agent/orchestrator/runtime-core/compaction-config-keys.mjs +62 -0
  124. package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +37 -16
  125. package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-delta.mjs +100 -23
  126. package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +1 -1
  127. package/src/runtime/agent/orchestrator/runtime-core/reaction-tool-defs.mjs +133 -0
  128. package/src/runtime/agent/orchestrator/runtime-core/session-text.mjs +2 -0
  129. package/src/runtime/agent/orchestrator/runtime-core/tool-bridge.mjs +19 -4
  130. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-data.mjs +3 -0
  131. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +125 -30
  132. package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +23 -5
  133. package/src/runtime/agent/orchestrator/runtime-core/tool-profile.mjs +35 -10
  134. package/src/runtime/agent/orchestrator/runtime-core/workflow/agents.mjs +57 -10
  135. package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +9 -6
  136. package/src/runtime/agent/orchestrator/runtime-core/workflow-ids.mjs +1 -1
  137. package/src/runtime/agent/orchestrator/session/agent-loop.mjs +18 -0
  138. package/src/runtime/agent/orchestrator/session/agent-room.d.mts +0 -3
  139. package/src/runtime/agent/orchestrator/session/agent-room.mjs +10 -4
  140. package/src/runtime/agent/orchestrator/session/cache-warm.mjs +792 -0
  141. package/src/runtime/agent/orchestrator/session/compact/runner.mjs +148 -25
  142. package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +475 -58
  143. package/src/runtime/agent/orchestrator/session/compaction-archive.mjs +42 -17
  144. package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +8 -0
  145. package/src/runtime/agent/orchestrator/session/human-gate/gate.mjs +47 -9
  146. package/src/runtime/agent/orchestrator/session/human-gate/outbound-policy.mjs +6 -2
  147. package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +36 -4
  148. package/src/runtime/agent/orchestrator/session/human-gate/store.mjs +14 -2
  149. package/src/runtime/agent/orchestrator/session/loop/assistant-commit.mjs +8 -0
  150. package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +18 -22
  151. package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +32 -3
  152. package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +11 -2
  153. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/segments.mjs +4 -1
  154. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +51 -3
  155. package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +17 -3
  156. package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +10 -2
  157. package/src/runtime/agent/orchestrator/session/loop/tool-exec/after-hook.mjs +2 -1
  158. package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +14 -4
  159. package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +16 -2
  160. package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +16 -1
  161. package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +10 -0
  162. package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +3 -10
  163. package/src/runtime/agent/orchestrator/session/loop/tool-phase.mjs +23 -5
  164. package/src/runtime/agent/orchestrator/session/loop/turn-limits.mjs +60 -0
  165. package/src/runtime/agent/orchestrator/session/manager/ask-queue.mjs +12 -2
  166. package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +19 -1
  167. package/src/runtime/agent/orchestrator/session/manager/ask-turn-commit.mjs +2 -0
  168. package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +133 -90
  169. package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +14 -0
  170. package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +2 -1
  171. package/src/runtime/agent/orchestrator/session/manager/ask-turn-state.mjs +31 -4
  172. package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +30 -18
  173. package/src/runtime/agent/orchestrator/session/manager/owner-route-fallbacks.mjs +23 -13
  174. package/src/runtime/agent/orchestrator/session/manager/pending-message-entry.mjs +11 -2
  175. package/src/runtime/agent/orchestrator/session/manager/provider-replay.mjs +13 -0
  176. package/src/runtime/agent/orchestrator/session/manager/route-fallback-chain.mjs +129 -0
  177. package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +20 -2
  178. package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +2 -0
  179. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +8 -0
  180. package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +1 -1
  181. package/src/runtime/agent/orchestrator/session/manager/session-tool-surface.mjs +13 -0
  182. package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +7 -2
  183. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-journal.mjs +102 -15
  184. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint.mjs +18 -5
  185. package/src/runtime/agent/orchestrator/session/message-ids.mjs +5 -3
  186. package/src/runtime/agent/orchestrator/session/message-reactions.mjs +89 -0
  187. package/src/runtime/agent/orchestrator/session/message-reactions.test-support.mjs +75 -0
  188. package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +19 -8
  189. package/src/runtime/agent/orchestrator/session/prompt-cache-idle-gaps.mjs +113 -0
  190. package/src/runtime/agent/orchestrator/session/prompt-cache-touch-store.mjs +127 -0
  191. package/src/runtime/agent/orchestrator/session/routine-result.d.mts +0 -2
  192. package/src/runtime/agent/orchestrator/session/routine-result.mjs +47 -11
  193. package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +20 -2
  194. package/src/runtime/agent/orchestrator/session/sensitive-projection.mjs +100 -0
  195. package/src/runtime/agent/orchestrator/session/sensitive-values.mjs +257 -0
  196. package/src/runtime/agent/orchestrator/session/side-question-store.mjs +20 -7
  197. package/src/runtime/agent/orchestrator/session/side-question.mjs +18 -0
  198. package/src/runtime/agent/orchestrator/session/skill-update-notice.mjs +60 -0
  199. package/src/runtime/agent/orchestrator/session/store/live-state.mjs +6 -3
  200. package/src/runtime/agent/orchestrator/session/store/save-delta.mjs +9 -5
  201. package/src/runtime/agent/orchestrator/session/store/serialize.mjs +9 -8
  202. package/src/runtime/agent/orchestrator/session/store/session-persistence-events.mjs +29 -0
  203. package/src/runtime/agent/orchestrator/session/store-agent-worker-header-cache.mjs +85 -0
  204. package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +133 -18
  205. package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +12 -2
  206. package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +44 -14
  207. package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +84 -3
  208. package/src/runtime/agent/orchestrator/session/stored-attachment-history.mjs +32 -0
  209. package/src/runtime/agent/orchestrator/session/tail-reminder-rules.mjs +11 -5
  210. package/src/runtime/agent/orchestrator/session/thinking-binding.mjs +108 -0
  211. package/src/runtime/agent/orchestrator/session/tool-batch/pre-dispatch.mjs +2 -2
  212. package/src/runtime/agent/orchestrator/session/tool-batch/record-outcome.mjs +2 -1
  213. package/src/runtime/agent/orchestrator/session/tool-batch/state.mjs +4 -0
  214. package/src/runtime/agent/orchestrator/session/tool-batch.mjs +5 -0
  215. package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +25 -2
  216. package/src/runtime/agent/orchestrator/session/transcript-restore/tool-result-status.mjs +9 -7
  217. package/src/runtime/agent/orchestrator/session/transcript-restore/tool-result-text.mjs +2 -2
  218. package/src/runtime/agent/orchestrator/session/turn-failure.mjs +5 -1
  219. package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +5 -2
  220. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/backgrounded-result.mjs +12 -1
  221. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/misuse-guard.mjs +240 -0
  222. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/result-format.mjs +1 -1
  223. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/shell-cwd.mjs +38 -0
  224. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +25 -5
  225. package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +65 -7
  226. package/src/runtime/agent/orchestrator/tools/builtin/shell-runtime.mjs +7 -1
  227. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +36 -13
  228. package/src/runtime/browser-bridge/action-schema.mjs +13 -2
  229. package/src/runtime/browser-bridge/client.mjs +73 -8
  230. package/src/runtime/browser-bridge/input-fields.mjs +8 -9
  231. package/src/runtime/browser-bridge/mail-links.mjs +107 -0
  232. package/src/runtime/browser-bridge/tool-defs.mjs +1 -1
  233. package/src/runtime/channels/lib/config.mjs +6 -61
  234. package/src/runtime/channels/lib/crash-log.mjs +1 -1
  235. package/src/runtime/channels/lib/event-pipeline.mjs +4 -19
  236. package/src/runtime/channels/lib/event-queue.mjs +3 -18
  237. package/src/runtime/channels/lib/owned-runtime/automation-services.mjs +2 -2
  238. package/src/runtime/channels/lib/owned-runtime/automation-start.mjs +3 -4
  239. package/src/runtime/channels/lib/owned-runtime/config-reload.mjs +4 -59
  240. package/src/runtime/channels/lib/owned-runtime/owned-start.mjs +33 -115
  241. package/src/runtime/channels/lib/owned-runtime/owned-stop.mjs +5 -22
  242. package/src/runtime/channels/lib/owned-runtime/state.mjs +2 -8
  243. package/src/runtime/channels/lib/owned-runtime.mjs +6 -23
  244. package/src/runtime/channels/lib/parent-bridge.mjs +2 -2
  245. package/src/runtime/channels/lib/runtime-paths.mjs +4 -43
  246. package/src/runtime/channels/lib/schedule-errors.mjs +51 -0
  247. package/src/runtime/channels/lib/scheduler.mjs +135 -154
  248. package/src/runtime/channels/lib/schedules-db.mjs +83 -11
  249. package/src/runtime/channels/lib/status-snapshot.mjs +1 -1
  250. package/src/runtime/channels/lib/tool-dispatch.mjs +14 -2
  251. package/src/runtime/channels/lib/webhooks-db.mjs +5 -9
  252. package/src/runtime/channels/lib/worker-bootstrap.mjs +0 -1
  253. package/src/runtime/channels/lib/worker-ipc.mjs +0 -1
  254. package/src/runtime/channels/lib/worker-main.mjs +19 -34
  255. package/src/runtime/computer-bridge/action-schema.mjs +42 -1
  256. package/src/runtime/computer-bridge/actions.mjs +9 -1
  257. package/src/runtime/computer-bridge/client.mjs +180 -8
  258. package/src/runtime/computer-bridge/core-actions.mjs +2 -2
  259. package/src/runtime/computer-bridge/error-recovery.mjs +27 -2
  260. package/src/runtime/computer-bridge/linux-readiness.mjs +65 -23
  261. package/src/runtime/computer-bridge/pending-continuation.mjs +1 -1
  262. package/src/runtime/connectors/connector-accounts-mcp.mjs +230 -0
  263. package/src/runtime/connectors/gmail-app-password.mjs +172 -39
  264. package/src/runtime/connectors/google-mcp.mjs +10 -12
  265. package/src/runtime/memory/lib/pg/adapter.mjs +77 -70
  266. package/src/runtime/memory/lib/pg/supervisor.mjs +24 -12
  267. package/src/runtime/memory/lib/runtime-fetcher.mjs +23 -5
  268. package/src/runtime/office/com/com-adapter.mjs +17 -1
  269. package/src/runtime/office/com/office-com-host.ps1 +51 -1
  270. package/src/runtime/office/pdf/cfb-fixture.mjs +328 -0
  271. package/src/runtime/office/pdf/cfb-protection.mjs +311 -0
  272. package/src/runtime/office/pdf/document-preview.mjs +326 -8
  273. package/src/runtime/office/pdf/ooxml-crypto.mjs +469 -0
  274. package/src/runtime/office/pdf/ooxml-key-worker.mjs +14 -0
  275. package/src/runtime/office/portable/portable-soffice.mjs +45 -5
  276. package/src/runtime/session-search/session-search-db.mjs +73 -9
  277. package/src/runtime/session-search/session-search-ingest.mjs +110 -20
  278. package/src/runtime/shared/abort-race.mjs +89 -0
  279. package/src/runtime/shared/agent-avatar.d.mts +0 -1
  280. package/src/runtime/shared/agent-kind.mjs +4 -3
  281. package/src/runtime/shared/bot-hops.mjs +62 -2
  282. package/src/runtime/shared/bounded-download.mjs +8 -3
  283. package/src/runtime/shared/config.mjs +51 -35
  284. package/src/runtime/shared/connector-accounts.mjs +20 -10
  285. package/src/runtime/shared/connector-catalog.d.mts +33 -2
  286. package/src/runtime/shared/connector-catalog.mjs +166 -8
  287. package/src/runtime/shared/connector-triggers.mjs +22 -19
  288. package/src/runtime/shared/defaults-separation.mjs +2 -14
  289. package/src/runtime/shared/delegated-approval-host.mjs +103 -11
  290. package/src/runtime/shared/developer-options.mjs +32 -1
  291. package/src/runtime/shared/err-text.mjs +24 -15
  292. package/src/runtime/shared/file-permissions.d.mts +0 -8
  293. package/src/runtime/shared/file-permissions.mjs +0 -11
  294. package/src/runtime/shared/git-direct.test-support.mjs +19 -0
  295. package/src/runtime/shared/google-oauth-client.generated.json +4 -0
  296. package/src/runtime/shared/google-oauth-client.mjs +34 -9
  297. package/src/runtime/shared/heartbeat-interval.d.mts +4 -0
  298. package/src/runtime/shared/heartbeat-interval.mjs +19 -0
  299. package/src/runtime/shared/idle-auto-clear-gate.mjs +104 -0
  300. package/src/runtime/shared/llm/anthropic-betas.mjs +7 -0
  301. package/src/runtime/shared/llm/anthropic-thinking-contract.mjs +12 -0
  302. package/src/runtime/shared/llm/provider-catalog-registry.mjs +1 -0
  303. package/src/runtime/shared/llm/usage-rollup.mjs +1 -1
  304. package/src/runtime/shared/llm/well-formed.mjs +66 -0
  305. package/src/runtime/shared/mixy-presence.mjs +22 -0
  306. package/src/runtime/shared/orchestration.d.mts +2 -0
  307. package/src/runtime/shared/pg-schema-db.mjs +27 -16
  308. package/src/runtime/shared/profile-config.cjs +1 -1
  309. package/src/runtime/shared/prompt-origin.d.mts +4 -0
  310. package/src/runtime/shared/prompt-origin.mjs +21 -0
  311. package/src/runtime/shared/provider-accounts.mjs +231 -59
  312. package/src/runtime/shared/provider-api-key.mjs +19 -8
  313. package/src/runtime/shared/provider-display-name.mjs +29 -0
  314. package/src/runtime/shared/provider-timeout-phase.mjs +2 -0
  315. package/src/runtime/shared/routine-trigger.d.mts +2 -0
  316. package/src/runtime/shared/routine-trigger.mjs +52 -0
  317. package/src/runtime/shared/sensitive-path-rules.d.mts +2 -10
  318. package/src/runtime/shared/sensitive-path-rules.mjs +19 -41
  319. package/src/runtime/shared/session-activity-signal.mjs +34 -1
  320. package/src/runtime/shared/session-sidebar-host.d.mts +1 -1
  321. package/src/runtime/shared/session-sidebar-host.mjs +7 -3
  322. package/src/runtime/shared/session-turn-prelude.mjs +18 -0
  323. package/src/runtime/shared/tool-execution-contract.mjs +2 -0
  324. package/src/runtime/shared/tool-result-summary.mjs +1 -14
  325. package/src/runtime/shared/transcript-metadata.mjs +38 -0
  326. package/src/runtime/shared/user-data-guard.mjs +30 -2
  327. package/src/runtime/shared/worktrees/activity-gate.mjs +12 -5
  328. package/src/runtime/shared/worktrees/test-support.mjs +9 -4
  329. package/src/runtime/terminal-bridge/client.mjs +10 -1
  330. package/src/runtime/visualize-bridge/client.mjs +27 -8
  331. package/src/runtime/visualize-bridge/tool-defs.mjs +22 -8
  332. package/src/runtime/visualize-bridge/tool-meta.d.mts +5 -0
  333. package/src/runtime/visualize-bridge/tool-meta.mjs +22 -0
  334. package/src/runtime/web-search/lib/fetch-pipeline.mjs +2 -2
  335. package/src/session-runtime/agent-home-delivery.mjs +486 -179
  336. package/src/session-runtime/agent-room-delivery.mjs +28 -1
  337. package/src/session-runtime/agent-task-sessions.mjs +561 -199
  338. package/src/session-runtime/boot/apis.mjs +9 -0
  339. package/src/session-runtime/boot/begin.mjs +3 -2
  340. package/src/session-runtime/boot/infrastructure.mjs +4 -0
  341. package/src/session-runtime/boot/providers.mjs +3 -0
  342. package/src/session-runtime/boot/tools.mjs +8 -1
  343. package/src/session-runtime/bot-chain.mjs +32 -0
  344. package/src/session-runtime/bot-status.mjs +7 -4
  345. package/src/session-runtime/channel-config-api.mjs +63 -17
  346. package/src/session-runtime/config-lifecycle.mjs +6 -0
  347. package/src/session-runtime/connector-merge-migration.mjs +305 -0
  348. package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +132 -28
  349. package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +2 -0
  350. package/src/session-runtime/internal-tool-executor/reaction-tool.mjs +45 -0
  351. package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +72 -5
  352. package/src/session-runtime/internal-tool-executor.mjs +4 -0
  353. package/src/session-runtime/lifecycle/inheritance.mjs +16 -3
  354. package/src/session-runtime/lifecycle/session-catalog.mjs +3 -1
  355. package/src/session-runtime/lifecycle/teardown/runtime-stops.mjs +50 -4
  356. package/src/session-runtime/lifecycle/teardown.mjs +23 -5
  357. package/src/session-runtime/mcp-glue/server-catalog.mjs +61 -3
  358. package/src/session-runtime/mcp-oauth-login.mjs +5 -3
  359. package/src/session-runtime/mixy-heartbeat.mjs +927 -0
  360. package/src/session-runtime/model-route/route-tuning.mjs +10 -6
  361. package/src/session-runtime/notification-bus.mjs +31 -117
  362. package/src/session-runtime/notification-completion-queue.mjs +54 -0
  363. package/src/session-runtime/notification-listeners.mjs +76 -0
  364. package/src/session-runtime/owned-automation-run.mjs +35 -13
  365. package/src/session-runtime/prewarm/channel-start.mjs +3 -7
  366. package/src/session-runtime/provider-auth/login.mjs +7 -0
  367. package/src/session-runtime/provider-models/row-hydration.mjs +13 -2
  368. package/src/session-runtime/resource-mcp-api.mjs +143 -224
  369. package/src/session-runtime/resource-mcp-connector-accounts.mjs +163 -0
  370. package/src/session-runtime/resource-mcp-oauth-api.mjs +217 -0
  371. package/src/session-runtime/resource-mcp-secrets.mjs +82 -0
  372. package/src/session-runtime/resource-mcp-servers.mjs +78 -0
  373. package/src/session-runtime/resource-mcp-store.mjs +49 -0
  374. package/src/session-runtime/routine-home-turn.mjs +33 -6
  375. package/src/session-runtime/routine-owner.mjs +40 -9
  376. package/src/session-runtime/schedule-session-run.mjs +7 -3
  377. package/src/session-runtime/services/agent-tool/close-flow.mjs +3 -0
  378. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-plan.mjs +8 -12
  379. package/src/session-runtime/services/agent-tool/spawn-preset.mjs +7 -2
  380. package/src/session-runtime/services/agent-tool/tag-registry.mjs +1 -0
  381. package/src/session-runtime/services/agent-tool/worker-index/awaiting-user-sync.mjs +51 -0
  382. package/src/session-runtime/services/agent-tool/worker-index/disposal.mjs +55 -0
  383. package/src/session-runtime/services/agent-tool/worker-index/released-store.mjs +123 -0
  384. package/src/session-runtime/services/agent-tool/worker-index/restart-settlement.mjs +112 -0
  385. package/src/session-runtime/services/agent-tool/worker-index/row-reads.mjs +36 -0
  386. package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +2 -0
  387. package/src/session-runtime/services/agent-tool/worker-index/row-store.mjs +17 -4
  388. package/src/session-runtime/services/agent-tool/worker-index/row-writes.mjs +58 -0
  389. package/src/session-runtime/services/agent-tool/worker-index.mjs +41 -241
  390. package/src/session-runtime/services/agent-tool/worker-rows.mjs +3 -0
  391. package/src/session-runtime/services/channel-admin.mjs +73 -31
  392. package/src/session-runtime/services/channel-session-router.mjs +4 -2
  393. package/src/session-runtime/services/channel-worker.mjs +1 -1
  394. package/src/session-runtime/services/provider-admin.mjs +128 -25
  395. package/src/session-runtime/services/schedule-access.mjs +14 -0
  396. package/src/session-runtime/services/seeds.mjs +0 -28
  397. package/src/session-runtime/services/usage-dashboard-model.mjs +1 -0
  398. package/src/session-runtime/session-compaction-sync.mjs +27 -0
  399. package/src/session-runtime/session-create/session-options.mjs +8 -4
  400. package/src/session-runtime/settings-builtin-tools-api.mjs +11 -0
  401. package/src/session-runtime/settings-compaction-api.mjs +2 -40
  402. package/src/session-runtime/settings-system-api.mjs +28 -1
  403. package/src/session-runtime/setup-tool/agent-settings-actions.mjs +65 -0
  404. package/src/session-runtime/setup-tool/executor.mjs +187 -29
  405. package/src/session-runtime/setup-tool/extended-actions.mjs +33 -2
  406. package/src/session-runtime/setup-tool/session-route-actions.mjs +152 -0
  407. package/src/session-runtime/setup-tool/settings-contract.mjs +68 -6
  408. package/src/session-runtime/setup-tool/tool-defs.mjs +92 -6
  409. package/src/session-runtime/task-session-route.mjs +99 -0
  410. package/src/session-runtime/tool-policy/agent-profile-fold.mjs +17 -13
  411. package/src/session-runtime/tool-policy/policy-stage.mjs +21 -4
  412. package/src/session-runtime/tool-policy/surface-helpers.mjs +2 -3
  413. package/src/session-runtime/tool-surface.mjs +4 -0
  414. package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +1 -0
  415. package/src/session-runtime/workflow-agents-api/agent-editor.mjs +98 -21
  416. package/src/session-runtime/workflow-agents-api/style-and-mode.mjs +4 -0
  417. package/src/session-runtime/workflow-agents-api/workflow-packs.mjs +6 -1
  418. package/src/session-runtime/workspace/transitions.mjs +10 -2
  419. package/src/standalone/channel-transport/client-registry/client-records.mjs +65 -0
  420. package/src/standalone/channel-transport/client-registry/client-registration.mjs +118 -0
  421. package/src/standalone/channel-transport/client-registry.mjs +24 -163
  422. package/src/standalone/channel-transport.mjs +1 -1
  423. package/src/standalone/daemon-channels-loader.mjs +10 -8
  424. package/src/standalone/daemon-session-control/list-page.mjs +72 -0
  425. package/src/standalone/daemon-session-control/request.mjs +51 -0
  426. package/src/standalone/daemon-session-control/room-host.mjs +57 -0
  427. package/src/standalone/daemon-session-control/route-control.mjs +48 -0
  428. package/src/standalone/daemon-session-control/send-turn.mjs +60 -0
  429. package/src/standalone/daemon-session-control/worktree-control.mjs +40 -0
  430. package/src/standalone/daemon-session-control.mjs +161 -157
  431. package/src/standalone/daemon.mjs +33 -2
  432. package/src/standalone/session-client.mjs +7 -3
  433. package/src/standalone/session-protocol.mjs +10 -0
  434. package/src/standalone/session-service/agent-tree/agent-cancel.mjs +6 -2
  435. package/src/standalone/session-service/agent-tree/agent-child.mjs +1 -0
  436. package/src/standalone/session-service/quota-resume.mjs +3 -0
  437. package/src/standalone/session-service/retention/busy.mjs +65 -1
  438. package/src/standalone/session-service/session-calls/session-action.mjs +23 -2
  439. package/src/standalone/session-service/session-calls/session-turns.mjs +6 -0
  440. package/src/standalone/session-service/session-calls/session-views.mjs +8 -0
  441. package/src/standalone/session-service.mjs +13 -0
  442. package/src/standalone/session-tool-output.mjs +21 -10
  443. package/src/tui/app/model-options.mjs +4 -27
  444. package/src/tui/dist/index.mjs +81 -65
  445. package/src/tui/session/agent-job-feed/model-notification.mjs +3 -0
  446. package/src/tui/session/initial-state.mjs +3 -0
  447. package/src/tui/session/notice-surface.mjs +23 -1
  448. package/src/tui/session/queue-helpers.mjs +3 -42
  449. package/src/tui/session/session-api/integrations.mjs +1 -0
  450. package/src/tui/session/session-api/lifecycle.mjs +8 -0
  451. package/src/tui/session/session-api/routes-agent-definitions.mjs +14 -2
  452. package/src/tui/session/session-api/routes-write.mjs +5 -1
  453. package/src/tui/session/session-api/routes.mjs +1 -0
  454. package/src/tui/session/session-api/settings.mjs +30 -2
  455. package/src/tui/session/session-flow/auto-clear.mjs +4 -33
  456. package/src/tui/session/session-flow/drain-closed-queue.mjs +38 -0
  457. package/src/tui/session/session-flow/drain-enqueue.mjs +86 -0
  458. package/src/tui/session/session-flow/drain-retry.mjs +35 -0
  459. package/src/tui/session/session-flow/drain.mjs +118 -149
  460. package/src/tui/session/session-flow/queue/entry-shape.mjs +5 -0
  461. package/src/tui/session/session-flow/queue/take-entries.mjs +5 -2
  462. package/src/tui/session/tool-approval-delegation.mjs +64 -0
  463. package/src/tui/session/tool-approval-request.mjs +39 -0
  464. package/src/tui/session/tool-approval-settle.mjs +62 -0
  465. package/src/tui/session/tool-approval.mjs +69 -115
  466. package/src/tui/session/tui-steering-persist.mjs +8 -1
  467. package/src/tui/session/turn-stream.mjs +36 -3
  468. package/src/tui/session/turn.mjs +23 -2
  469. package/src/vendor/statusline/bin/statusline-route.mjs +1 -219
  470. package/src/vendor/statusline/src/gateway/route-meta.mjs +35 -13
  471. package/scripts/code-graph-description-contract.mjs +0 -188
  472. package/src/runtime/channels/lib/owned-runtime/ownership-refresh.mjs +0 -36
@@ -2,10 +2,11 @@ import { reloadProviderApiKey, resolveProviderApiKey } from '../../../shared/pro
2
2
  import { sanitizeToolPairs } from '../session/context-utils.mjs';
3
3
  import { AnthropicFallbackTriggeredError } from './retry-classifier.mjs';
4
4
  import {
5
- announceAnthropicModelFallback,
6
5
  createAnthropicOverloadTracker,
7
6
  isTerminalOverloadModel,
7
+ takeAnthropicModelFallback,
8
8
  } from './anthropic-overload-fallback.mjs';
9
+ import { removeAbortListener } from './anthropic-oauth-request/abort-wiring.mjs';
9
10
  import { readStreamOutcome } from './lib/stream-outcome.mjs';
10
11
  import { createPassthroughSignal } from '../stall-policy.mjs';
11
12
  import { createAbortController } from '../../../shared/abort-controller.mjs';
@@ -18,6 +19,7 @@ import { ANTHROPIC_EFFORT_LEVELS, withEffortRejectionFallback } from './effort-r
18
19
  import { armFirstByteWatchdog, createAnthropicApiTransport } from './anthropic-api-transport.mjs';
19
20
  import { createAnthropicApiRecovery } from './anthropic-api-recovery.mjs';
20
21
  import { buildAnthropicTurnResult } from './anthropic-turn-result.mjs';
22
+ import { sendAnthropicCacheWarm } from './anthropic-cache-warm.mjs';
21
23
  import {
22
24
  assertAnthropicStreamNotEmpty,
23
25
  createAnthropicMidState,
@@ -38,6 +40,29 @@ import { streamCallbacks } from './lib/send-callbacks.mjs';
38
40
  import { preparePdfTextForProvider } from './media-normalization.mjs';
39
41
  export { _test, _toAnthropicMessagesForTest } from './anthropic-messages.mjs';
40
42
 
43
+ // One stream attempt's controller, aborted with the caller's reason when the
44
+ // send's signal aborts. An already-aborted send fails before the attempt.
45
+ function linkAttemptAbort(totalSignal) {
46
+ const streamController = createAbortController();
47
+ let cancelHandler = null;
48
+
49
+ if (totalSignal) {
50
+ if (totalSignal.aborted) {
51
+ const reason = totalSignal.reason;
52
+ throw reason instanceof Error ? reason : new Error('Anthropic request aborted');
53
+ }
54
+ cancelHandler = () => {
55
+ try {
56
+ streamController.abort(totalSignal.reason);
57
+ } catch {
58
+ // best-effort propagation of caller cancellation
59
+ }
60
+ };
61
+ totalSignal.addEventListener('abort', cancelHandler, { once: true });
62
+ }
63
+ return { streamController, cancelHandler };
64
+ }
65
+
41
66
  export class AnthropicProvider {
42
67
  // Takes a PDF as a native document block (decided by this adapter's wire protocol).
43
68
  nativePdf = true;
@@ -143,6 +168,38 @@ export class AnthropicProvider {
143
168
  throw err;
144
169
  }
145
170
  }
171
+ /**
172
+ * Cache-warm mode (anthropic-cache-warm.mjs): the request `send` would
173
+ * build for these arguments, sent once on the retry-free client — no
174
+ * key reload, fallback model or re-send — and cut at the first content
175
+ * block. `onUsage` receives the reported usage as it arrives.
176
+ */
177
+ async sendCacheWarm(messages, model, tools, opts = {}, { onUsage, accountId = '' } = {}) {
178
+ const prepared = await preparePdfTextForProvider(sanitizeToolPairs(messages), this);
179
+ const { params, requestHeaders } = await buildAnthropicApiRequest({
180
+ name: this.name,
181
+ config: this.config,
182
+ messages: prepared,
183
+ useModel: model,
184
+ tools,
185
+ opts,
186
+ fastModeLatched: this.fastModeBetaHeaderLatched,
187
+ modelInfo: isCustomProviderName(this.name) ? this.getCachedModelInfo?.(model) || null : null,
188
+ capabilityModel: this._capabilityModel(model),
189
+ });
190
+ return sendAnthropicCacheWarm({
191
+ providerName: this.name,
192
+ instance: this,
193
+ accountId,
194
+ model,
195
+ opts,
196
+ onUsage,
197
+ post: (signal) =>
198
+ this._currentClient()
199
+ .messages.create(params, { signal, ...(requestHeaders ? { headers: requestHeaders } : {}) })
200
+ .asResponse(),
201
+ });
202
+ }
146
203
  // The `anthropic` API-key provider and every custom `anthropic`-protocol
147
204
  // provider (a subclass of this one) share this send path.
148
205
  async _doSend(messages, model, tools, sendOpts) {
@@ -188,89 +245,20 @@ export class AnthropicProvider {
188
245
  const totalTimeout = createPassthroughSignal(externalSignal);
189
246
  const totalSignal = totalTimeout.signal;
190
247
 
191
- const cleanupCancelHandler = (handler) => {
192
- if (!handler) return;
193
- try {
194
- totalSignal.removeEventListener('abort', handler);
195
- } catch {}
196
- };
197
-
198
- // Request-loop 529s and SSE overload events share one counter; at the
199
- // limit the configured fallback model takes over the whole send.
200
- const overload = createAnthropicOverloadTracker({
201
- model: useModel,
202
- fallbackModel: opts._fallbackTriggered ? undefined : opts.fallbackModel,
203
- terminalAtLimit: !isCustomProviderName(this.name) && isTerminalOverloadModel(useModel),
204
- });
205
- // The SDK calls and their initial-response retry policy
206
- // (anthropic-api-transport.mjs).
207
- const transport = createAnthropicApiTransport({
208
- client: this._currentClient(),
209
- label: this.name,
248
+ const { transport, buildTurnResult, recovery, midstream } = this._createSendRecovery({
210
249
  opts,
211
250
  useModel,
212
251
  params,
213
252
  requestHeaders,
214
253
  totalSignal,
215
- overload,
216
- });
217
- // Usage accounting + caller-visible projection, shared by the streaming
218
- // success path and the non-streaming fallback (anthropic-turn-result.mjs).
219
- const buildTurnResult = (parseResult) =>
220
- buildAnthropicTurnResult(parseResult, { provider: this.name, useModel, opts });
221
- // Non-streaming re-issue of a dead stream, behind the transport-recovery
222
- // budget and the exposed-output retraction handshake
223
- // (anthropic-api-recovery.mjs).
224
- const recovery = createAnthropicApiRecovery({
225
- label: this.name,
226
- opts,
227
- useModel,
228
- params,
229
- totalSignal,
230
- transport,
231
- buildTurnResult,
232
254
  onStageChange,
233
255
  onTextReset,
234
256
  });
235
- // Bounded mid-stream retries for transient stream loss; jittered backoff
236
- // between attempts (anthropic-midstream-recovery.mjs, shared with
237
- // anthropic-oauth).
238
- const midstream = createAnthropicMidstreamRecovery({
239
- label: this.name,
240
- displayName: 'Anthropic',
241
- outcomeProvider: 'anthropic',
242
- midstreamOwner: `${this.name}-midstream`,
243
- unreachableMessage: 'Anthropic mid-stream retry: unreachable',
244
- // The transport's withRetry already exhausted the full request-level
245
- // budget for a non-OK initial response, so it must not earn an
246
- // additional SSE retry budget here.
247
- initialResponseErrorTerminal: true,
248
- maxRetries: ANTHROPIC_MAX_MIDSTREAM_RETRIES,
249
- totalSignal,
250
- recovery,
251
- onStageChange,
252
- retry529: opts.retry529 !== false,
253
- overload,
254
- });
255
257
 
256
258
  let streamingFallbackTried = false;
257
259
  try {
258
260
  for (let attemptIndex = 0; attemptIndex <= ANTHROPIC_MAX_MIDSTREAM_RETRIES; attemptIndex++) {
259
- const streamController = createAbortController();
260
- let cancelHandler = null;
261
-
262
- if (totalSignal) {
263
- if (totalSignal.aborted) {
264
- const reason = totalSignal.reason;
265
- throw reason instanceof Error ? reason : new Error('Anthropic request aborted');
266
- }
267
- cancelHandler = () => {
268
- try {
269
- streamController.abort(totalSignal.reason);
270
- } catch {}
271
- };
272
- totalSignal.addEventListener('abort', cancelHandler, { once: true });
273
- }
261
+ const { streamController, cancelHandler } = linkAttemptAbort(totalSignal);
274
262
 
275
263
  const midState = createAnthropicMidState(attemptIndex);
276
264
 
@@ -280,13 +268,17 @@ export class AnthropicProvider {
280
268
  try {
281
269
  try {
282
270
  onStageChange?.('requesting');
283
- } catch {}
271
+ } catch {
272
+ // the stage observer is advisory
273
+ }
284
274
 
285
275
  response = await transport.requestStreamingResponse();
286
276
 
287
277
  try {
288
278
  onStageChange?.('streaming');
289
- } catch {}
279
+ } catch {
280
+ // the stage observer is advisory
281
+ }
290
282
 
291
283
  firstByte = armFirstByteWatchdog(streamController, midState);
292
284
 
@@ -307,7 +299,9 @@ export class AnthropicProvider {
307
299
  );
308
300
  try {
309
301
  streamController.abort?.('Anthropic SSE complete');
310
- } catch {}
302
+ } catch {
303
+ // the stream is complete; the controller may already be aborted
304
+ }
311
305
 
312
306
  firstByte.cleanup();
313
307
  assertAnthropicStreamNotEmpty(midState, parseResult, 'Anthropic');
@@ -336,26 +330,80 @@ export class AnthropicProvider {
336
330
  return decision.value;
337
331
  } finally {
338
332
  firstByte?.cleanup();
339
- cleanupCancelHandler(cancelHandler);
333
+ removeAbortListener(totalSignal, cancelHandler);
340
334
  }
341
335
  }
342
336
  throw midstream.exhaustedError();
343
337
  } catch (err) {
344
- // The fallback trigger can surface from the request loop, a mid-stream
345
- // overload, or the non-streaming recovery: handle it around the whole
346
- // operation, not just the first request.
347
- if (!(err instanceof AnthropicFallbackTriggeredError)) throw err;
348
- process.stderr.write(`[${this.name}] ${err.message}\n`);
349
- announceAnthropicModelFallback(onStageChange, useModel, err.fallbackModel);
350
- return await this._doSend(messages, err.fallbackModel, tools, {
351
- ...opts,
352
- fallbackModel: undefined,
353
- _fallbackTriggered: true,
354
- });
338
+ const fallbackOpts = takeAnthropicModelFallback(err, { tag: this.name, model: useModel, opts, onStageChange });
339
+ return await this._doSend(messages, err.fallbackModel, tools, fallbackOpts);
355
340
  } finally {
356
341
  totalTimeout.cleanup();
357
342
  }
358
343
  }
344
+ // The recovery pipeline of one send over its fixed request: the shared
345
+ // overload counter, the transport, the turn-result projection, the
346
+ // non-streaming recovery and the bounded mid-stream retries.
347
+ _createSendRecovery({ opts, useModel, params, requestHeaders, totalSignal, onStageChange, onTextReset }) {
348
+ // Request-loop 529s and SSE overload events share one counter; at the
349
+ // limit the configured fallback model takes over the whole send.
350
+ const overload = createAnthropicOverloadTracker({
351
+ model: useModel,
352
+ fallbackModel: opts._fallbackTriggered ? undefined : opts.fallbackModel,
353
+ terminalAtLimit: !isCustomProviderName(this.name) && isTerminalOverloadModel(useModel),
354
+ });
355
+ // The SDK calls and their initial-response retry policy
356
+ // (anthropic-api-transport.mjs).
357
+ const transport = createAnthropicApiTransport({
358
+ client: this._currentClient(),
359
+ label: this.name,
360
+ opts,
361
+ useModel,
362
+ params,
363
+ requestHeaders,
364
+ totalSignal,
365
+ overload,
366
+ });
367
+ // Usage accounting + caller-visible projection, shared by the streaming
368
+ // success path and the non-streaming fallback (anthropic-turn-result.mjs).
369
+ const buildTurnResult = (parseResult) =>
370
+ buildAnthropicTurnResult(parseResult, { provider: this.name, useModel, opts });
371
+ // Non-streaming re-issue of a dead stream, behind the transport-recovery
372
+ // budget and the exposed-output retraction handshake
373
+ // (anthropic-api-recovery.mjs).
374
+ const recovery = createAnthropicApiRecovery({
375
+ label: this.name,
376
+ opts,
377
+ useModel,
378
+ params,
379
+ totalSignal,
380
+ transport,
381
+ buildTurnResult,
382
+ onStageChange,
383
+ onTextReset,
384
+ });
385
+ // Bounded mid-stream retries for transient stream loss; jittered backoff
386
+ // between attempts (anthropic-midstream-recovery.mjs, shared with
387
+ // anthropic-oauth).
388
+ const midstream = createAnthropicMidstreamRecovery({
389
+ label: this.name,
390
+ displayName: 'Anthropic',
391
+ outcomeProvider: 'anthropic',
392
+ midstreamOwner: `${this.name}-midstream`,
393
+ unreachableMessage: 'Anthropic mid-stream retry: unreachable',
394
+ // The transport's withRetry already exhausted the full request-level
395
+ // budget for a non-OK initial response, so it must not earn an
396
+ // additional SSE retry budget here.
397
+ initialResponseErrorTerminal: true,
398
+ maxRetries: ANTHROPIC_MAX_MIDSTREAM_RETRIES,
399
+ totalSignal,
400
+ recovery,
401
+ onStageChange,
402
+ retry529: opts.retry529 !== false,
403
+ overload,
404
+ });
405
+ return { transport, buildTurnResult, recovery, midstream };
406
+ }
359
407
  async listModels() {
360
408
  const apiKey = resolveProviderApiKey(this.name, this.config);
361
409
  if (!apiKey) return MODELS;
@@ -23,7 +23,8 @@ import {
23
23
  } from './antigravity-oauth-tokens.mjs';
24
24
 
25
25
  const ANTIGRAVITY_MODEL_CACHE_TTL_MS = 6 * 60 * 60 * 1000;
26
- const ANTIGRAVITY_MODEL_CACHE_VERSION = 1;
26
+ // v2: rows keep the gateway-declared per-model `maxOutputTokens`.
27
+ const ANTIGRAVITY_MODEL_CACHE_VERSION = 2;
27
28
  const FETCH_MODELS_TIMEOUT_MS = 15_000;
28
29
  // Tier labels the gateway puts in parentheses, in effort order.
29
30
  const TIER_EFFORTS = { 'extra low': 'minimal', minimal: 'minimal', low: 'low', medium: 'medium', high: 'high' };
@@ -145,10 +146,21 @@ export function normalizeAntigravityCatalog(rawModels) {
145
146
  const key = familyId(base);
146
147
  let family = families.get(key);
147
148
  if (!family) {
148
- family = { base, contextWindow: 0, supportsVision: false, supportsReasoning: false, wires: new Map() };
149
+ family = {
150
+ base,
151
+ contextWindow: 0,
152
+ maxOutputTokens: 0,
153
+ supportsVision: false,
154
+ supportsReasoning: false,
155
+ wires: new Map(),
156
+ };
149
157
  families.set(key, family);
150
158
  }
151
159
  family.contextWindow = Math.max(family.contextWindow, contextWindow);
160
+ // Wire ids sharing one record keep the smallest declared output limit, so
161
+ // the ceiling holds for every id the record can resolve to.
162
+ const declaredOutput = Math.floor(Number(entry.maxOutputTokens));
163
+ if (declaredOutput > 0) family.maxOutputTokens = Math.min(family.maxOutputTokens || declaredOutput, declaredOutput);
152
164
  family.supportsVision ||= entry.supportsImages === true;
153
165
  family.supportsReasoning ||= entry.supportsThinking === true;
154
166
  const slot = effort || '';
@@ -177,6 +189,7 @@ export function normalizeAntigravityCatalog(rawModels) {
177
189
  provider: 'antigravity-oauth',
178
190
  ...(kind ? { family: kind } : {}),
179
191
  contextWindow: family.contextWindow,
192
+ ...(family.maxOutputTokens ? { maxOutputTokens: family.maxOutputTokens } : {}),
180
193
  supportsVision: family.supportsVision,
181
194
  supportsReasoning: family.supportsReasoning,
182
195
  supportsFunctionCalling: true,
@@ -210,6 +223,19 @@ export function antigravityModelFamily(model, models = antigravityCatalogModels(
210
223
  return typeof record?.family === 'string' && record.family ? record.family : null;
211
224
  }
212
225
 
226
+ /**
227
+ * The output-token limit the gateway declared for a picker id or one of its
228
+ * wire ids, or null when the catalog row carries none (the curated fallback
229
+ * list and caches written before the field existed declare none).
230
+ */
231
+ export function antigravityOutputLimit(model, models = antigravityCatalogModels()) {
232
+ const id = String(model || '');
233
+ const wires = (entry) => (entry?.wire && typeof entry.wire === 'object' ? Object.values(entry.wire) : [entry?.wire]);
234
+ const record = models.find((entry) => entry?.id === id) || models.find((entry) => wires(entry).includes(id));
235
+ const limit = Math.floor(Number(record?.maxOutputTokens));
236
+ return limit > 0 ? limit : null;
237
+ }
238
+
213
239
  /**
214
240
  * Turn a picker model + effort into the wire id the gateway accepts. Tiered
215
241
  * families consume the effort (the id encodes it); a bare id whose record
@@ -232,7 +258,7 @@ export function resolveAntigravityWireModel(model, effort, models = antigravityC
232
258
  return { model: wire, effort: record.reasoningLevels?.length ? effort : null };
233
259
  }
234
260
 
235
- function quotaRow(label, bucket) {
261
+ function quotaRow(label, bucket, scope) {
236
262
  if (!bucket || typeof bucket !== 'object') return null;
237
263
  if (typeof bucket.remainingFraction !== 'number' || !Number.isFinite(bucket.remainingFraction)) return null;
238
264
  const usedPct = Math.round(Math.max(0, Math.min(100, (1 - bucket.remainingFraction) * 100)) * 100) / 100;
@@ -242,6 +268,7 @@ function quotaRow(label, bucket) {
242
268
  usedPct,
243
269
  ...(Number.isFinite(resetAt) && resetAt > 0 ? { resetAt } : {}),
244
270
  source: 'antigravity-quota-summary',
271
+ ...scope,
245
272
  };
246
273
  }
247
274
 
@@ -254,11 +281,21 @@ const ARGON_WEEKLY_BUCKET_ID = 'gemini-argon-wtu-weekly';
254
281
  const THIRD_PARTY_5H_BUCKET_ID = '3p-5h';
255
282
  const THIRD_PARTY_WEEKLY_BUCKET_ID = '3p-weekly';
256
283
 
284
+ // The model ids each separate bucket meters: the "Claude and GPT models"
285
+ // group (Claude Opus, Claude Sonnet, GPT-OSS) and the Gemini 4 Argon group.
286
+ const THIRD_PARTY_MODELS = Object.freeze(['claude', 'gpt']);
287
+ const ARGON_MODELS = Object.freeze(['argon']);
288
+
257
289
  /**
258
290
  * Gemini 5H/7D rows from retrieveUserQuotaSummary, the separate weekly limit
259
291
  * of the Gemini 4 Argon group (its own group with only a weekly bucket), and
260
292
  * the Claude/GPT-OSS 5H/7D pair. Rows are selected by bucket id and window.
261
293
  * Missing fields stay omitted.
294
+ *
295
+ * Each group's buckets gate its own models only: the 3p pair gates Claude and
296
+ * GPT-OSS, the Argon bucket gates Argon, and the shared Gemini pair gates every
297
+ * model no other bucket in this summary claims, so a full Claude/GPT window
298
+ * leaves Gemini serving and the reverse.
262
299
  */
263
300
  export function antigravityQuotaWindows(summary) {
264
301
  const groups = (Array.isArray(summary?.groups) ? summary.groups : []).filter(
@@ -268,11 +305,18 @@ export function antigravityQuotaWindows(summary) {
268
305
  const bucket = (id, window) =>
269
306
  buckets.find((entry) => entry && typeof entry === 'object' && entry.bucketId === id && entry.window === window) ??
270
307
  null;
308
+ const reported = (...ids) => buckets.some((entry) => ids.includes(entry?.bucketId));
309
+ const claimed = [
310
+ ...(reported(THIRD_PARTY_5H_BUCKET_ID, THIRD_PARTY_WEEKLY_BUCKET_ID) ? THIRD_PARTY_MODELS : []),
311
+ ...(reported(ARGON_WEEKLY_BUCKET_ID) ? ARGON_MODELS : []),
312
+ ];
313
+ const gemini = claimed.length ? { except: claimed } : {};
314
+ const thirdParty = { models: [...THIRD_PARTY_MODELS] };
271
315
  return [
272
- quotaRow('5H', bucket(GEMINI_5H_BUCKET_ID, '5h')),
273
- quotaRow('7D', bucket(GEMINI_WEEKLY_BUCKET_ID, 'weekly')),
274
- quotaRow('7D Argon', bucket(ARGON_WEEKLY_BUCKET_ID, 'weekly')),
275
- quotaRow('5H Claude/GPT', bucket(THIRD_PARTY_5H_BUCKET_ID, '5h')),
276
- quotaRow('7D Claude/GPT', bucket(THIRD_PARTY_WEEKLY_BUCKET_ID, 'weekly')),
316
+ quotaRow('5H', bucket(GEMINI_5H_BUCKET_ID, '5h'), gemini),
317
+ quotaRow('7D', bucket(GEMINI_WEEKLY_BUCKET_ID, 'weekly'), gemini),
318
+ quotaRow('7D Argon', bucket(ARGON_WEEKLY_BUCKET_ID, 'weekly'), { models: [...ARGON_MODELS] }),
319
+ quotaRow('5H Claude/GPT', bucket(THIRD_PARTY_5H_BUCKET_ID, '5h'), thirdParty),
320
+ quotaRow('7D Claude/GPT', bucket(THIRD_PARTY_WEEKLY_BUCKET_ID, 'weekly'), thirdParty),
277
321
  ].filter(Boolean);
278
322
  }
@@ -18,6 +18,8 @@ import { buildAntigravityRequest, isAntigravityClaude as isClaudeModel } from '.
18
18
  import { createPassthroughSignal } from '../stall-policy.mjs';
19
19
  import { preconnect } from '../../../shared/llm/http-agent.mjs';
20
20
  import { createAntigravityStreamCollector } from './antigravity-stream.mjs';
21
+ import { createGeminiReasoningRelay } from './gemini-reasoning-relay.mjs';
22
+ import { splitTailReminder } from './lib/tail-reminder-split.mjs';
21
23
  import { createAntigravityRequest } from './antigravity-transport.mjs';
22
24
  import { finalizeAntigravityTurn } from './antigravity-response.mjs';
23
25
  import {
@@ -41,6 +43,7 @@ import {
41
43
  fetchAvailableModels,
42
44
  fetchUserQuotaSummary,
43
45
  normalizeAntigravityCatalog,
46
+ antigravityOutputLimit,
44
47
  resolveAntigravityWireModel,
45
48
  } from './antigravity-oauth-catalog.mjs';
46
49
 
@@ -109,7 +112,7 @@ export class AntigravityOAuthProvider {
109
112
  }
110
113
 
111
114
  _buildBody(messages, model, tools, opts) {
112
- const body = buildAntigravityRequest(messages, model, tools, opts, this._projectId);
115
+ const body = buildAntigravityRequest(messages, model, tools, opts, this._projectId, antigravityOutputLimit(model));
113
116
  dumpAntigravityRequest(body);
114
117
  return body;
115
118
  }
@@ -131,6 +134,7 @@ export class AntigravityOAuthProvider {
131
134
  // Relayed through opts so the callback keeps its original receiver.
132
135
  const onTextDelta = typeof opts.onTextDelta === 'function' ? (text) => opts.onTextDelta(text) : null;
133
136
  const onStreamDelta = typeof opts.onStreamDelta === 'function' ? opts.onStreamDelta : null;
137
+ const reasoning = createGeminiReasoningRelay(opts);
134
138
  // Per-turn stream record: live text mirror, ordered parts, native/leaked
135
139
  // tool calls and the exposure marks a failed attempt carries
136
140
  // (antigravity-stream.mjs).
@@ -140,6 +144,8 @@ export class AntigravityOAuthProvider {
140
144
  onToolCall,
141
145
  onTextDelta,
142
146
  onStreamDelta,
147
+ onReasoningDelta: reasoning.onReasoningDelta,
148
+ retractReasoning: reasoning.retract,
143
149
  });
144
150
  if (signal?.aborted) {
145
151
  const reason = signal.reason;
@@ -181,6 +187,9 @@ export class AntigravityOAuthProvider {
181
187
  collector,
182
188
  sleepFn: this.config.sleepFn,
183
189
  firstByte: antigravityFirstBytePolicy(useModel),
190
+ // The tail reminder is not history: an empty answer right after a tool
191
+ // result is the model's answer, whatever reminder rides behind it.
192
+ afterToolResult: splitTailReminder(messages).messages.at(-1)?.role === 'tool',
184
193
  });
185
194
  try {
186
195
  try {
@@ -3,10 +3,17 @@ import { createProviderReplay, providerReplayItems } from './lib/provider-replay
3
3
  import { toGeminiContents, toGeminiRequestTools, toGeminiToolConfig } from './gemini-schema.mjs';
4
4
  import { geminiThinkingConfig } from './gemini-thinking.mjs';
5
5
  import { isGeminiFamilyModel } from './gemini-family.mjs';
6
+ import { geminiMaxOutputTokens } from './gemini-output-limit.mjs';
6
7
  import { splitTailReminder } from './lib/tail-reminder-split.mjs';
7
8
 
8
9
  const THOUGHT_SIGNATURE_SENTINEL = 'skip_thought_signature_validator';
10
+ // Used only when the gateway declared no output limit for a Claude id (the
11
+ // gateway enforces Claude's limit per model: one token over it is a 400).
9
12
  const CLAUDE_MAX_OUTPUT_TOKENS = 64000;
13
+ const claudeMaxOutputTokens = (declared) => {
14
+ const limit = Math.floor(Number(declared));
15
+ return limit > 0 ? limit : CLAUDE_MAX_OUTPUT_TOKENS;
16
+ };
10
17
 
11
18
  // Claude models behind the gateway speak a different thinking/replay dialect
12
19
  // (token budgets, anthropic-beta header, their own signatures). The roster
@@ -190,7 +197,7 @@ function claudeGatewayLevel(value) {
190
197
 
191
198
  // An explicit token budget is sent as-is; otherwise the chosen effort rides
192
199
  // on thinkingLevel with the wire id unchanged.
193
- function claudeThinkingConfig(opts) {
200
+ function claudeThinkingConfig(opts, cap) {
194
201
  const budget = opts.thinkingBudget ?? opts.thinkingBudgetTokens;
195
202
  const thinkingConfig = { includeThoughts: true };
196
203
  if (budget == null) {
@@ -199,8 +206,8 @@ function claudeThinkingConfig(opts) {
199
206
  return thinkingConfig;
200
207
  }
201
208
  const value = Number(budget);
202
- if (!Number.isInteger(value) || value < 1024 || value >= CLAUDE_MAX_OUTPUT_TOKENS) {
203
- throw new TypeError('Antigravity Claude thinkingBudget must be an integer from 1024 to 63999.');
209
+ if (!Number.isInteger(value) || value < 1024 || value >= cap) {
210
+ throw new TypeError(`Antigravity Claude thinkingBudget must be an integer from 1024 to ${cap - 1}.`);
204
211
  }
205
212
  thinkingConfig.thinkingBudget = value;
206
213
  return thinkingConfig;
@@ -220,7 +227,9 @@ function antigravityGeminiThinkingConfig(model, opts) {
220
227
  });
221
228
  }
222
229
 
223
- export function buildAntigravityRequest(requestMessages, model, tools, opts = {}, projectId) {
230
+ // `outputLimit` is the output-token limit the gateway declared for this wire id
231
+ // (the catalog row's `maxOutputTokens`), or null when it declared none.
232
+ export function buildAntigravityRequest(requestMessages, model, tools, opts = {}, projectId, outputLimit = null) {
224
233
  // The tail reminder is not history: the tool-loop closure below must see the
225
234
  // real tail, so the reminder is appended to the wire contents last.
226
235
  const { messages, reminder } = splitTailReminder(requestMessages);
@@ -232,10 +241,17 @@ export function buildAntigravityRequest(requestMessages, model, tools, opts = {}
232
241
  const history = toGeminiContents(signatureSafeMessages(chatMessages, model), model);
233
242
  if (!history.length) throw new Error('No messages to send');
234
243
  const claude = isAntigravityClaude(model);
235
- const thinkingConfig = claude ? claudeThinkingConfig(opts) : antigravityGeminiThinkingConfig(model, opts);
244
+ const claudeCap = claudeMaxOutputTokens(outputLimit);
245
+ const thinkingConfig = claude ? claudeThinkingConfig(opts, claudeCap) : antigravityGeminiThinkingConfig(model, opts);
236
246
  const contents = claude && claudeThinkingEnabled(model, thinkingConfig) ? closeUnthoughtToolLoop(history) : history;
247
+ // Gemini wire ids carry the model's output ceiling (thoughts count against
248
+ // it); Claude is always sent a cap (the declared limit, else a fixed one);
249
+ // GPT-OSS keeps the plain config its gateway accepts.
250
+ let maxOutputTokens;
251
+ if (claude) maxOutputTokens = claudeCap;
252
+ else if (isGeminiFamilyModel(model)) maxOutputTokens = geminiMaxOutputTokens(model, opts, null, outputLimit);
237
253
  const generationConfig = {
238
- ...(claude ? { maxOutputTokens: CLAUDE_MAX_OUTPUT_TOKENS } : {}),
254
+ ...(maxOutputTokens !== undefined ? { maxOutputTokens } : {}),
239
255
  ...(thinkingConfig ? { thinkingConfig } : {}),
240
256
  };
241
257
  const request = { contents: reminder ? [...contents, { role: 'user', parts: [{ text: reminder }] }] : contents };
@@ -23,10 +23,21 @@ export function normalizeAntigravityUsage(um) {
23
23
  (um.promptTokenCount || um.prompt_token_count || 0) +
24
24
  (um.toolUsePromptTokenCount || um.tool_use_prompt_token_count || 0);
25
25
  const cachedTokens = um.cachedContentTokenCount || um.cached_content_token_count || 0;
26
- const outputTokens =
27
- (um.candidatesTokenCount || um.candidates_token_count || 0) +
28
- (um.thoughtsTokenCount || um.thoughts_token_count || 0);
29
- return { inputTokens, outputTokens, cachedTokens, promptTokens: inputTokens, raw: um };
26
+ const thoughtTokens = um.thoughtsTokenCount ?? um.thoughts_token_count;
27
+ // Thought tokens are billed and capped as output.
28
+ const outputTokens = (um.candidatesTokenCount || um.candidates_token_count || 0) + (Number(thoughtTokens) || 0);
29
+ const reportedTotal = Number(um.totalTokenCount ?? um.total_token_count);
30
+ return {
31
+ inputTokens,
32
+ outputTokens,
33
+ cachedTokens,
34
+ promptTokens: inputTokens,
35
+ // Reasoning is reported only when the gateway reported thoughts (a missing
36
+ // count is not zero).
37
+ ...(typeof thoughtTokens === 'number' ? { reasoningTokens: thoughtTokens } : {}),
38
+ totalTokens: reportedTotal > 0 ? reportedTotal : inputTokens + outputTokens,
39
+ raw: um,
40
+ };
30
41
  }
31
42
 
32
43
  /**
@@ -36,8 +36,18 @@ function retiredModelError(err, streamedText, model) {
36
36
  * @param {Function|null} deps.onToolCall
37
37
  * @param {Function|null} deps.onTextDelta
38
38
  * @param {Function|null} deps.onStreamDelta
39
+ * @param {Function|null} [deps.onReasoningDelta] receives thought-summary text
40
+ * @param {Function|null} [deps.retractReasoning] drops thinking a dead attempt already showed
39
41
  */
40
- export function createAntigravityStreamCollector({ tools, useModel, onToolCall, onTextDelta, onStreamDelta }) {
42
+ export function createAntigravityStreamCollector({
43
+ tools,
44
+ useModel,
45
+ onToolCall,
46
+ onTextDelta,
47
+ onStreamDelta,
48
+ onReasoningDelta = null,
49
+ retractReasoning = null,
50
+ }) {
41
51
  let textLeakGuard = null;
42
52
  let terminalFailure = null;
43
53
  // Streamed text is kept so a retirement notice can be told apart from
@@ -66,6 +76,7 @@ export function createAntigravityStreamCollector({ tools, useModel, onToolCall,
66
76
  // Each attempt starts from an empty record: a replayed request must not
67
77
  // inherit the dead attempt's text or failure.
68
78
  const beginAttempt = () => {
79
+ retractReasoning?.();
69
80
  textLeakGuard = createGeminiTextLeakGuard({
70
81
  knownToolNames: tools?.map((t) => t.name).filter(Boolean) ?? [],
71
82
  onTextDelta: relayText,
@@ -80,6 +91,8 @@ export function createAntigravityStreamCollector({ tools, useModel, onToolCall,
80
91
  textLeakGuard = null;
81
92
  };
82
93
 
94
+ const failureUsage = { model: useModel, normalize: normalizeAntigravityUsage };
95
+
83
96
  const consume = async (res, attemptSignal, { firstByteTimeoutMs } = {}) => {
84
97
  try {
85
98
  return await consumeGeminiRestStreamResponse(res, {
@@ -87,10 +100,11 @@ export function createAntigravityStreamCollector({ tools, useModel, onToolCall,
87
100
  firstByteTimeoutMs,
88
101
  onStreamDelta,
89
102
  onTextDelta: relayText,
103
+ onReasoningDelta,
90
104
  onChunk,
91
105
  textLeakGuard,
92
106
  label: 'Antigravity streamGenerateContent',
93
- failureUsage: { model: useModel, normalize: normalizeAntigravityUsage },
107
+ failureUsage,
94
108
  // Cloud Code Assist nests the Gemini payload under
95
109
  // `response`; in-band error events stay top level.
96
110
  unwrapChunk: (chunk) => (chunk && typeof chunk === 'object' && chunk.response ? chunk.response : chunk),
@@ -105,6 +119,7 @@ export function createAntigravityStreamCollector({ tools, useModel, onToolCall,
105
119
  beginAttempt,
106
120
  releaseGuard,
107
121
  consume,
122
+ failureUsage,
108
123
  get leakGuard() {
109
124
  return textLeakGuard;
110
125
  },