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
@@ -14,13 +14,26 @@ import {
14
14
  } from '../runtime/shared/provider-accounts.mjs';
15
15
 
16
16
  const MAX_MODEL_LIMIT = 50;
17
+ const SNAPSHOT_REUSE_MS = 1000;
18
+ const SNAPSHOT_CACHE_LIMIT = 8;
17
19
 
18
20
  const quotaText = (value) => (typeof value === 'string' ? value.slice(0, 200) : '');
19
21
 
20
22
  // What the ledger cannot know: each subscription account's label and place in
21
23
  // its provider's account pool, the order the account picker lists them in.
22
- function labelQuotaHistory(history, accountPool) {
24
+ function labelQuotaHistory(history, accountPool, accountEmails) {
23
25
  const rosters = new Map();
26
+ const emails = new Map();
27
+ const emailsOf = (provider) => {
28
+ if (!emails.has(provider)) {
29
+ try {
30
+ emails.set(provider, accountEmails(provider) || {});
31
+ } catch {
32
+ emails.set(provider, {});
33
+ }
34
+ }
35
+ return emails.get(provider);
36
+ };
24
37
  const rosterOf = (provider) => {
25
38
  if (!ACCOUNT_PROVIDERS.includes(provider)) return [];
26
39
  if (!rosters.has(provider)) {
@@ -37,7 +50,19 @@ function labelQuotaHistory(history, accountPool) {
37
50
  subscriptions: (history.subscriptions || []).map((row) => {
38
51
  const roster = rosterOf(row.provider);
39
52
  const rank = roster.findIndex((entry) => entry.id === row.account);
40
- return { ...row, accountLabel: roster[rank]?.label || '', accountRank: rank < 0 ? null : rank };
53
+ const email = rank < 0 ? '' : quotaText(emailsOf(row.provider)[row.account]);
54
+ // History of an account that left the roster stays stored, but the
55
+ // picker must not offer it. The implicit `default` account of a provider
56
+ // with no stored roster is still current.
57
+ const inRoster =
58
+ !ACCOUNT_PROVIDERS.includes(row.provider) || rank >= 0 || (row.account === 'default' && !roster.length);
59
+ return {
60
+ ...row,
61
+ accountLabel: roster[rank]?.label || '',
62
+ accountRank: rank < 0 ? null : rank,
63
+ accountInRoster: inRoster,
64
+ ...(email ? { accountEmail: email } : {}),
65
+ };
41
66
  }),
42
67
  };
43
68
  }
@@ -122,10 +147,13 @@ export function createUsageStatsApi({
122
147
  ledger = getUsageLedger,
123
148
  importHistory = importUsageHistory,
124
149
  accountPool = readProviderAccountPool,
150
+ // provider -> { [accountId]: email } for the picker's secondary text.
151
+ accountEmails = () => ({}),
125
152
  getSessionId = () => null,
126
153
  } = {}) {
127
154
  let importing = null;
128
155
  let imported = false;
156
+ const snapshots = new Map();
129
157
  // Until the first instrumented send establishes the cutover, the legacy
130
158
  // writer may still be active. A previous import is not a live subscription.
131
159
  async function ensureHistoryImported(store, liveSince) {
@@ -156,6 +184,15 @@ export function createUsageStatsApi({
156
184
  const period = usagePeriodFor(options, now);
157
185
  // The rollup query runs off the event loop (usage-rollup-worker.mjs).
158
186
  const rollup = await store.rollupAsync(usageRollupQuery(period));
187
+ // The ledger returns the same rollup object while nothing was committed
188
+ // (and while a rolling window lost no record), so identical back-to-back
189
+ // requests over it are one answer; the clock bound keeps the snapshot's
190
+ // time-relative fields from ageing.
191
+ const cacheKey = JSON.stringify([options, liveSince]);
192
+ const held = snapshots.get(cacheKey);
193
+ if (held && held.rollup === rollup && now - held.now >= 0 && now - held.now < SNAPSHOT_REUSE_MS) {
194
+ return held.snapshot;
195
+ }
159
196
  const snapshot = usageStatsSnapshot({
160
197
  rollup,
161
198
  days: normalizeDays(options?.days),
@@ -170,6 +207,9 @@ export function createUsageStatsApi({
170
207
  });
171
208
  snapshot.coverage.ledger = true;
172
209
  snapshot.coverage.liveSince = liveSince || null;
210
+ snapshots.delete(cacheKey);
211
+ snapshots.set(cacheKey, { rollup, now, snapshot });
212
+ if (snapshots.size > SNAPSHOT_CACHE_LIMIT) snapshots.delete(snapshots.keys().next().value);
173
213
  return snapshot;
174
214
  },
175
215
 
@@ -216,7 +256,7 @@ export function createUsageStatsApi({
216
256
  toMs: period?.toMs ?? null,
217
257
  now,
218
258
  });
219
- return labelQuotaHistory(period ? { ...history, period } : history, accountPool);
259
+ return labelQuotaHistory(period ? { ...history, period } : history, accountPool, accountEmails);
220
260
  },
221
261
  };
222
262
  }
@@ -4,21 +4,35 @@ import { clean } from '../../runtime/agent/orchestrator/runtime-core/session-tex
4
4
  import { hasOwn } from '../../runtime/shared/object.mjs';
5
5
  import { serializeFrontmatterDoc } from '../../runtime/shared/markdown-frontmatter.mjs';
6
6
  import { isHiddenAgent } from '../../runtime/agent/orchestrator/internal-agents.mjs';
7
- import { AGENT_DELETED_MARKER, FIXED_AGENT_SLOTS, availableAgentId, clearAgentDefinitionCache } from '../../runtime/agent/orchestrator/runtime-core/workflow.mjs';
7
+ import {
8
+ AGENT_DELETED_MARKER,
9
+ FIXED_AGENT_SLOTS,
10
+ availableAgentId,
11
+ clearAgentDefinitionCache,
12
+ } from '../../runtime/agent/orchestrator/runtime-core/workflow.mjs';
8
13
  import {
9
14
  canonicalizeAgentRouteStorage,
10
15
  isAgentDisabled,
11
16
  withAgentDisabled,
12
17
  } from '../../runtime/shared/agent-route-config.mjs';
13
18
  import { agentEditorId, effectiveAgentRoute, oneLine, resolveDataDir } from './shared.mjs';
19
+ import { absorbSaveEqualToShipped } from '../../runtime/shared/shipped-definitions.mjs';
20
+ import { STANDALONE_ROOT } from '../runtime-paths.mjs';
14
21
 
15
22
  const isFixedAgent = (id) => FIXED_AGENT_SLOTS.some((agent) => agent.id === id);
16
23
  const hasUserAgentFile = (dataDir, id) => existsSync(join(dataDir, 'agents', id, 'AGENT.md'));
17
24
 
18
- function writeAgentFiles(dir, { name, description, body }) {
25
+ // Frontmatter the editor does not show (e.g. `permission`), taken from the
26
+ // definition in effect: the user's own copy if any, else the shipped one.
27
+ function hiddenFrontmatter(definition) {
28
+ const { name: _name, description: _description, ...rest } = definition?.frontmatter || {};
29
+ return rest;
30
+ }
31
+
32
+ function writeAgentFiles(dir, { name, description, body, extra = {} }) {
19
33
  const meta = { name, ...(description ? { description } : {}) };
20
34
  mkdirSync(dir, { recursive: true });
21
- writeFileSync(join(dir, 'AGENT.md'), serializeFrontmatterDoc(meta, body));
35
+ writeFileSync(join(dir, 'AGENT.md'), serializeFrontmatterDoc({ ...meta, ...extra }, body));
22
36
  // loadAgentDefinition prefers the manifest for name/description.
23
37
  writeFileSync(join(dir, 'agent.json'), `${JSON.stringify(meta, null, 2)}\n`);
24
38
  rmSync(join(dir, AGENT_DELETED_MARKER), { force: true });
@@ -99,8 +113,20 @@ export function createAgentEditorApi(deps) {
99
113
  if (!body) throw new Error('AGENT.md body must not be empty');
100
114
  const dataDir = resolveDataDir(deps);
101
115
  const { id, name, description } = resolveSaveTarget(payload, dataDir);
102
- const existed = Boolean(loadAgentDefinition(dataDir, id));
103
- writeAgentFiles(join(dataDir, 'agents', id), { name: name || id, description, body });
116
+ const current = loadAgentDefinition(dataDir, id);
117
+ const existed = Boolean(current);
118
+ const definition = { name: name || id, description, body };
119
+ // Equal to the shipped agent: keep no copy so it follows the shipped version.
120
+ const absorbed = absorbSaveEqualToShipped({
121
+ rootDir: deps.rootDir ?? STANDALONE_ROOT,
122
+ dataDir,
123
+ dir: 'agents',
124
+ id,
125
+ entry: 'AGENT.md',
126
+ files: ['AGENT.md', 'agent.json'],
127
+ definition,
128
+ });
129
+ if (!absorbed) writeAgentFiles(join(dataDir, 'agents', id), { ...definition, extra: hiddenFrontmatter(current) });
104
130
  clearAgentDefinitionCache(id);
105
131
  // A newly created agent starts enabled; a stale roster entry left by an
106
132
  // earlier agent of the same id must not disable it.
@@ -3,7 +3,7 @@ import { hasOwn } from '../../runtime/shared/object.mjs';
3
3
  import { isHiddenAgent } from '../../runtime/agent/orchestrator/internal-agents.mjs';
4
4
  import { normalizeWorkflowRoute } from '../../runtime/agent/orchestrator/runtime-core/workflow.mjs';
5
5
  import { ensureProviderEnabled } from '../../runtime/agent/orchestrator/runtime-core/config-helpers.mjs';
6
- import { fastCapableFor } from '../../runtime/agent/orchestrator/runtime-core/model-capabilities.mjs';
6
+ import { selectionFastCapable } from '../route-state.mjs';
7
7
  import { canonicalizeAgentRouteStorage, withAgentDisabled } from '../../runtime/shared/agent-route-config.mjs';
8
8
  import { agentEditorId } from './shared.mjs';
9
9
 
@@ -43,16 +43,20 @@ export function createAgentRouteApi(deps) {
43
43
  clean(selectedRoute.provider) === clean(stored.provider) && clean(selectedRoute.model) === clean(stored.model);
44
44
  const inheritedEffort = sameModel ? stored.effort || null : null;
45
45
  const inheritedModelParameters = sameModel ? stored.modelParameters || {} : {};
46
+ const inheritedContextPercent = sameModel ? stored.contextPercent : undefined;
46
47
  selectedRoute = {
47
48
  ...selectedRoute,
48
49
  effort: requested.effort !== undefined ? selectedRoute.effort : inheritedEffort,
49
50
  fast: requested.fast !== undefined ? selectedRoute.fast === true : sameModel && stored.fast === true,
50
51
  modelParameters:
51
52
  requested.modelParameters !== undefined ? selectedRoute.modelParameters : inheritedModelParameters,
53
+ // resolveRoute reads contextPercent from Main's modelSettings bucket;
54
+ // an agent route owns its own.
55
+ contextPercent: requested.contextPercent !== undefined ? requested.contextPercent : inheritedContextPercent,
52
56
  };
53
57
  await ensureProvidersReady(ensureProviderEnabled(getConfig(), selectedRoute.provider));
54
58
  const modelMeta = await lookupModelMeta(selectedRoute.provider, selectedRoute.model);
55
- const fastCapable = fastCapableFor(
59
+ const fastCapable = selectionFastCapable(
56
60
  selectedRoute.provider,
57
61
  modelMeta,
58
62
  selectedRoute.effort,
@@ -1,8 +1,15 @@
1
1
  import { join } from 'node:path';
2
2
  import { existsSync, mkdirSync, rmSync, writeFileSync } from 'node:fs';
3
3
  import { serializeFrontmatterDoc } from '../../runtime/shared/markdown-frontmatter.mjs';
4
- import { normalizeWorkflowId, workflowIdFromName, availableWorkflowId, DEFAULT_WORKFLOW_ID } from '../../runtime/agent/orchestrator/runtime-core/workflow.mjs';
4
+ import {
5
+ normalizeWorkflowId,
6
+ workflowIdFromName,
7
+ availableWorkflowId,
8
+ DEFAULT_WORKFLOW_ID,
9
+ } from '../../runtime/agent/orchestrator/runtime-core/workflow.mjs';
5
10
  import { oneLine, resolveDataDir } from './shared.mjs';
11
+ import { absorbSaveEqualToShipped } from '../../runtime/shared/shipped-definitions.mjs';
12
+ import { STANDALONE_ROOT } from '../runtime-paths.mjs';
6
13
 
7
14
  // Workflow packs: the catalog/active switch plus the editor surface (desktop
8
15
  // Workflows page). User packs live at <dataDir>/workflows/<id>/WORKFLOW.md;
@@ -75,12 +82,25 @@ export function createWorkflowPacksApi(deps) {
75
82
  if (!body) throw new Error('WORKFLOW.md body must not be empty');
76
83
  const name = oneLine(payload.name) || id;
77
84
  const description = oneLine(payload.description);
78
- const dir = join(resolveDataDir(deps), 'workflows', id);
79
- mkdirSync(dir, { recursive: true });
80
- writeFileSync(
81
- join(dir, 'WORKFLOW.md'),
82
- serializeFrontmatterDoc({ id, name, ...(description ? { description } : {}) }, body)
83
- );
85
+ const dataDir = resolveDataDir(deps);
86
+ // Equal to the shipped pack: keep no copy so it follows the shipped version.
87
+ const absorbed = absorbSaveEqualToShipped({
88
+ rootDir: deps.rootDir ?? STANDALONE_ROOT,
89
+ dataDir,
90
+ dir: 'workflows',
91
+ id,
92
+ entry: 'WORKFLOW.md',
93
+ files: ['WORKFLOW.md'],
94
+ definition: { name, description, body },
95
+ });
96
+ if (!absorbed) {
97
+ const dir = join(dataDir, 'workflows', id);
98
+ mkdirSync(dir, { recursive: true });
99
+ writeFileSync(
100
+ join(dir, 'WORKFLOW.md'),
101
+ serializeFrontmatterDoc({ id, name, ...(description ? { description } : {}) }, body)
102
+ );
103
+ }
84
104
  return getWorkflowPack(id);
85
105
  }
86
106
 
@@ -7,6 +7,9 @@
7
7
  export function createDaemonBootCoordinator({
8
8
  prewarmKeychain,
9
9
  recoverActiveGoals,
10
+ // Starts the quota auto-resume clock once the keychain is warm (usage
11
+ // readings need provider credentials); overdue resumes run right away.
12
+ startQuotaResume = null,
10
13
  // Catalog module imports (session summaries, projects) cost ~1.1s cold and
11
14
  // used to land on the FIRST rail click. They ride the background lane
12
15
  // after Goal recovery, behind a short delay so the user's first action —
@@ -58,6 +61,13 @@ export function createDaemonBootCoordinator({
58
61
  `active Goal recovery found=${result.found} resumed=${result.resumed}` +
59
62
  ` skipped=${result.skipped} failed=${result.failed}`
60
63
  );
64
+ if (typeof startQuotaResume === 'function') {
65
+ try {
66
+ startQuotaResume();
67
+ } catch (error) {
68
+ log(`quota resume start failed (non-fatal): ${error?.message || error}`);
69
+ }
70
+ }
61
71
  if (typeof prewarmCatalogs === 'function') {
62
72
  await new Promise((resolve) => delay(resolve, catalogDelayMs));
63
73
  await measure('catalog-prewarm', prewarmCatalogs).catch((error) => {
@@ -17,6 +17,7 @@ export function createDesktopRuntime({ getLocalSessionBridge }) {
17
17
  },
18
18
  loadProjects: () => import('../runtime/shared/projects.mjs'),
19
19
  loadSessionStore: () => import('../runtime/agent/orchestrator/session/store-summary-reader.mjs'),
20
+ loadSessionSearch: () => import('../runtime/session-search/session-search-db.mjs'),
20
21
  loadStatuslineSegments: () => import('../runtime/shared/statusline/statusline-segments.mjs'),
21
22
  loadConfig: () => import('../runtime/shared/config.mjs'),
22
23
  loadDocumentPreview: () => import('../runtime/office/pdf/document-preview.mjs'),
@@ -0,0 +1,9 @@
1
+ /** Whether self-shutdown must wait for in-flight work. A forced replacement
2
+ * never waits: shutdown() aborts busy sessions, service calls and agent runs. */
3
+ export function drainDeferral(work, { force = false } = {}) {
4
+ if (force) return null;
5
+ const { activeCalls = 0, queuedCalls = 0, busySessions = 0, busyMemoryAgents = 0 } = work || {};
6
+ if (activeCalls > 0 || queuedCalls > 0) return 'calls';
7
+ if (busySessions > 0 || busyMemoryAgents > 0) return 'busy';
8
+ return null;
9
+ }
@@ -6,7 +6,10 @@
6
6
  //
7
7
  // Inputs: `desktopRuntime` (lazy module loaders) and `dataDir` (goal
8
8
  // snapshots). Output: the read-only half of the session-service options.
9
- import { listStoredActiveGoalSessionIds, readStoredGoalSnapshot } from '../runtime/agent/orchestrator/runtime-core/goal-runtime.mjs';
9
+ import {
10
+ listStoredActiveGoalSessionIds,
11
+ readStoredGoalSnapshot,
12
+ } from '../runtime/agent/orchestrator/runtime-core/goal-runtime.mjs';
10
13
 
11
14
  export function createStoredSessionViews({ desktopRuntime, dataDir }) {
12
15
  return {
@@ -31,14 +34,10 @@ export function createStoredSessionViews({ desktopRuntime, dataDir }) {
31
34
  const store = await desktopRuntime.loadSessionStore();
32
35
  const metadata = await store.readStoredSessionTranscript?.(sessionId, { metadataOnly: true });
33
36
  if (!metadata) return null;
34
- const [{ createRuntimeReviewApi }, { turnReviewReply }] = await Promise.all([
35
- import('../session-runtime/runtime-review-api.mjs'),
36
- import('../runtime/shared/turn-review-reply.mjs'),
37
- ]);
37
+ const { createRuntimeReviewApi } = await import('../session-runtime/runtime-review-api.mjs');
38
38
  const review = createRuntimeReviewApi({ getCwd: () => metadata.cwd || '', getSessionId: () => sessionId });
39
- return action === 'getSessionReviewDiff'
40
- ? review.getSessionReviewDiff()
41
- : turnReviewReply(review.getTurnReviewDiff, args[0]);
39
+ // The runtime review API answers `known`/`summary` itself (turnReviewReply).
40
+ return action === 'getSessionReviewDiff' ? review.getSessionReviewDiff() : review.getTurnReviewDiff(args[0]);
42
41
  },
43
42
  forgetStoredSession: async (sessionId) => {
44
43
  const store = await desktopRuntime.loadSessionStore();
@@ -54,18 +54,23 @@ import {
54
54
  } from '../runtime/agent/orchestrator/providers/stream-json-pool.mjs';
55
55
  import { createAgentDispatchBroker } from './agent-dispatch-broker.mjs';
56
56
  import { createChannelTransport } from './channel-transport.mjs';
57
+ import { drainDeferral } from './daemon-drain-policy.mjs';
57
58
  import { createChannelSessionRouter } from '../session-runtime/services/channel-session-router.mjs';
58
59
  import { createSessionTransport } from './session-transport.mjs';
59
60
  import { createSessionService } from './session-service.mjs';
60
61
  import { createLocalSessionBridge } from './daemon-local-session-bridge.mjs';
61
62
  import { createStoredSessionViews } from './daemon-stored-session-views.mjs';
63
+ import * as quotaResumeStore from '../runtime/shared/quota-resume-store.mjs';
62
64
  import { createInlineSessionRuntimeHost } from './session-runtime-inline-host.mjs';
63
65
  import { getStandaloneMemoryRuntime } from '../session-runtime/services/memory-runtime-proxy.mjs';
64
66
  import { createBootPhaseProfiler } from './boot-phase-profiler.mjs';
65
67
  import { createDaemonBootCoordinator } from './daemon-boot-coordinator.mjs';
66
68
  import { createDaemonLog } from './daemon-log.mjs';
67
69
  import { daemonCrashCaptureDir } from '../session-runtime/services/daemon-crash-capture/paths.mjs';
68
- import { installDaemonExitRecorder, reconcileLostDaemonCaptures } from '../session-runtime/services/daemon-crash-capture/daemon-exit-record.mjs';
70
+ import {
71
+ installDaemonExitRecorder,
72
+ reconcileLostDaemonCaptures,
73
+ } from '../session-runtime/services/daemon-crash-capture/daemon-exit-record.mjs';
69
74
  import { createDaemonTelemetry } from './daemon-telemetry.mjs';
70
75
  import { createLagProfiler } from './daemon-lag-profiler.mjs';
71
76
  import { createChannelsRuntimeLoader } from './daemon-channels-loader.mjs';
@@ -128,8 +133,10 @@ let daemonTelemetry = null;
128
133
 
129
134
  function registerMemoryRuntimeLazy() {
130
135
  // Register the shared proxy immediately so daemon shutdown owns its
131
- // lifecycle, but keep the isolated process off the startup path. A real
132
- // memory call or the post-connect idle warmup starts the exact singleton.
136
+ // lifecycle, but keep the isolated process off the startup path. The first
137
+ // real memory call (memory/recall tools, the Memory install) starts the
138
+ // singleton; nothing warms it at boot. The PG cluster itself usually starts
139
+ // earlier: the channels schedules/webhooks stores open it at boot.
133
140
  if (process.env.MIXDOG_DAEMON_SKIP_MEMORY === '1') {
134
141
  log('memory runtime skipped (MIXDOG_DAEMON_SKIP_MEMORY=1)');
135
142
  return;
@@ -347,7 +354,11 @@ function maybeSelfShutdown(reason) {
347
354
  return;
348
355
  }
349
356
  const { activeCalls, queuedCalls, busySessions, busyMemoryAgents } = inFlightWork();
350
- if (activeCalls > 0 || queuedCalls > 0) {
357
+ const deferral = drainDeferral(
358
+ { activeCalls, queuedCalls, busySessions, busyMemoryAgents },
359
+ { force: replacementRequested?.force === true }
360
+ );
361
+ if (deferral === 'calls') {
351
362
  log(`shutdown deferred (${reason}): activeCalls=${activeCalls} queuedCalls=${queuedCalls}`);
352
363
  if (!shutdownRecheckTimer) {
353
364
  shutdownRecheckTimer = setTimeout(() => {
@@ -360,7 +371,7 @@ function maybeSelfShutdown(reason) {
360
371
  }
361
372
  // A turn in flight outlives every view — closing the app or the terminal is
362
373
  // not a reason to abandon work the daemon is still running.
363
- if (busySessions > 0 || busyMemoryAgents > 0) {
374
+ if (deferral === 'busy') {
364
375
  log(`shutdown deferred (${reason}): busySessions=${busySessions}` + ` memoryAgents=${busyMemoryAgents}`);
365
376
  if (!shutdownRecheckTimer) {
366
377
  shutdownRecheckTimer = setTimeout(() => {
@@ -378,8 +389,10 @@ function maybeSelfShutdown(reason) {
378
389
  void shutdown(reason);
379
390
  }
380
391
 
381
- function requestDaemonReplacement({ protocol, revision, version } = {}) {
392
+ function requestDaemonReplacement({ protocol, revision, version, force } = {}) {
393
+ const forced = force === true;
382
394
  const requested = {
395
+ force: forced,
383
396
  protocol: Number(protocol),
384
397
  revision: Math.max(0, Number(revision) || 0),
385
398
  version: String(version || '0.0.0'),
@@ -391,12 +404,14 @@ function requestDaemonReplacement({ protocol, revision, version } = {}) {
391
404
  if (
392
405
  replacementRequested &&
393
406
  requested.revision === replacementRequested.revision &&
394
- requested.version === replacementRequested.version
407
+ requested.version === replacementRequested.version &&
408
+ !(forced && replacementRequested.force !== true)
395
409
  )
396
410
  return true;
397
411
  replacementRequested = requested;
398
412
  const reason = `daemon replacement by revision/build ${requested.revision}/${requested.version}`;
399
- log(`${reason} requested — preserving clients until live work settles`);
413
+ if (forced) log(`${reason} FORCED — aborting in-flight work (sessions, service calls, agent runs)`);
414
+ else log(`${reason} requested — preserving clients until live work settles`);
400
415
  sessionTransport?.beginDrain?.(reason);
401
416
  transport?.beginDrain?.(reason);
402
417
  maybeSelfShutdown(reason);
@@ -607,6 +622,13 @@ async function main() {
607
622
  // The daemon owns prompt attachments; its census runs off the boot path
608
623
  // (first attempt after the store's start delay, then per its interval).
609
624
  void import('../runtime/attachments/store.mjs').then((store) => store.startAttachmentGc()).catch(() => {});
625
+ // Session-search backfill: once per run, well after boot, low priority.
626
+ const sessionSearchBackfillTimer = setTimeout(() => {
627
+ void import('../runtime/session-search/session-search-ingest.mjs')
628
+ .then((search) => search.backfillSessionSearch())
629
+ .catch((error) => log(`session-search backfill failed: ${error?.message || error}`));
630
+ }, 60_000);
631
+ sessionSearchBackfillTimer.unref?.();
610
632
  // The first session per repository would otherwise run `git status` and
611
633
  // `git check-ignore` synchronously while composing its prompt. Registered
612
634
  // projects (a small JSON list, most recently selected first) are the cwds
@@ -691,6 +713,7 @@ async function main() {
691
713
  const bootCoordinator = createDaemonBootCoordinator({
692
714
  prewarmKeychain: () => sessionRuntimeHost.prewarmKeychain(),
693
715
  recoverActiveGoals: () => sessionService.recoverActiveGoals(),
716
+ startQuotaResume: () => sessionService.startQuotaResume(),
694
717
  // The modules every rail catalog request needs (session summaries,
695
718
  // projects, statusline segments) — warm them once the desktop is up so
696
719
  // the first Sessions/Projects click reads a hot module graph.
@@ -717,6 +740,11 @@ async function main() {
717
740
  maybeSelfShutdown('remote clients changed');
718
741
  },
719
742
  onDesktopReady: () => bootCoordinator.notifyDesktopReady(),
743
+ quotaResumeStore,
744
+ readQuotaUsable: async (provider, model) => {
745
+ const { providerQuotaUsable } = await import('../runtime/agent/orchestrator/providers/quota-reading.mjs');
746
+ return providerQuotaUsable(provider, model);
747
+ },
720
748
  log,
721
749
  });
722
750
  sessionTransport = createSessionTransport({
@@ -18,6 +18,8 @@ import { createAgentJobFeed } from '../tui/session/agent-job-feed.mjs';
18
18
  import { createContextState } from '../tui/session/context-state.mjs';
19
19
  import { createSessionFlow } from '../tui/session/session-flow.mjs';
20
20
  import { createRunTurn } from '../tui/session/turn.mjs';
21
+ import { createQuotaResumeLane } from '../tui/session/quota-resume.mjs';
22
+ import { publicQuotaResume, quotaResumeEntry } from '../runtime/shared/quota-resume-store.mjs';
21
23
  import { createSessionApi } from '../tui/session/session-api.mjs';
22
24
  import { createSessionDraftStore } from '../tui/session/draft-store.mjs';
23
25
  import { createInitialSessionState } from '../tui/session/initial-state.mjs';
@@ -197,6 +199,8 @@ export async function createLocalSessionRuntime({
197
199
  effort,
198
200
  fast,
199
201
  modelParameters,
202
+ contextPercent,
203
+ selectedContextWindow,
200
204
  toolMode = 'full',
201
205
  remote = false,
202
206
  cwd,
@@ -223,6 +227,8 @@ export async function createLocalSessionRuntime({
223
227
  effort,
224
228
  fast,
225
229
  modelParameters,
230
+ contextPercent,
231
+ selectedContextWindow,
226
232
  toolMode,
227
233
  remote,
228
234
  ...(cwd ? { cwd } : {}),
@@ -235,6 +241,8 @@ export async function createLocalSessionRuntime({
235
241
  const stateStartedAt = performance.now();
236
242
  const flags = {
237
243
  disposed: false,
244
+ // Canonical-close execution fence: 'open' | 'closing' | 'terminal'.
245
+ admission: 'open',
238
246
  draining: false,
239
247
  autoClearRunning: false,
240
248
  pendingSessionReset: false,
@@ -272,6 +280,7 @@ export async function createLocalSessionRuntime({
272
280
  },
273
281
  getPendingSessionReset: () => flags.pendingSessionReset,
274
282
  getVisibleGoal: () => (visibleGoalStatus ? visibleGoalStatus() : runtime.goalStatus?.() || null),
283
+ getQuotaResume: () => publicQuotaResume(quotaResumeEntry(runtime.id)),
275
284
  });
276
285
  draft.state = createInitialSessionState({ runtime, runtimeCwd, baseRouteState });
277
286
  bootProfile('session:route-state-ready', { ms: (performance.now() - stateStartedAt).toFixed(1) });
@@ -368,6 +377,7 @@ export async function createLocalSessionRuntime({
368
377
  set,
369
378
  nextId,
370
379
  getDisposed: () => flags.disposed,
380
+ getAdmission: () => flags.admission || 'open',
371
381
  patchItem,
372
382
  enqueue: (...args) => bag.enqueue(...args),
373
383
  drain: (...args) => bag.drain(...args),
@@ -474,6 +484,7 @@ export async function createLocalSessionRuntime({
474
484
  })
475
485
  );
476
486
  visibleGoalStatus = bag.visibleGoalStatus;
487
+ Object.assign(bag, createQuotaResumeLane(bag));
477
488
  bag.runTurn = createRunTurn(bag);
478
489
  bag.doctor = { runDoctorChecks, formatDoctorReport };
479
490
  const api = createSessionApi(bag);
@@ -199,7 +199,41 @@ export function sessionDaemonCompatibility(
199
199
  return { status: 'compatible', ...details };
200
200
  }
201
201
 
202
- async function replaceLowerDaemon(discovery, initialHealth, { log }) {
202
+ /** Ask the running daemon to yield to this build immediately, aborting its
203
+ * in-flight work. Resolves true when the request was accepted. */
204
+ export async function forceDaemonUpgrade({ log = () => {} } = {}) {
205
+ const discovery = readSessionDiscovery();
206
+ if (!discovery) return false;
207
+ const result = await request({
208
+ port: discovery.port,
209
+ token: discovery.token,
210
+ method: 'POST',
211
+ path: '/upgrade',
212
+ body: {
213
+ protocol: SESSION_PROTOCOL,
214
+ revision: SESSION_REVISION,
215
+ version: runtimeVersion(),
216
+ force: true,
217
+ },
218
+ timeoutMs: 3_000,
219
+ control: true,
220
+ });
221
+ const accepted = result?.accepted === true;
222
+ log(`forced daemon upgrade ${accepted ? 'accepted' : 'not accepted'}`);
223
+ return accepted;
224
+ }
225
+
226
+ async function replaceLowerDaemon(discovery, initialHealth, { log, onUpgradeWait = null }) {
227
+ const info = { fromVersion: initialHealth?.version, toVersion: runtimeVersion() };
228
+ const notify = (state) => {
229
+ try {
230
+ onUpgradeWait?.({ state, ...info });
231
+ } catch {}
232
+ };
233
+ const done = () => {
234
+ notify('done');
235
+ return true;
236
+ };
203
237
  const configuredTimeoutMs = Number(process.env.MIXDOG_DAEMON_UPGRADE_TIMEOUT_MS);
204
238
  // A stuck older daemon (a worker that never finishes draining) must not hang
205
239
  // every newer client forever: the wait is always bounded, and the caller
@@ -226,17 +260,18 @@ async function replaceLowerDaemon(discovery, initialHealth, { log }) {
226
260
  });
227
261
  if (result?.accepted !== true) throw new Error('daemon replacement was not accepted');
228
262
  log(`waiting for daemon build ${initialHealth?.version || 'unknown'}` + ` to yield to ${runtimeVersion()}`);
263
+ notify('waiting');
229
264
  while (Date.now() < deadline) {
230
265
  const current = readSessionDiscovery();
231
- if (!current || Number(current.pid) !== Number(discovery.pid)) return true;
266
+ if (!current || Number(current.pid) !== Number(discovery.pid)) return done();
232
267
  const health = await probeSessionHealth({
233
268
  port: current.port,
234
269
  token: current.token,
235
270
  timeoutMs: 800,
236
271
  });
237
- if (!health || Number(health.pid) !== Number(discovery.pid)) return true;
272
+ if (!health || Number(health.pid) !== Number(discovery.pid)) return done();
238
273
  const compatibility = sessionDaemonCompatibility(health);
239
- if (compatibility.status === 'compatible' || compatibility.status === 'daemon-newer') return true;
274
+ if (compatibility.status === 'compatible' || compatibility.status === 'daemon-newer') return done();
240
275
  await delay(100);
241
276
  }
242
277
  const error = new Error('newer daemon build is still waiting for active work to finish');
@@ -285,14 +320,20 @@ export function spawnDaemonCandidate({ cwd, log, timeoutMs = 30_000, entry = dae
285
320
  }
286
321
 
287
322
  /** Spawn-or-attach discovery for the machine-global daemon. */
288
- export async function ensureDaemon({ cwd = process.cwd(), log = () => {}, attempts = 5, readyTimeoutMs = null } = {}) {
323
+ export async function ensureDaemon({
324
+ cwd = process.cwd(),
325
+ log = () => {},
326
+ attempts = 5,
327
+ readyTimeoutMs = null,
328
+ onUpgradeWait = null,
329
+ } = {}) {
289
330
  const configuredTimeoutMs = Number(process.env.MIXDOG_DAEMON_READY_TIMEOUT_MS);
290
331
  let requestedTimeoutMs = DEFAULT_DAEMON_READY_TIMEOUT_MS;
291
332
  if (Number.isFinite(Number(readyTimeoutMs)) && Number(readyTimeoutMs) > 0)
292
333
  requestedTimeoutMs = Number(readyTimeoutMs);
293
334
  else if (configuredTimeoutMs > 0) requestedTimeoutMs = configuredTimeoutMs;
294
335
  const timeoutMs = Math.max(1, requestedTimeoutMs);
295
- const deadline = Date.now() + timeoutMs;
336
+ let deadline = Date.now() + timeoutMs;
296
337
  const maxSpawnAttempts = Math.max(0, Math.floor(Number(attempts) || 0));
297
338
  let spawnAttempts = 0;
298
339
  let waitingOwnerPid = 0;
@@ -334,7 +375,10 @@ export async function ensureDaemon({ cwd = process.cwd(), log = () => {}, attemp
334
375
  return discovery;
335
376
  }
336
377
  if (compatibility.status === 'client-newer') {
337
- await replaceLowerDaemon(discovery, health, { log });
378
+ await replaceLowerDaemon(discovery, health, { log, onUpgradeWait });
379
+ // The older daemon's drain has its own bound; readiness of the
380
+ // successor gets a fresh budget instead of the one the drain spent.
381
+ deadline = Date.now() + timeoutMs;
338
382
  continue;
339
383
  }
340
384
  const err = new Error('daemon session protocol identity is invalid');
@@ -512,6 +556,7 @@ export async function shutdownDaemonForRuntimeRoot(root, options = {}) {
512
556
  export const createSession = createSessionProxyFactory({
513
557
  attachSession,
514
558
  ensureDaemon,
559
+ forceDaemonUpgrade,
515
560
  closeIdleConnections: () => {
516
561
  daemonCallAgent.destroy();
517
562
  daemonUrgentAgent.destroy();
@@ -25,6 +25,7 @@ export const SESSION_READ_ACTIONS = Object.freeze([
25
25
  'getProfile',
26
26
  'getProviderSetup',
27
27
  'getProviderAccounts',
28
+ 'getQuotaAutoResume',
28
29
  'getQuotaHistory',
29
30
  'getRecapSettings',
30
31
  'getWebSearchRoute',
@@ -95,6 +96,7 @@ export const SESSION_CONFIGURE_ACTIONS = Object.freeze([
95
96
  'deleteSchedule',
96
97
  'saveCustomProvider',
97
98
  'removeCustomProvider',
99
+ 'updateCustomProviderModel',
98
100
  'testCustomProvider',
99
101
  'discoverCustomProviderModels',
100
102
  'deleteSession',
@@ -115,6 +117,11 @@ export const SESSION_CONFIGURE_ACTIONS = Object.freeze([
115
117
  'reloadSkills',
116
118
  'rememberPromptHistory',
117
119
  'removeMcpServer',
120
+ 'continueSessionInModel',
121
+ 'scheduleQuotaResume',
122
+ 'cancelQuotaResume',
123
+ 'retryFailedTurn',
124
+ 'setQuotaAutoResume',
118
125
  'removeNotice',
119
126
  'removePlugin',
120
127
  'renameSessionTitle',
@@ -157,6 +164,7 @@ export const SESSION_CONFIGURE_ACTIONS = Object.freeze([
157
164
  'installLocalProviderModel',
158
165
  'startLocalProviderInstallation',
159
166
  'cancelLocalProviderInstallation',
167
+ 'discardLocalProviderInstallation',
160
168
  'setLocalProviderIdleTtl',
161
169
  'setLocalProviderContext',
162
170
  'registerHuggingFaceModel',
@@ -184,6 +192,7 @@ export const SESSION_CONFIGURE_ACTIONS = Object.freeze([
184
192
  'startMediaJob',
185
193
  'switchContext',
186
194
  'taskControl',
195
+ 'testWebhook',
187
196
  'toggleFast',
188
197
  'toggleVoice',
189
198
  'claimSetupRequest',
@@ -37,6 +37,8 @@ export function createAgentChildFactory({ registry, rehydrateAgentSessions, crea
37
37
  effort: preset.effort,
38
38
  fast: preset.fast === true,
39
39
  modelParameters: preset.modelParameters,
40
+ contextPercent: spec.contextPercent,
41
+ selectedContextWindow: spec.selectedContextWindow,
40
42
  toolMode: 'full',
41
43
  sessionProfile,
42
44
  });