mixdog 1.3.0 → 1.3.2

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 (423) hide show
  1. package/NOTICE.md +52 -9
  2. package/README.md +8 -4
  3. package/package.json +2 -2
  4. package/scripts/native-release-status.mjs +238 -0
  5. package/src/defaults/shipped-history.json +8 -1
  6. package/src/defaults/skills/pptx/scripts/qc-pages.mjs +3 -2
  7. package/src/defaults/skills/setup/SKILL.md +23 -1
  8. package/src/defaults/skills/setup/references/actions.md +54 -4
  9. package/src/defaults/skills/setup/references/surfaces.md +23 -3
  10. package/src/defaults/skills/setup-guide/SKILL.md +17 -10
  11. package/src/defaults/skills/visualize/SKILL.md +9 -6
  12. package/src/defaults/skills/visualize/references/craft.md +8 -1
  13. package/src/help.mjs +1 -1
  14. package/src/lib/keychain-cjs.cjs +4 -1
  15. package/src/lib/rules-builder.cjs +14 -7
  16. package/src/output-styles/common.md +13 -8
  17. package/src/rules/agent-mode/AGENT_MODE.md +9 -6
  18. package/src/rules/agent-mode/MIXY.md +11 -6
  19. package/src/rules/lead/LEAD.md +2 -2
  20. package/src/rules/shared/10-tool-workflow.md +4 -0
  21. package/src/rules/shared/20-research.md +2 -0
  22. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/preset.mjs +5 -0
  23. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/session-prep.mjs +8 -0
  24. package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +6 -1
  25. package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +114 -26
  26. package/src/runtime/agent/orchestrator/agent-runtime/maintenance-route.mjs +8 -0
  27. package/src/runtime/agent/orchestrator/agent-runtime/room-supervisor-completion.mjs +5 -4
  28. package/src/runtime/agent/orchestrator/agent-trace.mjs +3 -0
  29. package/src/runtime/agent/orchestrator/cache-break-trace.mjs +4 -0
  30. package/src/runtime/agent/orchestrator/config-presets.mjs +2 -0
  31. package/src/runtime/agent/orchestrator/config-storage.mjs +10 -3
  32. package/src/runtime/agent/orchestrator/config.mjs +11 -0
  33. package/src/runtime/agent/orchestrator/context/role-instructions.mjs +81 -16
  34. package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +97 -4
  35. package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +6 -10
  36. package/src/runtime/agent/orchestrator/mcp/client.mjs +7 -4
  37. package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +80 -31
  38. package/src/runtime/agent/orchestrator/providers/anthropic-model-resolve.mjs +1 -1
  39. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
  40. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +67 -38
  41. package/src/runtime/agent/orchestrator/providers/anthropic-turn-result.mjs +2 -0
  42. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-catalog.mjs +7 -2
  43. package/src/runtime/agent/orchestrator/providers/antigravity-request.mjs +6 -2
  44. package/src/runtime/agent/orchestrator/providers/auto-effort.mjs +34 -16
  45. package/src/runtime/agent/orchestrator/providers/cursor-wire.mjs +31 -4
  46. package/src/runtime/agent/orchestrator/providers/cursor.mjs +4 -1
  47. package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +11 -8
  48. package/src/runtime/agent/orchestrator/providers/lib/anthropic-prefix-trace.mjs +76 -0
  49. package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +19 -1
  50. package/src/runtime/agent/orchestrator/providers/lib/tail-reminder-split.mjs +13 -0
  51. package/src/runtime/agent/orchestrator/providers/lib/tool-call-wire-ids.mjs +65 -0
  52. package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +16 -1
  53. package/src/runtime/agent/orchestrator/providers/mixdog-local.mjs +3 -1
  54. package/src/runtime/agent/orchestrator/providers/model-proxy-provider.mjs +1 -0
  55. package/src/runtime/agent/orchestrator/providers/openai-codex-metadata.mjs +5 -5
  56. package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +9 -5
  57. package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +9 -1
  58. package/src/runtime/agent/orchestrator/providers/openai-compat-retry-profile.mjs +8 -2
  59. package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +10 -2
  60. package/src/runtime/agent/orchestrator/providers/openai-direct-request.mjs +30 -3
  61. package/src/runtime/agent/orchestrator/providers/openai-model-capabilities.mjs +1 -1
  62. package/src/runtime/agent/orchestrator/providers/openai-responses-input.mjs +3 -1
  63. package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +3 -1
  64. package/src/runtime/agent/orchestrator/providers/opencode-go-oauth.mjs +61 -8
  65. package/src/runtime/agent/orchestrator/providers/provider-error-kind.mjs +14 -2
  66. package/src/runtime/agent/orchestrator/providers/registry.mjs +9 -0
  67. package/src/runtime/agent/orchestrator/providers/retry-executor.mjs +17 -0
  68. package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +90 -24
  69. package/src/runtime/agent/orchestrator/runtime-core/fs-utils.mjs +8 -1
  70. package/src/runtime/agent/orchestrator/runtime-core/goal-mutations.mjs +1 -1
  71. package/src/runtime/agent/orchestrator/runtime-core/goal-storage.mjs +68 -22
  72. package/src/runtime/agent/orchestrator/runtime-core/goal-tool-exec.mjs +1 -1
  73. package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +5 -5
  74. package/src/runtime/agent/orchestrator/runtime-core/route-context-state.mjs +81 -0
  75. package/src/runtime/agent/orchestrator/runtime-core/session-text.mjs +2 -1
  76. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +12 -1
  77. package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +17 -6
  78. package/src/runtime/agent/orchestrator/runtime-core/workflow/agents.mjs +41 -10
  79. package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +6 -4
  80. package/src/runtime/agent/orchestrator/runtime-core/workflow/packs.mjs +8 -4
  81. package/src/runtime/agent/orchestrator/runtime-core/workflow.mjs +2 -0
  82. package/src/runtime/agent/orchestrator/session/agent-mode.mjs +0 -6
  83. package/src/runtime/agent/orchestrator/session/agent-room-supervisor.d.mts +1 -1
  84. package/src/runtime/agent/orchestrator/session/agent-room-supervisor.mjs +22 -4
  85. package/src/runtime/agent/orchestrator/session/agent-room.d.mts +21 -2
  86. package/src/runtime/agent/orchestrator/session/agent-room.mjs +149 -45
  87. package/src/runtime/agent/orchestrator/session/attachment-preflight.mjs +80 -0
  88. package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +4 -1
  89. package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +14 -11
  90. package/src/runtime/agent/orchestrator/session/compact/forked-summary.mjs +3 -0
  91. package/src/runtime/agent/orchestrator/session/compact/runner.mjs +68 -18
  92. package/src/runtime/agent/orchestrator/session/compact/summary-mode.mjs +16 -0
  93. package/src/runtime/agent/orchestrator/session/compact/summary-route.mjs +87 -0
  94. package/src/runtime/agent/orchestrator/session/compact/summary.mjs +2 -0
  95. package/src/runtime/agent/orchestrator/session/compact/text-utils.mjs +5 -1
  96. package/src/runtime/agent/orchestrator/session/compact/user-message-kind.mjs +1 -1
  97. package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +1 -1
  98. package/src/runtime/agent/orchestrator/session/context-utils.mjs +41 -10
  99. package/src/runtime/agent/orchestrator/session/human-gate/delegation.mjs +230 -0
  100. package/src/runtime/agent/orchestrator/session/human-gate/gate.mjs +156 -25
  101. package/src/runtime/agent/orchestrator/session/human-gate/outbound-policy.mjs +20 -0
  102. package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +21 -9
  103. package/src/runtime/agent/orchestrator/session/human-gate/run-policy.mjs +73 -0
  104. package/src/runtime/agent/orchestrator/session/human-gate/store.mjs +55 -27
  105. package/src/runtime/agent/orchestrator/session/human-gate/unattended-port.mjs +15 -0
  106. package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +4 -1
  107. package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +189 -105
  108. package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +9 -0
  109. package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +6 -2
  110. package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +111 -9
  111. package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +11 -14
  112. package/src/runtime/agent/orchestrator/session/loop/steering.mjs +3 -0
  113. package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +38 -5
  114. package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +21 -0
  115. package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +2 -1
  116. package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +12 -0
  117. package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +11 -5
  118. package/src/runtime/agent/orchestrator/session/loop/usage.mjs +46 -4
  119. package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +13 -2
  120. package/src/runtime/agent/orchestrator/session/manager/ask-turn-commit.mjs +18 -8
  121. package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +4 -0
  122. package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +6 -0
  123. package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +4 -0
  124. package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +44 -18
  125. package/src/runtime/agent/orchestrator/session/manager/orchestration-mode-switch-notice.mjs +99 -0
  126. package/src/runtime/agent/orchestrator/session/manager/owner-route-fallbacks.mjs +42 -0
  127. package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +3 -9
  128. package/src/runtime/agent/orchestrator/session/manager/pending-spool-file.mjs +1 -1
  129. package/src/runtime/agent/orchestrator/session/manager/pending-spool-shard.mjs +5 -3
  130. package/src/runtime/agent/orchestrator/session/manager/provider-replay.mjs +50 -0
  131. package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +40 -1
  132. package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +12 -0
  133. package/src/runtime/agent/orchestrator/session/manager/runtime-state.mjs +20 -0
  134. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +62 -47
  135. package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +6 -8
  136. package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +12 -1
  137. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-journal.mjs +6 -15
  138. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint.mjs +7 -1
  139. package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +24 -8
  140. package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +1 -1
  141. package/src/runtime/agent/orchestrator/session/manager/workflow-switch-notice.mjs +94 -13
  142. package/src/runtime/agent/orchestrator/session/mixy-name.mjs +5 -2
  143. package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +42 -10
  144. package/src/runtime/agent/orchestrator/session/provider-prefix-guard.mjs +21 -3
  145. package/src/runtime/agent/orchestrator/session/routine-result.d.mts +35 -4
  146. package/src/runtime/agent/orchestrator/session/routine-result.mjs +179 -16
  147. package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +5 -1
  148. package/src/runtime/agent/orchestrator/session/side-question-store.mjs +3 -1
  149. package/src/runtime/agent/orchestrator/session/store/canonical-reader.mjs +41 -7
  150. package/src/runtime/agent/orchestrator/session/store/lifecycle-barriers.mjs +10 -2
  151. package/src/runtime/agent/orchestrator/session/store/load-cache.mjs +14 -2
  152. package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +15 -1
  153. package/src/runtime/agent/orchestrator/session/store/sweep/sweep-record.mjs +8 -3
  154. package/src/runtime/agent/orchestrator/session/store/sweep/sweep-row.mjs +36 -1
  155. package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +4 -1
  156. package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +40 -5
  157. package/src/runtime/agent/orchestrator/session/store-summary-last-message.mjs +47 -2
  158. package/src/runtime/agent/orchestrator/session/tail-reminder-rules.mjs +125 -0
  159. package/src/runtime/agent/orchestrator/session/tool-batch/finalize.mjs +4 -0
  160. package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +78 -43
  161. package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +49 -14
  162. package/src/runtime/agent/orchestrator/session/transcript-restore/user-text.mjs +134 -17
  163. package/src/runtime/agent/orchestrator/tools/builtin/advisory-lock.mjs +35 -13
  164. package/src/runtime/agent/orchestrator/tools/builtin/atomic-write.mjs +25 -5
  165. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/backgrounded-result.mjs +4 -3
  166. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/completed-result.mjs +13 -14
  167. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/transport-artifacts.mjs +9 -0
  168. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +19 -14
  169. package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +7 -1
  170. package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +6 -14
  171. package/src/runtime/agent/orchestrator/tools/builtin/pdf-test-fixtures.mjs +5 -3
  172. package/src/runtime/agent/orchestrator/tools/builtin/read-image.mjs +4 -2
  173. package/src/runtime/agent/orchestrator/tools/builtin/read-single-media.mjs +47 -2
  174. package/src/runtime/agent/orchestrator/tools/builtin/read-special-files.mjs +264 -87
  175. package/src/runtime/agent/orchestrator/tools/builtin/shell-analysis.mjs +10 -4
  176. package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +34 -21
  177. package/src/runtime/agent/orchestrator/tools/code-graph/constants.mjs +8 -4
  178. package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +9 -30
  179. package/src/runtime/agent/orchestrator/tools/lib/shell-run-settle.mjs +24 -12
  180. package/src/runtime/agent/orchestrator/tools/lib/shell-run-spawn.mjs +3 -2
  181. package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +6 -2
  182. package/src/runtime/agent/orchestrator/tools/patch/delete-quarantine.mjs +2 -1
  183. package/src/runtime/agent/orchestrator/tools/patch/replay-capture.mjs +4 -2
  184. package/src/runtime/agent/orchestrator/tools/patch/rollback-state.mjs +33 -2
  185. package/src/runtime/agent/orchestrator/tools/patch-manifest.json +13 -13
  186. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +5 -3
  187. package/src/runtime/agent/orchestrator/tools/shell-exec-output.mjs +3 -1
  188. package/src/runtime/attachments/attachment-reference.mjs +155 -0
  189. package/src/runtime/attachments/limits.mjs +5 -1
  190. package/src/runtime/attachments/office-extract.mjs +3 -6
  191. package/src/runtime/attachments/pdf-extract.mjs +84 -10
  192. package/src/runtime/attachments/store.mjs +55 -30
  193. package/src/runtime/browser-bridge/client.mjs +73 -20
  194. package/src/runtime/channels/lib/runtime-paths.mjs +1 -1
  195. package/src/runtime/channels/lib/scheduler.mjs +14 -7
  196. package/src/runtime/channels/lib/state-file.mjs +15 -15
  197. package/src/runtime/channels/lib/voice-runtime-fetcher.mjs +14 -13
  198. package/src/runtime/channels/lib/webhook/relay-tunnel.mjs +22 -18
  199. package/src/runtime/channels/lib/webhook/session-dispatch.mjs +14 -36
  200. package/src/runtime/channels/lib/worker-main.mjs +3 -2
  201. package/src/runtime/effort-judge/compact-tokenizer.mjs +8 -2
  202. package/src/runtime/effort-judge/judge-client.mjs +6 -3
  203. package/src/runtime/effort-judge/model-install.mjs +16 -8
  204. package/src/runtime/effort-judge/model-manifest.json +7 -7
  205. package/src/runtime/local-provider/asset-installer.mjs +10 -4
  206. package/src/runtime/local-provider/catalog.mjs +5 -2
  207. package/src/runtime/local-provider/registered-models.mjs +64 -27
  208. package/src/runtime/local-provider/server.mjs +2 -3
  209. package/src/runtime/media/adapters/image-api.mjs +89 -0
  210. package/src/runtime/media/auth.mjs +64 -1
  211. package/src/runtime/media/catalog.mjs +66 -4
  212. package/src/runtime/media/jobs.mjs +4 -0
  213. package/src/runtime/media/lanes.mjs +46 -5
  214. package/src/runtime/media/media-usage.mjs +17 -0
  215. package/src/runtime/media/renditions.mjs +15 -15
  216. package/src/runtime/media/store.mjs +36 -35
  217. package/src/runtime/media/tool.mjs +8 -1
  218. package/src/runtime/memory/lib/cycle-scheduler/health-ledger.mjs +8 -2
  219. package/src/runtime/memory/lib/embedding-model-files.mjs +30 -7
  220. package/src/runtime/memory/lib/ingest/transcript-tail.mjs +16 -7
  221. package/src/runtime/memory/lib/pg/process.mjs +8 -4
  222. package/src/runtime/memory/lib/project-id-resolver.mjs +5 -1
  223. package/src/runtime/memory/lib/runtime-fetcher.mjs +6 -1
  224. package/src/runtime/office/core/journal.mjs +7 -14
  225. package/src/runtime/office/design/library/design-library-core.mjs +4 -16
  226. package/src/runtime/office/pdf/ocr-engine-worker.mjs +37 -0
  227. package/src/runtime/office/pdf/ocr-engine.mjs +146 -0
  228. package/src/runtime/office/pdf/pdf-ocr.mjs +51 -21
  229. package/src/runtime/office/pdf/pdf-render.mjs +30 -18
  230. package/src/runtime/office/portable/ooxml-validator.mjs +2 -2
  231. package/src/runtime/office/portable/portable-soffice.mjs +4 -0
  232. package/src/runtime/shared/agent-kind-migration.mjs +200 -0
  233. package/src/runtime/shared/agent-kind.mjs +152 -0
  234. package/src/runtime/shared/agent-message-envelope.d.mts +6 -0
  235. package/src/runtime/shared/agent-message-envelope.mjs +44 -0
  236. package/src/runtime/shared/agent-reap-state.d.mts +4 -0
  237. package/src/runtime/shared/agent-route-config.d.mts +1 -0
  238. package/src/runtime/shared/agent-route-config.mjs +22 -8
  239. package/src/runtime/shared/agent-store.mjs +149 -0
  240. package/src/runtime/shared/agent-task-starts.mjs +27 -0
  241. package/src/runtime/shared/atomic-file.d.mts +50 -0
  242. package/src/runtime/shared/atomic-file.mjs +394 -132
  243. package/src/runtime/shared/background-tasks.mjs +7 -4
  244. package/src/runtime/shared/bot-hops.mjs +30 -0
  245. package/src/runtime/shared/bot-split-migration.mjs +457 -0
  246. package/src/runtime/shared/bounded-download.mjs +4 -2
  247. package/src/runtime/shared/config-patch.mjs +20 -1
  248. package/src/runtime/shared/config.mjs +39 -9
  249. package/src/runtime/shared/connector-catalog.d.mts +1 -2
  250. package/src/runtime/shared/connector-catalog.mjs +2 -4
  251. package/src/runtime/shared/connector-triggers.mjs +2 -0
  252. package/src/runtime/shared/defaults-separation.mjs +6 -2
  253. package/src/runtime/shared/delegated-approval-host.mjs +74 -0
  254. package/src/runtime/shared/err-text.mjs +7 -1
  255. package/src/runtime/shared/error-presentation.mjs +113 -10
  256. package/src/runtime/shared/file-has-data.mjs +28 -0
  257. package/src/runtime/shared/handoff-artifacts.d.mts +20 -0
  258. package/src/runtime/shared/handoff-artifacts.mjs +61 -0
  259. package/src/runtime/shared/llm/provider-model-identities.mjs +6 -1
  260. package/src/runtime/shared/llm/usage-accounting.mjs +7 -1
  261. package/src/runtime/shared/llm/usage-ledger-import.mjs +37 -18
  262. package/src/runtime/shared/model-route-fallback.mjs +79 -7
  263. package/src/runtime/shared/pending-agent-work.mjs +54 -0
  264. package/src/runtime/shared/plain-preview.mjs +22 -17
  265. package/src/runtime/shared/process-lifecycle.mjs +8 -12
  266. package/src/runtime/shared/projects.mjs +50 -41
  267. package/src/runtime/shared/provider-accounts.mjs +17 -12
  268. package/src/runtime/shared/routine-trigger.d.mts +6 -1
  269. package/src/runtime/shared/routine-trigger.mjs +14 -6
  270. package/src/runtime/shared/run-child.d.mts +3 -0
  271. package/src/runtime/shared/run-child.mjs +24 -3
  272. package/src/runtime/shared/sensitive-path-rules.d.mts +15 -0
  273. package/src/runtime/shared/sensitive-path-rules.mjs +256 -0
  274. package/src/runtime/shared/session-baseline-store.mjs +8 -2
  275. package/src/runtime/shared/singleton-owner.mjs +7 -6
  276. package/src/runtime/shared/skill-tool-dependencies.mjs +4 -10
  277. package/src/runtime/shared/staged-update.mjs +4 -2
  278. package/src/runtime/shared/statusline/statusline-segments.mjs +4 -15
  279. package/src/runtime/shared/tool-execution-contract.mjs +6 -0
  280. package/src/runtime/shared/transcript-metadata.mjs +28 -3
  281. package/src/runtime/shared/transcript-writer/session-record.mjs +7 -6
  282. package/src/runtime/shared/turn-snapshot-store.mjs +5 -4
  283. package/src/runtime/shared/turn-snapshot.mjs +44 -2
  284. package/src/runtime/shared/usage-readout-totals.mjs +15 -13
  285. package/src/runtime/shared/user-cwd.mjs +9 -4
  286. package/src/runtime/shared/user-data-guard.mjs +46 -44
  287. package/src/runtime/shared/utf8-cut.mjs +10 -0
  288. package/src/runtime/shared/worktrees/activity-gate.mjs +269 -61
  289. package/src/runtime/shared/worktrees/registry.mjs +26 -26
  290. package/src/runtime/tidy/core-install.mjs +26 -4
  291. package/src/runtime/tidy/install.mjs +91 -23
  292. package/src/runtime/web-search/lib/config.mjs +4 -16
  293. package/src/session-runtime/agent-home-delivery.mjs +859 -136
  294. package/src/session-runtime/agent-room-delivery.mjs +167 -19
  295. package/src/session-runtime/agent-task-sessions.mjs +831 -69
  296. package/src/session-runtime/agent-tool-routing.mjs +1 -0
  297. package/src/session-runtime/boot/apis.mjs +58 -24
  298. package/src/session-runtime/boot/config.mjs +1 -0
  299. package/src/session-runtime/boot/facade.mjs +11 -1
  300. package/src/session-runtime/boot/infrastructure.mjs +14 -2
  301. package/src/session-runtime/boot/providers.mjs +16 -6
  302. package/src/session-runtime/boot/shared.mjs +12 -6
  303. package/src/session-runtime/boot/tools.mjs +2 -2
  304. package/src/session-runtime/bot-status.mjs +432 -0
  305. package/src/session-runtime/config-lifecycle/lead-route-sync.mjs +29 -0
  306. package/src/session-runtime/config-lifecycle.mjs +78 -32
  307. package/src/session-runtime/cwd-plugins/core-memory-context.mjs +2 -4
  308. package/src/session-runtime/handoff-attachments.mjs +593 -0
  309. package/src/session-runtime/held-requests.mjs +36 -33
  310. package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +10 -1
  311. package/src/session-runtime/internal-tool-executor/feature-tools.mjs +2 -2
  312. package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +45 -6
  313. package/src/session-runtime/lifecycle/session-catalog.mjs +12 -2
  314. package/src/session-runtime/lifecycle/teardown.mjs +11 -3
  315. package/src/session-runtime/mcp-glue/connect.mjs +100 -186
  316. package/src/session-runtime/mcp-glue/initial-connect-gate.mjs +57 -0
  317. package/src/session-runtime/mcp-glue/server-connection.mjs +71 -0
  318. package/src/session-runtime/media-api.mjs +5 -2
  319. package/src/session-runtime/model-route/route-persist.mjs +2 -2
  320. package/src/session-runtime/model-route/route-tuning.mjs +11 -2
  321. package/src/session-runtime/model-route/set-route.mjs +82 -2
  322. package/src/session-runtime/native-web-search.mjs +2 -2
  323. package/src/session-runtime/new-session-config.mjs +6 -1
  324. package/src/session-runtime/owned-automation-run.mjs +8 -1
  325. package/src/session-runtime/room-member-gate.mjs +16 -3
  326. package/src/session-runtime/route-resolution.mjs +21 -19
  327. package/src/session-runtime/route-state.mjs +1 -59
  328. package/src/session-runtime/routine-home-turn.mjs +5 -3
  329. package/src/session-runtime/runtime-bootstrap.mjs +5 -3
  330. package/src/session-runtime/runtime-paths.mjs +11 -5
  331. package/src/session-runtime/runtime-tunables.mjs +6 -0
  332. package/src/session-runtime/services/agent-tool/close-flow/close-all.mjs +11 -2
  333. package/src/session-runtime/services/agent-tool/close-flow.mjs +4 -2
  334. package/src/session-runtime/services/agent-tool/execute-send.mjs +1 -0
  335. package/src/session-runtime/services/agent-tool/execute-spawn.mjs +1 -0
  336. package/src/session-runtime/services/agent-tool/helpers.mjs +24 -5
  337. package/src/session-runtime/services/agent-tool/restart-notify.mjs +10 -0
  338. package/src/session-runtime/services/agent-tool/send-flow.mjs +36 -24
  339. package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +4 -0
  340. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +6 -3
  341. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +12 -6
  342. package/src/session-runtime/services/agent-tool/spawn-preset.mjs +5 -8
  343. package/src/session-runtime/services/agent-tool/tool-def.mjs +7 -0
  344. package/src/session-runtime/services/agent-tool/worker-index/row-liveness.mjs +22 -2
  345. package/src/session-runtime/services/agent-tool/worker-index.mjs +4 -6
  346. package/src/session-runtime/services/agent-tool.mjs +6 -0
  347. package/src/session-runtime/services/daemon-crash-capture/daemon-exit-record.mjs +1 -1
  348. package/src/session-runtime/services/daemon-crash-capture/retention.mjs +4 -3
  349. package/src/session-runtime/services/hook-bus/config-loader.mjs +14 -5
  350. package/src/session-runtime/services/hook-bus/rule-file.mjs +49 -11
  351. package/src/session-runtime/services/plugin-admin.mjs +26 -26
  352. package/src/session-runtime/services/provider-admin.mjs +14 -4
  353. package/src/session-runtime/services/schedule-access.mjs +33 -4
  354. package/src/session-runtime/services/seeds.mjs +4 -3
  355. package/src/session-runtime/services/usage-dashboard.mjs +1 -1
  356. package/src/session-runtime/services/usage-stats-model.mjs +2 -1
  357. package/src/session-runtime/session-create/materialize.mjs +2 -3
  358. package/src/session-runtime/session-create/session-options.mjs +15 -2
  359. package/src/session-runtime/settings-builtin-tools-api.mjs +63 -1
  360. package/src/session-runtime/settings-compaction-api.mjs +86 -39
  361. package/src/session-runtime/setup-tool/executor.mjs +20 -3
  362. package/src/session-runtime/setup-tool/extended-actions.mjs +19 -7
  363. package/src/session-runtime/setup-tool/settings-contract.mjs +37 -1
  364. package/src/session-runtime/setup-tool/tool-defs.mjs +20 -3
  365. package/src/session-runtime/skills-api.mjs +12 -5
  366. package/src/session-runtime/tool-policy/agent-profile-fold.mjs +265 -0
  367. package/src/session-runtime/tool-policy/mode-switch.mjs +54 -0
  368. package/src/session-runtime/tool-policy/pending-switches.mjs +59 -0
  369. package/src/session-runtime/tool-policy/policy-stage.mjs +165 -0
  370. package/src/session-runtime/tool-policy/session-switches.mjs +169 -0
  371. package/src/session-runtime/tool-policy/surface-helpers.mjs +114 -0
  372. package/src/session-runtime/tool-policy/workflow-overlay.mjs +145 -0
  373. package/src/session-runtime/tool-policy-refresh.mjs +47 -358
  374. package/src/session-runtime/tool-surface.mjs +5 -3
  375. package/src/session-runtime/turn/turn-run/turn-prepare.mjs +99 -81
  376. package/src/session-runtime/turn/turn-run/turn-timing.mjs +4 -3
  377. package/src/session-runtime/turn/turn-run.mjs +2 -1
  378. package/src/session-runtime/workflow-agents-api/agent-connectors.mjs +54 -7
  379. package/src/session-runtime/workflow-agents-api/agent-editor.mjs +578 -301
  380. package/src/session-runtime/workflow-agents-api/agent-route.mjs +113 -53
  381. package/src/session-runtime/workflow-agents-api/onboarding.mjs +11 -4
  382. package/src/session-runtime/workflow-agents-api/shared.mjs +5 -1
  383. package/src/session-runtime/workflow-agents-api/style-and-mode.mjs +14 -1
  384. package/src/session-runtime/workflow-agents-api/workflow-packs.mjs +6 -3
  385. package/src/session-runtime/workspace/workspace-state.mjs +7 -6
  386. package/src/standalone/daemon-agent-control.mjs +4 -1
  387. package/src/standalone/daemon-session-control.mjs +60 -11
  388. package/src/standalone/daemon.mjs +34 -4
  389. package/src/standalone/local-session-runtime.mjs +22 -14
  390. package/src/standalone/session-client.mjs +7 -2
  391. package/src/standalone/session-protocol.mjs +7 -0
  392. package/src/standalone/session-service/agent-tree/agent-turns.mjs +46 -3
  393. package/src/standalone/session-service/agent-tree.mjs +4 -3
  394. package/src/standalone/session-service/session-calls/session-turns.mjs +19 -0
  395. package/src/standalone/session-service.mjs +11 -0
  396. package/src/standalone/session-state-projection.mjs +19 -9
  397. package/src/standalone/session-tool-output.mjs +35 -9
  398. package/src/tui/app/maintenance-pickers/auto-clear-picker.mjs +19 -13
  399. package/src/tui/app/settings-picker/settings-rows.mjs +2 -2
  400. package/src/tui/app/slash-commands.mjs +1 -1
  401. package/src/tui/app/usage-context-panels/context-model.mjs +8 -2
  402. package/src/tui/dist/index.mjs +599 -342
  403. package/src/tui/prompt-history-store.mjs +16 -21
  404. package/src/tui/session/context-state.mjs +4 -0
  405. package/src/tui/session/notice-surface.mjs +3 -4
  406. package/src/tui/session/session-api/intake/abort.mjs +19 -1
  407. package/src/tui/session/session-api/media.mjs +2 -1
  408. package/src/tui/session/session-api/routes-agent-definitions.mjs +75 -0
  409. package/src/tui/session/session-api/routes-write.mjs +203 -0
  410. package/src/tui/session/session-api/routes.mjs +23 -236
  411. package/src/tui/session/session-api/settings.mjs +14 -1
  412. package/src/tui/session/session-flow/drain.mjs +28 -3
  413. package/src/tui/session/session-flow/failed-turn-rewind.mjs +4 -2
  414. package/src/tui/session/session-flow/queue/take-entries.mjs +8 -0
  415. package/src/tui/session/session-flow/steering.mjs +8 -3
  416. package/src/tui/session/tool-approval.mjs +185 -20
  417. package/src/tui/session/transcript-intake.mjs +4 -0
  418. package/src/tui/session/turn-live-call.mjs +11 -3
  419. package/src/tui/session/turn.mjs +36 -17
  420. package/src/tui/transcript-tool-failures.mjs +8 -2
  421. package/src/vendor/statusline/src/gateway/route-meta.mjs +7 -8
  422. package/src/vendor/statusline/src/gateway/session-routes.mjs +6 -7
  423. package/src/rules/agent-mode/ROUTINE.md +0 -6
@@ -3,9 +3,10 @@
3
3
  * Stored under MIXDOG data dir (not the repo working tree).
4
4
  */
5
5
  import { createHash } from 'node:crypto';
6
- import { chmodSync, existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
7
- import { chmod, mkdir, rename, writeFile } from 'node:fs/promises';
6
+ import { mkdirSync } from 'node:fs';
7
+ import { mkdir } from 'node:fs/promises';
8
8
  import { dirname, join, resolve } from 'node:path';
9
+ import { readJsonStateSync, writeFileAtomicAsync, writeFileAtomicSync } from '../runtime/shared/atomic-file.mjs';
9
10
  import { resolvePluginData } from '../runtime/shared/plugin-paths.mjs';
10
11
 
11
12
  export const PROMPT_HISTORY_LIMIT = 50;
@@ -33,10 +34,18 @@ function historyFilePath(cwd) {
33
34
  }
34
35
 
35
36
  function readEntries(filePath) {
36
- if (!filePath || !existsSync(filePath)) return [];
37
+ if (!filePath) return [];
37
38
  try {
38
- const parsed = JSON.parse(readFileSync(filePath, 'utf8'));
39
- const entries = Array.isArray(parsed?.entries) ? parsed.entries : [];
39
+ // A damaged file (NUL, truncated) is kept aside as *.corrupt-<ts> and the
40
+ // history starts empty; the next flush writes a fresh file.
41
+ const parsed = readJsonStateSync(filePath, {
42
+ mode: 0o600,
43
+ validate: (value) => {
44
+ if (!Array.isArray(value?.entries)) throw new TypeError('prompt history has no entries');
45
+ return value;
46
+ },
47
+ });
48
+ const entries = parsed ? parsed.entries : [];
40
49
  return entries.map((entry) => String(entry || '').trim()).filter((entry) => promptHistoryKey(entry));
41
50
  } catch {
42
51
  return [];
@@ -52,14 +61,7 @@ function writeEntriesSync(filePath, entries) {
52
61
  try {
53
62
  // Prompt text may be sensitive; restrict directory/file to the owning user.
54
63
  mkdirSync(dirname(filePath), { recursive: true, mode: 0o700 });
55
- const tmp = `${filePath}.${process.pid}.tmp`;
56
- writeFileSync(tmp, buildPayload(entries), { encoding: 'utf8', mode: 0o600 });
57
- renameSync(tmp, filePath);
58
- try {
59
- chmodSync(filePath, 0o600);
60
- } catch {
61
- /* best-effort; Windows may ignore mode bits */
62
- }
64
+ writeFileAtomicSync(filePath, buildPayload(entries), { mode: 0o600 });
63
65
  return true;
64
66
  } catch {
65
67
  return false;
@@ -72,14 +74,7 @@ async function writeEntriesAsync(filePath, entries) {
72
74
  if (!filePath) return false;
73
75
  try {
74
76
  await mkdir(dirname(filePath), { recursive: true, mode: 0o700 });
75
- const tmp = `${filePath}.${process.pid}.tmp`;
76
- await writeFile(tmp, buildPayload(entries), { encoding: 'utf8', mode: 0o600 });
77
- await rename(tmp, filePath);
78
- try {
79
- await chmod(filePath, 0o600);
80
- } catch {
81
- /* best-effort; Windows may ignore mode bits */
82
- }
77
+ await writeFileAtomicAsync(filePath, buildPayload(entries), { mode: 0o600 });
83
78
  return true;
84
79
  } catch {
85
80
  return false;
@@ -77,6 +77,10 @@ export function createContextState({
77
77
  autoClear: autoClearState(),
78
78
  workflow: runtime.workflow || null,
79
79
  orchestrationMode: runtime.orchestrationMode || 'none',
80
+ // A workflow / orchestration mode chosen during a turn: shown above,
81
+ // applied when the next turn starts (tool-policy-refresh.mjs).
82
+ pendingWorkflowSwitch: runtime.session?.pendingWorkflowId !== undefined,
83
+ pendingOrchestrationModeSwitch: runtime.session?.pendingOrchestrationMode !== undefined,
80
84
  // Every `set({ ...routeState() })` (the 2s runtime pulse, model/effort
81
85
  // switches, turn end, resume) republishes the Goal. It must read it
82
86
  // through the goal-continuation mask: the raw record still holds a
@@ -59,10 +59,9 @@ export function createNoticeSurface({ getState, set, isDisposed, pushItem, repla
59
59
  // A schedule result posted into a home thread (routine-result.mjs).
60
60
  ...(options.routine ? { routine: options.routine } : {}),
61
61
  ...(options.room ? { room: options.room } : {}),
62
- // A room user row's files, in the fields a prompt row draws them from.
63
- ...(userRow && Array.isArray(options.attachments) && options.attachments.length
64
- ? { attachments: options.attachments }
65
- : {}),
62
+ // A room user row's files, in the fields a prompt row draws them from;
63
+ // a task report's or member speech's returned files likewise.
64
+ ...(Array.isArray(options.attachments) && options.attachments.length ? { attachments: options.attachments } : {}),
66
65
  ...(userRow && Array.isArray(options.images) && options.images.length ? { images: options.images } : {}),
67
66
  // A held request of an unattended run (human-gate/held-message.mjs).
68
67
  ...(options.heldRequest ? { heldRequest: options.heldRequest } : {}),
@@ -2,6 +2,7 @@
2
2
  // during a turn cancels it and, unless a steering prompt is already queued,
3
3
  // reclaims the in-flight prompt, its history slot and its requeue entries.
4
4
  import { hydratePastedAttachments, hydrateRestorableFileParts } from '../../../../runtime/attachments/store.mjs';
5
+ import { USER_CANCEL_KEEP_PROMPT_REASON } from '../../../../runtime/agent/orchestrator/session/manager/turn-interruption.mjs';
5
6
  import { abortGoalTurn } from '../../goal-turn-state.mjs';
6
7
  import { promptHistoryWithout } from '../../prompt-history.mjs';
7
8
  import { isQueuedEntryEditable } from '../../queue-helpers.mjs';
@@ -146,8 +147,25 @@ export function createAbortAction(bag) {
146
147
  (entry) => entry?.abortDiscardOnAbort !== true && entry?.mode !== 'pending-resume'
147
148
  )
148
149
  : [];
149
- const aborted = abortGoalTurn(runtime, flags, hasPendingSteering, reason);
150
+ // A user Stop that hands the prompt back is rewound by the runtime (the
151
+ // prompt returns to the input box); one that does not keeps it in the
152
+ // stored transcript, as it stays in the visible one. A turn that already
153
+ // committed (output produced) needs neither.
154
+ const keepsPrompt = reason === 'user-cancel' && !canRestore && restoreState?.restorable && !restoreState.committed;
155
+ const aborted = abortGoalTurn(
156
+ runtime,
157
+ flags,
158
+ hasPendingSteering,
159
+ keepsPrompt ? USER_CANCEL_KEEP_PROMPT_REASON : reason
160
+ );
150
161
  if (restoreState) {
162
+ // A user Stop consumes this input even when no draft is requested.
163
+ // Explicit draft reclamation also releases it; automatic interruptions
164
+ // such as the watchdog must retain input that has not been committed.
165
+ if (aborted !== false && !restoreState.committed && (reason === 'user-cancel' || restoreText)) {
166
+ restoreState.onAborted?.();
167
+ restoreState.onAborted = null;
168
+ }
151
169
  if (aborted !== false && Array.isArray(restoreState.discardExecutionPendingResumeKeys)) {
152
170
  discardExecutionPendingResume?.(restoreState.discardExecutionPendingResumeKeys);
153
171
  }
@@ -119,7 +119,8 @@ export function createSessionMediaApi(bag) {
119
119
  // Media studio (image/video generation). Reads stay quiet, and there is no
120
120
  // notice on start either: the Studio surfaces progress on its own pending
121
121
  // tile, and a toast for a user-initiated generation is pure noise.
122
- listMediaLanes: () => runtime.listMediaLanes?.(),
122
+ // `{ budgetMs }` bounds the per-lane catalog wait (Studio, Settings).
123
+ listMediaLanes: (options) => runtime.listMediaLanes?.(options),
123
124
  getMediaDefault: (kind) => runtime.getMediaDefault?.(kind),
124
125
  setMediaDefault: (input) => runtime.setMediaDefault?.(input),
125
126
  getMediaPins: () => runtime.getMediaPins?.(),
@@ -0,0 +1,75 @@
1
+ /**
2
+ * routes-agent-definitions.mjs — the session route surface's passthroughs to
3
+ * the runtime's agent, workflow-pack, connector and lead-identity services.
4
+ */
5
+ export function createAgentDefinitionApi(runtime) {
6
+ return {
7
+ listAgents: () => {
8
+ return runtime.listAgents?.() || [];
9
+ },
10
+ listWorkflows: () => {
11
+ return runtime.listWorkflows?.() || [];
12
+ },
13
+ // Workflow pack editing (desktop Workflows page): direct passthroughs —
14
+ // the runtime owns validation, user-pack persistence, and delete guards.
15
+ getWorkflowPack: (workflowId) => runtime.getWorkflowPack?.(workflowId) ?? null,
16
+ saveWorkflowPack: async (payload) => runtime.saveWorkflowPack?.(payload) ?? null,
17
+ createWorkflow: async (payload) => runtime.createWorkflow?.(payload) ?? null,
18
+ deleteWorkflow: async (workflowId) => runtime.deleteWorkflow?.(workflowId) ?? null,
19
+ getAgentDefinition: (agentId) => runtime.getAgentDefinition?.(agentId) ?? null,
20
+ getAgentAvatarImage: (agentId) => runtime.getAgentAvatarImage?.(agentId) ?? null,
21
+ getAgentConnectors: (agentId) => runtime.getAgentConnectors?.(agentId) ?? [],
22
+ listConnectors: () => runtime.listConnectors?.() ?? [],
23
+ listConnectorTools: (connectorId) => runtime.listConnectorTools?.(connectorId) ?? [],
24
+ // `options.noWiden` is only ever added by the desktop's remote method table: the
25
+ // change is refused if it would give the agent more authority (checked atomically with the write).
26
+ setAgentConnectors: async (agentId, connectors, options) =>
27
+ runtime.setAgentConnectors?.(agentId, connectors, options) ?? null,
28
+ setAgentConnectorEnabled: async (agentId, connectorId, enabled, options) =>
29
+ runtime.setAgentConnectorEnabled?.(agentId, connectorId, enabled, options) ?? [],
30
+ getProjectConnectors: (projectPath) => runtime.getProjectConnectors?.(projectPath) ?? [],
31
+ setProjectConnectorEnabled: async (projectPath, connectorId, enabled, options) =>
32
+ runtime.setProjectConnectorEnabled?.(projectPath, connectorId, enabled, options) ?? [],
33
+ setAgentConnectorToolPermission: async (agentId, connectorId, toolName, permission, options) =>
34
+ runtime.setAgentConnectorToolPermission?.(agentId, connectorId, toolName, permission, options) ?? null,
35
+ getAgentAlwaysAllowedTools: (agentId) => runtime.getAgentAlwaysAllowedTools?.(agentId) ?? [],
36
+ // Per-agent action-kind permissions (ask / allow / block) for the profile.
37
+ getAgentPermissions: async (agentId) =>
38
+ (await import('../../../runtime/agent/orchestrator/session/human-gate/store.mjs')).agentPermissions(agentId),
39
+ setAgentPermission: async (agentId, action, mode, options) =>
40
+ (await import('../../../runtime/agent/orchestrator/session/human-gate/store.mjs')).setAgentPermission(
41
+ agentId,
42
+ action,
43
+ mode,
44
+ options
45
+ ),
46
+ recordAgentApprovalAudit: async (agentId, action, decision) =>
47
+ (await import('../../../runtime/agent/orchestrator/session/human-gate/store.mjs')).recordAgentApprovalAudit(
48
+ agentId,
49
+ action,
50
+ decision
51
+ ),
52
+ getLeadPersona: () => runtime.getLeadPersona?.() ?? '',
53
+ saveLeadPersona: async (text) => runtime.saveLeadPersona?.(text) ?? '',
54
+ getLeadAgentBody: () => runtime.getLeadAgentBody?.() ?? '',
55
+ saveLeadAgentBody: async (text) => runtime.saveLeadAgentBody?.(text) ?? '',
56
+ getLeadStatus: () =>
57
+ runtime.getLeadStatus?.() ?? { created: null, name: '', avatar: null, homeChatted: false, route: null },
58
+ saveLeadIdentity: async (payload) => runtime.saveLeadIdentity?.(payload) ?? null,
59
+ setLeadCreated: async (created, description) => runtime.setLeadCreated?.(created, description) ?? null,
60
+ saveAgentDefinition: async (payload, options) => runtime.saveAgentDefinition?.(payload, options) ?? null,
61
+ deleteAgentDefinition: async (agentId) => runtime.deleteAgentDefinition?.(agentId) ?? null,
62
+ agentDefinitionPresence: (agentIds) => runtime.agentDefinitionPresence?.(agentIds) ?? null,
63
+ restoreAgentDefinition: async (agentId) => runtime.restoreAgentDefinition?.(agentId) ?? null,
64
+ purgeAgentDefinition: async (agentId) => runtime.purgeAgentDefinition?.(agentId) ?? null,
65
+ archivedAgentIdentities: (agentIds) => runtime.archivedAgentIdentities?.(agentIds) ?? null,
66
+ // Group-room rows posted by the desktop host into a room's log session.
67
+ appendRoomRows: async (sessionId, rows) =>
68
+ (await import('../../../session-runtime/agent-room-delivery.mjs')).appendRoomRows(sessionId, rows),
69
+ // One group-room supervisor step on the Maintainer route.
70
+ decideRoomTurn: async (input) =>
71
+ (await import('../../../runtime/agent/orchestrator/agent-runtime/room-supervisor-completion.mjs')).decideRoomTurn(
72
+ input
73
+ ),
74
+ };
75
+ }
@@ -0,0 +1,203 @@
1
+ /**
2
+ * routes-write.mjs — the serialized, optimistic route write behind the
3
+ * session's setRoute (every model picker, presets, agent child routes).
4
+ */
5
+ import { modelSwitchItem } from '../../../runtime/agent/orchestrator/session/transcript-restore/restore.mjs';
6
+ import { selectedModel } from '../../../session-runtime/model-route/model-switch-target.mjs';
7
+
8
+ // Optimistic route preview: the requested provider/model/effort/fast are
9
+ // published before the runtime write settles. What is NOT previewed about the
10
+ // route (effort options, Fast capability, context window) is provider
11
+ // metadata the runtime resolves while the preview is already on screen.
12
+ const ROUTE_PREVIEW_KEYS = [
13
+ 'provider',
14
+ 'model',
15
+ 'effort',
16
+ 'fast',
17
+ 'autoEffort',
18
+ 'modelParameters',
19
+ 'contextPercent',
20
+ 'contextTokens',
21
+ ];
22
+
23
+ /**
24
+ * The patch that publishes a requested route before the runtime write settles.
25
+ * Returns null when the request carries nothing previewable.
26
+ */
27
+ function optimisticRoutePatch(requested = {}, current = {}) {
28
+ const route = requested && typeof requested === 'object' ? requested : {};
29
+ const has = (key) => Object.hasOwn(route, key);
30
+ const patch = {};
31
+ for (const key of ROUTE_PREVIEW_KEYS) {
32
+ if (has(key)) patch[key] = route[key];
33
+ }
34
+ if (!has('provider') && !has('model')) {
35
+ return Object.keys(patch).length > 0 ? patch : null;
36
+ }
37
+ const sameModel =
38
+ String(patch.provider ?? current.provider ?? '') === String(current.provider ?? '') &&
39
+ String(patch.model ?? current.model ?? '') === String(current.model ?? '');
40
+ // A different model carries none of the previous model's tuning: an omitted
41
+ // key means "this model has no such control", not "keep the old value".
42
+ if (!sameModel) {
43
+ if (!has('effort')) patch.effort = null;
44
+ if (!has('fast')) patch.fast = false;
45
+ if (!has('modelParameters')) patch.modelParameters = {};
46
+ }
47
+ return patch;
48
+ }
49
+
50
+ const SESSION_ONLY_KEYS = new Set(['provider', 'model', 'effort', 'fast', 'autoEffort']);
51
+
52
+ /**
53
+ * A session-only request (an agent child's route) may name just the model, just
54
+ * the tuning, or both. Completed here, inside the serialized route write,
55
+ * against the latest selected route — so a Fast-only change keeps the effort a
56
+ * previous write selected. `unchanged` when it asks for nothing the selected
57
+ * route does not already have.
58
+ */
59
+ function completeSessionOnlyRequest(request, selected) {
60
+ const named = Boolean(request.provider || request.model);
61
+ const target = named ? request : { ...request, provider: selected.provider, model: selected.model };
62
+ const sameModel = target.provider === selected.provider && target.model === selected.model;
63
+ if (!sameModel) return { request: target, unchanged: false };
64
+ const unchanged =
65
+ Object.keys(request).every((key) => SESSION_ONLY_KEYS.has(key)) &&
66
+ (request.effort === undefined || request.effort === selected.effort) &&
67
+ (request.fast === undefined || request.fast === (selected.fast === true)) &&
68
+ (request.autoEffort === undefined || request.autoEffort === (selected.autoEffort !== false));
69
+ return {
70
+ unchanged,
71
+ request: {
72
+ ...(selected.effort ? { effort: selected.effort } : {}),
73
+ fast: selected.fast === true,
74
+ autoEffort: selected.autoEffort !== false,
75
+ ...target,
76
+ },
77
+ };
78
+ }
79
+
80
+ /** The live divider of an in-place model switch (restored from message meta
81
+ * after a reload); every switch path publishes it the same way. */
82
+ export function publishModelSwitch(bag, modelSwitch) {
83
+ if (modelSwitch) bag.pushItem(modelSwitchItem(bag.nextId(), modelSwitch));
84
+ }
85
+
86
+ export function createRouteWrite(
87
+ bag,
88
+ { runtime, getState, set, flushEmitImmediate, routeState, syncContextStats, publishRoute }
89
+ ) {
90
+ let routeWrite = null;
91
+ let routeSequence = 0;
92
+ // Whether this API (not another command) is the one holding commandBusy.
93
+ let routeLocked = false;
94
+
95
+ // A preset selector previews as the preset's model, never as its id.
96
+ const previewedRequest = (routeOpts) => {
97
+ if (routeOpts.provider || !routeOpts.model) return routeOpts;
98
+ const target = selectedModel(runtime, routeOpts, '', '');
99
+ return target.provider ? { ...routeOpts, ...target } : routeOpts;
100
+ };
101
+
102
+ const setRoute = async (opts) => {
103
+ const routeOpts = opts && typeof opts === 'object' ? opts : {};
104
+ // All model pickers save a selection for the conversation's next turn; a
105
+ // running turn keeps the session model it started on. A selection is never
106
+ // refused: another command's lock neither blocks it nor is released by it.
107
+ const token = ++routeSequence;
108
+ const previousWrite = routeWrite;
109
+ // The session generation this selection was made under. The write below
110
+ // waits behind earlier ones, so "current" is never read later: the runtime
111
+ // validates this token before every route side effect, and `settle` below
112
+ // is the only place the display is touched once the write has started.
113
+ const originGeneration = runtime.sessionGeneration;
114
+ const owned = () => runtime.sessionGeneration === originGeneration;
115
+ // A conditional fill (only when the route is still empty) may not apply, so
116
+ // it never previews: the runtime's answer is what gets published.
117
+ const onlyIfEmpty = routeOpts.onlyIfEmpty === true;
118
+ const preview = onlyIfEmpty ? null : optimisticRoutePatch(previewedRequest(routeOpts), getState());
119
+ // Preview immediately, serialize persistence without dropping a later
120
+ // click. Earlier completions cannot replace the newest visible choice.
121
+ if (!getState().commandBusy) routeLocked = true;
122
+ set({ ...(routeLocked ? { commandBusy: true } : {}), ...(preview || {}) });
123
+ flushEmitImmediate();
124
+ const write = (async () => {
125
+ if (previousWrite) await previousWrite.catch(() => {});
126
+ const previousRoute = routeState();
127
+ // A stale selection only republishes the route that is actually
128
+ // selected; it never restores or announces its own session's state.
129
+ const settle = ({ failed = false, sync = false, modelSwitch = null } = {}) => {
130
+ const stillOwned = owned();
131
+ if (stillOwned) publishModelSwitch(bag, modelSwitch);
132
+ // A newer selection publishes the final route itself.
133
+ if (token !== routeSequence) return;
134
+ if (stillOwned && failed) {
135
+ if (preview) set({ ...previousRoute, stats: { ...getState().stats } });
136
+ return;
137
+ }
138
+ if (stillOwned && sync) syncContextStats({ allowEstimated: true });
139
+ publishRoute();
140
+ };
141
+ try {
142
+ // Keep the durable session address while deferring route application.
143
+ const applyToCurrentSession = routeOpts.applyToCurrentSession === true;
144
+ const keepMainModel = routeOpts.keepMainModel !== false;
145
+ const sessionOnly = routeOpts.sessionOnly === true;
146
+ const {
147
+ applyToCurrentSession: _drop,
148
+ keepMainModel: _keep,
149
+ sessionOnly: _scope,
150
+ onlyIfEmpty: _fill,
151
+ ...requested
152
+ } = routeOpts;
153
+ let nextRoute = requested;
154
+ if (sessionOnly) {
155
+ const completed = completeSessionOnlyRequest(requested, previousRoute);
156
+ if (completed.unchanged) {
157
+ // An earlier failed write skipped its rollback because this one is
158
+ // newer, so the shown route may still be that write's preview.
159
+ settle();
160
+ return previousRoute;
161
+ }
162
+ nextRoute = completed.request;
163
+ }
164
+ const resolvedRoute = await runtime.setRoute(nextRoute, {
165
+ applyToCurrentSession,
166
+ keepMainModel,
167
+ ...(sessionOnly ? { sessionOnly } : {}),
168
+ ...(onlyIfEmpty ? { onlyIfEmpty } : {}),
169
+ ...(originGeneration !== undefined ? { originGeneration } : {}),
170
+ switchEstablished: true,
171
+ deferUntilNextTurn: true,
172
+ });
173
+ settle({
174
+ sync: applyToCurrentSession || Boolean(resolvedRoute?.modelSwitch),
175
+ modelSwitch: resolvedRoute?.modelSwitch,
176
+ });
177
+ return resolvedRoute;
178
+ } catch (error) {
179
+ settle({ failed: true });
180
+ throw error;
181
+ } finally {
182
+ if (token === routeSequence) {
183
+ if (routeLocked) set({ commandBusy: false });
184
+ routeLocked = false;
185
+ // Publish the resolved route (or rollback) before an RPC reply
186
+ // reads getState(), even while the display-frame clock is busy.
187
+ flushEmitImmediate();
188
+ }
189
+ }
190
+ })();
191
+ routeWrite = write;
192
+ try {
193
+ return await write;
194
+ } finally {
195
+ if (routeWrite === write) routeWrite = null;
196
+ }
197
+ };
198
+ // The settings surface's setModel (/model, presets) is the same user
199
+ // model choice and runs through this one path.
200
+ bag.setSessionRoute = setRoute;
201
+
202
+ return setRoute;
203
+ }