mixdog 1.0.11 → 1.1.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 (471) hide show
  1. package/NOTICE.md +20 -0
  2. package/README.md +75 -181
  3. package/package.json +9 -4
  4. package/scripts/build-shipped-history.mjs +131 -0
  5. package/scripts/check-changelog-locales.mjs +203 -0
  6. package/scripts/computer-task-cost-report.mjs +0 -4
  7. package/scripts/lib/run-node-tests.mjs +235 -13
  8. package/scripts/lib/test-failure-records.mjs +5 -0
  9. package/scripts/lib/test-failure-summary.mjs +9 -3
  10. package/scripts/lib/test-spawn-ledger.mjs +19 -0
  11. package/scripts/prune-embedding-runtime.mjs +9 -5
  12. package/scripts/sync-client-version-floors.mjs +100 -0
  13. package/scripts/test-direct.mjs +16 -1
  14. package/src/agents/advisor/AGENT.md +38 -0
  15. package/src/agents/advisor/agent.json +6 -0
  16. package/src/agents/reviewer/AGENT.md +5 -2
  17. package/src/agents/reviewer/agent.json +1 -1
  18. package/src/defaults/shipped-history.json +381 -0
  19. package/src/defaults/skills/docx/SKILL.md +7 -5
  20. package/src/defaults/skills/docx/references/html.md +9 -8
  21. package/src/defaults/skills/docx/references/native-authoring.md +28 -18
  22. package/src/defaults/skills/goal-management/SKILL.md +11 -5
  23. package/src/defaults/skills/local-provider/SKILL.md +2 -1
  24. package/src/defaults/skills/pdf/SKILL.md +9 -6
  25. package/src/defaults/skills/pdf/references/html.md +17 -12
  26. package/src/defaults/skills/pptx/SKILL.md +8 -6
  27. package/src/defaults/skills/pptx/references/composition.md +4 -4
  28. package/src/defaults/skills/pptx/references/concepts.md +168 -0
  29. package/src/defaults/skills/pptx/references/direction.md +5 -4
  30. package/src/defaults/skills/pptx/references/html.md +6 -29
  31. package/src/defaults/skills/pptx/references/kit-index.md +11 -3
  32. package/src/defaults/skills/pptx/references/kit.md +27 -5
  33. package/src/defaults/skills/pptx/references/review.md +6 -5
  34. package/src/defaults/skills/setup/SKILL.md +5 -8
  35. package/src/defaults/skills/setup/references/actions.md +61 -31
  36. package/src/defaults/skills/setup/references/surfaces.md +12 -10
  37. package/src/defaults/skills/xlsx/SKILL.md +8 -6
  38. package/src/defaults/skills/xlsx/references/html.md +8 -4
  39. package/src/defaults/skills/xlsx/references/model-conventions.md +2 -0
  40. package/src/defaults/skills/xlsx/references/report-design.md +32 -16
  41. package/src/help.mjs +1 -1
  42. package/src/lib/rules-builder.cjs +1 -1
  43. package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +3 -1
  44. package/src/runtime/agent/orchestrator/agent-runtime/session-builder.mjs +4 -0
  45. package/src/runtime/agent/orchestrator/config-presets.d.mts +1 -0
  46. package/src/runtime/agent/orchestrator/config-presets.mjs +44 -0
  47. package/src/runtime/agent/orchestrator/config-providers-merge.mjs +9 -1
  48. package/src/runtime/agent/orchestrator/config.mjs +102 -21
  49. package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +3 -2
  50. package/src/runtime/agent/orchestrator/providers/account-pool.mjs +90 -26
  51. package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +44 -14
  52. package/src/runtime/agent/orchestrator/providers/anthropic-midstream-recovery.mjs +4 -4
  53. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +5 -3
  54. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +79 -8
  55. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +29 -4
  56. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn.mjs +3 -0
  57. package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +10 -1
  58. package/src/runtime/agent/orchestrator/providers/anthropic.mjs +11 -2
  59. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-login.mjs +9 -5
  60. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-tokens.mjs +9 -1
  61. package/src/runtime/agent/orchestrator/providers/antigravity-oauth.mjs +2 -0
  62. package/src/runtime/agent/orchestrator/providers/antigravity-response.mjs +30 -22
  63. package/src/runtime/agent/orchestrator/providers/antigravity-stream.mjs +2 -0
  64. package/src/runtime/agent/orchestrator/providers/auto-effort.mjs +28 -10
  65. package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +14 -72
  66. package/src/runtime/agent/orchestrator/providers/cursor-auth.mjs +19 -3
  67. package/src/runtime/agent/orchestrator/providers/cursor-client-version.mjs +20 -10
  68. package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-sink.mjs +36 -9
  69. package/src/runtime/agent/orchestrator/providers/cursor.mjs +11 -17
  70. package/src/runtime/agent/orchestrator/providers/custom-provider-config.mjs +388 -0
  71. package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +92 -109
  72. package/src/runtime/agent/orchestrator/providers/custom-reasoning.mjs +107 -0
  73. package/src/runtime/agent/orchestrator/providers/effort-configuration.mjs +138 -30
  74. package/src/runtime/agent/orchestrator/providers/gemini-response.mjs +32 -15
  75. package/src/runtime/agent/orchestrator/providers/gemini-sdk-request.mjs +2 -0
  76. package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +39 -5
  77. package/src/runtime/agent/orchestrator/providers/gemini.mjs +9 -2
  78. package/src/runtime/agent/orchestrator/providers/grok-client-version.mjs +3 -2
  79. package/src/runtime/agent/orchestrator/providers/grok-oauth-login.mjs +6 -1
  80. package/src/runtime/agent/orchestrator/providers/grok-oauth-tokens.mjs +10 -1
  81. package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +3 -2
  82. package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +5 -1
  83. package/src/runtime/agent/orchestrator/providers/lib/note-error-usage.mjs +7 -0
  84. package/src/runtime/agent/orchestrator/providers/lib/oauth-token-utils.mjs +57 -0
  85. package/src/runtime/agent/orchestrator/providers/model-cache.mjs +12 -5
  86. package/src/runtime/agent/orchestrator/providers/npm-cli-version.mjs +20 -15
  87. package/src/runtime/agent/orchestrator/providers/oauth-usage.mjs +14 -9
  88. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +56 -11
  89. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-result.mjs +2 -1
  90. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +28 -1
  91. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +27 -3
  92. package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +7 -5
  93. package/src/runtime/agent/orchestrator/providers/openai-compat-options.mjs +12 -0
  94. package/src/runtime/agent/orchestrator/providers/openai-compat-response-normalization.mjs +23 -8
  95. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-events.mjs +26 -6
  96. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-state.mjs +7 -1
  97. package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +34 -15
  98. package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +16 -2
  99. package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +12 -2
  100. package/src/runtime/agent/orchestrator/providers/openai-compat-xai-send.mjs +0 -6
  101. package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +0 -19
  102. package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +12 -43
  103. package/src/runtime/agent/orchestrator/providers/openai-direct-request.mjs +6 -0
  104. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/terminal-frames.mjs +39 -9
  105. package/src/runtime/agent/orchestrator/providers/openai-oauth-catalog.mjs +31 -9
  106. package/src/runtime/agent/orchestrator/providers/openai-oauth-dispatch.mjs +13 -38
  107. package/src/runtime/agent/orchestrator/providers/openai-oauth-login.mjs +5 -2
  108. package/src/runtime/agent/orchestrator/providers/openai-oauth-tokens.mjs +40 -9
  109. package/src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs +7 -39
  110. package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +28 -101
  111. package/src/runtime/agent/orchestrator/providers/openai-responses-input.mjs +8 -4
  112. package/src/runtime/agent/orchestrator/providers/openai-responses-payload.mjs +3 -6
  113. package/src/runtime/agent/orchestrator/providers/openai-service-tier.mjs +19 -0
  114. package/src/runtime/agent/orchestrator/providers/openai-startup-prewarm.mjs +5 -195
  115. package/src/runtime/agent/orchestrator/providers/openai-ws-delta.mjs +9 -18
  116. package/src/runtime/agent/orchestrator/providers/openai-ws-events.mjs +4 -66
  117. package/src/runtime/agent/orchestrator/providers/openai-ws-response-state.mjs +11 -5
  118. package/src/runtime/agent/orchestrator/providers/openai-ws-send/acquire-attempt.mjs +3 -15
  119. package/src/runtime/agent/orchestrator/providers/openai-ws-send/attempt-request.mjs +6 -56
  120. package/src/runtime/agent/orchestrator/providers/openai-ws-send/send-context.mjs +1 -19
  121. package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/attempt-context.mjs +2 -2
  122. package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/handshake-failure.mjs +2 -1
  123. package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/policy.mjs +3 -0
  124. package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/stream-failure-stamps.mjs +0 -1
  125. package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/stream-failure.mjs +3 -1
  126. package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts.mjs +3 -5
  127. package/src/runtime/agent/orchestrator/providers/openai-ws-send-outcome.mjs +10 -89
  128. package/src/runtime/agent/orchestrator/providers/openai-ws-send-span.mjs +1 -1
  129. package/src/runtime/agent/orchestrator/providers/openai-ws-send-trace.mjs +0 -6
  130. package/src/runtime/agent/orchestrator/providers/openai-ws-stream/terminal-frames.mjs +34 -11
  131. package/src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs +0 -1
  132. package/src/runtime/agent/orchestrator/providers/openai-ws-watchdogs.mjs +3 -7
  133. package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +44 -19
  134. package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +40 -12
  135. package/src/runtime/agent/orchestrator/providers/quota-reading.mjs +70 -0
  136. package/src/runtime/agent/orchestrator/providers/registry.mjs +38 -3
  137. package/src/runtime/agent/orchestrator/providers/retry-classification.mjs +4 -0
  138. package/src/runtime/agent/orchestrator/providers/retry-classifier.mjs +1 -0
  139. package/src/runtime/agent/orchestrator/providers/retry-executor.mjs +2 -0
  140. package/src/runtime/agent/orchestrator/providers/retry-midstream.mjs +11 -0
  141. package/src/runtime/agent/orchestrator/runtime-core/builtin-features.mjs +31 -41
  142. package/src/runtime/agent/orchestrator/runtime-core/effort.mjs +5 -0
  143. package/src/runtime/agent/orchestrator/runtime-core/goal-mutations.mjs +0 -17
  144. package/src/runtime/agent/orchestrator/runtime-core/goal-state.mjs +0 -3
  145. package/src/runtime/agent/orchestrator/runtime-core/goal-store.mjs +0 -1
  146. package/src/runtime/agent/orchestrator/runtime-core/goal-text.mjs +1 -1
  147. package/src/runtime/agent/orchestrator/runtime-core/goal-tool-defs.mjs +1 -1
  148. package/src/runtime/agent/orchestrator/runtime-core/goal-tool-exec.mjs +1 -2
  149. package/src/runtime/agent/orchestrator/runtime-core/goal-turns.mjs +18 -4
  150. package/src/runtime/agent/orchestrator/runtime-core/model-capabilities.mjs +8 -1
  151. package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +7 -1
  152. package/src/runtime/agent/orchestrator/runtime-core/session-route-policy.mjs +16 -0
  153. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +2 -0
  154. package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +6 -2
  155. package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +7 -7
  156. package/src/runtime/agent/orchestrator/runtime-core/workflow.mjs +6 -0
  157. package/src/runtime/agent/orchestrator/session/compact/observation-supersession.mjs +45 -2
  158. package/src/runtime/agent/orchestrator/session/compact/runner.mjs +5 -3
  159. package/src/runtime/agent/orchestrator/session/eager-dispatch/entry.mjs +5 -0
  160. package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +6 -13
  161. package/src/runtime/agent/orchestrator/session/loop/request-boundary.mjs +6 -2
  162. package/src/runtime/agent/orchestrator/session/loop/step-auto-effort.mjs +114 -0
  163. package/src/runtime/agent/orchestrator/session/loop/tool-phase.mjs +2 -0
  164. package/src/runtime/agent/orchestrator/session/loop/usage.mjs +5 -9
  165. package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +51 -18
  166. package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +7 -4
  167. package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +3 -1
  168. package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +0 -2
  169. package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +6 -9
  170. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +63 -3
  171. package/src/runtime/agent/orchestrator/session/manager/session-owner-liveness.mjs +10 -28
  172. package/src/runtime/agent/orchestrator/session/manager/session-tool-surface.mjs +4 -4
  173. package/src/runtime/agent/orchestrator/session/manager/status-telemetry.mjs +13 -0
  174. package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +10 -19
  175. package/src/runtime/agent/orchestrator/session/tool-batch/execute-call.mjs +7 -1
  176. package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +1 -0
  177. package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +1 -3
  178. package/src/runtime/agent/orchestrator/stall-policy.mjs +0 -1
  179. package/src/runtime/agent/orchestrator/tools/builtin/atomic-write.mjs +18 -8
  180. package/src/runtime/agent/orchestrator/tools/builtin/cache-layers.mjs +19 -20
  181. package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.mjs +6 -11
  182. package/src/runtime/agent/orchestrator/tools/builtin/file-version-test-helpers.mjs +11 -0
  183. package/src/runtime/agent/orchestrator/tools/builtin/file-version.mjs +13 -0
  184. package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-single-file-rescue.mjs +8 -5
  185. package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-task-output.mjs +25 -12
  186. package/src/runtime/agent/orchestrator/tools/builtin/raw-content-publication.mjs +17 -0
  187. package/src/runtime/agent/orchestrator/tools/builtin/read-range-index.mjs +136 -76
  188. package/src/runtime/agent/orchestrator/tools/builtin/read-single-render.mjs +15 -17
  189. package/src/runtime/agent/orchestrator/tools/builtin/read-single-tool.mjs +4 -2
  190. package/src/runtime/agent/orchestrator/tools/builtin/read-snapshot-runtime.mjs +11 -10
  191. package/src/runtime/agent/orchestrator/tools/builtin/read-source-windows.mjs +5 -3
  192. package/src/runtime/agent/orchestrator/tools/builtin/read-streaming.mjs +30 -16
  193. package/src/runtime/agent/orchestrator/tools/builtin/shell-lossless-compact.mjs +2 -2
  194. package/src/runtime/agent/orchestrator/tools/builtin/snapshot-helpers.mjs +4 -11
  195. package/src/runtime/agent/orchestrator/tools/builtin/snapshot-store.mjs +7 -3
  196. package/src/runtime/agent/orchestrator/tools/builtin/snapshot-validation.mjs +16 -19
  197. package/src/runtime/agent/orchestrator/tools/graph-manifest.json +13 -13
  198. package/src/runtime/agent/orchestrator/tools/lib/shell-run-background.mjs +4 -1
  199. package/src/runtime/agent/orchestrator/tools/lib/shell-run-settle.mjs +14 -4
  200. package/src/runtime/agent/orchestrator/tools/patch/apply-patch/codex-batch.mjs +58 -8
  201. package/src/runtime/agent/orchestrator/tools/patch/content-guard.mjs +47 -0
  202. package/src/runtime/agent/orchestrator/tools/patch/delete-quarantine.mjs +155 -0
  203. package/src/runtime/agent/orchestrator/tools/patch/dispatch/native-proofs.mjs +6 -2
  204. package/src/runtime/agent/orchestrator/tools/patch/dispatch/native-snapshots.mjs +6 -2
  205. package/src/runtime/agent/orchestrator/tools/patch/dispatch.mjs +19 -16
  206. package/src/runtime/agent/orchestrator/tools/patch/matcher.mjs +13 -44
  207. package/src/runtime/agent/orchestrator/tools/patch/orchestrator.mjs +2 -2
  208. package/src/runtime/agent/orchestrator/tools/patch/post-patch-excerpts.mjs +5 -2
  209. package/src/runtime/agent/orchestrator/tools/patch/replay-capture.mjs +47 -7
  210. package/src/runtime/agent/orchestrator/tools/patch/rollback-state.mjs +72 -8
  211. package/src/runtime/agent/orchestrator/tools/patch/section-coalesce.mjs +3 -2
  212. package/src/runtime/agent/orchestrator/tools/patch/sequence/run.mjs +9 -1
  213. package/src/runtime/agent/orchestrator/tools/patch/sequence/units.mjs +9 -1
  214. package/src/runtime/agent/orchestrator/tools/patch/sequence.mjs +6 -6
  215. package/src/runtime/agent/orchestrator/tools/patch/ui-diff.mjs +16 -4
  216. package/src/runtime/agent/orchestrator/tools/patch/v4a-convert.mjs +35 -14
  217. package/src/runtime/agent/orchestrator/tools/patch/wave.mjs +42 -4
  218. package/src/runtime/agent/orchestrator/tools/progress-message.mjs +2 -0
  219. package/src/runtime/agent/orchestrator/tools/shell-codepage.mjs +296 -0
  220. package/src/runtime/agent/orchestrator/tools/shell-exec-output.mjs +75 -24
  221. package/src/runtime/browser-bridge/tool-defs.mjs +1 -0
  222. package/src/runtime/channels/lib/config.mjs +3 -8
  223. package/src/runtime/channels/lib/voice-runtime-fetcher.mjs +7 -3
  224. package/src/{tui → runtime/channels}/lib/voice-setup.mjs +38 -22
  225. package/src/runtime/channels/lib/webhook/request-handler.mjs +42 -8
  226. package/src/runtime/computer-bridge/actions.mjs +2 -0
  227. package/src/runtime/effort-judge/judge-client.mjs +125 -25
  228. package/src/runtime/effort-judge/judge-input.mjs +96 -0
  229. package/src/runtime/effort-judge/judge-worker.mjs +52 -20
  230. package/src/runtime/effort-judge/model-install.mjs +74 -0
  231. package/src/runtime/effort-judge/model-manifest.json +21 -0
  232. package/src/runtime/effort-judge/previous-human-request.mjs +162 -0
  233. package/src/runtime/effort-judge/verified-context-input.mjs +10 -0
  234. package/src/runtime/github/tool.mjs +214 -14
  235. package/src/runtime/local-provider/context-settings.mjs +15 -6
  236. package/src/runtime/local-provider/gguf-header.mjs +13 -5
  237. package/src/runtime/local-provider/hugging-face.mjs +27 -5
  238. package/src/runtime/local-provider/install-progress.mjs +7 -0
  239. package/src/runtime/local-provider/managed-runtime.mjs +2 -1
  240. package/src/runtime/local-provider/model-maintenance.mjs +15 -6
  241. package/src/runtime/local-provider/resumable-installations.mjs +40 -1
  242. package/src/runtime/local-provider/server.mjs +2 -0
  243. package/src/runtime/memory/lib/embedding-provider.mjs +12 -0
  244. package/src/runtime/memory/lib/http-router/session-routes.mjs +2 -1
  245. package/src/runtime/memory/lib/memory-config-flags.mjs +3 -2
  246. package/src/runtime/memory/lib/memory-embed.mjs +5 -0
  247. package/src/runtime/memory/lib/pg/process.mjs +57 -5
  248. package/src/runtime/office/README.md +13 -7
  249. package/src/runtime/office/authoring/docx-html-build.mjs +4 -4
  250. package/src/runtime/office/authoring/docx-html-measure.mjs +60 -0
  251. package/src/runtime/office/authoring/pdf-author-action.mjs +6 -1
  252. package/src/runtime/office/authoring/pptx-brief.mjs +40 -1
  253. package/src/runtime/office/authoring/pptx-html-build.mjs +1 -1
  254. package/src/runtime/office/authoring/pptx-html-measure.mjs +1 -1
  255. package/src/runtime/office/bench/deck-bench.mjs +1 -1
  256. package/src/runtime/office/com/office-com-host.ps1 +8 -0
  257. package/src/runtime/office/core/office-actions-render.mjs +2 -0
  258. package/src/runtime/office/design/design-art-direction.mjs +10 -2
  259. package/src/runtime/office/design/design-discipline.mjs +4 -5
  260. package/src/runtime/office/design/design-tokens.mjs +20 -1
  261. package/src/runtime/office/design/docx/design-docx/front-matter.mjs +7 -4
  262. package/src/runtime/office/design/docx/design-docx/section.mjs +3 -1
  263. package/src/runtime/office/design/docx/design-docx/writer.mjs +1 -0
  264. package/src/runtime/office/design/docx/design-docx-components.mjs +19 -15
  265. package/src/runtime/office/design/docx/design-docx.mjs +5 -6
  266. package/src/runtime/office/design/docx/document-typography.mjs +20 -6
  267. package/src/runtime/office/design/xlsx/design-xlsx.mjs +9 -2
  268. package/src/runtime/office/pdf/document-preview.mjs +133 -12
  269. package/src/runtime/office/pdf/pdf-writer.mjs +56 -22
  270. package/src/runtime/office/portable/portable-snapshot-docx.mjs +46 -3
  271. package/src/runtime/office/portable/portable-snapshot-shared.mjs +27 -1
  272. package/src/runtime/office/quality/assurance-rendered.mjs +21 -5
  273. package/src/runtime/office/quality/assurance-structure-docx.mjs +41 -9
  274. package/src/runtime/office/quality/design-aesthetics.mjs +4 -2
  275. package/src/runtime/office/quality/design-deck-diversity.mjs +15 -3
  276. package/src/runtime/office/quality/design-review.mjs +13 -5
  277. package/src/runtime/office/quality/document-brief.mjs +8 -2
  278. package/src/runtime/office/quality/forced-break-pages.mjs +203 -0
  279. package/src/runtime/office/quality/pptx-deck-rubric.mjs +21 -3
  280. package/src/runtime/office/quality/quality-pipeline.mjs +14 -17
  281. package/src/runtime/session-search/session-search-db.mjs +183 -0
  282. package/src/runtime/session-search/session-search-ingest.mjs +106 -0
  283. package/src/runtime/shared/agent-route-config.mjs +50 -2
  284. package/src/runtime/shared/bounded-file-read.mjs +166 -0
  285. package/src/runtime/shared/builtin-grandfathering.mjs +37 -0
  286. package/src/runtime/shared/config.mjs +24 -4
  287. package/src/runtime/shared/defaults-separation.mjs +263 -0
  288. package/src/runtime/shared/error-presentation.mjs +8 -1
  289. package/src/runtime/shared/llm/anthropic-effort.mjs +4 -0
  290. package/src/runtime/shared/llm/cost.mjs +4 -2
  291. package/src/runtime/shared/llm/model-catalog-projection.mjs +1 -1
  292. package/src/runtime/shared/llm/model-catalog.mjs +25 -0
  293. package/src/runtime/shared/llm/reasoning-usage.mjs +1 -2
  294. package/src/runtime/shared/llm/usage-accounting.mjs +14 -4
  295. package/src/runtime/shared/llm/usage-context.mjs +11 -1
  296. package/src/runtime/shared/llm/usage-ledger-repair.mjs +3 -1
  297. package/src/runtime/shared/llm/usage-ledger-rollup.mjs +105 -1
  298. package/src/runtime/shared/llm/usage-ledger-worker.mjs +2 -1
  299. package/src/runtime/shared/llm/usage-ledger.mjs +72 -5
  300. package/src/runtime/shared/onnx-runtime-support.mjs +6 -0
  301. package/src/runtime/shared/orchestration.mjs +14 -6
  302. package/src/runtime/shared/pristine-execution-contract.json +7 -2
  303. package/src/runtime/shared/projects.mjs +65 -48
  304. package/src/runtime/shared/provider-accounts.mjs +47 -6
  305. package/src/runtime/shared/quota-resume-store.mjs +255 -0
  306. package/src/runtime/shared/shipped-definitions.mjs +275 -0
  307. package/src/runtime/shared/tool-card-model/agent-surface.mjs +30 -9
  308. package/src/runtime/shared/tool-card-model/aggregate-card.mjs +7 -3
  309. package/src/runtime/shared/tool-card-model/background-task.mjs +17 -1
  310. package/src/runtime/shared/tool-card-model/card-detail.mjs +10 -4
  311. package/src/runtime/shared/tool-card-model/card-header.mjs +10 -4
  312. package/src/runtime/shared/tool-card-model/card-status.mjs +22 -5
  313. package/src/runtime/shared/tool-card-model/displayed-result.mjs +6 -1
  314. package/src/runtime/shared/tool-card-model/media-result.mjs +53 -0
  315. package/src/runtime/shared/tool-card-model/terminal-status.mjs +17 -1
  316. package/src/runtime/shared/tool-card-model.golden-cases.mjs +1 -1
  317. package/src/runtime/shared/tool-card-model.golden.json +75 -66
  318. package/src/runtime/shared/tool-card-model.mjs +1 -0
  319. package/src/runtime/shared/tool-output-limit.mjs +3 -0
  320. package/src/runtime/shared/tool-primitives.mjs +24 -18
  321. package/src/runtime/shared/tool-result-summary.mjs +128 -17
  322. package/src/runtime/shared/tool-status.mjs +20 -7
  323. package/src/runtime/shared/tool-surface.mjs +105 -28
  324. package/src/runtime/shared/tool-work-units.mjs +221 -18
  325. package/src/runtime/shared/transcript-metadata.mjs +2 -0
  326. package/src/runtime/shared/turn-review-reply.mjs +2 -0
  327. package/src/runtime/shared/turn-snapshot.mjs +65 -6
  328. package/src/runtime/shared/turn-worktree-snapshot.mjs +202 -22
  329. package/src/runtime/shared/worker-requests.mjs +14 -2
  330. package/src/runtime/terminal-bridge/client.mjs +311 -0
  331. package/src/runtime/terminal-bridge/tool-defs.mjs +36 -0
  332. package/src/runtime/web-search/lib/ssrf-guard.mjs +12 -56
  333. package/src/runtime/web-search/tool-defs.mjs +2 -0
  334. package/src/session-runtime/boot/apis.mjs +30 -5
  335. package/src/session-runtime/boot/config.mjs +4 -0
  336. package/src/session-runtime/boot/facade.mjs +4 -1
  337. package/src/session-runtime/boot/infrastructure.mjs +21 -2
  338. package/src/session-runtime/boot/session.mjs +5 -5
  339. package/src/session-runtime/boot/tools.mjs +2 -0
  340. package/src/session-runtime/builtin-features.d.mts +1 -0
  341. package/src/session-runtime/channel-config-api.mjs +5 -0
  342. package/src/session-runtime/config-lifecycle/config-writers.mjs +3 -0
  343. package/src/session-runtime/config-lifecycle.mjs +31 -6
  344. package/src/session-runtime/goal-facade-api.mjs +4 -0
  345. package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +15 -3
  346. package/src/session-runtime/lifecycle/inheritance.mjs +28 -6
  347. package/src/session-runtime/lifecycle/session-switch/context-switch.mjs +3 -0
  348. package/src/session-runtime/lifecycle/session-switch/resume.mjs +7 -1
  349. package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +9 -0
  350. package/src/session-runtime/lifecycle/teardown/session-close.mjs +14 -2
  351. package/src/session-runtime/lifecycle/teardown.mjs +5 -0
  352. package/src/session-runtime/local-provider-settings.mjs +10 -0
  353. package/src/session-runtime/media-api.mjs +32 -22
  354. package/src/session-runtime/model-recency.mjs +14 -0
  355. package/src/session-runtime/model-route/route-persist.mjs +17 -2
  356. package/src/session-runtime/model-route/route-tuning.mjs +16 -5
  357. package/src/session-runtime/model-route/set-route.mjs +55 -22
  358. package/src/session-runtime/model-route/web-search-route.mjs +2 -2
  359. package/src/session-runtime/model-route-api.mjs +2 -1
  360. package/src/session-runtime/notification-bus.mjs +31 -6
  361. package/src/session-runtime/provider-auth/login.mjs +6 -0
  362. package/src/session-runtime/provider-models/catalog-load.mjs +3 -1
  363. package/src/session-runtime/provider-models/row-hydration.mjs +36 -10
  364. package/src/session-runtime/quick-model-rows/model-meta.mjs +26 -0
  365. package/src/session-runtime/quick-model-rows/provider-rows.mjs +40 -14
  366. package/src/session-runtime/resource-api.mjs +8 -1
  367. package/src/session-runtime/route-state.mjs +9 -0
  368. package/src/session-runtime/runtime-core.mjs +4 -0
  369. package/src/session-runtime/runtime-facade.mjs +20 -1
  370. package/src/session-runtime/runtime-feature-gates.mjs +2 -0
  371. package/src/session-runtime/runtime-review-api.mjs +12 -1
  372. package/src/session-runtime/services/agent-tool/helpers.mjs +14 -1
  373. package/src/session-runtime/services/agent-tool/index-write-queue.mjs +10 -15
  374. package/src/session-runtime/services/agent-tool/lead-worker-index/reap-timers.mjs +6 -1
  375. package/src/session-runtime/services/agent-tool/lead-worker-index.mjs +20 -2
  376. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +14 -6
  377. package/src/session-runtime/services/agent-tool/spawn-preset.mjs +2 -0
  378. package/src/session-runtime/services/agent-tool/tag-registry.mjs +12 -1
  379. package/src/session-runtime/services/agent-tool/worker-index.mjs +17 -1
  380. package/src/session-runtime/services/agent-tool.mjs +1 -0
  381. package/src/session-runtime/services/channel-admin.mjs +87 -13
  382. package/src/session-runtime/services/provider-admin.mjs +306 -66
  383. package/src/session-runtime/services/seeds.mjs +73 -142
  384. package/src/session-runtime/services/usage-dashboard-model.mjs +29 -0
  385. package/src/session-runtime/services/usage-dashboard.mjs +7 -0
  386. package/src/session-runtime/session-address.mjs +125 -0
  387. package/src/session-runtime/session-create.mjs +57 -2
  388. package/src/session-runtime/settings-api.mjs +1 -0
  389. package/src/session-runtime/settings-builtin-tools-api.mjs +15 -10
  390. package/src/session-runtime/settings-compaction-api.mjs +13 -0
  391. package/src/session-runtime/setup-tool/executor.mjs +93 -40
  392. package/src/session-runtime/setup-tool/extended-actions.mjs +64 -5
  393. package/src/session-runtime/setup-tool/settings-contract.mjs +46 -3
  394. package/src/session-runtime/setup-tool/tool-defs.mjs +14 -6
  395. package/src/session-runtime/tool-surface.mjs +16 -9
  396. package/src/session-runtime/turn/session-ops.mjs +3 -0
  397. package/src/session-runtime/turn/share-ops.mjs +4 -1
  398. package/src/session-runtime/turn/turn-run/turn-prepare.mjs +6 -0
  399. package/src/session-runtime/usage-stats-api.mjs +43 -3
  400. package/src/session-runtime/workflow-agents-api/agent-editor.mjs +31 -5
  401. package/src/session-runtime/workflow-agents-api/agent-route.mjs +6 -2
  402. package/src/session-runtime/workflow-agents-api/workflow-packs.mjs +27 -7
  403. package/src/standalone/daemon-boot-coordinator.mjs +10 -0
  404. package/src/standalone/daemon-desktop-runtime.mjs +1 -0
  405. package/src/standalone/daemon-drain-policy.mjs +9 -0
  406. package/src/standalone/daemon-stored-session-views.mjs +7 -8
  407. package/src/standalone/daemon.mjs +36 -8
  408. package/src/standalone/local-session-runtime.mjs +11 -0
  409. package/src/standalone/session-client.mjs +52 -7
  410. package/src/standalone/session-protocol.mjs +9 -0
  411. package/src/standalone/session-service/agent-tree/agent-child.mjs +2 -0
  412. package/src/standalone/session-service/entries/lifecycle.mjs +2 -0
  413. package/src/standalone/session-service/entries/session-loads.mjs +9 -0
  414. package/src/standalone/session-service/projection/revisions.mjs +28 -4
  415. package/src/standalone/session-service/projection.mjs +1 -0
  416. package/src/standalone/session-service/quota-resume.mjs +140 -0
  417. package/src/standalone/session-service/session-calls/session-action.mjs +2 -2
  418. package/src/standalone/session-service/session-calls.mjs +10 -2
  419. package/src/standalone/session-service/stored-reader.mjs +26 -1
  420. package/src/standalone/session-service.mjs +21 -0
  421. package/src/standalone/session-transport/routes.mjs +2 -0
  422. package/src/tui/app/doctor.mjs +7 -11
  423. package/src/tui/app/maintenance-pickers/auto-clear-picker.mjs +3 -5
  424. package/src/tui/app/model-picker/model-footer.mjs +2 -2
  425. package/src/tui/app/model-picker/route-selection/fast-parameters.mjs +21 -2
  426. package/src/tui/app/model-picker/route-selection.mjs +6 -1
  427. package/src/tui/app/settings-picker/settings-rows.mjs +4 -6
  428. package/src/tui/app/settings-picker/settings-toggles/store-toggles.mjs +1 -1
  429. package/src/tui/app/slash-commands.mjs +1 -1
  430. package/src/tui/app/slash-dispatch/route-commands.mjs +5 -3
  431. package/src/tui/app/transcript-row-estimate.mjs +17 -5
  432. package/src/tui/components/ContextPanel.jsx +5 -1
  433. package/src/tui/components/Spinner.jsx +34 -319
  434. package/src/tui/components/SpinnerByline.jsx +256 -0
  435. package/src/tui/components/tool-execution/aggregate-card.jsx +4 -2
  436. package/src/tui/components/tool-execution/text-format.mjs +1 -0
  437. package/src/tui/components/use-spinner-progress.mjs +113 -0
  438. package/src/tui/dist/index.mjs +15896 -14452
  439. package/src/tui/session/agent-job-feed/execution-delivery.mjs +13 -1
  440. package/src/tui/session/agent-job-feed/notification-router.mjs +3 -0
  441. package/src/tui/session/agent-job-feed/pending-resume.mjs +14 -1
  442. package/src/tui/session/agent-job-feed.mjs +4 -0
  443. package/src/tui/session/context-state.mjs +13 -1
  444. package/src/tui/session/initial-state.mjs +6 -0
  445. package/src/tui/session/quota-resume.mjs +263 -0
  446. package/src/tui/session/session-api/intake/abort.mjs +39 -35
  447. package/src/tui/session/session-api/intake/submission.mjs +13 -21
  448. package/src/tui/session/session-api/intake.mjs +3 -3
  449. package/src/tui/session/session-api/integrations.mjs +5 -1
  450. package/src/tui/session/session-api/lifecycle/dispose.mjs +1 -0
  451. package/src/tui/session/session-api/lifecycle/inheritance.mjs +2 -2
  452. package/src/tui/session/session-api/lifecycle/session-reset.mjs +4 -0
  453. package/src/tui/session/session-api/lifecycle.mjs +71 -2
  454. package/src/tui/session/session-api/media.mjs +2 -2
  455. package/src/tui/session/session-api/quota-resume.mjs +21 -0
  456. package/src/tui/session/session-api/routes.mjs +5 -2
  457. package/src/tui/session/session-api/settings.mjs +2 -0
  458. package/src/tui/session/session-api.mjs +2 -0
  459. package/src/tui/session/session-flow/auto-clear.mjs +14 -6
  460. package/src/tui/session/session-flow/drain.mjs +52 -5
  461. package/src/tui/session/session-flow/queue/take-entries.mjs +9 -4
  462. package/src/tui/session/session-flow/queue.mjs +4 -0
  463. package/src/tui/session/session-flow/steering.mjs +11 -0
  464. package/src/tui/session/session-flow.mjs +1 -0
  465. package/src/tui/session/tool-approval.mjs +7 -2
  466. package/src/tui/session/transcript-intake.mjs +1 -0
  467. package/src/tui/session/turn-tool-cards.mjs +4 -6
  468. package/src/tui/session/turn.mjs +40 -4
  469. package/src/vendor/statusline/bin/statusline-route.mjs +3 -2
  470. package/src/vendor/statusline/src/gateway/route-meta.mjs +1 -1
  471. package/src/runtime/agent/orchestrator/providers/openai-ws-warmup.mjs +0 -165
@@ -15,9 +15,18 @@ import { boundProviderAuthPath } from '../../../shared/provider-auth-binding.mjs
15
15
  import { resolvePluginData } from '../../../shared/plugin-paths.mjs';
16
16
  import { getLlmDispatcher } from '../../../shared/llm/http-agent.mjs';
17
17
  import { claudeCliUserAgent, resolveCliVersion } from './anthropic-oauth-client-version.mjs';
18
- import { expiryFromAccessToken, oauthCredentialStatus, scrubOAuthSecrets } from './lib/oauth-token-utils.mjs';
18
+ import {
19
+ accountIdentityFields,
20
+ expiryFromAccessToken,
21
+ isDefinitiveOAuthFailure,
22
+ normalizeAccountIdentity,
23
+ oauthCredentialStatus,
24
+ scrubOAuthSecrets,
25
+ } from './lib/oauth-token-utils.mjs';
19
26
  import { createOAuthPkce, parseOAuthCodeInput } from './lib/oauth-pkce.mjs';
20
27
 
28
+ const SIGN_IN_EXPIRED_PREFIX = 'Anthropic sign-in expired. Sign in again from Providers.';
29
+
21
30
  // SSRF guard for the OAuth token endpoint override. Env-supplied URLs must be
22
31
  // https with a valid http(s) URL shape; reject file:/data:/ftp:/etc. and any
23
32
  // http override so a hostile env cannot redirect refresh-token requests.
@@ -88,15 +97,26 @@ function _loadCredentialsFile(path) {
88
97
  mtimeMs: stat.mtimeMs,
89
98
  accessToken: oauth.accessToken,
90
99
  refreshToken: oauth.refreshToken || null,
100
+ reauthRequired: oauth.reauthRequired === true,
91
101
  expiresAt: _normalizeExpiresAt(oauth.expiresAt ?? oauth.expires_at) || expiryFromAccessToken(oauth.accessToken),
92
102
  scopes: Array.isArray(oauth.scopes) ? oauth.scopes : [],
93
103
  subscriptionType: oauth.subscriptionType || null,
104
+ identity: normalizeAccountIdentity(oauth.identity),
94
105
  };
95
106
  } catch {
96
107
  return null;
97
108
  }
98
109
  }
99
110
 
111
+ // The token endpoint names the signed-in account next to the tokens.
112
+ export function identityFromTokenResponse(json) {
113
+ return normalizeAccountIdentity({
114
+ id: json?.account?.uuid,
115
+ email: json?.account?.email_address,
116
+ organizationId: json?.organization?.uuid,
117
+ });
118
+ }
119
+
100
120
  // Cross-process safe credential save. Lockfile (O_EXCL) prevents two Mixdog
101
121
  // refreshers from clobbering each other; atomic rename guarantees readers see
102
122
  // either the old or new file, never a half-written one. Used so refresh_token
@@ -174,7 +194,21 @@ export function describeAnthropicOAuthCredentials() {
174
194
  expiresAt,
175
195
  };
176
196
  }
177
- return oauthCredentialStatus({ hasRefresh, expiresAt, detail, refreshSkewMs: TOKEN_REFRESH_SKEW_MS });
197
+ if (creds.reauthRequired) {
198
+ return {
199
+ authenticated: false,
200
+ usable: false,
201
+ refreshable: false,
202
+ reauthRequired: true,
203
+ status: 'Reauth Required',
204
+ detail,
205
+ expiresAt,
206
+ };
207
+ }
208
+ return {
209
+ ...oauthCredentialStatus({ hasRefresh, expiresAt, detail, refreshSkewMs: TOKEN_REFRESH_SKEW_MS }),
210
+ ...accountIdentityFields(creds.identity),
211
+ };
178
212
  } catch (err) {
179
213
  return {
180
214
  authenticated: false,
@@ -289,10 +323,14 @@ async function _refreshOAuthCredentialsUnlocked(creds) {
289
323
  }
290
324
  if (!res.ok) {
291
325
  const isInvalidGrant = text.includes('invalid_grant') || json?.error === 'invalid_grant';
292
- throw Object.assign(
293
- _tokenEndpointError('token refresh', res.status, text, [creds.refreshToken, creds.accessToken]),
294
- { isInvalidGrant }
295
- );
326
+ const failure = _tokenEndpointError('token refresh', res.status, text, [creds.refreshToken, creds.accessToken]);
327
+ if (isDefinitiveOAuthFailure(text, res.status)) {
328
+ throw Object.assign(new Error(`${SIGN_IN_EXPIRED_PREFIX} ${failure.message}`), {
329
+ isInvalidGrant: true,
330
+ reauthRequired: true,
331
+ });
332
+ }
333
+ throw Object.assign(failure, { isInvalidGrant });
296
334
  }
297
335
 
298
336
  const accessToken = json?.access_token || json?.accessToken;
@@ -305,6 +343,7 @@ async function _refreshOAuthCredentialsUnlocked(creds) {
305
343
  expiresAt,
306
344
  scopes: Array.isArray(json?.scope) ? json.scope : creds.scopes,
307
345
  subscriptionType: creds.subscriptionType,
346
+ identity: identityFromTokenResponse(json) || creds.identity || null,
308
347
  };
309
348
  // Persist rotated tokens back so any other Mixdog reader of the same
310
349
  // credentials file picks up the new refresh_token. Without this, a
@@ -320,6 +359,8 @@ async function _refreshOAuthCredentialsUnlocked(creds) {
320
359
  refreshToken: refreshed.refreshToken,
321
360
  expiresAt: refreshed.expiresAt,
322
361
  scopes: refreshed.scopes,
362
+ reauthRequired: undefined,
363
+ ...(refreshed.identity ? { identity: refreshed.identity } : {}),
323
364
  },
324
365
  }));
325
366
  } catch (err) {
@@ -364,7 +405,31 @@ export async function refreshOAuthCredentials(creds) {
364
405
  ) {
365
406
  return disk;
366
407
  }
367
- return _refreshOAuthCredentialsUnlocked(disk || { ...creds, path: credentialPath });
408
+ const attempt = disk || { ...creds, path: credentialPath };
409
+ try {
410
+ return await _refreshOAuthCredentialsUnlocked(attempt);
411
+ } catch (err) {
412
+ if (err?.reauthRequired !== true) throw err;
413
+ const latest = _loadCredentialsFile(credentialPath);
414
+ if (latest?.refreshToken && latest.refreshToken !== attempt.refreshToken) {
415
+ if (!latest.expiresAt || latest.expiresAt > Date.now()) return latest;
416
+ return _refreshOAuthCredentialsUnlocked(latest);
417
+ }
418
+ try {
419
+ _updateCredentialsFile(credentialPath, (raw) => {
420
+ const oauth = raw?.claudeAiOauth;
421
+ if (!oauth || oauth.refreshToken !== attempt.refreshToken) return undefined;
422
+ // Non-destructive: tokens stay intact; a new sign-in or a
423
+ // successful refresh rewrites the entry without this marker.
424
+ return { ...raw, claudeAiOauth: { ...oauth, reauthRequired: true } };
425
+ });
426
+ } catch (saveErr) {
427
+ process.stderr.write(
428
+ `[anthropic-oauth] dead-account mark failed: ${_scrubTokens(saveErr?.message || String(saveErr)).slice(0, 200)}\n`
429
+ );
430
+ }
431
+ throw err;
432
+ }
368
433
  },
369
434
  {
370
435
  timeoutMs: 120_000,
@@ -536,6 +601,7 @@ async function exchangeAuthorizationCode({ pkce, code, state, redirectUri }) {
536
601
  }
537
602
  const expiresAt = expiresAtFromTokenResponse(json);
538
603
  const scopes = _oauthParseScopeField(json?.scope);
604
+ const identity = identityFromTokenResponse(json);
539
605
  const credPath = _oauthCredentialsWritePath();
540
606
  const raw = _updateCredentialsFile(credPath, (current) => {
541
607
  const base = current && typeof current === 'object' ? current : {};
@@ -548,7 +614,10 @@ async function exchangeAuthorizationCode({ pkce, code, state, redirectUri }) {
548
614
  refreshToken,
549
615
  expiresAt,
550
616
  scopes,
617
+ reauthRequired: undefined,
551
618
  subscriptionType: existingOauth.subscriptionType ?? null,
619
+ // A fresh sign-in replaces the account: never keep the previous identity.
620
+ identity: identity || undefined,
552
621
  },
553
622
  };
554
623
  });
@@ -559,10 +628,11 @@ async function exchangeAuthorizationCode({ pkce, code, state, redirectUri }) {
559
628
  expiresAt,
560
629
  scopes,
561
630
  subscriptionType: raw.claudeAiOauth.subscriptionType,
631
+ identity,
562
632
  };
563
633
  }
564
634
 
565
- export async function beginOAuthLogin({ openBrowserFn = null } = {}) {
635
+ export async function beginOAuthLogin({ openBrowserFn = null, openBrowser = true } = {}) {
566
636
  const pkce = createOAuthPkce();
567
637
  const state = randomBytes(32).toString('base64url');
568
638
  const buildUrl = (redirectUri) => {
@@ -580,6 +650,7 @@ export async function beginOAuthLogin({ openBrowserFn = null } = {}) {
580
650
  const url = buildUrl(OAUTH_REDIRECT_URI);
581
651
  const manualUrl = buildUrl(OAUTH_MANUAL_REDIRECT_URI);
582
652
  const openLoginUrl = async (targetUrl, label = 'login') => {
653
+ if (!openBrowser) return;
583
654
  try {
584
655
  const openInBrowser = openBrowserFn || (await import('../../../shared/open-url.mjs')).openInBrowser;
585
656
  await openInBrowser(targetUrl.toString());
@@ -62,6 +62,8 @@ import {
62
62
  } from './lib/anthropic-request-utils.mjs';
63
63
  import {
64
64
  EFFORT_CONFIGURATION_BETA,
65
+ isEffortConfigurationRejection,
66
+ markEffortConfigurationUnsupported,
65
67
  projectEffortConfiguration,
66
68
  lowerAnthropicEffortHistory,
67
69
  markAnthropicEffortBody,
@@ -293,7 +295,9 @@ export class AnthropicOAuthProvider {
293
295
  this.credentials = loadCredentials();
294
296
  }
295
297
  if (!this.credentials) {
296
- throw new Error('Anthropic OAuth credentials not found. Open /providers in mixdog to sign in.');
298
+ throw Object.assign(new Error('Anthropic OAuth credentials not found. Open /providers in mixdog to sign in.'), {
299
+ reauthRequired: true,
300
+ });
297
301
  }
298
302
 
299
303
  // Pick up Mixdog-updated tokens the moment the credentials file is
@@ -359,12 +363,20 @@ export class AnthropicOAuthProvider {
359
363
  return latest;
360
364
  }
361
365
 
362
- if (!latest?.refreshToken) {
366
+ if (!latest?.refreshToken || latest.reauthRequired) {
363
367
  if (!force && latest?.accessToken && (!latest.expiresAt || latest.expiresAt > Date.now())) {
364
- logQuiet('WARNING: token expiring but no refresh token; using current token until expiry');
368
+ logQuiet('WARNING: token expiring but no usable refresh token; using current token until expiry');
365
369
  return latest;
366
370
  }
367
- throw new Error('Anthropic OAuth refresh token not available. Open /providers in mixdog to sign in again.');
371
+ if (latest?.reauthRequired) {
372
+ throw Object.assign(new Error('Anthropic sign-in expired. Sign in again from Providers.'), {
373
+ reauthRequired: true,
374
+ });
375
+ }
376
+ throw Object.assign(
377
+ new Error('Anthropic OAuth refresh token not available. Open /providers in mixdog to sign in again.'),
378
+ { reauthRequired: true }
379
+ );
368
380
  }
369
381
 
370
382
  try {
@@ -608,6 +620,19 @@ export class AnthropicOAuthProvider {
608
620
  throw anthropicQuotaError(response.status, response.headers, safeText);
609
621
  }
610
622
 
623
+ // A newer model that rejects the mid-conversation effort update: switch
624
+ // the updates off for it in this process and replay the turn once
625
+ // without them (the request keeps its turn effort).
626
+ if (isEffortConfigurationRejection(response.status, scrubbedText) && !opts._effortConfigurationRetry) {
627
+ markEffortConfigurationUnsupported('anthropic-oauth', useModel);
628
+ process.stderr.write(`[anthropic-oauth] ${useModel} rejected the mid-conversation effort update; retrying once without it\n`);
629
+ return this.send(messages, useModel, tools, {
630
+ ...opts,
631
+ effortConfigurationEnabled: false,
632
+ _effortConfigurationRetry: true,
633
+ });
634
+ }
635
+
611
636
  // Anthropic can gate a newly launched model on a newer Claude
612
637
  // Code client identity. Learn only the exact minimum-version
613
638
  // rejection, persist the raised floor, and replay this untouched
@@ -71,6 +71,9 @@ export function createAnthropicSseTurn({
71
71
  ...events,
72
72
  // Stream ended: flush any held-back leaked-tool-call buffer.
73
73
  flushLeak: leak.flush,
74
+ // Usage the provider reported so far, in the success result's shape (a
75
+ // cancelled turn hands it to its send's accounting).
76
+ reportedUsage: () => ({ usage: turn.usage, model: turn.model || undefined }),
74
77
  ...outcome,
75
78
  };
76
79
  }
@@ -16,6 +16,7 @@ import { OAUTH_STREAM_LABELS } from './lib/anthropic-stream-labels.mjs';
16
16
  import { stampStreamOutcome, STREAM_TRANSPORTS, STREAM_OUTCOME_VERSION } from './lib/stream-outcome.mjs';
17
17
  import { createAnthropicSseTurn } from './anthropic-sse-turn.mjs';
18
18
  import { createAnthropicSseWatchdogs } from './anthropic-sse-watchdogs.mjs';
19
+ import { noteAbandonedUsage } from '../../../shared/llm/usage-context.mjs';
19
20
 
20
21
  /** Bounded mid-stream SSE retries (transient stream loss); shared with anthropic.mjs.
21
22
  * Sourced from the single shared retry-budget table (MIDSTREAM_RETRY_POLICY.sse). */
@@ -234,7 +235,15 @@ export async function parseSSEStream(
234
235
  chunk = await watchdogs.read();
235
236
  } catch (err) {
236
237
  const stopped = watchdogs.readFailure() ?? (signal?.aborted ? abortedError() : null);
237
- if (stopped) throw stopped;
238
+ if (stopped) {
239
+ // The caller's cancellation reason may be shared: never stamp this
240
+ // request's usage on it; the usage reported so far goes to this send.
241
+ if (signal?.aborted && state?.sawMessageStart) {
242
+ const reported = turn.reportedUsage();
243
+ noteAbandonedUsage(reported.usage, reported.model);
244
+ }
245
+ throw stopped;
246
+ }
238
247
  // The connection dropped mid-body: carry what this turn completed so
239
248
  // the loop can continue from finished tool calls instead of failing.
240
249
  throw state?.sawMessageStart ? turn.attachTransportPartial(err) : err;
@@ -7,6 +7,7 @@ import { createAbortController } from '../../../shared/abort-controller.mjs';
7
7
  import { ANTHROPIC_MAX_MIDSTREAM_RETRIES, parseSSEStream } from './anthropic-sse.mjs';
8
8
  import { buildAnthropicBetaHeaders } from './anthropic-betas.mjs';
9
9
  import { buildAnthropicApiRequest } from './anthropic-api-request.mjs';
10
+ import { isCustomProviderName } from './custom-reasoning.mjs';
10
11
  import { armFirstByteWatchdog, createAnthropicApiTransport } from './anthropic-api-transport.mjs';
11
12
  import { createAnthropicApiRecovery } from './anthropic-api-recovery.mjs';
12
13
  import { buildAnthropicTurnResult } from './anthropic-turn-result.mjs';
@@ -47,12 +48,18 @@ export class AnthropicProvider {
47
48
  // off the client defaults and add it only on turns that actually serialize
48
49
  // defer_loading tools.
49
50
  _createClient(apiKey) {
50
- const betaHeaders = this.config.disableBetaHeaders ? null : buildAnthropicBetaHeaders();
51
+ // A custom gateway gets no first-party default betas and only its own
52
+ // credential: never the SDK's env/credential-file fallbacks, and none at
53
+ // all when keyless (config.keyless).
54
+ const custom = isCustomProviderName(this.name);
55
+ const keyless = custom && this.config.keyless === true;
56
+ const betaHeaders = this.config.disableBetaHeaders || custom ? null : buildAnthropicBetaHeaders();
51
57
  return new (loadAnthropic())({
52
- apiKey,
58
+ ...(custom ? { apiKey: keyless ? '' : apiKey || '', authToken: null } : { apiKey }),
53
59
  ...(this.config.baseURL ? { baseURL: this.config.baseURL } : {}),
54
60
  defaultHeaders: {
55
61
  ...(betaHeaders ? { 'anthropic-beta': betaHeaders } : {}),
62
+ ...(keyless ? { 'x-api-key': null, authorization: null } : {}),
56
63
  ...(this.config.extraHeaders || {}),
57
64
  },
58
65
  maxRetries: 0,
@@ -114,6 +121,8 @@ export class AnthropicProvider {
114
121
  tools,
115
122
  opts,
116
123
  fastModeLatched: this.fastModeBetaHeaderLatched,
124
+ // Custom providers carry per-model reasoning settings on their own rows.
125
+ modelInfo: isCustomProviderName(this.name) ? this.getCachedModelInfo?.(useModel) || null : null,
117
126
  });
118
127
  this.fastModeBetaHeaderLatched = fastModeLatched;
119
128
 
@@ -103,19 +103,20 @@ async function requestCodeAssist(action, body, context, timeoutMs = PROJECT_TIME
103
103
  return payload;
104
104
  }
105
105
 
106
- async function fetchAccountEmail(accessToken, { fetchFn = fetch, signal = null } = {}) {
106
+ // The userinfo response carries the Google account's email and stable user id.
107
+ async function fetchAccountInfo(accessToken, { fetchFn = fetch, signal = null } = {}) {
107
108
  try {
108
109
  const res = await fetchFn(USERINFO_URL, {
109
110
  headers: { Authorization: `Bearer ${accessToken}` },
110
111
  redirect: 'error',
111
112
  signal: withTimeoutSignal(signal, TOKEN_TIMEOUT_MS),
112
113
  });
113
- if (!res.ok) return '';
114
+ if (!res.ok) return { email: '', userId: '' };
114
115
  const json = await res.json();
115
- return String(json?.email || '');
116
+ return { email: String(json?.email || ''), userId: String(json?.id || json?.sub || '') };
116
117
  } catch {
117
118
  signal?.throwIfAborted();
118
- return '';
119
+ return { email: '', userId: '' };
119
120
  }
120
121
  }
121
122
 
@@ -266,7 +267,7 @@ export async function exchangeAuthorizationCode({ code, verifier, fetchFn = fetc
266
267
  if (!json?.access_token || !json?.refresh_token) {
267
268
  throw new Error('[antigravity-oauth] token exchange response missing access_token or refresh_token');
268
269
  }
269
- const email = await fetchAccountEmail(json.access_token, { fetchFn, signal });
270
+ const { email, userId } = await fetchAccountInfo(json.access_token, { fetchFn, signal });
270
271
  const projectId = await discoverProject(json.access_token, { fetchFn, onProgress, signal, email });
271
272
  const tokens = {
272
273
  access_token: json.access_token,
@@ -274,6 +275,7 @@ export async function exchangeAuthorizationCode({ code, verifier, fetchFn = fetc
274
275
  expires_at: typeof json.expires_in === 'number' ? Date.now() + json.expires_in * 1000 : 0,
275
276
  project_id: projectId,
276
277
  email,
278
+ user_id: userId,
277
279
  };
278
280
  signal?.throwIfAborted();
279
281
  saveTokens(tokens);
@@ -285,6 +287,7 @@ export async function beginOAuthLogin({
285
287
  onProgress = null,
286
288
  createServerFn = createServer,
287
289
  openBrowserFn = null,
290
+ openBrowser = true,
288
291
  } = {}) {
289
292
  const controller = new AbortController();
290
293
  const pkce = createOAuthPkce();
@@ -396,6 +399,7 @@ export async function beginOAuthLogin({
396
399
  server.listen(CALLBACK_PORT, CALLBACK_HOST, async () => {
397
400
  if (settled) return;
398
401
  process.stderr.write(`\n[antigravity-oauth] Open this URL to log in:\n${url.toString()}\n\n`);
402
+ if (!openBrowser) return;
399
403
  try {
400
404
  if (openBrowserFn) await openBrowserFn(url.toString());
401
405
  else {
@@ -18,7 +18,11 @@ import { join, resolve } from 'node:path';
18
18
  import { getPluginData } from '../config.mjs';
19
19
  import { writeJsonAtomicSync } from '../../../shared/atomic-file.mjs';
20
20
  import { boundProviderAuthPath } from '../../../shared/provider-auth-binding.mjs';
21
- import { normalizeExpiresAtMs as _normalizeExpiresAt, scrubOAuthSecrets } from './lib/oauth-token-utils.mjs';
21
+ import {
22
+ accountIdentityFields,
23
+ normalizeExpiresAtMs as _normalizeExpiresAt,
24
+ scrubOAuthSecrets,
25
+ } from './lib/oauth-token-utils.mjs';
22
26
  import { ANTIGRAVITY_MODELS } from '../../../shared/llm/provider-model-identities.mjs';
23
27
  import { readLastKnownVersion, rememberLastKnownVersion } from './client-version-store.mjs';
24
28
  import { maxSemver } from './npm-cli-version.mjs';
@@ -199,6 +203,7 @@ export function loadTokens() {
199
203
  expires_at: _normalizeExpiresAt(raw.expires_at ?? raw.expiresAt),
200
204
  project_id: String(raw.project_id || raw.projectId || ''),
201
205
  email: String(raw.email || ''),
206
+ user_id: String(raw.user_id || raw.userId || ''),
202
207
  source: 'own',
203
208
  mtimeMs: mtimeMs(path),
204
209
  };
@@ -216,6 +221,7 @@ export function saveTokens(tokens) {
216
221
  expires_at: tokens.expires_at || 0,
217
222
  project_id: tokens.project_id || tokens.projectId || '',
218
223
  email: tokens.email || '',
224
+ user_id: tokens.user_id || tokens.userId || '',
219
225
  },
220
226
  { lock: true, fsyncDir: true, mode: 0o600, secret: true }
221
227
  );
@@ -263,6 +269,7 @@ export function describeAntigravityOAuthCredentials() {
263
269
  reauthRequired: !usable,
264
270
  status: usable ? 'Signed In' : 'Reauth Required',
265
271
  detail,
272
+ ...accountIdentityFields({ id: tokens.user_id, email: tokens.email }),
266
273
  email: tokens.email || '',
267
274
  projectId: tokens.project_id || '',
268
275
  };
@@ -332,6 +339,7 @@ export function refreshTokens({ fetchFn = fetch } = {}) {
332
339
  expires_at: typeof json.expires_in === 'number' ? Date.now() + json.expires_in * 1000 : 0,
333
340
  project_id: current.project_id,
334
341
  email: current.email,
342
+ user_id: current.user_id,
335
343
  };
336
344
  saveTokens(next);
337
345
  return next;
@@ -12,6 +12,7 @@
12
12
  * Auth, endpoints, and headers live in antigravity-oauth-tokens.mjs.
13
13
  */
14
14
  import { mkdirSync, writeFileSync } from 'node:fs';
15
+ import { noteErrorUsage } from './lib/note-error-usage.mjs';
15
16
  import { join } from 'node:path';
16
17
  import { buildAntigravityRequest, isAntigravityClaude as isClaudeModel } from './antigravity-request.mjs';
17
18
  import { createPassthroughSignal } from '../stall-policy.mjs';
@@ -167,6 +168,7 @@ export class AntigravityOAuthProvider {
167
168
  response = await requestOnce();
168
169
  } catch (err) {
169
170
  lastErr = err;
171
+ noteErrorUsage(err);
170
172
  const status = Number(err?.status || err?.httpStatus || 0);
171
173
  const emitted = err?.unsafeToRetry === true || err?.liveTextEmitted === true || err?.emittedToolCall === true;
172
174
  // A typed 401 says THIS access token is no longer accepted.
@@ -10,6 +10,17 @@ import { traceAgentUsage } from '../agent-trace.mjs';
10
10
  import { createProviderReplay } from './lib/provider-replay.mjs';
11
11
  import { parseToolCalls, collectGeminiGroundingSources, parseGeminiTextPartMetadata } from './gemini-schema.mjs';
12
12
 
13
+ // Pure usageMetadata normalization shared by the success path and a failed
14
+ // stream's partialUsage.
15
+ export function normalizeAntigravityUsage(um) {
16
+ const inputTokens = um.promptTokenCount || um.prompt_token_count || 0;
17
+ const cachedTokens = um.cachedContentTokenCount || um.cached_content_token_count || 0;
18
+ const outputTokens =
19
+ (um.candidatesTokenCount || um.candidates_token_count || 0) +
20
+ (um.thoughtsTokenCount || um.thoughts_token_count || 0);
21
+ return { inputTokens, outputTokens, cachedTokens, promptTokens: inputTokens, raw: um };
22
+ }
23
+
13
24
  /**
14
25
  * @param {object} deps
15
26
  * @param {object} deps.response final unwrapped Gemini-shaped payload
@@ -48,31 +59,11 @@ export function finalizeAntigravityTurn({ response, collector, useModel, opts, o
48
59
  const finishReason =
49
60
  collector.terminalFailure || candidate?.finishReason || (promptBlockReason ? `PROMPT_${promptBlockReason}` : null);
50
61
  const normalizedFinish = String(finishReason || '').replace(/^FINISH_REASON_/, '');
51
- if (finishReason && normalizedFinish !== 'STOP') {
52
- throw Object.assign(new Error(`Antigravity response incomplete: finishReason=${finishReason}`), {
53
- name: 'ProviderIncompleteError',
54
- code: 'PROVIDER_INCOMPLETE',
55
- providerIncomplete: true,
56
- finishReason,
57
- partialContent: content,
58
- partialToolCalls: toolCalls,
59
- partialProviderReplay: providerReplay,
60
- providerMetadata,
61
- model: useModel,
62
- rawUsage: response.usageMetadata || null,
63
- ...(collector.emittedToolCount ? { emittedToolCall: true, unsafeToRetry: true } : {}),
64
- });
65
- }
66
-
67
62
  const um = response.usageMetadata || null;
68
63
  let usage;
69
64
  if (um) {
70
- const inputTokens = um.promptTokenCount || um.prompt_token_count || 0;
71
- const cachedTokens = um.cachedContentTokenCount || um.cached_content_token_count || 0;
72
- const outputTokens =
73
- (um.candidatesTokenCount || um.candidates_token_count || 0) +
74
- (um.thoughtsTokenCount || um.thoughts_token_count || 0);
75
- usage = { inputTokens, outputTokens, cachedTokens, promptTokens: inputTokens, raw: um };
65
+ usage = normalizeAntigravityUsage(um);
66
+ const { inputTokens, outputTokens, cachedTokens } = usage;
76
67
  traceAgentUsage({
77
68
  sessionId: opts.sessionId || opts.session?.id || null,
78
69
  iteration: Number.isFinite(Number(opts.iteration)) ? Number(opts.iteration) : null,
@@ -88,6 +79,23 @@ export function finalizeAntigravityTurn({ response, collector, useModel, opts, o
88
79
  });
89
80
  }
90
81
 
82
+ if (finishReason && normalizedFinish !== 'STOP') {
83
+ throw Object.assign(new Error(`Antigravity response incomplete: finishReason=${finishReason}`), {
84
+ name: 'ProviderIncompleteError',
85
+ code: 'PROVIDER_INCOMPLETE',
86
+ providerIncomplete: true,
87
+ finishReason,
88
+ partialContent: content,
89
+ partialToolCalls: toolCalls,
90
+ partialProviderReplay: providerReplay,
91
+ providerMetadata,
92
+ model: useModel,
93
+ rawUsage: response.usageMetadata || null,
94
+ ...(usage ? { partialUsage: usage, partialModel: useModel } : {}),
95
+ ...(collector.emittedToolCount ? { emittedToolCall: true, unsafeToRetry: true } : {}),
96
+ });
97
+ }
98
+
91
99
  return {
92
100
  content,
93
101
  model: useModel,
@@ -13,6 +13,7 @@
13
13
  import { createProviderReplay } from './lib/provider-replay.mjs';
14
14
  import { createGeminiTextLeakGuard, consumeGeminiRestStreamResponse } from './gemini-stream.mjs';
15
15
  import { parseToolCalls, emitGeminiToolCalls } from './gemini-schema.mjs';
16
+ import { normalizeAntigravityUsage } from './antigravity-response.mjs';
16
17
 
17
18
  // A retired wire id answers with one plain-text notice and no finishReason.
18
19
  // That is a terminal answer about the model, not a truncated stream.
@@ -118,6 +119,7 @@ export function createAntigravityStreamCollector({ tools, useModel, onToolCall,
118
119
  onChunk,
119
120
  textLeakGuard,
120
121
  label: 'Antigravity streamGenerateContent',
122
+ failureUsage: { model: useModel, normalize: normalizeAntigravityUsage },
121
123
  // Cloud Code Assist nests the Gemini payload under
122
124
  // `response`; in-band error events stay top level.
123
125
  unwrapChunk: (chunk) => (chunk && typeof chunk === 'object' && chunk.response ? chunk.response : chunk),
@@ -25,18 +25,36 @@ export function autoEffortBase(chosen) {
25
25
 
26
26
  export const AUTO_EFFORT_MODES = Object.freeze(['off', 'observe', 'on']);
27
27
 
28
- // Below this top-class probability the judge is unsure and the default stays.
29
- export const AUTO_EFFORT_MIN_CONFIDENCE = 0.4;
30
- // xhigh costs far more than high, so "very hard" needs a firmer judge;
31
- // below this it is treated as "hard". 0.65 minimised the eval cost with a
32
- // false xhigh weighted three times a missed one.
33
- export const AUTO_EFFORT_VERY_HARD_CONFIDENCE = 0.65;
34
-
35
28
  // The judge rates four levels, each one ladder step from the base: easy -1
36
29
  // (low), normal 0 (medium), hard +1 (high), very hard +2 (xhigh).
37
30
  export const AUTO_EFFORT_LEVELS = Object.freeze(['easy', 'normal', 'hard', 'very hard']);
38
31
  const STEP_OF_LEVEL = [-1, 0, 1, 2];
39
32
 
33
+ // The chosen level minimises the expected cost under the judge distribution.
34
+ // A miss costs one per level, plus extra for an opposite call and for a
35
+ // needless "very hard" (xhigh). Opposite calls are asymmetric: "easy" for a
36
+ // hard turn degrades the answer, "hard" for an easy turn only costs tokens.
37
+ // On the held-out test splits the heavier under-call cost cut hard-as-easy
38
+ // calls by a third (20 -> 13 of 7,180) for -0.2 points of exact accuracy.
39
+ export const AUTO_EFFORT_UNDER_OPPOSITE_COST = 3;
40
+ export const AUTO_EFFORT_OVER_OPPOSITE_COST = 1;
41
+ export const AUTO_EFFORT_FALSE_VERY_HARD_COST = 1;
42
+ // Ties keep the default first, then the cheaper side.
43
+ const TIE_ORDER = [1, 0, 2, 3];
44
+
45
+ function expectedCost(values, level) {
46
+ let cost = 0;
47
+ values.forEach((p, actual) => {
48
+ cost +=
49
+ p *
50
+ (Math.abs(level - actual) +
51
+ (level === 0 && actual >= 2 ? AUTO_EFFORT_UNDER_OPPOSITE_COST : 0) +
52
+ (actual === 0 && level >= 2 ? AUTO_EFFORT_OVER_OPPOSITE_COST : 0) +
53
+ (level === 3 && actual < 3 ? AUTO_EFFORT_FALSE_VERY_HARD_COST : 0));
54
+ });
55
+ return cost;
56
+ }
57
+
40
58
  export function normalizeAutoEffortMode(value) {
41
59
  const mode = String(value ?? '')
42
60
  .trim()
@@ -57,9 +75,9 @@ export function judgedStep(probs) {
57
75
  const values = Array.isArray(probs) && probs.length === AUTO_EFFORT_LEVELS.length ? probs.map(Number) : null;
58
76
  if (!values || values.some((value) => !Number.isFinite(value))) return { step: 0, level: null, confidence: 0 };
59
77
  const confidence = Math.max(...values);
60
- if (confidence < AUTO_EFFORT_MIN_CONFIDENCE) return { step: 0, level: null, confidence };
61
- let level = values.indexOf(confidence);
62
- if (level === 3 && confidence < AUTO_EFFORT_VERY_HARD_CONFIDENCE) level = 2;
78
+ let level = TIE_ORDER[0];
79
+ for (const candidate of TIE_ORDER)
80
+ if (expectedCost(values, candidate) < expectedCost(values, level) - 1e-12) level = candidate;
63
81
  return { step: STEP_OF_LEVEL[level], level, confidence };
64
82
  }
65
83