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
@@ -92,8 +92,10 @@ export function createCatalogLoader({
92
92
  const key = `${row.provider}:${row.id}`;
93
93
  if (seen.has(key)) continue;
94
94
  seen.add(key);
95
- results.push(row);
96
95
  if (meta.snapshotIsCurrent(revision, seq)) meta.remember(row.provider, row.id, row);
96
+ // A hidden custom model leaves the picker; its metadata still resolves
97
+ // for sessions and saved routes already on it.
98
+ if (row.hidden !== true) results.push(row);
97
99
  }
98
100
  profile('load:done', {
99
101
  ms: (performance.now() - startedAt).toFixed(1),
@@ -3,32 +3,58 @@
3
3
  // settings (alias, effort, fast, parameters, context budget) layered on top,
4
4
  // then the route-provider-first sort.
5
5
  import { effortItemsFor } from '../../runtime/agent/orchestrator/runtime-core/effort.mjs';
6
- import { fastCapableFor, fastPreferenceFor } from '../../runtime/agent/orchestrator/runtime-core/model-capabilities.mjs';
6
+ import {
7
+ fastCapableFor,
8
+ fastPreferenceFor,
9
+ ultrafastCapableFor,
10
+ } from '../../runtime/agent/orchestrator/runtime-core/model-capabilities.mjs';
7
11
  import { modelSettingsFor } from '../../runtime/agent/orchestrator/runtime-core/config-helpers.mjs';
8
- import { effortConfigurationMode } from '../../runtime/agent/orchestrator/providers/effort-configuration.mjs';
12
+ import {
13
+ customAutoEffortCapable,
14
+ effortConfigurationMode,
15
+ } from '../../runtime/agent/orchestrator/providers/effort-configuration.mjs';
9
16
  import { getProvider } from '../../runtime/agent/orchestrator/providers/registry.mjs';
10
17
 
18
+ const ULTRAFAST_SPEED_OPTION = Object.freeze({
19
+ id: 'serviceTier',
20
+ label: 'Speed',
21
+ kind: 'enum',
22
+ options: [
23
+ { value: 'priority', label: 'Fast' },
24
+ { value: 'ultrafast', label: 'Ultrafast' },
25
+ ],
26
+ });
27
+
11
28
  export function hydrateProviderModelRow(cfg, row) {
12
29
  const saved = modelSettingsFor(cfg, row.provider, row.id);
13
30
  // Display-only user alias (modelSettings["provider/model"].alias). It
14
31
  // replaces the label everywhere the row's `display` is shown; the id and
15
32
  // route selection are untouched.
16
33
  const alias = typeof saved.alias === 'string' ? saved.alias.trim() : '';
34
+ const fastCapable = fastCapableFor(row.provider, row);
35
+ const existingOptions = Array.isArray(row.modelParameterOptions) ? row.modelParameterOptions : [];
36
+ const modelParameterOptions =
37
+ fastCapable && ultrafastCapableFor(row.provider, row)
38
+ ? [...existingOptions.filter((option) => option?.id !== ULTRAFAST_SPEED_OPTION.id), ULTRAFAST_SPEED_OPTION]
39
+ : row.modelParameterOptions;
17
40
  return {
18
41
  ...row,
19
42
  ...(alias ? { display: alias, displayAlias: alias } : {}),
43
+ ...(modelParameterOptions ? { modelParameterOptions } : {}),
20
44
  effortOptions: effortItemsFor(row.provider, row, null),
21
- fastCapable: fastCapableFor(row.provider, row),
45
+ fastCapable,
22
46
  fastPreferred: Object.hasOwn(saved, 'fast')
23
47
  ? saved.fast === true
24
48
  : row.defaultFast === true || fastPreferenceFor(cfg, row.provider, row.id),
25
- // Auto effort only changes effort where that keeps the prompt cache.
26
- autoEffortCapable: Boolean(
27
- effortConfigurationMode(row.provider, row.id, {
28
- ...(getProvider(row.provider)?.config || {}),
29
- modelParameters: saved.modelParameters || {},
30
- })
31
- ),
49
+ // Auto effort only changes effort where that keeps the prompt cache, or
50
+ // per request on a custom Chat/Responses model that declares levels.
51
+ autoEffortCapable:
52
+ Boolean(
53
+ effortConfigurationMode(row.provider, row.id, {
54
+ ...(getProvider(row.provider)?.config || {}),
55
+ modelParameters: saved.modelParameters || {},
56
+ })
57
+ ) || customAutoEffortCapable(row.provider, cfg?.providers?.[row.provider]?.protocol, row),
32
58
  savedEffort: saved.effort || null,
33
59
  savedFast: Object.hasOwn(saved, 'fast') ? saved.fast === true : undefined,
34
60
  savedModelParameters: saved.modelParameters || {},
@@ -2,6 +2,31 @@
2
2
  // model record filled from it.
3
3
  import { clean } from '../../runtime/agent/orchestrator/runtime-core/session-text.mjs';
4
4
  import { getModelMetadataSync } from '../../runtime/agent/orchestrator/providers/model-catalog.mjs';
5
+ import { isCustomProviderName } from '../../runtime/agent/orchestrator/providers/custom-reasoning.mjs';
6
+
7
+ const CUSTOM_DECLARED_FIELDS = [
8
+ 'supportsReasoning',
9
+ 'reasoningOptions',
10
+ 'reasoningLevels',
11
+ 'reasoningContentField',
12
+ 'hidden',
13
+ 'manual',
14
+ 'customReasoning',
15
+ ];
16
+
17
+ /** A custom provider's effective row is authoritative: every contract field it
18
+ * states (an explicit [] or false included) wins over catalog metadata, and
19
+ * declared levels are not overridden by catalog effort options. First-party
20
+ * rows get nothing here. */
21
+ export function declaredCustomFields(provider, model) {
22
+ if (!isCustomProviderName(provider) || !model || typeof model !== 'object') return {};
23
+ const out = {};
24
+ for (const key of CUSTOM_DECLARED_FIELDS) {
25
+ if (Object.hasOwn(model, key) && model[key] !== undefined) out[key] = model[key];
26
+ }
27
+ if (Object.hasOwn(out, 'reasoningLevels') && !Object.hasOwn(out, 'reasoningOptions')) out.reasoningOptions = [];
28
+ return out;
29
+ }
5
30
 
6
31
  export function metadataFor(provider, modelId) {
7
32
  try {
@@ -28,5 +53,6 @@ export function hydratedModel(provider, model = {}) {
28
53
  ? base.reasoningOptions
29
54
  : meta.reasoningOptions || [],
30
55
  reasoningContentField: base?.reasoningContentField || meta.reasoningContentField || null,
56
+ ...declaredCustomFields(provider, base),
31
57
  };
32
58
  }
@@ -3,7 +3,27 @@
3
3
  // workflow and agent routes), deduplicated per provider:model.
4
4
  import { clean } from '../../runtime/agent/orchestrator/runtime-core/session-text.mjs';
5
5
  import { providerCachedModelsSync } from '../../runtime/agent/orchestrator/providers/provider-catalog-cache.mjs';
6
- import { metadataFor } from './model-meta.mjs';
6
+ import {
7
+ effectiveCustomModelRows,
8
+ normalizeCustomProviderConfig,
9
+ } from '../../runtime/agent/orchestrator/providers/custom-provider.mjs';
10
+ import { declaredCustomFields, metadataFor } from './model-meta.mjs';
11
+
12
+ // A custom provider's picker models: its effective rows (discovered + saved
13
+ // overrides + manual models), read from the v2 config; a legacy `models`
14
+ // config is migrated by the normalizer. A config that does not normalize
15
+ // cannot run, so it lists nothing. `discovered` defaults to the cached catalog;
16
+ // a saved route on an uncached model passes its own row so the same overrides
17
+ // (hidden, metadata, reasoning) apply to it as in the full catalog.
18
+ function customProviderModels(provider, providerConfig, discovered = providerCachedModelsSync(provider)) {
19
+ let config;
20
+ try {
21
+ config = normalizeCustomProviderConfig(providerConfig);
22
+ } catch {
23
+ return [];
24
+ }
25
+ return effectiveCustomModelRows(config, discovered, { providerId: provider });
26
+ }
7
27
 
8
28
  export function createQuickProviderRows({
9
29
  getRoute,
@@ -39,16 +59,19 @@ export function createQuickProviderRows({
39
59
  reasoningOptions: model.reasoningOptions?.length ? model.reasoningOptions : meta.reasoningOptions || [],
40
60
  reasoningContentField: model.reasoningContentField || meta.reasoningContentField || null,
41
61
  mode: model.mode || meta.mode || 'chat',
62
+ ...declaredCustomFields(provider, model),
42
63
  });
43
- rows.push(row);
44
64
  modelMetaByRoute.set(modelMetaKey(provider, modelId), row);
65
+ // A hidden model leaves the picker (a saved route on it included) while
66
+ // its metadata keeps resolving for sessions already on it.
67
+ if (row.hidden !== true) rows.push(row);
45
68
  };
46
69
  const addRoute = (routeLike = {}) => {
47
70
  const provider = clean(routeLike.provider);
48
71
  const model = clean(routeLike.model);
49
72
  if (!provider || !model || isDeletedCustom(provider)) return;
50
73
  const meta = metadataFor(provider, model);
51
- addModel(provider, {
74
+ const routeRow = {
52
75
  id: model,
53
76
  name: routeLike.modelDisplay || routeLike.display || model,
54
77
  display: routeLike.modelDisplay || routeLike.display || model,
@@ -61,7 +84,14 @@ export function createQuickProviderRows({
61
84
  reasoningOptions: meta.reasoningOptions || [],
62
85
  reasoningContentField: meta.reasoningContentField || null,
63
86
  mode: 'chat',
64
- });
87
+ };
88
+ const customConfig = customProviders[provider];
89
+ if (customConfig?.type === 'custom') {
90
+ const row = customProviderModels(provider, customConfig, [routeRow]).find((item) => item.id === model);
91
+ if (row) addModel(provider, row);
92
+ return;
93
+ }
94
+ addModel(provider, routeRow);
65
95
  };
66
96
 
67
97
  // A custom-* id with no live custom config entry was deleted: stale
@@ -72,16 +102,12 @@ export function createQuickProviderRows({
72
102
  !(customProviders[provider]?.type === 'custom' && customProviders[provider].enabled !== false);
73
103
  for (const [provider, providerConfig] of Object.entries(customProviders)) {
74
104
  if (!providerConfig?.enabled) continue;
75
- if (providerConfig.type === 'custom') {
76
- // Configured models are listed at once, before any catalog refresh.
77
- for (const model of providerConfig.models || []) {
78
- addModel(provider, {
79
- ...model,
80
- outputTokens: model.maxOutputTokens || null,
81
- });
82
- }
83
- }
84
- for (const model of providerCachedModelsSync(provider)) addModel(provider, model);
105
+ // Configured custom models are listed at once, before any catalog refresh.
106
+ const models =
107
+ providerConfig.type === 'custom'
108
+ ? customProviderModels(provider, providerConfig)
109
+ : providerCachedModelsSync(provider);
110
+ for (const model of models) addModel(provider, model);
85
111
  }
86
112
  addRoute(route);
87
113
  for (const preset of pickerConfig.presets || []) addRoute(preset);
@@ -3,7 +3,10 @@
3
3
  // live state getters plus the closure callbacks (`deps`). Each surface lives in
4
4
  // its own module and shares the extension-change sync and scope decorators.
5
5
  import { clean } from '../runtime/agent/orchestrator/runtime-core/session-text.mjs';
6
- import { EXTENSION_SCOPE_KINDS, withExtensionScope } from '../runtime/agent/orchestrator/runtime-core/extension-scopes.mjs';
6
+ import {
7
+ EXTENSION_SCOPE_KINDS,
8
+ withExtensionScope,
9
+ } from '../runtime/agent/orchestrator/runtime-core/extension-scopes.mjs';
7
10
  import { createExtensionSync } from './resource-extension-sync.mjs';
8
11
  import { createScopeDecorators } from './resource-scope-decorate.mjs';
9
12
  import { createMcpResourceApi } from './resource-mcp-api.mjs';
@@ -60,5 +63,9 @@ export function createResourceApi(deps) {
60
63
  deleteHookRule(index) {
61
64
  return hooks.deleteRule(index);
62
65
  },
66
+ /** Write debounced rule toggles now; throws when the save fails. */
67
+ flushHookRules() {
68
+ hooks.flushRules();
69
+ },
63
70
  };
64
71
  }
@@ -24,6 +24,15 @@ export function resolveRouteEffortState(targetRoute = {}, modelMeta = null) {
24
24
  return { effectiveEffort, fastCapable, metadataResolved };
25
25
  }
26
26
 
27
+ // Fast capability for a route selection or tuning write. Placeholder metadata
28
+ // (`{ id, provider }`, a catalog that is not loaded yet) is unknown, not "no
29
+ // Fast": clamping on it turned the selected route AND the saved model setting
30
+ // to fast:false. Unknown keeps the requested value; the provider still checks
31
+ // the exact tier before send.
32
+ export function selectionFastCapable(provider, modelMeta, effort, modelParameters) {
33
+ return !modelMetaLooksResolved(modelMeta) || fastCapableFor(provider, modelMeta, effort, modelParameters);
34
+ }
35
+
27
36
  // The persisted provider model rows are the SAME source the picker sized its
28
37
  // slider against, so they carry both windows (openai-oauth: 272k default /
29
38
  // 1M max). Reading them keeps a percentage saved against the picker's scale
@@ -19,6 +19,8 @@ function bootParams({
19
19
  effort,
20
20
  fast,
21
21
  modelParameters,
22
+ contextPercent,
23
+ selectedContextWindow,
22
24
  cwd = process.cwd(),
23
25
  toolMode = 'full',
24
26
  toolProfile = 'interactive',
@@ -36,6 +38,8 @@ function bootParams({
36
38
  effort,
37
39
  fast,
38
40
  modelParameters,
41
+ contextPercent,
42
+ selectedContextWindow,
39
43
  cwd,
40
44
  toolMode,
41
45
  toolProfile,
@@ -1,4 +1,5 @@
1
1
  import { SESSION_ID_PATTERN } from '../runtime/agent/orchestrator/runtime-core/session-id.mjs';
2
+ import { SessionAddressError, bindSessionAddress } from './session-address.mjs';
2
3
 
3
4
  function requiredSessionId(value) {
4
5
  const sessionId = String(value || '').trim();
@@ -25,9 +26,19 @@ export function createRuntimeFacade({
25
26
  getContextStatusForSession,
26
27
  renameSessionTitle,
27
28
  }) {
28
- const currentSessionId = () => state.session?.id || state.reservedSessionId || null;
29
+ // The durable address outlives the session object (terminal/closed, evicted).
30
+ const currentSessionId = () => state.session?.id || state.reservedSessionId || state.addressedSessionId || null;
29
31
  return {
30
32
  ...leadingApi,
33
+ /** Bind the durable address to the conversation this runtime just
34
+ * loaded (resume / load-on-demand). Idempotent for the same id. */
35
+ bindSessionAddress(sessionId) {
36
+ const id = requiredSessionId(sessionId);
37
+ if (state.session?.id && state.session.id !== id) {
38
+ throw new SessionAddressError(`runtime holds ${state.session.id}, not ${id}`, id);
39
+ }
40
+ return bindSessionAddress(state, id) === id;
41
+ },
31
42
  get id() {
32
43
  return currentSessionId();
33
44
  },
@@ -48,6 +59,14 @@ export function createRuntimeFacade({
48
59
  get model() {
49
60
  return state.route.model;
50
61
  },
62
+ // The current session object's own route; diverges from provider/model
63
+ // (the selected route) after a model change on a session with history.
64
+ get sessionProvider() {
65
+ return state.session?.provider ?? null;
66
+ },
67
+ get sessionModel() {
68
+ return state.session?.model ?? null;
69
+ },
51
70
  get effort() {
52
71
  return state.route.effectiveEffort || state.route.effort || state.route.preset?.effort || null;
53
72
  },
@@ -8,6 +8,7 @@ import { builtinFeatureActive, featureDisallowedToolsFor, localGitToolsActive }
8
8
  import { recapEnabled } from '../runtime/agent/orchestrator/runtime-core/config-helpers.mjs';
9
9
  import { browserBridgeAvailableSync } from '../runtime/browser-bridge/client.mjs';
10
10
  import { computerBridgeAvailableSync } from '../runtime/computer-bridge/client.mjs';
11
+ import { terminalBridgeAvailableSync } from '../runtime/terminal-bridge/client.mjs';
11
12
 
12
13
  export function createRuntimeFeatureGates({ getConfig, getToolProfile }) {
13
14
  return {
@@ -28,6 +29,7 @@ export function createRuntimeFeatureGates({ getConfig, getToolProfile }) {
28
29
  featureDisallowedToolsFor(getConfig(), {
29
30
  browserAvailable: browserBridgeAvailableSync(),
30
31
  computerAvailable: computerBridgeAvailableSync(),
32
+ terminalAvailable: terminalBridgeAvailableSync(),
31
33
  toolProfile: getToolProfile(),
32
34
  }),
33
35
  };
@@ -1,13 +1,24 @@
1
+ import { registerCacheInvalidationListener } from '../runtime/agent/orchestrator/tools/builtin/cache-layers.mjs';
2
+ import { turnReviewReply } from '../runtime/shared/turn-review-reply.mjs';
1
3
  import {
2
4
  getSessionReviewDiff,
3
5
  getTurnReviewDiff,
4
6
  revertTurnReview,
5
7
  revertTurnReviewFile,
6
8
  } from '../runtime/shared/turn-snapshot.mjs';
9
+ import { noteTurnWorktreeChange } from '../runtime/shared/turn-worktree-snapshot.mjs';
10
+
11
+ // Tool writes (apply_patch, mutating shell commands, git, watcher events)
12
+ // reach the live review snapshot as its change signal: a review poll right
13
+ // after them captures the worktree, an unsignaled poll may reuse the last one.
14
+ registerCacheInvalidationListener((paths) => noteTurnWorktreeChange(paths));
7
15
 
8
16
  export function createRuntimeReviewApi({ getCwd, getSessionId }) {
9
17
  return {
10
- getTurnReviewDiff: (options = {}) => getTurnReviewDiff(getCwd(), getSessionId(), options),
18
+ // `known` (the client's tag) and `summary` are answered here, so an
19
+ // unchanged review crosses the wire as a short tag reply.
20
+ getTurnReviewDiff: (options = {}) =>
21
+ turnReviewReply((reviewOptions) => getTurnReviewDiff(getCwd(), getSessionId(), reviewOptions), options),
11
22
  getSessionReviewDiff: () => getSessionReviewDiff(getCwd(), getSessionId()),
12
23
  revertTurnReview: (checkpointId) => revertTurnReview(getCwd(), getSessionId(), checkpointId),
13
24
  revertTurnReviewFile: (file, checkpointId) => revertTurnReviewFile(getCwd(), getSessionId(), file, checkpointId),
@@ -30,7 +30,10 @@ let exitFlushInstalled = false;
30
30
  /** Run every registered flush once on process exit (best effort). */
31
31
  export function registerExitFlush(flush) {
32
32
  exitFlushes.add(flush);
33
- if (exitFlushInstalled) return;
33
+ const unregister = () => {
34
+ exitFlushes.delete(flush);
35
+ };
36
+ if (exitFlushInstalled) return unregister;
34
37
  exitFlushInstalled = true;
35
38
  process.on('exit', () => {
36
39
  for (const entry of exitFlushes) {
@@ -41,6 +44,12 @@ export function registerExitFlush(flush) {
41
44
  }
42
45
  }
43
46
  });
47
+ return unregister;
48
+ }
49
+
50
+ /** Test seam: number of live exit registrations. */
51
+ export function exitFlushCount() {
52
+ return exitFlushes.size;
44
53
  }
45
54
 
46
55
  /** Unstamped legacy rows report alive: only the freshness window judges them. */
@@ -211,6 +220,10 @@ export function normalizeAgentRoute(routeLike) {
211
220
  model,
212
221
  effort: clean(routeLike?.effort) || undefined,
213
222
  fast: routeLike?.fast === true,
223
+ ...(routeLike?.modelParameters && typeof routeLike.modelParameters === 'object'
224
+ ? { modelParameters: { ...routeLike.modelParameters } }
225
+ : {}),
226
+ ...(Number(routeLike?.contextPercent) > 0 ? { contextPercent: Number(routeLike.contextPercent) } : {}),
214
227
  };
215
228
  }
216
229
 
@@ -78,9 +78,11 @@ function compactOps(batch) {
78
78
  for (const [key, json] of op.set) slot.final.set(key, json);
79
79
  });
80
80
  }
81
- return slots.map((slot) =>
82
- !slot ? null : slot.add ? { add: slot.add } : { del: slot.del, set: slot.final }
83
- );
81
+ return slots.map((slot) => {
82
+ if (!slot) return null;
83
+ if (slot.add) return { add: slot.add };
84
+ return { del: slot.del, set: slot.final };
85
+ });
84
86
  }
85
87
 
86
88
  function replayOps(ops, args) {
@@ -132,12 +134,7 @@ export function createIndexWriteQueue({ file, rewrite, readDoc, onPersisted = ()
132
134
  async function persist(batch) {
133
135
  for (let attempt = 0; ; attempt += 1) {
134
136
  try {
135
- await updateJsonAtomic(
136
- file,
137
- (cur) =>
138
- rewrite(cur, (...args) => replayBatch(batch, args)),
139
- { lock: true }
140
- );
137
+ await updateJsonAtomic(file, (cur) => rewrite(cur, (...args) => replayBatch(batch, args)), { lock: true });
141
138
  return;
142
139
  } catch {
143
140
  if (attempt >= RETRY_DELAYS_MS.length) return; // dropped, like the sync writer's swallowed failure
@@ -184,12 +181,10 @@ export function createIndexWriteQueue({ file, rewrite, readDoc, onPersisted = ()
184
181
  clearTimer();
185
182
  pending = [];
186
183
  try {
187
- updateJsonAtomicSync(
188
- file,
189
- (cur) =>
190
- rewrite(cur, (...args) => replayBatch(ops, args)),
191
- { lock: true, timeoutMs: EXIT_LOCK_TIMEOUT_MS }
192
- );
184
+ updateJsonAtomicSync(file, (cur) => rewrite(cur, (...args) => replayBatch(ops, args)), {
185
+ lock: true,
186
+ timeoutMs: EXIT_LOCK_TIMEOUT_MS,
187
+ });
193
188
  } catch {
194
189
  pending = ops;
195
190
  return false;
@@ -27,5 +27,10 @@ export function createLeadReapTimers({ removeRow }) {
27
27
  reapTimers.set(sessionId, handle);
28
28
  }
29
29
 
30
- return { cancel, schedule };
30
+ function cancelAll() {
31
+ for (const handle of reapTimers.values()) clearTimeout(handle);
32
+ reapTimers.clear();
33
+ }
34
+
35
+ return { cancel, cancelAll, schedule };
31
36
  }
@@ -117,13 +117,31 @@ export function createLeadWorkerIndex({ dataDir, cfgMod, workerRowFromSession })
117
117
  }
118
118
 
119
119
  recoverStaleLeadRows();
120
- registerExitFlush(() => {
120
+ function flushLeadIndexOnExit() {
121
121
  flushActiveLeadRows();
122
122
  // Writes are persisted by an async queue; the loop is gone at exit.
123
123
  index.flushSync();
124
- });
124
+ }
125
+ const unregisterExitFlush = registerExitFlush(flushLeadIndexOnExit);
126
+ let disposed = false;
127
+
128
+ /** Persist queued rows, drop owned reap timers, unregister. `settle` (a real
129
+ * teardown) also idles this runtime's own active Lead rows; a dispose that
130
+ * keeps background work (idle eviction) leaves them for the next owner. */
131
+ function dispose({ settle = false } = {}) {
132
+ if (disposed) return;
133
+ disposed = true;
134
+ try {
135
+ if (settle) flushActiveLeadRows();
136
+ index.flushSync();
137
+ } finally {
138
+ reaps.cancelAll();
139
+ unregisterExitFlush();
140
+ }
141
+ }
125
142
 
126
143
  return {
144
+ dispose,
127
145
  leadWorkerIndexPath: index.path,
128
146
  readLeadWorkerRows: index.read,
129
147
  /** Resolves once every queued Lead index write is on disk. */
@@ -8,6 +8,7 @@ import { presetKey, writeAgentStatuslineRoute } from '../helpers.mjs';
8
8
  import { resolveAgentWatchdogPolicy } from '../../../../runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs';
9
9
  import { prepareAgentSession } from '../../../../runtime/agent/orchestrator/agent-runtime/session-builder.mjs';
10
10
  import { getProvider } from '../../../../runtime/agent/orchestrator/providers/registry.mjs';
11
+ import { resolveRouteContextState } from '../../../route-state.mjs';
11
12
  import { createSpawnPlanner } from './spawn-plan.mjs';
12
13
 
13
14
  /** The route fields every worker-row and tag record carries. */
@@ -22,9 +23,9 @@ export function presetDescriptor(agent, preset, presetName) {
22
23
  };
23
24
  }
24
25
 
25
- // Spawn prewarm builds the materialized stable prompt and keeps the resulting
26
- // Codex-style client handle reserved for the first turn. Fire-and-forget:
27
- // failures fall back to the lazy per-send handshake.
26
+ // Spawn prewarm opens the session's pooled socket ahead of the first turn
27
+ // (connection only). Fire-and-forget: failures fall back to the lazy
28
+ // per-send handshake.
28
29
  // MIXDOG_AGENT_SPAWN_WS_PREWARM=0 disables.
29
30
  function maybePrewarmSpawnTransport(plan, session) {
30
31
  if (process.env.MIXDOG_AGENT_SPAWN_WS_PREWARM === '0') return;
@@ -80,14 +81,21 @@ export function createSpawnPreparer({
80
81
  }
81
82
 
82
83
  async function createSpawnedSession(plan, spec, prepState) {
84
+ // A sub-100 context share needs the window it selects; a percent alone
85
+ // keeps the full served window.
86
+ const sessionSpec = { ...spec };
87
+ if (plan.preset.contextPercent) {
88
+ const { contextPercent, selectedContextWindow } = resolveRouteContextState(plan.preset, null);
89
+ Object.assign(sessionSpec, { contextPercent, selectedContextWindow });
90
+ }
83
91
  if (sessionSurface?.canonical === true && typeof sessionSurface.createChild === 'function') {
84
- return sessionSurface.createChild({ spec, prompt: plan.prompt, tag: plan.tag });
92
+ return sessionSurface.createChild({ spec: sessionSpec, prompt: plan.prompt, tag: plan.tag });
85
93
  }
86
94
  await ensureProvider(plan.config, plan.preset.provider);
87
95
  if (prepState?.timedOut) {
88
96
  throw new Error('agent spawn prep timed out before session bind');
89
97
  }
90
- return prepareAgentSession(spec);
98
+ return prepareAgentSession(sessionSpec);
91
99
  }
92
100
 
93
101
  async function prepareSpawnInProcess(args, callerCwd = null, context = {}, prepState = null) {
@@ -116,5 +124,5 @@ export function createSpawnPreparer({
116
124
  return prepareSpawnInProcess(args, callerCwd, context, prepState);
117
125
  }
118
126
 
119
- return { prepareSpawn, prepareSpawnInProcess };
127
+ return { prepareSpawn, prepareSpawnInProcess, createSpawnedSession };
120
128
  }
@@ -42,6 +42,8 @@ export function resolveAgentSpawnPreset(config, args = {}) {
42
42
  model: agentRoute.model,
43
43
  effort: agentRoute.effort,
44
44
  fast: agentRoute.fast === true,
45
+ ...(agentRoute.modelParameters ? { modelParameters: agentRoute.modelParameters } : {}),
46
+ ...(agentRoute.contextPercent ? { contextPercent: agentRoute.contextPercent } : {}),
45
47
  tools: 'full',
46
48
  },
47
49
  };
@@ -23,12 +23,22 @@ export function createTagRegistry({ dataDir, cfgMod, mgr }) {
23
23
  tagCwds: tagMaps.tagCwds,
24
24
  });
25
25
  const { readWorkerRows, upsertWorkerSessionDeferred, removeWorkerRow, refreshTagsFromIndex } = index;
26
- const { upsertLeadSession } = createLeadWorkerIndex({
26
+ const leadIndex = createLeadWorkerIndex({
27
27
  dataDir,
28
28
  cfgMod,
29
29
  workerRowFromSession: index.workerRowFromSession,
30
30
  });
31
31
 
32
+ const { upsertLeadSession } = leadIndex;
33
+
34
+ function dispose(options) {
35
+ try {
36
+ index.dispose();
37
+ } finally {
38
+ leadIndex.dispose(options);
39
+ }
40
+ }
41
+
32
42
  function getLiveSession(sessionId) {
33
43
  if (!sessionId) return null;
34
44
  const session = mgr.getSession(sessionId);
@@ -84,6 +94,7 @@ export function createTagRegistry({ dataDir, cfgMod, mgr }) {
84
94
  reaper.recoverTerminalReaps();
85
95
 
86
96
  return {
97
+ dispose,
87
98
  readAllTagTombstones: index.readAllTagTombstones,
88
99
  readTagTombstones: index.readTagTombstones,
89
100
  readWorkerRows,
@@ -128,9 +128,25 @@ export function createWorkerIndex({ dataDir, cfgMod, mgr, tags, tagAgents, tagCw
128
128
  }
129
129
 
130
130
  recoverStaleWorkerRows();
131
- registerExitFlush(flushWorkerIndexOnExit);
131
+ const unregisterExitFlush = registerExitFlush(flushWorkerIndexOnExit);
132
+ let disposed = false;
133
+
134
+ /** Persist queued rows, then release the exit registration. Active rows are
135
+ * NOT settled: they are keyed by process pid, which every inline runtime in
136
+ * the daemon shares, so settling here would idle other runtimes' workers. */
137
+ function dispose() {
138
+ if (disposed) return;
139
+ disposed = true;
140
+ try {
141
+ batch.flush();
142
+ store.flushSync();
143
+ } finally {
144
+ unregisterExitFlush();
145
+ }
146
+ }
132
147
 
133
148
  return {
149
+ dispose,
134
150
  workerIndexPath: () => file,
135
151
  invalidateWorkerRowsCache: store.invalidate,
136
152
  readAllWorkerRows: store.readAll,
@@ -147,5 +147,6 @@ export function createStandaloneAgent({
147
147
  recoverWorkers,
148
148
  upsertLeadSession: registry.upsertLeadSession,
149
149
  closeAll: closeFlow.closeAll,
150
+ dispose: (options) => registry.dispose(options),
150
151
  };
151
152
  }