mixdog 1.4.2 → 1.4.3

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 (417) hide show
  1. package/package.json +2 -2
  2. package/scripts/build-shipped-history.mjs +15 -5
  3. package/scripts/gate-local.mjs +65 -19
  4. package/scripts/graph-parity.mjs +8 -3
  5. package/scripts/lib/gate-scheduler.mjs +2 -1
  6. package/scripts/lib/run-node-tests.mjs +17 -5
  7. package/scripts/lib/test-failure-summary.mjs +1 -8
  8. package/scripts/lib/test-spawn-ledger.mjs +33 -2
  9. package/scripts/post-release-check.mjs +26 -16
  10. package/scripts/provider-pingpong-live.mjs +1 -1
  11. package/scripts/prune-embedding-runtime.mjs +3 -1
  12. package/scripts/release-paths.mjs +7 -1
  13. package/src/defaults/shipped-history.json +20 -0
  14. package/src/defaults/skills/setup/SKILL.md +2 -2
  15. package/src/defaults/skills/setup/references/actions.md +16 -3
  16. package/src/defaults/skills/setup/references/surfaces.md +3 -0
  17. package/src/defaults/skills/setup-guide/SKILL.md +6 -1
  18. package/src/lib/instruction-text.cjs +36 -0
  19. package/src/lib/rules-builder.cjs +34 -20
  20. package/src/orchestration/balanced.md +23 -0
  21. package/src/orchestration/focused.md +22 -0
  22. package/src/orchestration/none.md +5 -0
  23. package/src/orchestration/swarm.md +24 -0
  24. package/src/rules/agent-mode/AGENT_MODE.md +3 -1
  25. package/src/rules/agent-mode/MIXY.md +2 -2
  26. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/session-prep.mjs +3 -3
  27. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch.mjs +0 -1
  28. package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +4 -2
  29. package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +0 -9
  30. package/src/runtime/agent/orchestrator/agent-runtime/heartbeat-completion.mjs +2 -2
  31. package/src/runtime/agent/orchestrator/agent-runtime/session-builder.mjs +67 -0
  32. package/src/runtime/agent/orchestrator/agent-trace-format.mjs +1 -0
  33. package/src/runtime/agent/orchestrator/context/role-instructions.mjs +4 -4
  34. package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +3 -1
  35. package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +199 -46
  36. package/src/runtime/agent/orchestrator/mcp/client-config.mjs +3 -5
  37. package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +9 -3
  38. package/src/runtime/agent/orchestrator/mcp/client.mjs +3 -5
  39. package/src/runtime/agent/orchestrator/mcp/oauth-client.mjs +1 -1
  40. package/src/runtime/agent/orchestrator/mcp/oauth-credentials.mjs +8 -2
  41. package/src/runtime/agent/orchestrator/mcp/oauth-probe.mjs +1 -1
  42. package/src/runtime/agent/orchestrator/mcp/oauth-provider.mjs +14 -0
  43. package/src/runtime/agent/orchestrator/mcp/oauth.mjs +1 -1
  44. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
  45. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-stop.mjs +3 -3
  46. package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +1 -1
  47. package/src/runtime/agent/orchestrator/providers/gemini-thinking.mjs +2 -2
  48. package/src/runtime/agent/orchestrator/providers/openai-compat-response-normalization.mjs +4 -6
  49. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-head-parity.json +2784 -2872
  50. package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +5 -8
  51. package/src/runtime/agent/orchestrator/providers/openai-responses-payload-parity.fixture.json +288 -300
  52. package/src/runtime/agent/orchestrator/providers/vertex-ai.mjs +10 -1
  53. package/src/runtime/agent/orchestrator/providers/xai-tool-search-head-parity.json +10 -30
  54. package/src/runtime/agent/orchestrator/runtime-core/builtin-features.mjs +30 -0
  55. package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +0 -11
  56. package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-availability.mjs +8 -0
  57. package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-delta.mjs +17 -3
  58. package/src/runtime/agent/orchestrator/runtime-core/goal-control.mjs +47 -27
  59. package/src/runtime/agent/orchestrator/runtime-core/goal-deadlines.mjs +141 -10
  60. package/src/runtime/agent/orchestrator/runtime-core/goal-mutations.mjs +26 -63
  61. package/src/runtime/agent/orchestrator/runtime-core/goal-reminder.mjs +28 -3
  62. package/src/runtime/agent/orchestrator/runtime-core/goal-runtime.mjs +36 -11
  63. package/src/runtime/agent/orchestrator/runtime-core/goal-state.mjs +88 -56
  64. package/src/runtime/agent/orchestrator/runtime-core/goal-storage.mjs +4 -1
  65. package/src/runtime/agent/orchestrator/runtime-core/goal-store.mjs +51 -32
  66. package/src/runtime/agent/orchestrator/runtime-core/goal-text.mjs +45 -145
  67. package/src/runtime/agent/orchestrator/runtime-core/goal-tool-defs.mjs +15 -98
  68. package/src/runtime/agent/orchestrator/runtime-core/goal-tool-exec.mjs +32 -99
  69. package/src/runtime/agent/orchestrator/runtime-core/goal-turns.mjs +23 -78
  70. package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +69 -48
  71. package/src/runtime/agent/orchestrator/runtime-core/todo-list.mjs +367 -0
  72. package/src/runtime/agent/orchestrator/runtime-core/todo-tool-defs.mjs +47 -0
  73. package/src/runtime/agent/orchestrator/runtime-core/tool-availability.mjs +155 -0
  74. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-data.mjs +9 -0
  75. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +119 -35
  76. package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +1 -1
  77. package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +1 -1
  78. package/src/runtime/agent/orchestrator/session/agent-loop.mjs +28 -22
  79. package/src/runtime/agent/orchestrator/session/agent-pool-progress.mjs +30 -0
  80. package/src/runtime/agent/orchestrator/session/attachment-preflight.mjs +1 -1
  81. package/src/runtime/agent/orchestrator/session/cache-warm.mjs +2 -2
  82. package/src/runtime/agent/orchestrator/session/catalog-db/index.mjs +2 -2
  83. package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +1 -1
  84. package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +1 -1
  85. package/src/runtime/agent/orchestrator/session/compact/runner.mjs +3 -0
  86. package/src/runtime/agent/orchestrator/session/compact/summary-route.mjs +1 -1
  87. package/src/runtime/agent/orchestrator/session/context-utils.mjs +8 -12
  88. package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +1 -1
  89. package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +1 -1
  90. package/src/runtime/agent/orchestrator/session/conversation-import/convert.mjs +1 -1
  91. package/src/runtime/agent/orchestrator/session/conversation-import/imported-session.mjs +7 -3
  92. package/src/runtime/agent/orchestrator/session/human-gate/held-message.mjs +1 -1
  93. package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +1 -2
  94. package/src/runtime/agent/orchestrator/session/human-gate/run-policy.mjs +1 -1
  95. package/src/runtime/agent/orchestrator/session/image-strip-recovery.mjs +1 -1
  96. package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +11 -1
  97. package/src/runtime/agent/orchestrator/session/loop/context-overflow.mjs +1 -1
  98. package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +8 -1
  99. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/todo-check.mjs +196 -0
  100. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +116 -50
  101. package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +8 -1
  102. package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +1 -1
  103. package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +1 -1
  104. package/src/runtime/agent/orchestrator/session/loop/steering.mjs +3 -1
  105. package/src/runtime/agent/orchestrator/session/loop/stored-tool-args.mjs +5 -6
  106. package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +6 -1
  107. package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +16 -2
  108. package/src/runtime/agent/orchestrator/session/loop/turn-report.mjs +35 -0
  109. package/src/runtime/agent/orchestrator/session/loop/usage.mjs +1 -1
  110. package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +57 -26
  111. package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +9 -7
  112. package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +21 -3
  113. package/src/runtime/agent/orchestrator/session/manager/ask-turn-failure.mjs +27 -11
  114. package/src/runtime/agent/orchestrator/session/manager/ask-turn-open.mjs +37 -34
  115. package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +15 -0
  116. package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +25 -15
  117. package/src/runtime/agent/orchestrator/session/manager/ask-turn-state.mjs +79 -24
  118. package/src/runtime/agent/orchestrator/session/manager/ask-turn-steering-drain.mjs +3 -0
  119. package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +12 -1
  120. package/src/runtime/agent/orchestrator/session/manager/context-meta.mjs +1 -1
  121. package/src/runtime/agent/orchestrator/session/manager/idle-cleanup.mjs +6 -1
  122. package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +9 -1
  123. package/src/runtime/agent/orchestrator/session/manager/pending-spool-path.mjs +2 -2
  124. package/src/runtime/agent/orchestrator/session/manager/pending-spool-shard.mjs +1 -1
  125. package/src/runtime/agent/orchestrator/session/manager/prompt-settings.mjs +598 -0
  126. package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +19 -0
  127. package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +19 -10
  128. package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +5 -0
  129. package/src/runtime/agent/orchestrator/session/manager/session-fallback-title.mjs +1 -1
  130. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +31 -0
  131. package/src/runtime/agent/orchestrator/session/manager/session-lock.mjs +31 -0
  132. package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +42 -6
  133. package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +2 -0
  134. package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +11 -1
  135. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-context.mjs +8 -9
  136. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-journal.mjs +339 -88
  137. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-recovery.mjs +135 -11
  138. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint.mjs +377 -104
  139. package/src/runtime/agent/orchestrator/session/manager/turn-durability.mjs +144 -0
  140. package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +1 -1
  141. package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +4 -0
  142. package/src/runtime/agent/orchestrator/session/manager.mjs +6 -0
  143. package/src/runtime/agent/orchestrator/session/mixy-name.mjs +1 -1
  144. package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +8 -1
  145. package/src/runtime/agent/orchestrator/session/save-session-worker.mjs +5 -1
  146. package/src/runtime/agent/orchestrator/session/store/canonical-reader.mjs +1 -1
  147. package/src/runtime/agent/orchestrator/session/store/liveness-veto.mjs +2 -2
  148. package/src/runtime/agent/orchestrator/session/store/save-worker.mjs +23 -2
  149. package/src/runtime/agent/orchestrator/session/store/sweep/sub-agent-retention.mjs +3 -3
  150. package/src/runtime/agent/orchestrator/session/store/transcript-durability.mjs +88 -0
  151. package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +5 -0
  152. package/src/runtime/agent/orchestrator/session/store-summary-log.mjs +1 -1
  153. package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +14 -5
  154. package/src/runtime/agent/orchestrator/session/store-transcript-worker.mjs +2 -2
  155. package/src/runtime/agent/orchestrator/session/store.mjs +5 -0
  156. package/src/runtime/agent/orchestrator/session/synthetic-user-envelope.mjs +7 -1
  157. package/src/runtime/agent/orchestrator/session/tail-reminder-rules.mjs +9 -1
  158. package/src/runtime/agent/orchestrator/session/transcript-restore/agent-envelope.mjs +1 -1
  159. package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +3 -1
  160. package/src/runtime/agent/orchestrator/session/transcript-restore/user-text.mjs +2 -2
  161. package/src/runtime/agent/orchestrator/stall-policy.mjs +3 -5
  162. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/backgrounded-result.mjs +4 -1
  163. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/misuse-guard.mjs +21 -3
  164. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/result-format.mjs +1 -1
  165. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/worktree-add-guard.mjs +77 -0
  166. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +0 -1
  167. package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +7 -3
  168. package/src/runtime/agent/orchestrator/tools/builtin/git-worktree-tool.mjs +27 -9
  169. package/src/runtime/agent/orchestrator/tools/builtin/lib/search-input-helpers.mjs +2 -2
  170. package/src/runtime/agent/orchestrator/tools/builtin/read-range-index.mjs +1 -1
  171. package/src/runtime/agent/orchestrator/tools/builtin/read-single-fast-paths.mjs +0 -1
  172. package/src/runtime/agent/orchestrator/tools/builtin/search-tool.mjs +0 -10
  173. package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +1 -2
  174. package/src/runtime/agent/orchestrator/tools/builtin.mjs +1 -24
  175. package/src/runtime/agent/orchestrator/tools/code-graph/graph-binary/child-kill.mjs +4 -3
  176. package/src/runtime/agent/orchestrator/tools/code-graph/graph-binary.mjs +1 -2
  177. package/src/runtime/agent/orchestrator/tools/code-graph/modes/calls.mjs +1 -1
  178. package/src/runtime/agent/orchestrator/tools/code-graph/modes/symbols.mjs +2 -2
  179. package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +4 -5
  180. package/src/runtime/agent/orchestrator/tools/code-graph/symbol-index.mjs +3 -4
  181. package/src/runtime/agent/orchestrator/tools/code-graph.mjs +4 -22
  182. package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +2 -2
  183. package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +1 -1
  184. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +0 -4
  185. package/src/runtime/agent/orchestrator/tools/shell-policy.mjs +0 -1
  186. package/src/runtime/attachments/attachment-reference.mjs +1 -1
  187. package/src/runtime/attachments/pdf-extract.mjs +1 -1
  188. package/src/runtime/attachments/store.d.mts +1 -0
  189. package/src/runtime/attachments/store.mjs +2 -2
  190. package/src/runtime/channels/lib/config-reload-watch.mjs +42 -0
  191. package/src/runtime/channels/lib/owned-runtime/config-reload.mjs +29 -9
  192. package/src/runtime/channels/lib/scheduler.mjs +33 -0
  193. package/src/runtime/channels/lib/schedules-db.mjs +11 -4
  194. package/src/runtime/channels/lib/webhook/session-dispatch.mjs +4 -1
  195. package/src/runtime/channels/lib/webhooks-db.mjs +9 -3
  196. package/src/runtime/channels/lib/whisper-server.mjs +12 -12
  197. package/src/runtime/channels/lib/worker-main.mjs +9 -31
  198. package/src/runtime/computer-bridge/linux-readiness.mjs +10 -14
  199. package/src/runtime/connectors/connector-accounts-mcp.mjs +169 -33
  200. package/src/runtime/connectors/gmail-app-password.mjs +2 -2
  201. package/src/runtime/connectors/google-mcp.mjs +1 -1
  202. package/src/runtime/effort-judge/judge-client.mjs +2 -2
  203. package/src/runtime/effort-judge/judge-input.mjs +4 -4
  204. package/src/runtime/explore/explorer.mjs +0 -5
  205. package/src/runtime/explore/tool.mjs +3 -3
  206. package/src/runtime/local-provider/hardware.mjs +1 -1
  207. package/src/runtime/media/adapters/codex-image.mjs +3 -3
  208. package/src/runtime/media/adapters/gemini-video.mjs +1 -1
  209. package/src/runtime/media/media-usage.mjs +1 -1
  210. package/src/runtime/media/store.mjs +1 -1
  211. package/src/runtime/memory/index.mjs +11 -1
  212. package/src/runtime/memory/lib/embedding-reindex.mjs +27 -0
  213. package/src/runtime/memory/lib/memory-embed.mjs +83 -14
  214. package/src/runtime/memory/lib/memory-process-lock.mjs +159 -36
  215. package/src/runtime/memory/lib/memory-text-utils.mjs +6 -1
  216. package/src/runtime/memory/lib/memory.mjs +17 -0
  217. package/src/runtime/memory/lib/pg/process.mjs +1 -1
  218. package/src/runtime/memory/lib/pg/supervisor.mjs +16 -96
  219. package/src/runtime/memory/lib/recall-hybrid/hybrid-sql.mjs +12 -3
  220. package/src/runtime/office/authoring/docx-html-runner.mjs +1 -1
  221. package/src/runtime/office/authoring/pptx-author-action.mjs +1 -1
  222. package/src/runtime/office/authoring/xlsx-html-build.mjs +1 -1
  223. package/src/runtime/office/authoring/xlsx-html-runner.mjs +1 -1
  224. package/src/runtime/office/capabilities.mjs +1 -1
  225. package/src/runtime/office/core/office-core.mjs +1 -1
  226. package/src/runtime/office/design/content-model.mjs +3 -3
  227. package/src/runtime/office/design/docx/design-docx/section.mjs +6 -6
  228. package/src/runtime/office/design/xlsx/design-xlsx-components.mjs +1 -1
  229. package/src/runtime/office/design/xlsx/design-xlsx.mjs +1 -1
  230. package/src/runtime/office/pdf/ocr-engine.mjs +1 -1
  231. package/src/runtime/office/pdf/pdf-writer.mjs +4 -4
  232. package/src/runtime/office/portable/portable-docx-operations.mjs +2 -2
  233. package/src/runtime/office/portable/portable-soffice.mjs +8 -6
  234. package/src/runtime/office/portable/xlsx-contract.mjs +1 -1
  235. package/src/runtime/shared/atomic-file.d.mts +8 -0
  236. package/src/runtime/shared/background-tasks.mjs +22 -4
  237. package/src/runtime/shared/background-wait.mjs +66 -0
  238. package/src/runtime/shared/child-guardian.mjs +17 -7
  239. package/src/runtime/shared/config.mjs +313 -16
  240. package/src/runtime/shared/connector-catalog.d.mts +4 -5
  241. package/src/runtime/shared/connector-catalog.mjs +11 -1
  242. package/src/runtime/shared/file-lock.mjs +8 -3
  243. package/src/runtime/shared/git-runner.mjs +7 -2
  244. package/src/runtime/shared/idle-gc.mjs +30 -7
  245. package/src/runtime/shared/llm/http-agent.mjs +8 -5
  246. package/src/runtime/shared/llm/system-proxy.mjs +2 -1
  247. package/src/runtime/shared/llm/usage-ledger-quota.mjs +31 -12
  248. package/src/runtime/shared/llm/usage-ledger-rollup.mjs +84 -8
  249. package/src/runtime/shared/llm/usage-ledger.mjs +3 -0
  250. package/src/runtime/shared/llm/usage-rollup.mjs +48 -0
  251. package/src/runtime/shared/maintenance-schedule.mjs +109 -0
  252. package/src/runtime/shared/process-runner.mjs +8 -4
  253. package/src/runtime/shared/routine-trigger.d.mts +13 -0
  254. package/src/runtime/shared/routine-trigger.mjs +34 -0
  255. package/src/runtime/shared/run-child.d.mts +2 -1
  256. package/src/runtime/shared/run-child.mjs +70 -18
  257. package/src/runtime/shared/session-scratch.mjs +14 -2
  258. package/src/runtime/shared/shipped-definitions.mjs +7 -1
  259. package/src/runtime/shared/tool-card-model.golden.json +3 -12
  260. package/src/runtime/shared/tool-execution-contract.mjs +2 -0
  261. package/src/runtime/shared/tool-work-units.mjs +31 -6
  262. package/src/runtime/shared/turn-snapshot.mjs +26 -4
  263. package/src/runtime/shared/turn-worktree-snapshot.mjs +6 -11
  264. package/src/runtime/shared/worker-requests.mjs +17 -3
  265. package/src/runtime/shared/worktrees/branch-management.mjs +1 -5
  266. package/src/runtime/shared/worktrees/contract.mjs +16 -6
  267. package/src/runtime/shared/worktrees/dependencies.mjs +127 -89
  268. package/src/runtime/shared/worktrees/disk.mjs +79 -2
  269. package/src/runtime/shared/worktrees/git.mjs +44 -11
  270. package/src/runtime/shared/worktrees/include.mjs +6 -4
  271. package/src/runtime/shared/worktrees/maintenance.mjs +422 -30
  272. package/src/runtime/shared/worktrees/manager.mjs +772 -75
  273. package/src/runtime/shared/worktrees/settings.mjs +33 -7
  274. package/src/runtime/shared/worktrees/test-support.mjs +5 -1
  275. package/src/runtime/shared/worktrees/worker-snapshots.mjs +82 -0
  276. package/src/runtime/tidy/process.mjs +2 -1
  277. package/src/runtime/web-search/index.mjs +3 -22
  278. package/src/runtime/web-search/lib/web-tools.mjs +2 -2
  279. package/src/runtime/web-search/tool-defs.mjs +17 -26
  280. package/src/session-runtime/agent-profile-changes.mjs +55 -4
  281. package/src/session-runtime/boot/apis.mjs +27 -4
  282. package/src/session-runtime/boot/begin.mjs +2 -0
  283. package/src/session-runtime/boot/config.mjs +10 -1
  284. package/src/session-runtime/boot/facade.mjs +1 -0
  285. package/src/session-runtime/boot/providers.mjs +70 -3
  286. package/src/session-runtime/boot/session.mjs +2 -0
  287. package/src/session-runtime/boot/tools.mjs +69 -25
  288. package/src/session-runtime/channel-config-api.mjs +1 -0
  289. package/src/session-runtime/config-change-effects.mjs +179 -0
  290. package/src/session-runtime/config-lifecycle/config-writers.mjs +1 -0
  291. package/src/session-runtime/config-lifecycle.mjs +160 -24
  292. package/src/session-runtime/conversation-import/discovery.mjs +86 -7
  293. package/src/session-runtime/conversation-import/service.mjs +3 -2
  294. package/src/session-runtime/goal-facade-api.mjs +49 -3
  295. package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +3 -0
  296. package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +3 -2
  297. package/src/session-runtime/internal-tool-executor/feature-tools.mjs +3 -11
  298. package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +18 -4
  299. package/src/session-runtime/internal-tool-executor.mjs +12 -19
  300. package/src/session-runtime/lifecycle/cold-heir.mjs +7 -0
  301. package/src/session-runtime/lifecycle/memory-ingest.mjs +3 -3
  302. package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +53 -5
  303. package/src/session-runtime/lifecycle/session-switch.mjs +13 -2
  304. package/src/session-runtime/lifecycle/teardown/session-close.mjs +4 -4
  305. package/src/session-runtime/lifecycle-api.mjs +1 -0
  306. package/src/session-runtime/mcp-glue/server-catalog.mjs +14 -3
  307. package/src/session-runtime/mcp-glue/server-connection.mjs +34 -8
  308. package/src/session-runtime/model-route/set-route.mjs +40 -7
  309. package/src/session-runtime/native-web-search/routes.mjs +3 -3
  310. package/src/session-runtime/provider-auth/refresh.mjs +6 -3
  311. package/src/session-runtime/provider-auth/setup.mjs +1 -1
  312. package/src/session-runtime/provider-readiness.mjs +53 -4
  313. package/src/session-runtime/resource-api.mjs +1 -1
  314. package/src/session-runtime/resource-extension-sync.mjs +4 -8
  315. package/src/session-runtime/resource-mcp-connector-accounts.mjs +5 -1
  316. package/src/session-runtime/resource-mcp-secrets.mjs +3 -3
  317. package/src/session-runtime/resource-plugins-api.mjs +4 -0
  318. package/src/session-runtime/routine-executor.mjs +152 -0
  319. package/src/session-runtime/routine-home-turn.mjs +46 -5
  320. package/src/session-runtime/runtime-facade.mjs +5 -0
  321. package/src/session-runtime/runtime-feature-gates.mjs +2 -11
  322. package/src/session-runtime/schedule-session-run.mjs +1 -0
  323. package/src/session-runtime/services/agent-tool/job-task-reconcile.mjs +6 -1
  324. package/src/session-runtime/services/agent-tool/job-views/session-progress.mjs +7 -0
  325. package/src/session-runtime/services/agent-tool/send-flow.mjs +110 -6
  326. package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +12 -0
  327. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-plan.mjs +5 -0
  328. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +24 -6
  329. package/src/session-runtime/services/agent-tool.mjs +51 -1
  330. package/src/session-runtime/services/channel-admin.mjs +18 -0
  331. package/src/session-runtime/services/hook-bus/command-handler.mjs +7 -11
  332. package/src/session-runtime/services/plugin-admin.mjs +4 -0
  333. package/src/session-runtime/services/seeds.mjs +7 -0
  334. package/src/session-runtime/services/usage-stats-model.mjs +32 -11
  335. package/src/session-runtime/session-create/materialize.mjs +4 -2
  336. package/src/session-runtime/session-create/session-options.mjs +2 -0
  337. package/src/session-runtime/settings-builtin-tools-api.mjs +1 -9
  338. package/src/session-runtime/setup-tool/connector-widen-approval.mjs +1 -1
  339. package/src/session-runtime/setup-tool/executor.mjs +8 -1
  340. package/src/session-runtime/setup-tool/extended-actions.mjs +2 -0
  341. package/src/session-runtime/setup-tool/settings-contract.mjs +28 -0
  342. package/src/session-runtime/setup-tool/tool-defs.mjs +26 -1
  343. package/src/session-runtime/tool-policy/agent-profile-fold.mjs +40 -43
  344. package/src/session-runtime/tool-policy/mode-switch.mjs +1 -1
  345. package/src/session-runtime/tool-policy/policy-stage.mjs +106 -8
  346. package/src/session-runtime/tool-policy/workflow-overlay.mjs +2 -1
  347. package/src/session-runtime/tool-policy-refresh.mjs +182 -5
  348. package/src/session-runtime/tool-surface.mjs +38 -1
  349. package/src/session-runtime/turn/agent-ops.mjs +10 -2
  350. package/src/session-runtime/turn/session-ops.mjs +2 -0
  351. package/src/session-runtime/turn/turn-run/turn-prepare.mjs +5 -0
  352. package/src/session-runtime/turn/turn-run.mjs +1 -1
  353. package/src/session-runtime/webhook-session-run.mjs +2 -0
  354. package/src/session-runtime/workflow-agents-api/agent-connectors.mjs +1 -4
  355. package/src/session-runtime/workflow-agents-api/agent-route.mjs +3 -10
  356. package/src/session-runtime/workflow-agents-api/instruction-files.mjs +165 -0
  357. package/src/session-runtime/workflow-agents-api/style-and-mode.mjs +5 -4
  358. package/src/session-runtime/workflow-agents-api/workflow-packs.mjs +2 -3
  359. package/src/session-runtime/workflow-agents-api.mjs +2 -0
  360. package/src/session-runtime/workspace/project-branches.mjs +1 -1
  361. package/src/session-runtime/workspace/session-view.mjs +1 -1
  362. package/src/session-runtime/workspace/transitions.mjs +20 -4
  363. package/src/session-runtime/workspace/worktree-maintenance.mjs +126 -6
  364. package/src/session-runtime/workspace/worktree-setup.mjs +13 -1
  365. package/src/session-runtime/workspace/worktree-tool.mjs +16 -0
  366. package/src/standalone/daemon-agent-control.mjs +25 -8
  367. package/src/standalone/daemon-desktop-runtime.mjs +6 -2
  368. package/src/standalone/daemon-lag-profiler.mjs +7 -7
  369. package/src/standalone/daemon.mjs +54 -2
  370. package/src/standalone/local-session-runtime.mjs +16 -0
  371. package/src/standalone/session-client/daemon-unavailable.mjs +1 -1
  372. package/src/standalone/session-protocol.mjs +11 -0
  373. package/src/standalone/session-service/agent-route-follow.mjs +23 -20
  374. package/src/standalone/session-service/agent-tree/agent-turns.mjs +18 -6
  375. package/src/standalone/session-service/quota-resume.mjs +9 -0
  376. package/src/standalone/session-service/session-calls/session-action.mjs +51 -1
  377. package/src/standalone/session-service/session-calls/session-turns.mjs +37 -18
  378. package/src/standalone/session-service/session-calls/turn-gate.mjs +34 -0
  379. package/src/standalone/session-service/session-calls.mjs +2 -1
  380. package/src/tui/App.jsx +8 -0
  381. package/src/tui/app/clipboard.mjs +1 -1
  382. package/src/tui/app/create-app-pickers.mjs +2 -0
  383. package/src/tui/app/doctor.mjs +2 -2
  384. package/src/tui/app/panel-signature.mjs +1 -1
  385. package/src/tui/app/settings-picker.mjs +53 -8
  386. package/src/tui/app/shell-layout/row-budgets.mjs +2 -2
  387. package/src/tui/app/slash-commands.mjs +1 -1
  388. package/src/tui/app/slash-dispatch/route-commands.mjs +1 -1
  389. package/src/tui/app/slash-dispatch/session-commands.mjs +1 -1
  390. package/src/tui/app/use-prompt-queue-history.mjs +2 -2
  391. package/src/tui/app/use-transcript-activity.mjs +1 -1
  392. package/src/tui/app/use-transcript-window/geometry.mjs +1 -1
  393. package/src/tui/components/prompt-input/escape-policy.d.mts +0 -1
  394. package/src/tui/components/prompt-input/escape-policy.mjs +1 -1
  395. package/src/tui/components/question-panel-model.mjs +4 -4
  396. package/src/tui/components/tool-execution/standard-card.jsx +3 -4
  397. package/src/tui/components/user-message-skills.mjs +1 -1
  398. package/src/tui/dist/index.mjs +309 -30
  399. package/src/tui/markdown/render-ansi.mjs +1 -1
  400. package/src/tui/session/agent-job-feed/notification-router.mjs +10 -0
  401. package/src/tui/session/agent-job-feed.mjs +2 -0
  402. package/src/tui/session/context-state.mjs +3 -0
  403. package/src/tui/session/quota-resume.mjs +1 -1
  404. package/src/tui/session/session-api/lifecycle/dispose.mjs +1 -0
  405. package/src/tui/session/session-api/lifecycle/session-reset.mjs +7 -0
  406. package/src/tui/session/session-api/routes-agent-definitions.mjs +5 -0
  407. package/src/tui/session/session-api/worktree.mjs +13 -1
  408. package/src/tui/session/session-flow/drain.mjs +11 -14
  409. package/src/tui/session/tool-card-results/grouped-result.mjs +2 -2
  410. package/src/tui/session/turn-quiet.mjs +1 -1
  411. package/src/tui/session/turn.mjs +3 -0
  412. package/src/tui/session/worktree-setup-notice.mjs +1 -1
  413. package/src/tui/spinner-meta.mjs +3 -3
  414. package/src/tui/spinner-verbs.mjs +2 -2
  415. package/src/defaults/skills/goal-management/SKILL.md +0 -169
  416. package/src/runtime/agent/orchestrator/runtime-core/goal-tasks.mjs +0 -156
  417. package/src/session-runtime/goal-tasks.mjs +0 -1
@@ -11,9 +11,17 @@ export const WORKTREE_NEW_TASK_DEFAULTS = Object.freeze(['branch', 'worktree']);
11
11
  /**
12
12
  * @typedef {object} WorktreeSettings
13
13
  * @property {'branch'|'worktree'} newTaskDefault
14
- * @property {string} branchPrefix Ref prefix for created branches; ends with "/".
14
+ * @property {string} branchPrefix Ref prefix for created branches, ending with "/";
15
+ * "" (default) names the branch after the task alone.
15
16
  * @property {number} sizeWarnBytes Repository size that asks for confirmation; 0 never asks.
16
17
  * @property {boolean} autoCleanup Remove clean, merged worktrees when their session ends.
18
+ * The four settings below apply only while it is on.
19
+ * @property {number} maxWorktrees Keep at most this many managed worktrees (oldest
20
+ * activity cleaned first); 0 keeps any number.
21
+ * @property {number} unusedDays Clean up worktrees unused this many days; 0 never.
22
+ * @property {boolean} cleanupArchived Archiving a session makes its worktrees disposable.
23
+ * @property {boolean} deleteBranch Cleanup deletes the worktree's branch too (its tip
24
+ * stays under the recovery ref); off keeps the branch.
17
25
  */
18
26
 
19
27
  /** @type {Readonly<WorktreeSettings>} */
@@ -22,8 +30,15 @@ export const WORKTREE_SETTINGS_DEFAULTS = Object.freeze({
22
30
  branchPrefix: DEFAULT_WORKTREE_BRANCH_PREFIX,
23
31
  sizeWarnBytes: 2 * 1024 ** 3,
24
32
  autoCleanup: true,
33
+ maxWorktrees: 15,
34
+ unusedDays: 30,
35
+ cleanupArchived: true,
36
+ deleteBranch: false,
25
37
  });
26
38
 
39
+ const WORKTREE_MAX_WORKTREES_LIMIT = 1000;
40
+ const WORKTREE_UNUSED_DAYS_LIMIT = 3650;
41
+
27
42
  const KEYS = Object.keys(WORKTREE_SETTINGS_DEFAULTS);
28
43
  const PREFIX_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]*(\/[A-Za-z0-9][A-Za-z0-9._-]*)*\/$/;
29
44
 
@@ -35,16 +50,27 @@ function fieldError(key, value) {
35
50
  ? null
36
51
  : `must be one of ${WORKTREE_NEW_TASK_DEFAULTS.join(', ')}`;
37
52
  case 'branchPrefix':
38
- return typeof value === 'string' &&
39
- value.length <= 64 &&
40
- PREFIX_PATTERN.test(value) &&
41
- !value.includes('..') &&
42
- !/\.lock\//i.test(value)
53
+ return value === '' ||
54
+ (typeof value === 'string' &&
55
+ value.length <= 64 &&
56
+ PREFIX_PATTERN.test(value) &&
57
+ !value.includes('..') &&
58
+ !/\.lock\//i.test(value))
43
59
  ? null
44
- : 'must be a ref path ending with "/", e.g. "mixdog/"';
60
+ : 'must be empty or a ref path ending with "/", e.g. "mixdog/"';
45
61
  case 'sizeWarnBytes':
46
62
  return Number.isSafeInteger(value) && value >= 0 ? null : 'must be a non-negative integer';
63
+ case 'maxWorktrees':
64
+ return Number.isSafeInteger(value) && value >= 0 && value <= WORKTREE_MAX_WORKTREES_LIMIT
65
+ ? null
66
+ : `must be an integer from 0 to ${WORKTREE_MAX_WORKTREES_LIMIT}`;
67
+ case 'unusedDays':
68
+ return Number.isSafeInteger(value) && value >= 0 && value <= WORKTREE_UNUSED_DAYS_LIMIT
69
+ ? null
70
+ : `must be an integer from 0 to ${WORKTREE_UNUSED_DAYS_LIMIT}`;
47
71
  case 'autoCleanup':
72
+ case 'cleanupArchived':
73
+ case 'deleteBranch':
48
74
  return typeof value === 'boolean' ? null : 'must be a boolean';
49
75
  default:
50
76
  return 'is not a worktree setting';
@@ -106,7 +106,11 @@ export async function createTestWorktree(projectPath, extra = {}) {
106
106
  return { entry, ...id, ...extra };
107
107
  }
108
108
 
109
- /** The repository's branches under the default managed prefix. */
109
+ /** The branch prefix the suites configure (the default is none), so their
110
+ * managed branches are told apart from the repository's own. */
111
+ export const TEST_BRANCH_PREFIX = 'mixdog/';
112
+
113
+ /** The repository's branches under TEST_BRANCH_PREFIX. */
110
114
  export function prefixedBranches(repo) {
111
115
  return git(repo, 'for-each-ref', '--format=%(refname:short)', 'refs/heads/mixdog/').split('\n').filter(Boolean);
112
116
  }
@@ -0,0 +1,82 @@
1
+ // Read-only snapshot worktrees of delegated workers (`git worktree add
2
+ // --detach` through the git tool): the worker's session holds each one, and
3
+ // it is removed when that worker's turn settles (the session runtime's
4
+ // unload), like the Lead's turn snapshots. What a removal leaves (something
5
+ // still runs there, the process ends first) is the prune's and the startup
6
+ // reconcile's: a snapshot never outlives its holder.
7
+ //
8
+ // Dependency-free at load (the manager loads on first use) and shared through
9
+ // a global symbol, so every bundle copy of this module sees one ledger.
10
+ import { randomUUID } from 'node:crypto';
11
+ import { setTimeout as delay } from 'node:timers/promises';
12
+
13
+ const STATE_KEY = Symbol.for('mixdog.workerSnapshots.v1');
14
+ const RETRY_MS = 2_000;
15
+ const RETRY_LIMIT = 5;
16
+
17
+ const loadManager = () => import('./manager.mjs');
18
+
19
+ function state() {
20
+ globalThis[STATE_KEY] ??= { runtimeToken: `worker-snapshots-${randomUUID()}`, turns: new Map() };
21
+ return globalThis[STATE_KEY];
22
+ }
23
+
24
+ /**
25
+ * A snapshot of `commit` in the repository at `projectPath`, held by worker
26
+ * session `sessionId` until its turn settles (releaseWorkerSnapshots).
27
+ * @param {{ sessionId: string, projectPath: string, commit: string, txId?: string, confirmLarge?: boolean, manager?: object }} input
28
+ */
29
+ export async function createWorkerSnapshot({
30
+ sessionId,
31
+ projectPath,
32
+ commit,
33
+ txId = '',
34
+ confirmLarge = false,
35
+ manager = null,
36
+ }) {
37
+ const id = String(sessionId || '').trim();
38
+ if (!id) throw new Error('A worker snapshot needs the worker session.');
39
+ const tx = String(txId || '').trim() || `worker-snapshot-${randomUUID()}`;
40
+ const backend = manager || (await loadManager());
41
+ const entry = await backend.createSnapshotWorktree({
42
+ projectPath,
43
+ sessionId: id,
44
+ runtimeToken: state().runtimeToken,
45
+ commit,
46
+ txId: tx,
47
+ confirmLarge: confirmLarge === true,
48
+ });
49
+ const { turns } = state();
50
+ if (!turns.has(id)) turns.set(id, new Set());
51
+ turns.get(id).add(tx);
52
+ return entry;
53
+ }
54
+
55
+ /**
56
+ * The worker's turn settled: remove the snapshots it made. One a worker or
57
+ * background shell still runs in is retried with a doubling delay a few
58
+ * times; the rest stays for the prune / startup reconcile.
59
+ * @returns {Promise<{ removed: string[], kept: object[] }>}
60
+ */
61
+ export async function releaseWorkerSnapshots(
62
+ sessionId,
63
+ { manager = null, retryMs = RETRY_MS, retryLimit = RETRY_LIMIT } = {}
64
+ ) {
65
+ const id = String(sessionId || '');
66
+ const { turns } = state();
67
+ const made = turns.get(id);
68
+ const report = { removed: [], kept: [] };
69
+ if (!made?.size) return report;
70
+ turns.delete(id);
71
+ const backend = manager || (await loadManager());
72
+ let pending = [...made];
73
+ for (let attempt = 0; pending.length && attempt < retryLimit; attempt++) {
74
+ if (attempt > 0) await delay(retryMs * 2 ** (attempt - 1), undefined, { ref: false });
75
+ const result = await backend.removeSessionSnapshots(id, { txIds: pending });
76
+ report.removed.push(...result.removed);
77
+ const inUse = result.kept.filter((row) => row.reason === 'in-use');
78
+ report.kept = result.kept;
79
+ pending = inUse.map((row) => row.txId);
80
+ }
81
+ return report;
82
+ }
@@ -5,6 +5,7 @@
5
5
  // parser.
6
6
  import { spawn } from 'node:child_process';
7
7
  import { existsSync, readdirSync, statSync } from 'node:fs';
8
+ import { spawnTreeKill } from '../agent/orchestrator/mcp/child-tree.mjs';
8
9
  import { delimiter, extname, isAbsolute, join } from 'node:path';
9
10
 
10
11
  const DEFAULT_PROCESS_TIMEOUT_MS = 90_000;
@@ -166,7 +167,7 @@ export function runProcess(
166
167
  if (child.exitCode != null || child.signalCode != null) return;
167
168
  try {
168
169
  if (process.platform === 'win32' && child.pid) {
169
- spawn('taskkill', ['/pid', String(child.pid), '/t', '/f'], { windowsHide: true, stdio: 'ignore' });
170
+ spawnTreeKill([child.pid], { root: child });
170
171
  } else {
171
172
  child.kill('SIGKILL');
172
173
  }
@@ -28,7 +28,6 @@ const webSearchArgsSchema = z.object({
28
28
  .union([z.string().min(1), z.array(z.string().min(1)).min(1)])
29
29
  .describe('Search query string or array of queries.'),
30
30
  site: z.string().optional().describe('Restrict results to a specific domain.'),
31
- type: z.enum(['web', 'news', 'images']).optional().describe('Search type. Default: web.'),
32
31
  maxResults: z.number().int().min(1).max(20).optional().describe('Maximum number of results to return (1-20).'),
33
32
  locale: z
34
33
  .union([
@@ -65,7 +64,7 @@ const urlArgsSchema = z.object({
65
64
  cwd: z.string().optional(),
66
65
  });
67
66
 
68
- const WEB_SEARCH_EMPTY_STRING_FIELDS = ['keywords', 'site', 'type', 'locale', 'contextSize'];
67
+ const WEB_SEARCH_EMPTY_STRING_FIELDS = ['keywords', 'site', 'locale', 'contextSize'];
69
68
 
70
69
  function normalizeWebSearchArgs(rawArgs) {
71
70
  if (!rawArgs || typeof rawArgs !== 'object' || Array.isArray(rawArgs)) return rawArgs;
@@ -153,17 +152,7 @@ function dropInvalidWebSearchResults(payload) {
153
152
  };
154
153
  }
155
154
 
156
- function getWebSearchCacheTtlMs(type = 'web') {
157
- switch (type) {
158
- case 'news':
159
- return 20 * 60 * 1000;
160
- case 'images':
161
- return 60 * 60 * 1000;
162
- // 'web' and any unknown type.
163
- default:
164
- return 30 * 60 * 1000;
165
- }
166
- }
155
+ const WEB_SEARCH_CACHE_TTL_MS = 30 * 60 * 1000;
167
156
 
168
157
  const SCRAPE_CACHE_TTL_MS = 60 * 60 * 1000;
169
158
 
@@ -207,7 +196,6 @@ function webSearchArgsForCacheKey(args) {
207
196
  return {
208
197
  keywords,
209
198
  site: args.site || null,
210
- type: args.type || 'web',
211
199
  locale: args.locale || null,
212
200
  contextSize: args.contextSize || 'low',
213
201
  maxResults: clampMaxResults(args.maxResults),
@@ -222,7 +210,6 @@ function buildAgentWebSearchPrompt(args) {
222
210
  '',
223
211
  `Query: ${query}`,
224
212
  args.site ? `Site/domain restriction: ${args.site}` : null,
225
- args.type ? `Search type: ${args.type}` : null,
226
213
  args.locale ? `Locale: ${localeLabel}` : null,
227
214
  `Max results: ${clampMaxResults(args.maxResults)}`,
228
215
  '',
@@ -326,7 +313,6 @@ function normalizeNativeWebSearchPayload(result, args, startedAt) {
326
313
  usage: result?.usage || null,
327
314
  results,
328
315
  warnings,
329
- type: cacheArgs.type,
330
316
  site: cacheArgs.site,
331
317
  locale: cacheArgs.locale,
332
318
  },
@@ -360,12 +346,7 @@ async function _webSearchCore(args, { cacheState, nativeWebSearch, signal }) {
360
346
  signal: controller.signal,
361
347
  });
362
348
  const payload = normalizeNativeWebSearchPayload(result, { ...args, ...cacheArgs }, startedAt);
363
- const cachedEntry = setCachedEntry(
364
- cacheState,
365
- webSearchCacheKey,
366
- payload,
367
- getWebSearchCacheTtlMs(cacheArgs.type)
368
- );
349
+ const cachedEntry = setCachedEntry(cacheState, webSearchCacheKey, payload, WEB_SEARCH_CACHE_TTL_MS);
369
350
  flushCacheState();
370
351
  return { ...payload, cache: buildCacheMeta(cachedEntry, false) };
371
352
  }
@@ -67,8 +67,8 @@ function _notifyPoolWaiter() {
67
67
 
68
68
  async function _acquirePoolSlot(signal) {
69
69
  const abortError = () => signal?.reason || new Error('aborted');
70
- // Waiting for a pool slot used to be uncancellable: an aborted tool call kept
71
- // queueing until a slot freed, then launched a page nobody was waiting for.
70
+ // Waiting for a pool slot is cancellable: otherwise an aborted tool call keeps
71
+ // queueing until a slot frees, then launches a page nobody was waiting for.
72
72
  while (_poolActive >= PUPPETEER_POOL_MAX_PAGES) {
73
73
  if (signal?.aborted) throw abortError();
74
74
  await new Promise((resolve, reject) => {
@@ -1,5 +1,8 @@
1
- import { TOOL_SYNC_EXECUTION_CONTRACT } from '../shared/tool-execution-contract.mjs';
2
-
1
+ // Model-facing text is kept minimal: every constraint dropped from these schemas
2
+ // (minLength, pattern, minItems, maxItems, format) is enforced by the zod
3
+ // schemas in index.mjs, which trim blanks and reject empty or non-URL input.
4
+ // `trigger` shows only in the deferred listing, so `description` carries the
5
+ // when-to-use guidance itself.
3
6
  const TOOL_DEFS_PLACEHOLDER = Symbol('web-fetch-schema');
4
7
 
5
8
  export const TOOL_DEFS = [
@@ -7,21 +10,18 @@ export const TOOL_DEFS = [
7
10
  name: 'web_search',
8
11
  title: 'Mixdog Web Search',
9
12
  trigger: 'Unfamiliar names, products, models, recent or external facts; search before answering from memory.',
10
- description: `Cached web/docs/current-info search; batch queries sharing filters. ${TOOL_SYNC_EXECUTION_CONTRACT}`,
13
+ description:
14
+ 'Search the web for recent, external or unfamiliar facts (names, products, models) before answering from memory.',
11
15
  inputSchema: {
12
16
  type: 'object',
13
17
  properties: {
14
18
  query: {
15
- anyOf: [
16
- { type: 'string', minLength: 1, pattern: '\\S' },
17
- { type: 'array', minItems: 1, items: { type: 'string', minLength: 1, pattern: '\\S' } },
18
- ],
19
- description: 'Non-empty query or array for lossless fan-out.',
19
+ anyOf: [{ type: 'string' }, { type: 'array', items: { type: 'string' } }],
20
+ description: 'One query, or an array run as a batch.',
20
21
  },
21
- site: { type: 'string', description: 'Site/domain filter.' },
22
- type: { type: 'string', enum: ['web', 'news', 'images'], description: 'Default web.' },
23
- maxResults: { type: 'integer', minimum: 1, maximum: 20, description: 'Result count; default 10; 1-20.' },
24
- locale: { type: 'string', description: 'Optional locale hint, e.g. ko-KR or a city/region name.' },
22
+ site: { type: 'string', description: 'Domain filter.' },
23
+ maxResults: { type: 'integer', minimum: 1, maximum: 20, description: 'Default 10.' },
24
+ locale: { type: 'string', description: 'e.g. ko-KR.' },
25
25
  contextSize: { type: 'string', enum: ['low', 'medium', 'high'], description: 'Default low.' },
26
26
  },
27
27
  required: ['query'],
@@ -39,25 +39,16 @@ export const TOOL_DEFS = [
39
39
  name: 'web_fetch',
40
40
  title: 'Mixdog Web Fetch',
41
41
  trigger: 'Page or docs body from a known URL; not discovery (web_search).',
42
- description: 'Fetch page/docs body from URL; batch known URLs with shared slice options.',
42
+ description: 'Fetch the page or docs body of known URLs; to find pages, use web_search.',
43
43
  inputSchema: {
44
44
  type: 'object',
45
45
  properties: {
46
46
  url: {
47
- anyOf: [
48
- { type: 'string', format: 'uri' },
49
- { type: 'array', items: { type: 'string', format: 'uri' }, minItems: 1, maxItems: 10 },
50
- ],
51
- description:
52
- 'Public or loopback HTTP(S) URL, or an array of up to 10; keep loopback and public URLs in separate calls.',
53
- },
54
- startIndex: { type: 'integer', minimum: 0, description: 'Character offset; default 0.' },
55
- maxLength: {
56
- type: 'integer',
57
- minimum: 0,
58
- description:
59
- 'Maximum characters; default 20000; 0 unlimited. A cut page ends with [output capped …; startIndex:N for more].',
47
+ anyOf: [{ type: 'string' }, { type: 'array', items: { type: 'string' } }],
48
+ description: 'URL, or an array of up to 10; loopback and public URLs in separate calls.',
60
49
  },
50
+ startIndex: { type: 'integer', minimum: 0, description: 'Character offset.' },
51
+ maxLength: { type: 'integer', minimum: 0, description: 'Default 20000; 0 unlimited.' },
61
52
  },
62
53
  required: ['url'],
63
54
  additionalProperties: false,
@@ -14,6 +14,18 @@ export function subscribeAgentProfileChanges(listener) {
14
14
  return { unsubscribe: () => listeners.delete(listener) };
15
15
  }
16
16
 
17
+ /** The keys of a saved agent route its chats and reused workers follow. */
18
+ export const AGENT_ROUTE_KEYS = Object.freeze([
19
+ 'provider',
20
+ 'model',
21
+ 'effort',
22
+ 'fast',
23
+ 'autoEffort',
24
+ 'modelParameters',
25
+ 'contextPercent',
26
+ 'contextTokens',
27
+ ]);
28
+
17
29
  // A bot's saved model route: the hosts of its chats (the session service)
18
30
  // move them onto it from their next turn.
19
31
  const routeListeners = new Set();
@@ -23,11 +35,50 @@ export function subscribeAgentRouteChanges(listener) {
23
35
  return { unsubscribe: () => routeListeners.delete(listener) };
24
36
  }
25
37
 
26
- /** Settles once every host has taken the route; one failing host never fails the save. */
27
- export async function publishAgentRouteChange(agentId, route) {
28
- await Promise.allSettled(
38
+ // Per bot, the route every host of this process took last (recorded only once
39
+ // all of them took it), and the publication in flight.
40
+ const publishedRoutes = new Map();
41
+ const publishingRoutes = new Map();
42
+
43
+ /** Every host takes the route; rejects with the hosts' failures. A
44
+ * publication of the same route already in flight is joined, not repeated. */
45
+ function deliverAgentRoute(agentId, route) {
46
+ const key = JSON.stringify(route ?? null);
47
+ const inFlight = publishingRoutes.get(agentId);
48
+ if (inFlight?.key === key) return inFlight.done;
49
+ const done = Promise.allSettled(
29
50
  [...routeListeners].map((listener) => Promise.resolve().then(() => listener(agentId, route)))
30
- );
51
+ ).then((results) => {
52
+ if (publishingRoutes.get(agentId)?.done === done) publishingRoutes.delete(agentId);
53
+ const failures = results.filter((one) => one.status === 'rejected').map((one) => one.reason);
54
+ if (failures.length) {
55
+ throw new AggregateError(
56
+ failures,
57
+ `the ${agentId} route reached ${results.length - failures.length} of ${results.length} hosts`
58
+ );
59
+ }
60
+ publishedRoutes.set(agentId, key);
61
+ });
62
+ publishingRoutes.set(agentId, { key, done });
63
+ return done;
64
+ }
65
+
66
+ /** Settles once every host has taken the route; one failing host never fails
67
+ * the save (the change step that follows it publishes the route again). */
68
+ export async function publishAgentRouteChange(agentId, route) {
69
+ try {
70
+ await deliverAgentRoute(agentId, route);
71
+ } catch {}
72
+ }
73
+
74
+ /** A bot route read from a changed config (saved by another process, edited
75
+ * by hand, or this process's own save): every runtime of the process applies
76
+ * the same change, so the hosts hear each route once, unless one failed to
77
+ * take it. Rejects when a host failed, so the change step retries it. */
78
+ export function publishStoredAgentRoute(agentId, route) {
79
+ const inFlight = publishingRoutes.get(agentId);
80
+ if (!inFlight && publishedRoutes.get(agentId) === JSON.stringify(route ?? null)) return Promise.resolve();
81
+ return deliverAgentRoute(agentId, route);
31
82
  }
32
83
 
33
84
  /** Settles once every runtime has applied the edit; one failing runtime never fails the save. */
@@ -118,6 +118,8 @@ export function wireApis(boot) {
118
118
  console.warn(`[connectors] merging connector accounts failed: ${error?.message || error}`);
119
119
  bootProfile('connector-accounts:merge-failed', { error: error?.message || String(error) });
120
120
  }
121
+ // After the merge: every account has its identity before anything connects.
122
+ if (boot.ensureConnectorAccountIds()) boot.reloadFullConfig();
121
123
  }
122
124
  boot.disposeGlobalExtensionSubscription = () => {
123
125
  boot.disposeConfigSync?.();
@@ -164,12 +166,18 @@ export function wireApis(boot) {
164
166
  getSession: () => boot.rt.session,
165
167
  getSessionId: getFacadeSessionId,
166
168
  goalRuntime: boot.goalRuntime,
169
+ persistSession: (session) => saveSessionAsync(session, { expectedGeneration: session.generation }),
167
170
  });
168
171
  }
169
172
 
170
173
  function wireToolPolicyRefresh(boot) {
171
174
  const { rt, cfgMod } = boot;
172
175
  const {
176
+ reconcileTurnSettings,
177
+ reconcileEmptySession,
178
+ emptySessionStale,
179
+ noteToolAvailability,
180
+ settingsReachCurrentSession,
173
181
  refreshEmptySessionToolPolicy,
174
182
  switchSessionWorkflow,
175
183
  switchSessionOrchestrationMode,
@@ -196,7 +204,14 @@ function wireToolPolicyRefresh(boot) {
196
204
  // A switch is acknowledged only once saved; a session closed or replaced
197
205
  // since (its generation moved) is not resurrected.
198
206
  persistSession: (session) => saveSessionAsync(session, { expectedGeneration: session.generation }),
207
+ toolDefinitionsFor: boot.toolDefinitionsFor,
208
+ getSurfaceGeneration: boot.surfaceGeneration,
199
209
  });
210
+ boot.reconcileTurnSettings = reconcileTurnSettings;
211
+ boot.reconcileEmptySession = reconcileEmptySession;
212
+ boot.emptySessionStale = emptySessionStale;
213
+ boot.noteToolAvailability = noteToolAvailability;
214
+ boot.settingsReachCurrentSession = settingsReachCurrentSession;
200
215
  boot.refreshEmptySessionToolPolicy = refreshEmptySessionToolPolicy;
201
216
  boot.switchSessionWorkflow = switchSessionWorkflow;
202
217
  boot.switchSessionOrchestrationMode = switchSessionOrchestrationMode;
@@ -347,7 +362,6 @@ function settingsApiFor(boot) {
347
362
  getUpdateProcessState: () => selfUpdate.getProcessState(),
348
363
  invalidateContextStatusCache: (...a) => boot.invalidateContextStatusCache(...a),
349
364
  invalidatePreSessionToolSurface: (...a) => boot.invalidatePreSessionToolSurface(...a),
350
- refreshEmptySessionToolPolicy: boot.refreshEmptySessionToolPolicy,
351
365
  scheduleChannelStart: (...a) => boot.scheduleChannelStart(...a),
352
366
  channels: boot.channels,
353
367
  clearChannelStartTimer: () => {
@@ -410,6 +424,7 @@ function providerAuthApiFor(boot) {
410
424
  saveConfigAndAdopt: boot.saveConfigAndAdopt,
411
425
  displayConfig: boot.displayConfig,
412
426
  reloadFullConfig: boot.reloadFullConfig,
427
+ applyConfigChange: boot.applyConfigChange,
413
428
  awaitKeychainPrewarm: boot.awaitKeychainPrewarm,
414
429
  isKeychainPrewarmReady: () => rt.keychainPrewarmWaitDone,
415
430
  hasProviderSetupCached: boot.hasProviderSetupCached,
@@ -527,7 +542,6 @@ function resourceApiFor(boot) {
527
542
  getMcpServerOAuthState: (cfg) => boot.mcpClient.getMcpServerOAuthState(cfg),
528
543
  probeMcpServerAuth: (cfg) => boot.mcpClient.probeMcpServerAuth(cfg),
529
544
  invalidatePreSessionToolSurface: boot.invalidatePreSessionToolSurface,
530
- refreshEmptySessionToolPolicy: boot.refreshEmptySessionToolPolicy,
531
545
  normalizeMcpServerInput: boot.normalizeMcpServerInput,
532
546
  mcpStatus: boot.mcpStatus,
533
547
  getMcpServerConfig: boot.getMcpServerConfig,
@@ -561,6 +575,8 @@ function modelRouteApiFor(boot) {
561
575
  getSession: () => rt.session,
562
576
  getSessionGeneration: () => rt.sessionGeneration,
563
577
  setSession: boot.adoptSession,
578
+ // A held model pick is saved with its session (a replaced one is not resurrected).
579
+ persistSession: (session) => saveSessionAsync(session, { expectedGeneration: session.generation }).catch(() => {}),
564
580
  getAddressedSessionId: () => rt.addressedSessionId,
565
581
  getConfigHasSecrets: () => rt.configHasSecrets,
566
582
  getWebSearchRouteState: () => rt.webSearchRoute,
@@ -626,7 +642,7 @@ function workflowAgentsApiFor(boot) {
626
642
  scheduleOutputStyleSave: boot.scheduleOutputStyleSave,
627
643
  invalidateContextStatusCache: boot.invalidateContextStatusCache,
628
644
  invalidatePreSessionToolSurface: boot.invalidatePreSessionToolSurface,
629
- refreshEmptySessionToolPolicy: boot.refreshEmptySessionToolPolicy,
645
+ settingsReachCurrentSession: () => boot.settingsReachCurrentSession(),
630
646
  switchSessionWorkflow: boot.switchSessionWorkflow,
631
647
  switchSessionOrchestrationMode: boot.switchSessionOrchestrationMode,
632
648
  });
@@ -653,7 +669,12 @@ function workspaceApiFor(boot) {
653
669
  // waits on the save worker, which may never come up.
654
670
  persistSession: (session) => saveSession(session, { sync: true }),
655
671
  refreshWorkspaceContext: (session, cwd, move) =>
656
- refreshWorkspacePrompt(session, cwd, { loadCoreMemoryContext: boot.loadCoreMemoryContext, move }),
672
+ refreshWorkspacePrompt(session, cwd, {
673
+ loadCoreMemoryContext: boot.loadCoreMemoryContext,
674
+ move,
675
+ // The runtime's in-memory setting, not the debounced file.
676
+ instructionFilesMode: rt.config?.instructionFiles,
677
+ }),
657
678
  invalidateCaches: () => {
658
679
  boot.invalidateContextStatusCache();
659
680
  boot.invalidatePreSessionToolSurface();
@@ -671,6 +692,8 @@ function sessionTurnApiFor(boot) {
671
692
  return createSessionTurnApi({
672
693
  applyPendingRoute: () => boot.modelRouteApi.applyPendingRoute(),
673
694
  applyPendingAgentProfile: boot.applyPendingAgentProfile,
695
+ reconcileTurnSettings: boot.reconcileTurnSettings,
696
+ reconcileEmptySession: () => boot.reconcileEmptySession(),
674
697
  currentAgents: boot.currentAgents,
675
698
  applyPendingSessionSwitches: boot.applyPendingSessionSwitches,
676
699
  prepareTurnWorkspace: boot.workspaceApi.prepareTurnWorkspace,
@@ -35,6 +35,7 @@ export function beginBoot(params) {
35
35
  const {
36
36
  awaitKeychainPrewarm,
37
37
  invalidateProviderCaches,
38
+ reinitProviders,
38
39
  ensureProvidersReady,
39
40
  modelMetaByRoute,
40
41
  providerModelCaches,
@@ -54,6 +55,7 @@ export function beginBoot(params) {
54
55
  return Object.assign(boot, {
55
56
  awaitKeychainPrewarm,
56
57
  invalidateProviderCaches,
58
+ reinitProviders,
57
59
  ensureProvidersReady,
58
60
  modelMetaByRoute,
59
61
  providerModelCaches,
@@ -1,6 +1,7 @@
1
1
  // Boot stage 3: the initial config/route state, the runtime scalars, the
2
2
  // timer/prewarm holders teardown sweeps, and the env-tunable boot delays.
3
3
  import { performance } from 'node:perf_hooks';
4
+ import { SessionClosedError } from '../../runtime/agent/orchestrator/session/manager/session-errors.mjs';
4
5
  import { setConfiguredShell } from '../../runtime/agent/orchestrator/tools/builtin/shell-runtime.mjs';
5
6
  import { LOCAL_PROVIDER_ID, configureLocalProviderIdleTtl } from '../../runtime/local-provider/managed-runtime.mjs';
6
7
  import { normalizeToolMode } from '../../runtime/agent/orchestrator/runtime-core/effort.mjs';
@@ -26,6 +27,7 @@ export async function resolveConfig(boot) {
26
27
  } = resolveInitialConfigState({
27
28
  initialConfig: params.initialConfig,
28
29
  loadConfig: () => cfgMod.loadConfig({ secrets: false }),
30
+ readStoredOutputStyle: () => sharedCfgMod.readConfig?.()?.outputStyle,
29
31
  resolveRoute,
30
32
  provider: params.provider,
31
33
  model: params.model,
@@ -97,9 +99,16 @@ function initRuntimeState(rt, params) {
97
99
  rt.startupProviderCatalogRefreshPending = false;
98
100
  }
99
101
 
100
- function activeTurnControls(rt) {
102
+ export function activeTurnControls(rt) {
101
103
  return {
102
104
  registerActiveTurnController: (controller) => {
105
+ // Close aborts the turns registered when it starts; a turn opened after
106
+ // that (a caller already past its own checks) starts aborted, so a
107
+ // closing runtime never reaches the provider again.
108
+ if (rt.closeRequested && !controller.signal.aborted) {
109
+ const sessionId = rt.session?.id || rt.reservedSessionId || 'pending';
110
+ controller.abort(new SessionClosedError(sessionId, 'runtime is closing', 'runtime-close'));
111
+ }
103
112
  rt.activeTurnAbortControllers.add(controller);
104
113
  return () => rt.activeTurnAbortControllers.delete(controller);
105
114
  },
@@ -118,6 +118,7 @@ function facadeGetters(boot) {
118
118
  : configuredOrchestrationMode(rt.config),
119
119
  getOutputStyle: () => boot.getOutputStyleStatusCached().current,
120
120
  getContextStatus: boot.computeContextStatus,
121
+ getContextStatusSettled: boot.computeContextStatusSettled,
121
122
  getContextStatusForSession: boot.computeContextStatusForSession,
122
123
  renameSessionTitle: (sessionId, title) => mgr.updateSessionManualTitle(sessionId, title),
123
124
  };