mixdog 1.3.1 → 1.3.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 (468) hide show
  1. package/README.md +8 -4
  2. package/package.json +8 -8
  3. package/scripts/native-release-status.mjs +238 -0
  4. package/scripts/verify-runtime-dependency-versions.mjs +158 -0
  5. package/src/agents/reviewer/AGENT.md +5 -7
  6. package/src/agents/reviewer/agent.json +1 -1
  7. package/src/defaults/shipped-history.json +9 -1
  8. package/src/defaults/skills/browser-use/SKILL.md +6 -3
  9. package/src/defaults/skills/local-provider/SKILL.md +33 -6
  10. package/src/defaults/skills/pptx/scripts/qc-pages.mjs +3 -2
  11. package/src/defaults/skills/setup/SKILL.md +23 -1
  12. package/src/defaults/skills/setup/references/actions.md +50 -3
  13. package/src/defaults/skills/setup/references/surfaces.md +23 -3
  14. package/src/defaults/skills/setup-guide/SKILL.md +7 -3
  15. package/src/defaults/skills/visualize/SKILL.md +9 -6
  16. package/src/defaults/skills/visualize/references/craft.md +8 -1
  17. package/src/help.mjs +1 -1
  18. package/src/lib/keychain-cjs.cjs +4 -1
  19. package/src/lib/rules-builder.cjs +14 -7
  20. package/src/rules/agent-mode/AGENT_MODE.md +8 -5
  21. package/src/rules/agent-mode/MIXY.md +6 -8
  22. package/src/rules/lead/LEAD.md +7 -10
  23. package/src/rules/shared/10-tool-workflow.md +4 -0
  24. package/src/rules/shared/20-research.md +2 -0
  25. package/src/rules/shared/45-destructive.md +5 -1
  26. package/src/rules/shared/60-verification.md +6 -4
  27. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/preset.mjs +5 -0
  28. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/session-prep.mjs +8 -0
  29. package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +6 -1
  30. package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +114 -26
  31. package/src/runtime/agent/orchestrator/agent-runtime/maintenance-route.mjs +8 -0
  32. package/src/runtime/agent/orchestrator/agent-runtime/room-supervisor-completion.mjs +5 -4
  33. package/src/runtime/agent/orchestrator/agent-trace.mjs +3 -0
  34. package/src/runtime/agent/orchestrator/cache-break-trace.mjs +4 -0
  35. package/src/runtime/agent/orchestrator/config-presets.mjs +2 -0
  36. package/src/runtime/agent/orchestrator/config-storage.mjs +10 -3
  37. package/src/runtime/agent/orchestrator/config.mjs +11 -0
  38. package/src/runtime/agent/orchestrator/context/role-instructions.mjs +9 -2
  39. package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +97 -5
  40. package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +6 -10
  41. package/src/runtime/agent/orchestrator/mcp/client.mjs +7 -4
  42. package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +84 -32
  43. package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens.mjs +38 -11
  44. package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +15 -3
  45. package/src/runtime/agent/orchestrator/providers/anthropic-model-resolve.mjs +1 -1
  46. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
  47. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +84 -42
  48. package/src/runtime/agent/orchestrator/providers/anthropic-turn-result.mjs +2 -0
  49. package/src/runtime/agent/orchestrator/providers/anthropic.mjs +14 -1
  50. package/src/runtime/agent/orchestrator/providers/antigravity-request.mjs +6 -2
  51. package/src/runtime/agent/orchestrator/providers/auto-effort.mjs +27 -8
  52. package/src/runtime/agent/orchestrator/providers/cursor-client-version.mjs +1 -1
  53. package/src/runtime/agent/orchestrator/providers/cursor-wire.mjs +31 -4
  54. package/src/runtime/agent/orchestrator/providers/cursor.mjs +4 -1
  55. package/src/runtime/agent/orchestrator/providers/custom-provider-config.mjs +14 -1
  56. package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +11 -8
  57. package/src/runtime/agent/orchestrator/providers/grok-client-version.mjs +1 -1
  58. package/src/runtime/agent/orchestrator/providers/lib/anthropic-prefix-trace.mjs +76 -0
  59. package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +16 -0
  60. package/src/runtime/agent/orchestrator/providers/lib/tail-reminder-split.mjs +13 -0
  61. package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +16 -1
  62. package/src/runtime/agent/orchestrator/providers/mixdog-local.mjs +3 -1
  63. package/src/runtime/agent/orchestrator/providers/model-proxy-provider.mjs +1 -0
  64. package/src/runtime/agent/orchestrator/providers/openai-codex-metadata.mjs +5 -5
  65. package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +9 -5
  66. package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +9 -1
  67. package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +2 -1
  68. package/src/runtime/agent/orchestrator/providers/openai-direct-request.mjs +30 -3
  69. package/src/runtime/agent/orchestrator/providers/openai-model-capabilities.mjs +1 -1
  70. package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +3 -1
  71. package/src/runtime/agent/orchestrator/providers/opencode-go-oauth.mjs +61 -8
  72. package/src/runtime/agent/orchestrator/providers/registry.mjs +19 -0
  73. package/src/runtime/agent/orchestrator/providers/wire-gateway.mjs +13 -1
  74. package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +90 -24
  75. package/src/runtime/agent/orchestrator/runtime-core/fs-utils.mjs +8 -1
  76. package/src/runtime/agent/orchestrator/runtime-core/goal-mutations.mjs +1 -1
  77. package/src/runtime/agent/orchestrator/runtime-core/goal-runtime.mjs +5 -0
  78. package/src/runtime/agent/orchestrator/runtime-core/goal-storage.mjs +68 -22
  79. package/src/runtime/agent/orchestrator/runtime-core/goal-tool-exec.mjs +1 -1
  80. package/src/runtime/agent/orchestrator/runtime-core/goal-turns.mjs +10 -1
  81. package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +4 -6
  82. package/src/runtime/agent/orchestrator/runtime-core/route-context-state.mjs +81 -0
  83. package/src/runtime/agent/orchestrator/runtime-core/session-text.mjs +2 -1
  84. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +52 -6
  85. package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +35 -13
  86. package/src/runtime/agent/orchestrator/runtime-core/workflow/agents.mjs +7 -6
  87. package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +1 -1
  88. package/src/runtime/agent/orchestrator/runtime-core/workflow/packs.mjs +8 -4
  89. package/src/runtime/agent/orchestrator/runtime-core/workflow.mjs +8 -3
  90. package/src/runtime/agent/orchestrator/session/agent-loop.mjs +1 -1
  91. package/src/runtime/agent/orchestrator/session/agent-mode.mjs +0 -6
  92. package/src/runtime/agent/orchestrator/session/agent-room-supervisor.d.mts +1 -1
  93. package/src/runtime/agent/orchestrator/session/agent-room-supervisor.mjs +22 -4
  94. package/src/runtime/agent/orchestrator/session/agent-room.d.mts +30 -2
  95. package/src/runtime/agent/orchestrator/session/agent-room.mjs +196 -45
  96. package/src/runtime/agent/orchestrator/session/attachment-preflight.mjs +80 -0
  97. package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +4 -1
  98. package/src/runtime/agent/orchestrator/session/compact/continuation.mjs +15 -6
  99. package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +45 -19
  100. package/src/runtime/agent/orchestrator/session/compact/forked-summary.mjs +3 -0
  101. package/src/runtime/agent/orchestrator/session/compact/messages.mjs +44 -0
  102. package/src/runtime/agent/orchestrator/session/compact/runner.mjs +185 -37
  103. package/src/runtime/agent/orchestrator/session/compact/summary-mode.mjs +16 -0
  104. package/src/runtime/agent/orchestrator/session/compact/summary-route.mjs +87 -0
  105. package/src/runtime/agent/orchestrator/session/compact/summary.mjs +2 -0
  106. package/src/runtime/agent/orchestrator/session/compact/text-utils.mjs +6 -2
  107. package/src/runtime/agent/orchestrator/session/compact/user-message-kind.mjs +4 -1
  108. package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +1 -1
  109. package/src/runtime/agent/orchestrator/session/context-utils.mjs +41 -10
  110. package/src/runtime/agent/orchestrator/session/human-gate/delegation.mjs +240 -0
  111. package/src/runtime/agent/orchestrator/session/human-gate/gate.mjs +102 -35
  112. package/src/runtime/agent/orchestrator/session/human-gate/outbound-policy.mjs +20 -0
  113. package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +19 -9
  114. package/src/runtime/agent/orchestrator/session/human-gate/run-policy.mjs +73 -0
  115. package/src/runtime/agent/orchestrator/session/human-gate/store.mjs +55 -27
  116. package/src/runtime/agent/orchestrator/session/human-gate/unattended-port.mjs +15 -0
  117. package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +4 -1
  118. package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +199 -109
  119. package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +5 -0
  120. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/continuation.mjs +2 -0
  121. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/empty-nudge.mjs +1 -1
  122. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/output-limit.mjs +62 -13
  123. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +22 -6
  124. package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +6 -2
  125. package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +5 -5
  126. package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +10 -0
  127. package/src/runtime/agent/orchestrator/session/loop/steering.mjs +3 -0
  128. package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +33 -8
  129. package/src/runtime/agent/orchestrator/session/loop/tool-exec/call-prep.mjs +5 -0
  130. package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +27 -0
  131. package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +2 -1
  132. package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +12 -0
  133. package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +11 -5
  134. package/src/runtime/agent/orchestrator/session/manager/agent-listing-notice.mjs +102 -0
  135. package/src/runtime/agent/orchestrator/session/manager/ask-queue.mjs +2 -0
  136. package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +13 -1
  137. package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +13 -2
  138. package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +27 -14
  139. package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +14 -0
  140. package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +4 -0
  141. package/src/runtime/agent/orchestrator/session/manager/ask-turn-steering-drain.mjs +1 -0
  142. package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +44 -18
  143. package/src/runtime/agent/orchestrator/session/manager/idle-cleanup.mjs +32 -1
  144. package/src/runtime/agent/orchestrator/session/manager/orchestration-mode-switch-notice.mjs +115 -0
  145. package/src/runtime/agent/orchestrator/session/manager/owner-route-fallbacks.mjs +42 -0
  146. package/src/runtime/agent/orchestrator/session/manager/pending-message-entry.mjs +6 -0
  147. package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +3 -9
  148. package/src/runtime/agent/orchestrator/session/manager/pending-spool-file.mjs +1 -1
  149. package/src/runtime/agent/orchestrator/session/manager/pending-spool-shard.mjs +5 -3
  150. package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +36 -0
  151. package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +40 -1
  152. package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +12 -0
  153. package/src/runtime/agent/orchestrator/session/manager/runtime-state.mjs +20 -0
  154. package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +28 -9
  155. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +55 -27
  156. package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +4 -9
  157. package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +14 -1
  158. package/src/runtime/agent/orchestrator/session/manager/session-tool-surface.mjs +7 -3
  159. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-journal.mjs +6 -15
  160. package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +24 -8
  161. package/src/runtime/agent/orchestrator/session/manager/workflow-switch-notice.mjs +94 -13
  162. package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +52 -11
  163. package/src/runtime/agent/orchestrator/session/provider-prefix-guard.mjs +21 -3
  164. package/src/runtime/agent/orchestrator/session/routine-result.d.mts +18 -3
  165. package/src/runtime/agent/orchestrator/session/routine-result.mjs +126 -12
  166. package/src/runtime/agent/orchestrator/session/runtime-user-context.mjs +3 -1
  167. package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +16 -3
  168. package/src/runtime/agent/orchestrator/session/side-question-store.mjs +3 -1
  169. package/src/runtime/agent/orchestrator/session/store/canonical-reader.mjs +41 -7
  170. package/src/runtime/agent/orchestrator/session/store/lifecycle-barriers.mjs +10 -2
  171. package/src/runtime/agent/orchestrator/session/store/load-cache.mjs +14 -2
  172. package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +15 -1
  173. package/src/runtime/agent/orchestrator/session/store/sweep/stale-sweep.mjs +5 -4
  174. package/src/runtime/agent/orchestrator/session/store/sweep/sub-agent-retention.mjs +140 -0
  175. package/src/runtime/agent/orchestrator/session/store/sweep/sweep-plan.mjs +5 -0
  176. package/src/runtime/agent/orchestrator/session/store/sweep/sweep-record.mjs +15 -5
  177. package/src/runtime/agent/orchestrator/session/store/sweep/sweep-row.mjs +49 -1
  178. package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +80 -1
  179. package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +40 -5
  180. package/src/runtime/agent/orchestrator/session/store-summary-last-message.mjs +47 -2
  181. package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +33 -1
  182. package/src/runtime/agent/orchestrator/session/store-summary-visibility.d.mts +5 -0
  183. package/src/runtime/agent/orchestrator/session/store-summary-visibility.mjs +37 -0
  184. package/src/runtime/agent/orchestrator/session/store.mjs +1 -0
  185. package/src/runtime/agent/orchestrator/session/tail-reminder-rules.mjs +125 -0
  186. package/src/runtime/agent/orchestrator/session/tool-batch/finalize.mjs +4 -0
  187. package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +78 -43
  188. package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +35 -5
  189. package/src/runtime/agent/orchestrator/session/transcript-restore/user-text.mjs +42 -2
  190. package/src/runtime/agent/orchestrator/tools/builtin/advisory-lock.mjs +47 -14
  191. package/src/runtime/agent/orchestrator/tools/builtin/atomic-write.mjs +25 -5
  192. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/backgrounded-result.mjs +6 -3
  193. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/completed-result.mjs +13 -14
  194. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/transport-artifacts.mjs +9 -0
  195. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +19 -14
  196. package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +7 -1
  197. package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +127 -20
  198. package/src/runtime/agent/orchestrator/tools/builtin/git-worktree-tool.mjs +557 -0
  199. package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +10 -12
  200. package/src/runtime/agent/orchestrator/tools/builtin/pdf-test-fixtures.mjs +5 -3
  201. package/src/runtime/agent/orchestrator/tools/builtin/read-image.mjs +4 -2
  202. package/src/runtime/agent/orchestrator/tools/builtin/read-single-media.mjs +47 -2
  203. package/src/runtime/agent/orchestrator/tools/builtin/read-special-files.mjs +264 -87
  204. package/src/runtime/agent/orchestrator/tools/builtin/shell-analysis.mjs +10 -4
  205. package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +42 -23
  206. package/src/runtime/agent/orchestrator/tools/code-graph/constants.mjs +8 -4
  207. package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +9 -30
  208. package/src/runtime/agent/orchestrator/tools/lib/shell-run-settle.mjs +24 -12
  209. package/src/runtime/agent/orchestrator/tools/lib/shell-run-spawn.mjs +3 -2
  210. package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +6 -2
  211. package/src/runtime/agent/orchestrator/tools/patch/delete-quarantine.mjs +2 -1
  212. package/src/runtime/agent/orchestrator/tools/patch/replay-capture.mjs +4 -2
  213. package/src/runtime/agent/orchestrator/tools/patch/rollback-state.mjs +33 -2
  214. package/src/runtime/agent/orchestrator/tools/patch-manifest.json +13 -13
  215. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +5 -3
  216. package/src/runtime/agent/orchestrator/tools/shell-exec-output.mjs +3 -1
  217. package/src/runtime/attachments/attachment-reference.mjs +155 -0
  218. package/src/runtime/attachments/legacy-office.mjs +110 -0
  219. package/src/runtime/attachments/limits.mjs +5 -1
  220. package/src/runtime/attachments/office-extract.mjs +3 -6
  221. package/src/runtime/attachments/pdf-extract.mjs +84 -10
  222. package/src/runtime/attachments/prompt-restore.mjs +70 -0
  223. package/src/runtime/attachments/store.mjs +109 -33
  224. package/src/runtime/browser-bridge/client.mjs +73 -20
  225. package/src/runtime/channels/lib/runtime-paths.mjs +1 -1
  226. package/src/runtime/channels/lib/scheduler.mjs +14 -7
  227. package/src/runtime/channels/lib/state-file.mjs +15 -15
  228. package/src/runtime/channels/lib/voice-runtime-fetcher.mjs +14 -13
  229. package/src/runtime/channels/lib/webhook/relay-tunnel.mjs +22 -18
  230. package/src/runtime/channels/lib/webhook/session-dispatch.mjs +14 -36
  231. package/src/runtime/channels/lib/worker-main.mjs +3 -2
  232. package/src/runtime/effort-judge/compact-tokenizer.mjs +8 -2
  233. package/src/runtime/effort-judge/judge-client.mjs +66 -16
  234. package/src/runtime/effort-judge/model-install.mjs +47 -7
  235. package/src/runtime/local-provider/asset-installer.mjs +10 -4
  236. package/src/runtime/local-provider/catalog.mjs +5 -2
  237. package/src/runtime/local-provider/registered-models.mjs +64 -27
  238. package/src/runtime/local-provider/server.mjs +2 -3
  239. package/src/runtime/media/adapters/image-api.mjs +89 -0
  240. package/src/runtime/media/auth.mjs +64 -1
  241. package/src/runtime/media/catalog.mjs +66 -4
  242. package/src/runtime/media/jobs.mjs +4 -0
  243. package/src/runtime/media/lanes.mjs +46 -5
  244. package/src/runtime/media/media-usage.mjs +17 -0
  245. package/src/runtime/media/renditions.mjs +15 -15
  246. package/src/runtime/media/store.mjs +36 -35
  247. package/src/runtime/media/tool.mjs +8 -1
  248. package/src/runtime/memory/lib/cycle-scheduler/health-ledger.mjs +8 -2
  249. package/src/runtime/memory/lib/embedding-model-files.mjs +30 -7
  250. package/src/runtime/memory/lib/ingest/transcript-tail.mjs +16 -7
  251. package/src/runtime/memory/lib/memory-chunk-quality.mjs +14 -2
  252. package/src/runtime/memory/lib/pg/process.mjs +8 -4
  253. package/src/runtime/memory/lib/project-id-resolver.mjs +5 -1
  254. package/src/runtime/memory/lib/runtime-fetcher.mjs +6 -1
  255. package/src/runtime/office/core/journal.mjs +7 -14
  256. package/src/runtime/office/design/library/design-library-core.mjs +4 -16
  257. package/src/runtime/office/pdf/ocr-engine-worker.mjs +37 -0
  258. package/src/runtime/office/pdf/ocr-engine.mjs +146 -0
  259. package/src/runtime/office/pdf/pdf-ocr.mjs +51 -21
  260. package/src/runtime/office/pdf/pdf-render.mjs +30 -18
  261. package/src/runtime/office/portable/ooxml-validator.mjs +2 -2
  262. package/src/runtime/office/portable/portable-soffice.mjs +135 -29
  263. package/src/runtime/shared/agent-avatar-sprites.mjs +23 -8
  264. package/src/runtime/shared/agent-avatar.mjs +3 -2
  265. package/src/runtime/shared/agent-kind-migration.mjs +200 -0
  266. package/src/runtime/shared/agent-message-envelope.d.mts +6 -0
  267. package/src/runtime/shared/agent-message-envelope.mjs +44 -0
  268. package/src/runtime/shared/agent-reap-state.d.mts +4 -0
  269. package/src/runtime/shared/agent-room-host.d.mts +31 -0
  270. package/src/runtime/shared/agent-room-host.mjs +58 -0
  271. package/src/runtime/shared/agent-store.mjs +24 -7
  272. package/src/runtime/shared/agent-task-starts.mjs +27 -0
  273. package/src/runtime/shared/atomic-file.d.mts +50 -0
  274. package/src/runtime/shared/atomic-file.mjs +394 -132
  275. package/src/runtime/shared/background-tasks.mjs +7 -4
  276. package/src/runtime/shared/bot-hops.mjs +35 -0
  277. package/src/runtime/shared/bot-split-migration.mjs +1 -1
  278. package/src/runtime/shared/bounded-download.mjs +4 -2
  279. package/src/runtime/shared/config.mjs +39 -9
  280. package/src/runtime/shared/defaults-separation.mjs +6 -2
  281. package/src/runtime/shared/delegated-approval-host.mjs +74 -0
  282. package/src/runtime/shared/err-text.mjs +4 -0
  283. package/src/runtime/shared/error-presentation.mjs +22 -4
  284. package/src/runtime/shared/file-has-data.mjs +28 -0
  285. package/src/runtime/shared/llm/usage-ledger-import.mjs +37 -18
  286. package/src/runtime/shared/pending-agent-work.mjs +54 -0
  287. package/src/runtime/shared/process-lifecycle.mjs +8 -12
  288. package/src/runtime/shared/projects.mjs +50 -41
  289. package/src/runtime/shared/provider-accounts.mjs +17 -12
  290. package/src/runtime/shared/redact-directories.mjs +18 -0
  291. package/src/runtime/shared/remove-directory.mjs +28 -0
  292. package/src/runtime/shared/routine-trigger.d.mts +6 -1
  293. package/src/runtime/shared/routine-trigger.mjs +14 -6
  294. package/src/runtime/shared/run-child.d.mts +3 -0
  295. package/src/runtime/shared/run-child.mjs +24 -3
  296. package/src/runtime/shared/session-baseline-store.mjs +8 -2
  297. package/src/runtime/shared/session-sidebar-host.d.mts +11 -2
  298. package/src/runtime/shared/session-sidebar-host.mjs +16 -3
  299. package/src/runtime/shared/singleton-owner.mjs +7 -6
  300. package/src/runtime/shared/skill-tool-dependencies.mjs +4 -10
  301. package/src/runtime/shared/staged-update.mjs +4 -2
  302. package/src/runtime/shared/statusline/statusline-segments.mjs +4 -15
  303. package/src/runtime/shared/tool-execution-contract.mjs +10 -0
  304. package/src/runtime/shared/tool-work-units.mjs +12 -9
  305. package/src/runtime/shared/transcript-metadata.mjs +28 -3
  306. package/src/runtime/shared/transcript-writer/session-record.mjs +7 -6
  307. package/src/runtime/shared/turn-snapshot-store.mjs +5 -4
  308. package/src/runtime/shared/turn-snapshot.mjs +277 -124
  309. package/src/runtime/shared/user-cwd.mjs +9 -4
  310. package/src/runtime/shared/user-data-guard.mjs +92 -61
  311. package/src/runtime/shared/utf8-cut.mjs +10 -0
  312. package/src/runtime/shared/worktrees/activity-gate.mjs +251 -61
  313. package/src/runtime/shared/worktrees/contract.mjs +11 -3
  314. package/src/runtime/shared/worktrees/maintenance.mjs +11 -2
  315. package/src/runtime/shared/worktrees/manager.mjs +419 -52
  316. package/src/runtime/shared/worktrees/registry.mjs +29 -27
  317. package/src/runtime/shared/worktrees/tool-host.mjs +39 -0
  318. package/src/runtime/tidy/core-install.mjs +26 -4
  319. package/src/runtime/tidy/install.mjs +91 -23
  320. package/src/runtime/tidy/process.mjs +41 -8
  321. package/src/runtime/tidy/resolve.mjs +10 -7
  322. package/src/runtime/web-search/lib/config.mjs +4 -16
  323. package/src/session-runtime/agent-home-delivery.mjs +542 -204
  324. package/src/session-runtime/agent-profile-changes.mjs +16 -0
  325. package/src/session-runtime/agent-room-delivery.mjs +81 -35
  326. package/src/session-runtime/agent-task-sessions.mjs +811 -179
  327. package/src/session-runtime/agent-tool-routing.mjs +1 -0
  328. package/src/session-runtime/boot/apis.mjs +48 -24
  329. package/src/session-runtime/boot/config.mjs +1 -0
  330. package/src/session-runtime/boot/facade.mjs +16 -7
  331. package/src/session-runtime/boot/infrastructure.mjs +14 -2
  332. package/src/session-runtime/boot/providers.mjs +2 -2
  333. package/src/session-runtime/boot/shared.mjs +12 -6
  334. package/src/session-runtime/boot/tools.mjs +23 -3
  335. package/src/session-runtime/bot-status.mjs +432 -0
  336. package/src/session-runtime/config-lifecycle/lead-route-sync.mjs +29 -0
  337. package/src/session-runtime/config-lifecycle.mjs +60 -55
  338. package/src/session-runtime/cwd-plugins/core-memory-context.mjs +2 -4
  339. package/src/session-runtime/held-requests.mjs +31 -33
  340. package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +10 -1
  341. package/src/session-runtime/internal-tool-executor/feature-tools.mjs +2 -2
  342. package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +24 -26
  343. package/src/session-runtime/lifecycle/session-catalog.mjs +12 -2
  344. package/src/session-runtime/lifecycle/teardown.mjs +11 -3
  345. package/src/session-runtime/mcp-glue/connect.mjs +100 -186
  346. package/src/session-runtime/mcp-glue/initial-connect-gate.mjs +57 -0
  347. package/src/session-runtime/mcp-glue/server-connection.mjs +71 -0
  348. package/src/session-runtime/media-api.mjs +5 -2
  349. package/src/session-runtime/model-recency.mjs +1 -0
  350. package/src/session-runtime/model-route/route-tuning.mjs +4 -1
  351. package/src/session-runtime/model-route/set-route.mjs +61 -1
  352. package/src/session-runtime/owned-automation-run.mjs +8 -1
  353. package/src/session-runtime/provider-models/row-hydration.mjs +8 -1
  354. package/src/session-runtime/quick-model-rows/model-meta.mjs +2 -0
  355. package/src/session-runtime/quick-model-rows/provider-rows.mjs +7 -1
  356. package/src/session-runtime/route-resolution.mjs +16 -8
  357. package/src/session-runtime/route-state.mjs +1 -59
  358. package/src/session-runtime/routine-home-turn.mjs +5 -3
  359. package/src/session-runtime/runtime-bootstrap.mjs +5 -3
  360. package/src/session-runtime/runtime-paths.mjs +11 -5
  361. package/src/session-runtime/runtime-review-api.mjs +4 -1
  362. package/src/session-runtime/runtime-tunables.mjs +6 -0
  363. package/src/session-runtime/services/agent-tool/close-flow/close-all.mjs +11 -2
  364. package/src/session-runtime/services/agent-tool/close-flow.mjs +4 -2
  365. package/src/session-runtime/services/agent-tool/execute-send.mjs +1 -0
  366. package/src/session-runtime/services/agent-tool/execute-spawn.mjs +1 -0
  367. package/src/session-runtime/services/agent-tool/job-views/agent-list.mjs +34 -19
  368. package/src/session-runtime/services/agent-tool/restart-notify.mjs +10 -0
  369. package/src/session-runtime/services/agent-tool/send-flow.mjs +25 -21
  370. package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +7 -0
  371. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +6 -3
  372. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +8 -5
  373. package/src/session-runtime/services/agent-tool/worker-index/row-liveness.mjs +22 -2
  374. package/src/session-runtime/services/agent-tool/worker-index.mjs +4 -6
  375. package/src/session-runtime/services/agent-tool.mjs +6 -0
  376. package/src/session-runtime/services/daemon-crash-capture/daemon-exit-record.mjs +1 -1
  377. package/src/session-runtime/services/daemon-crash-capture/retention.mjs +4 -3
  378. package/src/session-runtime/services/hook-bus/config-loader.mjs +14 -5
  379. package/src/session-runtime/services/hook-bus/rule-file.mjs +49 -11
  380. package/src/session-runtime/services/plugin-admin.mjs +26 -26
  381. package/src/session-runtime/services/provider-admin.mjs +26 -6
  382. package/src/session-runtime/services/schedule-access.mjs +33 -4
  383. package/src/session-runtime/services/seeds.mjs +4 -3
  384. package/src/session-runtime/services/usage-dashboard.mjs +1 -1
  385. package/src/session-runtime/services/usage-stats-model.mjs +2 -1
  386. package/src/session-runtime/services/worktree-access.mjs +27 -0
  387. package/src/session-runtime/session-create/materialize.mjs +2 -3
  388. package/src/session-runtime/session-create/session-options.mjs +15 -2
  389. package/src/session-runtime/session-hooks.mjs +9 -17
  390. package/src/session-runtime/settings-builtin-tools-api.mjs +65 -1
  391. package/src/session-runtime/settings-compaction-api.mjs +86 -39
  392. package/src/session-runtime/setup-tool/executor.mjs +12 -2
  393. package/src/session-runtime/setup-tool/settings-contract.mjs +34 -1
  394. package/src/session-runtime/setup-tool/tool-defs.mjs +20 -3
  395. package/src/session-runtime/skills-api.mjs +12 -5
  396. package/src/session-runtime/tool-policy/agent-profile-fold.mjs +349 -0
  397. package/src/session-runtime/tool-policy/mode-switch.mjs +54 -0
  398. package/src/session-runtime/tool-policy/pending-switches.mjs +59 -0
  399. package/src/session-runtime/tool-policy/policy-stage.mjs +183 -0
  400. package/src/session-runtime/tool-policy/session-switches.mjs +169 -0
  401. package/src/session-runtime/tool-policy/surface-helpers.mjs +114 -0
  402. package/src/session-runtime/tool-policy/workflow-overlay.mjs +145 -0
  403. package/src/session-runtime/tool-policy-refresh.mjs +48 -369
  404. package/src/session-runtime/tool-surface.mjs +10 -4
  405. package/src/session-runtime/turn/session-ops.mjs +8 -0
  406. package/src/session-runtime/turn/turn-run/turn-prepare.mjs +95 -88
  407. package/src/session-runtime/turn/turn-run/turn-timing.mjs +4 -3
  408. package/src/session-runtime/turn/turn-run.mjs +7 -2
  409. package/src/session-runtime/workflow-agents-api/agent-connectors.mjs +54 -7
  410. package/src/session-runtime/workflow-agents-api/agent-editor.mjs +527 -333
  411. package/src/session-runtime/workflow-agents-api/agent-route.mjs +85 -63
  412. package/src/session-runtime/workflow-agents-api/shared.mjs +5 -1
  413. package/src/session-runtime/workflow-agents-api/style-and-mode.mjs +14 -1
  414. package/src/session-runtime/workflow-agents-api/workflow-packs.mjs +6 -3
  415. package/src/session-runtime/workspace/transition-steps.mjs +1 -18
  416. package/src/session-runtime/workspace/transitions.mjs +279 -67
  417. package/src/session-runtime/workspace/workspace-state.mjs +7 -6
  418. package/src/session-runtime/workspace/worktree-tool.mjs +194 -0
  419. package/src/standalone/daemon-agent-control.mjs +4 -1
  420. package/src/standalone/daemon-lag-profiler.mjs +3 -1
  421. package/src/standalone/daemon-session-control.mjs +173 -15
  422. package/src/standalone/daemon-telemetry.mjs +9 -0
  423. package/src/standalone/daemon.mjs +33 -10
  424. package/src/standalone/local-session-runtime.mjs +33 -16
  425. package/src/standalone/session-client.mjs +7 -2
  426. package/src/standalone/session-protocol.mjs +8 -0
  427. package/src/standalone/session-runtime-inline-host/boot-loaders.mjs +2 -0
  428. package/src/standalone/session-service/agent-route-follow.mjs +69 -0
  429. package/src/standalone/session-service/session-calls/session-turns.mjs +33 -4
  430. package/src/standalone/session-service.mjs +21 -0
  431. package/src/standalone/session-state-projection.mjs +19 -9
  432. package/src/standalone/session-tool-output.mjs +36 -9
  433. package/src/standalone/staged-import.mjs +47 -0
  434. package/src/tui/App.jsx +2 -0
  435. package/src/tui/app/maintenance-pickers/auto-clear-picker.mjs +19 -13
  436. package/src/tui/app/message-selector.mjs +15 -2
  437. package/src/tui/app/model-options.mjs +16 -2
  438. package/src/tui/app/model-picker.mjs +2 -1
  439. package/src/tui/app/route-pickers.mjs +3 -1
  440. package/src/tui/app/settings-picker/settings-rows.mjs +2 -2
  441. package/src/tui/app/slash-commands.mjs +1 -1
  442. package/src/tui/app/usage-context-panels/context-model.mjs +8 -2
  443. package/src/tui/dist/index.mjs +617 -369
  444. package/src/tui/paste-attachments.mjs +0 -1
  445. package/src/tui/paste-text-policy.mjs +4 -5
  446. package/src/tui/prompt-history-store.mjs +16 -21
  447. package/src/tui/session/agent-job-feed/execution-delivery.mjs +4 -1
  448. package/src/tui/session/context-state.mjs +4 -0
  449. package/src/tui/session/notice-surface.mjs +3 -0
  450. package/src/tui/session/session-api/intake/abort.mjs +52 -18
  451. package/src/tui/session/session-api/intake/rewind.mjs +39 -4
  452. package/src/tui/session/session-api/media.mjs +2 -1
  453. package/src/tui/session/session-api/routes-agent-definitions.mjs +76 -0
  454. package/src/tui/session/session-api/routes-write.mjs +203 -0
  455. package/src/tui/session/session-api/routes.mjs +23 -247
  456. package/src/tui/session/session-api/settings.mjs +14 -1
  457. package/src/tui/session/session-flow/drain.mjs +28 -3
  458. package/src/tui/session/session-flow/failed-turn-rewind.mjs +4 -2
  459. package/src/tui/session/session-flow/queue/take-entries.mjs +8 -0
  460. package/src/tui/session/session-flow/steering.mjs +8 -3
  461. package/src/tui/session/tool-approval.mjs +142 -14
  462. package/src/tui/session/transcript-intake.mjs +2 -0
  463. package/src/tui/session/turn.mjs +23 -14
  464. package/src/tui/transcript-tool-failures.mjs +8 -2
  465. package/src/vendor/statusline/src/gateway/route-meta.mjs +7 -8
  466. package/src/vendor/statusline/src/gateway/session-routes.mjs +6 -7
  467. package/src/rules/agent-mode/ROUTINE.md +0 -6
  468. package/src/session-runtime/room-member-gate.mjs +0 -48
@@ -0,0 +1,169 @@
1
+ // Mid-conversation workflow and orchestration-mode switches of a coding
2
+ // session (see createToolPolicyRefresh for the cache contract they share).
3
+ import { sessionHasConversationMessages } from '../../runtime/agent/orchestrator/runtime-core/session-text.mjs';
4
+ import { toSessionWorkflowMeta } from '../../runtime/agent/orchestrator/runtime-core/workflow.mjs';
5
+ import { isAgentOwner } from '../../runtime/agent/orchestrator/agent-owner.mjs';
6
+ import { AGENT_MODE, sessionModeOf } from '../../runtime/agent/orchestrator/session/agent-mode.mjs';
7
+ import { applyOrchestrationModeSwitch } from './mode-switch.mjs';
8
+ import { createPendingSwitchApplier } from './pending-switches.mjs';
9
+ import { configForSession, configForWorkflow, currentMode, leadPartsFor } from './surface-helpers.mjs';
10
+ import { createWorkflowOverlay } from './workflow-overlay.mjs';
11
+
12
+ // The session a mid-conversation switch applies to: a coding session with a
13
+ // conversation (null: none, the caller's empty-session path applies);
14
+ // anything else cannot switch.
15
+ function switchableConversation(session, what) {
16
+ if (!session?.id) return false;
17
+ if (
18
+ !sessionHasConversationMessages(session) &&
19
+ !sessionHasConversationMessages({ messages: session.liveTurnMessages })
20
+ ) {
21
+ return false;
22
+ }
23
+ if (isAgentOwner(session) || sessionModeOf(session) === AGENT_MODE) {
24
+ throw new Error(`Only a coding session has a ${what}.`);
25
+ }
26
+ if (!session.promptIdentity) throw new Error(`This session is too old to switch its ${what}; start a new task.`);
27
+ return true;
28
+ }
29
+
30
+ // A choice made while a turn runs waits for the next turn: the latest one
31
+ // wins and a choice of what the session already runs cancels it.
32
+ function stagePendingSwitch(session, field, value, current) {
33
+ if (value === current) delete session[field];
34
+ else session[field] = value;
35
+ session.updatedAt = Date.now();
36
+ }
37
+
38
+ export function createSessionSwitches({
39
+ getSession,
40
+ getConfig,
41
+ getDataDir,
42
+ modelStandaloneTools,
43
+ activeWorkflowContext,
44
+ persistSession,
45
+ liveDeniedTools,
46
+ turnInFlight,
47
+ }) {
48
+ const { applyWorkflowSwitch } = createWorkflowOverlay({
49
+ liveDeniedTools,
50
+ modelStandaloneTools,
51
+ });
52
+
53
+ // The workflow `workflowId` names with orchestration mode `mode`, and its
54
+ // Lead prompt parts, read before anything changes. The pack loader falls
55
+ // back to the default pack for a missing id, so a different id is a gone one.
56
+ function resolveWorkflow(session, workflowId, mode) {
57
+ const target = activeWorkflowContext(configForSession(getConfig(), workflowId, mode), getDataDir());
58
+ if (target.summary?.id !== workflowId) throw new Error(`workflow "${workflowId}" not found`);
59
+ return { target, parts: leadPartsFor(session, target.leadPromptParts) };
60
+ }
61
+
62
+ // The shared flow of a mid-conversation switch: null without a conversation;
63
+ // while a turn runs the choice is staged, else applied; saved either way.
64
+ async function switchConversation(what, { pendingField, value, current, deferredResult, apply }) {
65
+ const session = getSession?.();
66
+ if (!switchableConversation(session, what)) return null;
67
+ let result;
68
+ if (turnInFlight(session)) {
69
+ stagePendingSwitch(session, pendingField, value, current(session));
70
+ result = deferredResult(session);
71
+ } else {
72
+ result = apply(session);
73
+ }
74
+ await persistSession(session);
75
+ return result;
76
+ }
77
+
78
+ /**
79
+ * Switch the current coding session's workflow mid-conversation (the
80
+ * composer's workflow selector). The request prefix — BP1, BP2, BP3 and the
81
+ * tool schemas — stays byte-identical, so the provider cache survives: the
82
+ * session's workflow metadata changes now, and the next turn carries a
83
+ * self-contained reminder with the new workflow's rules, orchestration,
84
+ * agents and tool changes (manager/workflow-switch-notice.mjs). Tools the new
85
+ * workflow denies keep their schema and are refused at call time; tools it
86
+ * allows that the schema lacks stay unavailable until a new session. The
87
+ * prompt takes the new workflow at the next point where the cache is cold
88
+ * anyway (foldPromptIfCold). Never refused while a turn runs: the choice is
89
+ * staged (`pendingWorkflowId`, the last one wins, a pick of the current
90
+ * workflow cancels it) and applied when the next turn starts
91
+ * (applyPendingSessionSwitches). Either way the session is saved before
92
+ * this returns, so an acknowledged choice outlives a daemon restart. The
93
+ * configured workflow (the default for new sessions) is the caller's and
94
+ * stays as it is; the session keeps its own orchestration mode.
95
+ *
96
+ * Running work is untouched: agents and workers the session started under
97
+ * the old workflow are separate sessions with their own prompts and tools,
98
+ * so they keep running as they are (unlike a working-folder change, running
99
+ * agents never refuse this); only delegation made from the next turn on
100
+ * uses the new surface.
101
+ *
102
+ * Returns null when the session has no conversation (the caller applies the
103
+ * configured workflow to an empty session as before), else
104
+ * `{ appliedToCurrentSession: true, workflow, workflowSwitch }` where
105
+ * `workflowSwitch` is the transcript boundary (null when unchanged or
106
+ * deferred; a deferred switch answers `deferred: true` and the workflow
107
+ * the session will run).
108
+ */
109
+ async function switchSessionWorkflow(workflowId) {
110
+ return switchConversation('workflow', {
111
+ pendingField: 'pendingWorkflowId',
112
+ value: workflowId,
113
+ current: (session) => session.workflow?.id,
114
+ deferredResult: (session) => {
115
+ const shown = session.pendingWorkflowId
116
+ ? toSessionWorkflowMeta(
117
+ activeWorkflowContext(configForWorkflow(getConfig(), session.pendingWorkflowId), getDataDir()).summary
118
+ )
119
+ : session.workflow;
120
+ return { appliedToCurrentSession: true, deferred: true, workflow: shown, workflowSwitch: null };
121
+ },
122
+ apply: (session) => {
123
+ const resolved = resolveWorkflow(session, workflowId, currentMode(session));
124
+ delete session.pendingWorkflowId;
125
+ return applyWorkflowSwitch(session, resolved);
126
+ },
127
+ });
128
+ }
129
+
130
+ /**
131
+ * Switch the current coding session's orchestration (delegation) mode
132
+ * mid-conversation, on the workflow switch's pattern: the request prefix
133
+ * stays byte-identical, the session's mode changes now, and the next turn
134
+ * carries a reminder with the new mode's rules (the block BP3 carries;
135
+ * manager/orchestration-mode-switch-notice.mjs). The mode never changes
136
+ * which tools may run — Solo still lets the Lead load `agent` when the user
137
+ * asks — only how eagerly delegation is offered: the eager/deferred split
138
+ * stays the prompt's (tool-catalog.mjs), so a mode that delegates while the
139
+ * schema holds `agent` only as a deferred tool tells the model to load it.
140
+ * Back on the prompt's mode the overlay is dropped; the prompt takes the
141
+ * new mode at the next cold point (foldPromptIfCold). While a turn runs the
142
+ * choice waits for the next turn (stagePendingSwitch). Either way the
143
+ * session is saved before this returns. The configured mode (the default
144
+ * for new sessions) is the caller's and stays as it is.
145
+ * Returns null without a conversation (the caller's empty-session path),
146
+ * else `{ appliedToCurrentSession: true, mode, orchestrationModeSwitch }`.
147
+ */
148
+ async function switchSessionOrchestrationMode(mode) {
149
+ return switchConversation('orchestration mode', {
150
+ pendingField: 'pendingOrchestrationMode',
151
+ value: mode,
152
+ current: currentMode,
153
+ deferredResult: (session) => ({
154
+ appliedToCurrentSession: true,
155
+ deferred: true,
156
+ mode: session.pendingOrchestrationMode ?? currentMode(session),
157
+ orchestrationModeSwitch: null,
158
+ }),
159
+ apply: (session) => {
160
+ delete session.pendingOrchestrationMode;
161
+ return applyOrchestrationModeSwitch(session, mode);
162
+ },
163
+ });
164
+ }
165
+
166
+ const applyPendingSessionSwitches = createPendingSwitchApplier({ getSession, resolveWorkflow, applyWorkflowSwitch });
167
+
168
+ return { switchSessionWorkflow, switchSessionOrchestrationMode, applyPendingSessionSwitches };
169
+ }
@@ -0,0 +1,114 @@
1
+ // Pure helpers of the tool-policy refresh: reading a session's tool surface,
2
+ // rewriting its system blocks (BP1 heading, BP3 core), and the configs a
3
+ // session's workflow and orchestration mode give.
4
+ import { AGENT_MODE, resolveSessionMode, sessionModeOf } from '../../runtime/agent/orchestrator/session/agent-mode.mjs';
5
+ import { MIXY_AGENT_ID } from '../../runtime/agent/orchestrator/session/agent-home.mjs';
6
+ import { refreshSessionBp3Environment } from '../../runtime/agent/orchestrator/session/manager/prompt-utils.mjs';
7
+ import { promptOrchestrationModeOf } from '../../runtime/agent/orchestrator/session/manager/orchestration-mode-switch-notice.mjs';
8
+ import { sessionOrchestrationMode } from '../../runtime/shared/orchestration.mjs';
9
+
10
+ export const toolName = (tool) => String(tool?.name || '');
11
+
12
+ // Every tool definition the session's schema or deferred catalogs hold.
13
+ export function schemaTools(session) {
14
+ return [
15
+ ...(Array.isArray(session.tools) ? session.tools : []),
16
+ ...(Array.isArray(session.deferredToolCatalog) ? session.deferredToolCatalog : []),
17
+ ...(Array.isArray(session.deferredLateToolCatalog) ? session.deferredLateToolCatalog : []),
18
+ ];
19
+ }
20
+
21
+ export function toolNames(list) {
22
+ return (Array.isArray(list) ? list : [])
23
+ .map((item) => (typeof item === 'string' ? item : item?.name))
24
+ .filter(Boolean);
25
+ }
26
+
27
+ function replaceMessageContent(messages, target, content) {
28
+ const index = messages.indexOf(target);
29
+ if (index < 0) return false;
30
+ messages[index] = { ...target, content };
31
+ return true;
32
+ }
33
+
34
+ export function rewriteSystemHeading(session, heading, nextContent) {
35
+ if (!nextContent) return;
36
+ const messages = Array.isArray(session.messages) ? session.messages : [];
37
+ const target = messages.find(
38
+ (message) =>
39
+ message?.role === 'system' && typeof message.content === 'string' && message.content.startsWith(heading)
40
+ );
41
+ if (target) replaceMessageContent(messages, target, nextContent);
42
+ }
43
+
44
+ function bp3Message(session) {
45
+ const messages = Array.isArray(session.messages) ? session.messages : [];
46
+ return (
47
+ messages.find((message) => message?.role === 'system' && message.cacheTier === 'tier3') ||
48
+ messages.find(
49
+ (message) =>
50
+ message?.role === 'system' &&
51
+ typeof message.content === 'string' &&
52
+ message.content.startsWith('# Active Workflow:')
53
+ )
54
+ );
55
+ }
56
+
57
+ // The BP3 core the session's prompt carries now (split layout: the whole
58
+ // tier3 block; combined: the stored core beside the environment).
59
+ export function presentedBp3Core(session) {
60
+ return session.bp3EnvSplit === true ? bp3Message(session)?.content : session.bp3CoreContext;
61
+ }
62
+
63
+ export function rewriteBp3Core(session, nextCore) {
64
+ const messages = Array.isArray(session.messages) ? session.messages : [];
65
+ const bp3 = bp3Message(session);
66
+ if (!bp3 || typeof bp3.content !== 'string') return;
67
+ if (session.bp3EnvSplit === true) {
68
+ // Split layout: the environment lives in its own cacheTier:'env' system
69
+ // block — the tier3 block carries the core only.
70
+ replaceMessageContent(messages, bp3, nextCore || '');
71
+ session.bp3CoreContext = nextCore || '';
72
+ return;
73
+ }
74
+ const env = session.bp3EnvironmentContext || '';
75
+ replaceMessageContent(messages, bp3, [nextCore, env].filter((part) => String(part || '').trim()).join('\n\n---\n\n'));
76
+ session.bp3CoreContext = nextCore || '';
77
+ }
78
+
79
+ // A Lead's workflow slices (orchestration, agent and contact catalogs) for its
80
+ // mode, Mixy's with the contacts.
81
+ export function leadPartsFor(session, leadPromptParts) {
82
+ return leadPromptParts({
83
+ agentMode: sessionModeOf(session) === AGENT_MODE,
84
+ mixy: resolveSessionMode({ session }).agentId === MIXY_AGENT_ID,
85
+ });
86
+ }
87
+
88
+ // A conversation keeps its `# Session` block: the legacy combined layout
89
+ // rebuilds the tier3 block from the new core (rooted where it was).
90
+ export function rewriteConversationBp3Core(session, nextCore) {
91
+ if (session.bp3EnvSplit !== true && typeof session.bp3CoreContext === 'string') {
92
+ const previous = session.bp3CoreContext;
93
+ session.bp3CoreContext = nextCore;
94
+ if (refreshSessionBp3Environment(session, session.cwd)) return;
95
+ session.bp3CoreContext = previous;
96
+ }
97
+ rewriteBp3Core(session, nextCore);
98
+ }
99
+
100
+ // `config` with `workflowId` as the active workflow (itself when absent).
101
+ export function configForWorkflow(config, workflowId) {
102
+ return workflowId ? { ...config, workflow: { ...(config?.workflow || {}), active: workflowId } } : config;
103
+ }
104
+
105
+ // A conversation's config: its workflow and its own orchestration mode
106
+ // (`mode`), never the configured default for new sessions.
107
+ export function configForSession(config, workflowId, mode) {
108
+ return { ...configForWorkflow(config, workflowId), orchestrationMode: mode };
109
+ }
110
+
111
+ // The session's orchestration mode now (a legacy record derives it).
112
+ export const currentMode = (session) => sessionOrchestrationMode(session);
113
+ // The mode its prompt was built with.
114
+ export const promptMode = (session) => promptOrchestrationModeOf(session) ?? currentMode(session);
@@ -0,0 +1,145 @@
1
+ // Applying a mid-conversation workflow switch: the overlay it lays over the
2
+ // session's prompt, and the tool changes it makes reachable without touching
3
+ // the prefix.
4
+ import { toSessionWorkflowMeta } from '../../runtime/agent/orchestrator/runtime-core/workflow.mjs';
5
+ import {
6
+ promptWorkflowOf,
7
+ stageWorkflowSwitchNotice,
8
+ workflowOverlayContent,
9
+ } from '../../runtime/agent/orchestrator/session/manager/workflow-switch-notice.mjs';
10
+ import { mergePendingDeferredToolDelta } from '../../runtime/agent/orchestrator/runtime-core/deferred-tool-delta.mjs';
11
+ import { recordTranscriptBoundary } from '../model-route/set-route.mjs';
12
+ import { promptMode, schemaTools, toolName } from './surface-helpers.mjs';
13
+
14
+ export function createWorkflowOverlay({ liveDeniedTools, modelStandaloneTools }) {
15
+ // The overlay of a switch to `target` while the prompt carries `prompt`
16
+ // (manager/workflow-switch-notice.mjs): what the reminder tells the Lead and
17
+ // which calls are refused. Nothing in the request prefix moves.
18
+ function workflowOverlay(session, { target, parts }, { prompt, promptOrchestrationMode }) {
19
+ const denied = new Set(liveDeniedTools(session, target.summary).map((name) => name.toLowerCase()));
20
+ const disallowed = new Set((session.disallowedTools || []).map((name) => String(name).toLowerCase()));
21
+ const deniedTools = [
22
+ ...new Set(
23
+ schemaTools(session)
24
+ .map(toolName)
25
+ .filter((name) => name && denied.has(name.toLowerCase()) && !disallowed.has(name.toLowerCase()))
26
+ ),
27
+ ];
28
+ // Tools the new workflow allows that the session's policy denied (`agent`
29
+ // after a switch to a workflow with agents): reachable by deferred loading.
30
+ // `modelStandaloneTools` follows the session's workflow here (the caller
31
+ // drops the old overlay first), so their definitions are current.
32
+ // An earlier switch may have opened one already (workflowOpenedTools).
33
+ const reopened = [
34
+ ...new Set([...(session.disallowedTools || []), ...(session.workflowOpenedTools || [])].map(String)),
35
+ ].filter((name) => !denied.has(name.toLowerCase()));
36
+ const known = new Set(schemaTools(session).map(toolName));
37
+ const fresh = modelStandaloneTools().filter(
38
+ (tool) => reopened.includes(toolName(tool)) && !known.has(toolName(tool))
39
+ );
40
+ for (const tool of fresh) known.add(toolName(tool));
41
+ const loadableTools = reopened.filter((name) => known.has(name));
42
+ const unavailableTools = reopened.filter((name) => !known.has(name));
43
+ const workflow = { id: target.summary.id, name: target.summary.name || target.summary.id };
44
+ const instructions = [
45
+ target.packContext,
46
+ parts.orchestrationContext ||
47
+ `# Delegation\n\n${workflow.name} has no agents to delegate to: do the work yourself.`,
48
+ parts.agentCatalogContext,
49
+ ]
50
+ .map((part) => String(part || '').trim())
51
+ .filter(Boolean)
52
+ .join('\n\n');
53
+ const overlay = {
54
+ prompt,
55
+ promptOrchestrationMode,
56
+ workflow,
57
+ orchestrationMode: target.orchestrationMode,
58
+ deniedTools,
59
+ loadableTools,
60
+ unavailableTools,
61
+ content: workflowOverlayContent({
62
+ promptName: prompt?.name || prompt?.id || 'the previous workflow',
63
+ workflow,
64
+ instructions,
65
+ deniedTools,
66
+ loadableTools,
67
+ unavailableTools,
68
+ }),
69
+ };
70
+ return { overlay, fresh };
71
+ }
72
+
73
+ // Make a switch's loadable tools reachable without touching the prefix: their
74
+ // definitions join the deferred catalog, the policy stops denying them, and
75
+ // the next turn's deferred_tools_delta names them. Switching back refuses
76
+ // them again (the overlay's deniedTools, or the policy's deny list below).
77
+ function openLoadableTools(session, { loadableTools, fresh }) {
78
+ if (!loadableTools.length) return;
79
+ const opened = session.workflowOpenedTools || [];
80
+ session.workflowOpenedTools = [...new Set([...opened, ...loadableTools])];
81
+ if (fresh.length) session.deferredToolCatalog = [...(session.deferredToolCatalog || []), ...fresh];
82
+ session.disallowedTools = (session.disallowedTools || []).filter((name) => !loadableTools.includes(String(name)));
83
+ const byName = new Map(schemaTools(session).map((tool) => [toolName(tool), tool]));
84
+ // Announced on every switch that opens them: a pending removal (a switch
85
+ // back in between) cancels against it rather than lingering.
86
+ mergePendingDeferredToolDelta(session, {
87
+ added: loadableTools.map((name) => ({ name, description: byName.get(name)?.description || '' })),
88
+ });
89
+ }
90
+
91
+ // Back on the workflow the prompt carries: tools an earlier switch opened
92
+ // that it denies are denied again (call-time refusal; the schema stays).
93
+ function closeReopenedTools(session, target) {
94
+ const denied = new Set(liveDeniedTools(session, target.summary));
95
+ const disallowed = new Set((session.disallowedTools || []).map(String));
96
+ const known = new Set(schemaTools(session).map(toolName));
97
+ const closed = [...denied].filter((name) => known.has(name) && !disallowed.has(name));
98
+ if (!closed.length) return;
99
+ session.disallowedTools = [...disallowed, ...closed];
100
+ mergePendingDeferredToolDelta(session, { removed: closed });
101
+ }
102
+
103
+ function applyWorkflowSwitch(session, resolved) {
104
+ const { target } = resolved;
105
+ const before = session.workflow;
106
+ const from = before?.id ? before : null;
107
+ const prompt = promptWorkflowOf(session);
108
+ const promptOrchestrationMode = promptMode(session);
109
+ session.workflow = toSessionWorkflowMeta(target.summary);
110
+ session.orchestrationMode = target.orchestrationMode;
111
+ delete session.workflowOverlay;
112
+ if (session.workflow.id === prompt?.id) closeReopenedTools(session, target);
113
+ else {
114
+ const { overlay, fresh } = workflowOverlay(session, resolved, { prompt, promptOrchestrationMode });
115
+ openLoadableTools(session, { loadableTools: overlay.loadableTools, fresh });
116
+ session.workflowOverlay = overlay;
117
+ }
118
+ session.updatedAt = Date.now();
119
+ stageWorkflowSwitchNotice(session, from, session.workflow);
120
+ let workflowSwitch = null;
121
+ if (from?.id !== session.workflow.id) {
122
+ workflowSwitch = {
123
+ fromId: from?.id || '',
124
+ from: from?.name || from?.id || '',
125
+ toId: session.workflow.id,
126
+ to: session.workflow.name,
127
+ at: Date.now(),
128
+ };
129
+ // Two switches can land in the same millisecond (A→B→A): the same
130
+ // switch is a repeat only when its direction matches too.
131
+ recordTranscriptBoundary(
132
+ session,
133
+ 'workflowSwitches',
134
+ workflowSwitch,
135
+ (entry) =>
136
+ entry?.at === workflowSwitch.at &&
137
+ entry?.fromId === workflowSwitch.fromId &&
138
+ entry?.toId === workflowSwitch.toId
139
+ );
140
+ }
141
+ return { appliedToCurrentSession: true, workflow: session.workflow, workflowSwitch };
142
+ }
143
+
144
+ return { applyWorkflowSwitch };
145
+ }