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,17 +11,21 @@
11
11
  // conversation, else the connector's last-used account (connectorAccountInUse),
12
12
  // else the topmost connected account. A named or remembered account that is
13
13
  // switched off, removed or needs a sign-in fails the call with the usable
14
- // accounts listed; no other account ever stands in for it. A conversation's
14
+ // accounts listed; no other account ever stands in for it, a new account
15
+ // given a removed one's name included (a remembered account is bound to its
16
+ // identity, not its name). A conversation's
15
17
  // call (`_meta[CONVERSATION_META]`) makes its account the last used, for the
16
18
  // conversation and the connector. Every result of a call made on an account,
17
19
  // errors included, says which account answered. A name binds a call to one
18
20
  // account; an address or label two accounts share binds none.
19
21
  // An account that fails stays listed with why (connectorAccountHealth); the
20
22
  // server only fails to start when no account can be used.
23
+ import { randomUUID } from 'node:crypto';
21
24
  import { join } from 'node:path';
22
25
  import { readJsonStateSync, updateJsonAtomicSync } from '../shared/atomic-file.mjs';
26
+ import { readSection, updateSection } from '../shared/config.mjs';
23
27
  import { accountsOfInstructions, connectorAccountsInstructions } from '../shared/connector-accounts.mjs';
24
- import { connectorById } from '../shared/connector-catalog.mjs';
28
+ import { connectorAccountsOf, connectorById, connectorOfServer } from '../shared/connector-catalog.mjs';
25
29
  import { resolvePluginData } from '../shared/plugin-paths.mjs';
26
30
 
27
31
  const PROTOCOL_VERSION = '2025-06-18';
@@ -49,8 +53,8 @@ export function forgetConnectorAccountHealth(name) {
49
53
  }
50
54
 
51
55
  // ── The last-used account ───────────────────────────────────────────────────
52
- // Per connector, in the data dir (every runtime reads the same one); per
53
- // conversation, in memory (the newest conversations kept).
56
+ // Per connector and per conversation, in the data dir (every runtime and every
57
+ // restart reads the same ones).
54
58
  const ACCOUNTS_IN_USE_FILE = 'connector-accounts-in-use.json';
55
59
  const inUseFile = () => join(resolvePluginData(), ACCOUNTS_IN_USE_FILE);
56
60
  const isRecord = (value) => Boolean(value) && typeof value === 'object' && !Array.isArray(value);
@@ -59,37 +63,149 @@ const validInUse = (value) => {
59
63
  return value;
60
64
  };
61
65
 
66
+ // A remembered account is `{ name, id }`: the name it was called by and its
67
+ // identity (connector-catalog.mjs connectorAccountId: the random id stored
68
+ // with it). A name can be given to a new account once the old one is
69
+ // removed; the identity cannot, so it binds the choice to the account.
70
+ const readInUse = () => readJsonStateSync(inUseFile(), { validate: validInUse, fallback: {} });
71
+
72
+ // Set in the accounts-in-use file once its name-only records (from before
73
+ // identities) were bound to the accounts then under those names.
74
+ const IDS_MIGRATED = '#ids';
75
+
76
+ const hasId = (account) => typeof account?.id === 'string' && account.id !== '';
77
+ const missingIds = (servers) =>
78
+ Object.values(isRecord(servers) ? servers : {}).some((cfg) => connectorAccountsOf(cfg).some((one) => !hasId(one)));
79
+
80
+ /** Test seam: runs once the config lock that gave the ids is released, before
81
+ * the binding (where another process's write may land). */
82
+ export const accountIdsDeps = { afterIdsGiven: () => {} };
83
+
84
+ /** `servers` with a random id given to every connector account stored
85
+ * without one; null when every account has one. */
86
+ function withAccountIds(servers) {
87
+ if (!missingIds(servers)) return null;
88
+ return Object.fromEntries(
89
+ Object.entries(servers).map(([name, cfg]) => {
90
+ if (!connectorAccountsOf(cfg).some((one) => !hasId(one))) return [name, cfg];
91
+ const accounts = cfg.accounts.map((account) =>
92
+ isRecord(account) && !hasId(account) ? { ...account, id: randomUUID() } : account
93
+ );
94
+ return [name, { ...cfg, accounts }];
95
+ })
96
+ );
97
+ }
98
+
99
+ /**
100
+ * Every stored connector account gets an identity, once, at every start and
101
+ * after a config change (an account written by hand has none). All under the
102
+ * accounts-in-use file's lock, so concurrent runs (processes, runtimes) and
103
+ * choices serialize: the config is changed only where an id is missing (an id
104
+ * once given is never replaced), and the first run also binds each name-only
105
+ * record (from before identities) to the account then under that name, which
106
+ * is where such a record routed until now, and marks that done. A name-only
107
+ * record found afterwards stays unbound (it fails closed). Records already
108
+ * holding an identity are never touched. True when it changed the config.
109
+ *
110
+ * The binding uses the accounts exactly as the ids were given or confirmed:
111
+ * the config is re-read nowhere after that, so an account replaced under the
112
+ * same name meanwhile (by another process) is never the one bound; it fails
113
+ * the identity check instead.
114
+ */
115
+ export function ensureConnectorAccountIds() {
116
+ let changed = false;
117
+ updateJsonAtomicSync(inUseFile(), (current) => {
118
+ const stored = isRecord(current) ? current : {};
119
+ // The stored servers whose ids the binding below uses.
120
+ let snapshot = readSection('agent')?.mcpServers;
121
+ if (missingIds(snapshot)) {
122
+ updateSection('agent', (agent) => {
123
+ const servers = withAccountIds(agent.mcpServers);
124
+ snapshot = servers ?? agent.mcpServers;
125
+ if (!servers) return agent;
126
+ changed = true;
127
+ return { ...agent, mcpServers: servers };
128
+ });
129
+ accountIdsDeps.afterIdsGiven();
130
+ }
131
+ if (stored[IDS_MIGRATED]) return undefined;
132
+ const servers = Object.values(isRecord(snapshot) ? snapshot : {});
133
+ const next = { ...stored, [IDS_MIGRATED]: true };
134
+ for (const [connector, name] of Object.entries(stored)) {
135
+ if (typeof name !== 'string' || !name) continue;
136
+ const cfg = servers.find((one) => connectorOfServer(one) === connector && connectorAccountsOf(one).length);
137
+ const account = cfg && connectorAccountsOf(cfg).find((one) => one.name === name);
138
+ if (hasId(account)) next[connector] = { name, id: account.id };
139
+ }
140
+ return next;
141
+ });
142
+ return changed;
143
+ }
144
+
145
+ /** The account catalog connector `connector` used last, null when none was
146
+ * recorded. A name-only record (from before identities, unbound) has an
147
+ * empty `id`. */
148
+ export function connectorAccountInUseRecord(connector) {
149
+ const value = readInUse()[connector];
150
+ if (typeof value === 'string') return value ? { name: value, id: '' } : null;
151
+ if (!isRecord(value) || typeof value.name !== 'string' || !value.name) return null;
152
+ return { name: value.name, id: typeof value.id === 'string' ? value.id : '' };
153
+ }
154
+
62
155
  /** The name of the account catalog connector `connector` used last, '' when
63
156
  * none was recorded. */
64
157
  export function connectorAccountInUse(connector) {
65
- const stored = readJsonStateSync(inUseFile(), { validate: validInUse, fallback: {} });
66
- return typeof stored[connector] === 'string' ? stored[connector] : '';
158
+ return connectorAccountInUseRecord(connector)?.name || '';
67
159
  }
68
160
 
69
- function rememberAccountInUse(connector, name) {
70
- if (connectorAccountInUse(connector) === name) return;
71
- updateJsonAtomicSync(inUseFile(), (current) => ({ ...(isRecord(current) ? current : {}), [connector]: name }));
161
+ function rememberAccountInUse(connector, account) {
162
+ const current = connectorAccountInUseRecord(connector);
163
+ if (current?.name === account.name && current.id === account.id) return;
164
+ updateJsonAtomicSync(inUseFile(), (stored) => ({
165
+ ...(isRecord(stored) ? stored : {}),
166
+ [connector]: { name: account.name, id: account.id },
167
+ }));
72
168
  }
73
169
 
74
- const CONVERSATIONS_KEPT = 500;
75
- // conversation → (connector → account name), oldest first.
76
- const conversations = new Map();
170
+ // Per conversation, in the data dir too, so a conversation resumed after a
171
+ // restart keeps its own account: conversation (its session id) → { accounts:
172
+ // (connector → { name, id }) }. A binding lives as long as its session: it is
173
+ // dropped only when the session is deleted (forgetConversationConnectorAccounts,
174
+ // a session purge hook), never to make room, so no live conversation falls
175
+ // back to another conversation's choice.
176
+ const CONVERSATION_ACCOUNTS_FILE = 'connector-accounts-by-conversation.json';
177
+ const conversationsFile = () => join(resolvePluginData(), CONVERSATION_ACCOUNTS_FILE);
77
178
 
78
- /** Account `name` of `connector` was removed: wherever it is the last used it
79
- * stays a removed account, so a call that would default to it keeps failing
80
- * closed, even once a new account is given the same name. */
81
- export function retireConnectorAccount(connector, name) {
82
- const removed = `${name} (removed)`;
83
- for (const own of conversations.values()) if (own.get(connector) === name) own.set(connector, removed);
84
- if (connectorAccountInUse(connector) === name) rememberAccountInUse(connector, removed);
179
+ /** Drop the connector accounts conversation `conversation` used (its session
180
+ * was deleted). */
181
+ export function forgetConversationConnectorAccounts(conversation) {
182
+ const id = text(conversation);
183
+ if (!id || !Object.hasOwn(readJsonStateSync(conversationsFile(), { validate: validInUse, fallback: {} }), id)) return;
184
+ updateJsonAtomicSync(conversationsFile(), (stored) => {
185
+ const { [id]: _gone, ...rest } = isRecord(stored) ? stored : {};
186
+ return rest;
187
+ });
85
188
  }
86
189
 
87
- function rememberConversationAccount(conversation, connector, name) {
88
- const own = conversations.get(conversation) || new Map();
89
- conversations.delete(conversation);
90
- own.set(connector, name);
91
- conversations.set(conversation, own);
92
- if (conversations.size > CONVERSATIONS_KEPT) conversations.delete(conversations.keys().next().value);
190
+ /** The account conversation `conversation` used last on `connector`, or null. */
191
+ function conversationAccount(conversation, connector) {
192
+ const own = readJsonStateSync(conversationsFile(), { validate: validInUse, fallback: {} })[conversation];
193
+ const value = isRecord(own?.accounts) ? own.accounts[connector] : null;
194
+ if (!isRecord(value) || typeof value.name !== 'string' || !value.name) return null;
195
+ return { name: value.name, id: typeof value.id === 'string' ? value.id : '' };
196
+ }
197
+
198
+ function rememberConversationAccount(conversation, connector, account) {
199
+ const current = conversationAccount(conversation, connector);
200
+ if (current?.name === account.name && current.id === account.id) return;
201
+ updateJsonAtomicSync(conversationsFile(), (stored) => {
202
+ const all = isRecord(stored) ? stored : {};
203
+ const accounts = isRecord(all[conversation]?.accounts) ? all[conversation].accounts : {};
204
+ return {
205
+ ...all,
206
+ [conversation]: { accounts: { ...accounts, [connector]: { name: account.name, id: account.id } } },
207
+ };
208
+ });
93
209
  }
94
210
 
95
211
  const ACCOUNT_PROPERTY = Object.freeze({
@@ -102,7 +218,9 @@ const ACCOUNT_PROPERTY = Object.freeze({
102
218
  const canonical = (value) => {
103
219
  if (Array.isArray(value)) return `[${value.map(canonical).join(',')}]`;
104
220
  if (isRecord(value)) {
105
- const keys = Object.keys(value).filter((key) => value[key] !== undefined).sort();
221
+ const keys = Object.keys(value)
222
+ .filter((key) => value[key] !== undefined)
223
+ .sort();
106
224
  return `{${keys.map((key) => `${JSON.stringify(key)}:${canonical(value[key])}`).join(',')}}`;
107
225
  }
108
226
  return JSON.stringify(value) ?? 'null';
@@ -146,7 +264,8 @@ const withAccountNote = (result, service, label) => ({
146
264
 
147
265
  /**
148
266
  * A `fetch` answering the accounts server of `connector` in-process. Each of
149
- * `accounts` is `{ name, email, connect(signal), callTool(params, { signal, onprogress }) }`:
267
+ * `accounts` is `{ name, id, email, connect(signal), callTool(params, { signal, onprogress }) }`
268
+ * (`id`: its identity, connector-catalog.mjs connectorAccountId):
150
269
  * `connect` resolves `{ instructions, tools }` of that account's own MCP
151
270
  * connection, `callTool` sends it one tools/call (reporting its progress to
152
271
  * `onprogress`, when given) and resolves the result; both
@@ -189,9 +308,25 @@ export function withConnectorAccountsMcp({ connector, accounts }) {
189
308
  [account] = matches;
190
309
  } else {
191
310
  const remembered =
192
- (conversation && conversations.get(conversation)?.get(connector)) || connectorAccountInUse(connector);
193
- account = remembered ? accounts.find((one) => one.name === remembered) : accounts[0];
194
- if (!account) throw refuse(`The ${service} account used last (${remembered}) is not connected now.`);
311
+ (conversation && conversationAccount(conversation, connector)) || connectorAccountInUseRecord(connector);
312
+ if (remembered) {
313
+ account = accounts.find((one) => one.name === remembered.name);
314
+ // The name must still be the account it named: one removed and its
315
+ // name given to a new account, or a record without an identity (one
316
+ // ensureConnectorAccountIds did not bind, or an account picked before
317
+ // it had an id), fails closed until an account is picked again.
318
+ if (account && !remembered.id) {
319
+ throw refuse(
320
+ `The ${service} account used last (${remembered.name}) cannot be confirmed as the same account.`
321
+ );
322
+ }
323
+ if (account && account.id !== remembered.id) {
324
+ throw refuse(`The ${service} account used last (${remembered.name} (removed)) is not connected now.`);
325
+ }
326
+ if (!account) throw refuse(`The ${service} account used last (${remembered.name}) is not connected now.`);
327
+ } else {
328
+ account = accounts[0];
329
+ }
195
330
  }
196
331
  if (!usable(account)) throw refuse(`${labelOf(account)} needs a sign-in in Connectors.`);
197
332
  const has = toolsOf.get(account.name);
@@ -275,8 +410,8 @@ export function withConnectorAccountsMcp({ connector, accounts }) {
275
410
  try {
276
411
  account = choose({ tool: name, wanted, conversation });
277
412
  if (conversation) {
278
- rememberConversationAccount(conversation, connector, account.name);
279
- rememberAccountInUse(connector, account.name);
413
+ rememberConversationAccount(conversation, connector, account);
414
+ rememberAccountInUse(connector, account);
280
415
  }
281
416
  } catch (error) {
282
417
  return reply(errorResult(error?.message || String(error)));
@@ -289,7 +424,8 @@ export function withConnectorAccountsMcp({ connector, accounts }) {
289
424
  const progressToken = params?._meta?.progressToken;
290
425
  const onprogress =
291
426
  notify && progressToken !== undefined
292
- ? (progress) => notify({ jsonrpc: '2.0', method: 'notifications/progress', params: { ...progress, progressToken } })
427
+ ? (progress) =>
428
+ notify({ jsonrpc: '2.0', method: 'notifications/progress', params: { ...progress, progressToken } })
293
429
  : undefined;
294
430
  try {
295
431
  // An unlisted tool (one only the approval gate calls) is the account's to answer.
@@ -7,7 +7,7 @@
7
7
  // for each call. The password is checked with Gmail before it is saved, and
8
8
  // never appears in a config, log, error or tool result.
9
9
  import { createHash } from 'node:crypto';
10
- import keychain from '../../lib/keychain-cjs.cjs';
10
+ import { keychainSecretStore as keychain } from '../shared/config.mjs';
11
11
  import { GMAIL_APP_PASSWORD, gmailAddress } from '../shared/connector-catalog.mjs';
12
12
  import { connectorAccountsInstructions } from '../shared/connector-accounts.mjs';
13
13
 
@@ -724,7 +724,7 @@ const TOOLS = [
724
724
 
725
725
  /** The tool definitions (name, description, schema, annotations) the server
726
726
  * lists: never the ones only the approval gate calls. */
727
- export function gmailAppPasswordTools() {
727
+ function gmailAppPasswordTools() {
728
728
  return TOOLS.filter((tool) => !tool.hidden).map(({ run, hidden: _hidden, ...tool }) => tool);
729
729
  }
730
730
 
@@ -331,7 +331,7 @@ const SERVICES = {
331
331
 
332
332
  /** The tool definitions (name, description, schema, annotations) of built-in
333
333
  * Google service `service` (`gmail`, `calendar`, `drive`). */
334
- export function googleMcpTools(service) {
334
+ function googleMcpTools(service) {
335
335
  return (SERVICES[service]?.tools || []).map(({ run, ...tool }) => tool);
336
336
  }
337
337
 
@@ -83,7 +83,7 @@ function waitReady(ms) {
83
83
  });
84
84
  }
85
85
 
86
- export function effortJudgeModelDir() {
86
+ function effortJudgeModelDir() {
87
87
  return process.env.MIXDOG_EFFORT_JUDGE_DIR || join(resolvePluginData(), 'models', 'effort-judge');
88
88
  }
89
89
 
@@ -280,7 +280,7 @@ async function runInstall() {
280
280
  * background. Runs on the first judged turn of the process, never at runtime
281
281
  * creation, so booting touches no network.
282
282
  */
283
- export function refreshEffortJudge() {
283
+ function refreshEffortJudge() {
284
284
  if (!onnxRuntimeSupported()) return;
285
285
  installEffortJudge().catch((error) => {
286
286
  // An older complete install still works.
@@ -17,7 +17,7 @@ const HEX = /(?<![0-9A-Za-z])[0-9a-fA-F]{12,}(?![0-9A-Za-z])/g;
17
17
  const SPACES = /[ \t]+/g;
18
18
  const BLANK_LINES = /\n[ \t]*\n[\n \t]*/g;
19
19
 
20
- export function cleanJudgeText(text) {
20
+ function cleanJudgeText(text) {
21
21
  return String(text || '')
22
22
  .replace(/\r\n?/g, '\n')
23
23
  .replace(ANSI, '')
@@ -49,10 +49,10 @@ export function judgeInputClean(request, prev) {
49
49
  // continues), the previous reply's first line (its topic), then as much of the
50
50
  // reply's END (what a short approval answers) as remains. Training builds the
51
51
  // same id sequence (clean_text.pack_ids) with the identical tokenizer.
52
- export const PACK_BUDGET = Object.freeze({ request: 64, prevRequest: 24, replyHead: 16 });
52
+ const PACK_BUDGET = Object.freeze({ request: 64, prevRequest: 24, replyHead: 16 });
53
53
 
54
54
  /** Split the cleaned previous reply into its first line and the remaining text. */
55
- export function splitReply(reply) {
55
+ function splitReply(reply) {
56
56
  const at = reply.indexOf('\n');
57
57
  return at < 0 ? [reply, ''] : [reply.slice(0, at), reply.slice(at + 1)];
58
58
  }
@@ -63,7 +63,7 @@ export function splitReply(reply) {
63
63
  // A result keeps its start and end (where errors and summaries sit); the
64
64
  // stored window (2000 + 1000 code points) bounds the cleaning work on huge
65
65
  // outputs. Training builds the same text (clean_text.step_judge_text).
66
- export const STEP_CALLS = 3;
66
+ const STEP_CALLS = 3;
67
67
 
68
68
  export function stepResultWindow(text) {
69
69
  const cps = Array.from(String(text ?? ''));
@@ -32,11 +32,6 @@ export const EXPLORER_SYSTEM_PROMPT = [
32
32
  const EXPLORER_TOOLS = readOnlyFilesystemTools();
33
33
  export const EXPLORER_TOOL_NAMES = Object.freeze(EXPLORER_TOOLS.map((tool) => tool.name));
34
34
 
35
- /** Exact provider prefix inputs, for cache-stability checks. */
36
- export function explorerPrefix() {
37
- return { system: EXPLORER_SYSTEM_PROMPT, tools: EXPLORER_TOOLS };
38
- }
39
-
40
35
  /**
41
36
  * Answer `query` on `route` with `provider`. Resolves the answer text (on a
42
37
  * salvage-flagged abort, the text written so far); rejects on failure.
@@ -8,8 +8,8 @@ import { runExplorer } from './explorer.mjs';
8
8
 
9
9
  // Hidden ids are reserved from user agents, so this one keeps the `-agent`
10
10
  // suffix: a plain `explorer` would hide a user's own Explorer agent.
11
- export const EXPLORER_AGENT = 'explore-agent';
12
- export const EXPLORE_TIMEOUT_MS = 120_000;
11
+ const EXPLORER_AGENT = 'explore-agent';
12
+ const EXPLORE_TIMEOUT_MS = 120_000;
13
13
  export const EXPLORE_OUTPUT_CAP = 24_000;
14
14
  const TRUNCATED = '\n[explore: answer truncated]';
15
15
 
@@ -17,7 +17,7 @@ function result(text, isError = false) {
17
17
  return { content: [{ type: 'text', text }], ...(isError ? { isError: true } : {}) };
18
18
  }
19
19
 
20
- export function normalizeExploreQueries(raw) {
20
+ function normalizeExploreQueries(raw) {
21
21
  const list = Array.isArray(raw) ? raw : [raw];
22
22
  return list.map((q) => (typeof q === 'string' ? q.trim() : '')).filter(Boolean);
23
23
  }
@@ -19,7 +19,7 @@ export function localProviderPlatformKey(platform = process.platform, arch = pro
19
19
  * RAM — exactly what llama.cpp's Metal backend reports on a 16 GB M4; larger
20
20
  * Macs may allow more, which this leaves unused. Metal reports that whole
21
21
  * working set as free, so free equals total here as it does in llama.cpp. */
22
- export function appleSiliconGpu({ name, totalBytes, wiredLimitMb }) {
22
+ function appleSiliconGpu({ name, totalBytes, wiredLimitMb }) {
23
23
  const memoryBytes = wiredLimitMb > 0 ? wiredLimitMb * 1024 ** 2 : Math.floor((totalBytes * 2) / 3);
24
24
  return { index: 0, uuid: 'MTL0', vendor: 'Apple', name, memoryBytes, freeMemoryBytes: memoryBytes };
25
25
  }
@@ -32,9 +32,9 @@ import {
32
32
 
33
33
  const REQUEST_TIMEOUT_MS = 400_000;
34
34
  const LABEL = 'ChatGPT image';
35
- export const CODEX_IMAGE_MODEL = 'gpt-image-2';
36
- export const CODEX_IMAGES_GENERATIONS_URL = new URL('images/generations', CODEX_RESPONSES_URL).href;
37
- export const CODEX_IMAGES_EDITS_URL = new URL('images/edits', CODEX_RESPONSES_URL).href;
35
+ const CODEX_IMAGE_MODEL = 'gpt-image-2';
36
+ const CODEX_IMAGES_GENERATIONS_URL = new URL('images/generations', CODEX_RESPONSES_URL).href;
37
+ const CODEX_IMAGES_EDITS_URL = new URL('images/edits', CODEX_RESPONSES_URL).href;
38
38
  const BACKGROUNDS = new Set(['transparent', 'opaque', 'auto']);
39
39
 
40
40
  const dataUrl = (ref) => `data:${ref.mime || 'image/png'};base64,${ref.base64}`;
@@ -83,7 +83,7 @@ async function generateViaVeo({ model, prompt, options, references = [], signal,
83
83
  if ([4, 6, 8].includes(duration)) parameters.durationSeconds = duration;
84
84
 
85
85
  // The budget starts at submission, not after it: a hung predictLongRunning
86
- // POST used to run without any ceiling of its own.
86
+ // POST would otherwise run without any ceiling of its own.
87
87
  const deadline = Date.now() + TOTAL_TIMEOUT_MS;
88
88
  const started = await fetch(`${BASE_URL}/models/${encodeURIComponent(model)}:predictLongRunning`, {
89
89
  method: 'POST',
@@ -91,7 +91,7 @@ export function imageApiUsage(body) {
91
91
  }
92
92
 
93
93
  /** True when the provider reported something billable for the request. */
94
- export function hasReportedUsage(usage) {
94
+ function hasReportedUsage(usage) {
95
95
  if (!usage) return false;
96
96
  // Seconds are only attached once a video generation completed (billed per second).
97
97
  return (
@@ -231,7 +231,7 @@ export function saveMediaAsset({ kind, lane, model, prompt, options = {}, mime,
231
231
  // whose bytes are all NUL.
232
232
  writeFileAtomicSync(path, bytes);
233
233
  entry.file = file;
234
- // The gallery is NOT capped (user). An entry-count trim used to unlink the
234
+ // The gallery is NOT capped (user). An entry-count trim would unlink the
235
235
  // oldest files here, which is data loss nobody asked for: a generated asset
236
236
  // leaves this store only through an explicit delete.
237
237
  mutateIndex((assets) => [entry, ...assets]);
@@ -59,7 +59,8 @@ import {
59
59
  resolveCoalesceMaxRetries,
60
60
  scheduleCoalescedCycleRetry,
61
61
  } from './lib/memory-cycle-requests.mjs';
62
- import { drainEmbeddingReindex } from './lib/embedding-reindex.mjs';
62
+ import { drainEmbeddingReindex, runRootEmbedSweep } from './lib/embedding-reindex.mjs';
63
+ import { sweepRootEmbedText } from './lib/memory-embed.mjs';
63
64
  import { refreshCoreMemoryFile } from './lib/core-memory-file.mjs';
64
65
  import { resolveProjectId, resolveProjectScope } from './lib/project-id-resolver.mjs';
65
66
  import {
@@ -432,6 +433,15 @@ function _startEmbeddingReindex() {
432
433
  `ok=${summary.succeeded} failed=${summary.failed}\n`
433
434
  );
434
435
  }
436
+ return runRootEmbedSweep({
437
+ sweepStep: ({ signal }) => sweepRootEmbedText(db, { signal }),
438
+ signal: controller.signal,
439
+ });
440
+ })
441
+ .then((sweep) => {
442
+ if (sweep.replaced > 0) {
443
+ __mixdogMemoryLog(`[memory-service] root text sweep steps=${sweep.steps} replaced=${sweep.replaced}\n`);
444
+ }
435
445
  })
436
446
  .catch((error) => {
437
447
  if (!controller.signal.aborted) {
@@ -46,3 +46,30 @@ export async function drainEmbeddingReindex({
46
46
 
47
47
  return { passes, attempted, succeeded, failed };
48
48
  }
49
+
50
+ // The root-text sweep replaces vectors that still work, so it has no urgency:
51
+ // small steps with long rests keep a ~62k-root backfill in the background of a
52
+ // working session instead of competing with it.
53
+ const ROOT_SWEEP_PAUSE_MS = 4_000;
54
+
55
+ export async function runRootEmbedSweep({
56
+ sweepStep,
57
+ signal,
58
+ pauseMs = ROOT_SWEEP_PAUSE_MS,
59
+ wait = waitForNextPass,
60
+ } = {}) {
61
+ if (typeof sweepStep !== 'function') {
62
+ throw new TypeError('runRootEmbedSweep: sweepStep required');
63
+ }
64
+ let steps = 0;
65
+ let replaced = 0;
66
+ while (true) {
67
+ throwIfAborted(signal);
68
+ const result = await sweepStep({ signal });
69
+ steps += 1;
70
+ replaced += Number(result?.replaced ?? 0);
71
+ if (result?.done) break;
72
+ await wait(pauseMs, signal);
73
+ }
74
+ return { steps, replaced };
75
+ }