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,349 @@
1
+ // Bringing a Lead session's prompt to the saved bots and folding pending prompt
2
+ // changes (a switched workflow or mode, moved tool gates, changed shipped
3
+ // rules) in where the provider cache is cold anyway.
4
+ import { sessionHasConversationMessages } from '../../runtime/agent/orchestrator/runtime-core/session-text.mjs';
5
+ import { ORCHESTRATION_MODES } from '../../runtime/shared/orchestration.mjs';
6
+ import { orchestrationModeFromPrompt } from '../../runtime/agent/orchestrator/session/manager/orchestration-mode-switch-notice.mjs';
7
+ import { promptRulesRevision } from '../../runtime/agent/orchestrator/session/manager/rules-cache.mjs';
8
+ import { isAgentOwner } from '../../runtime/agent/orchestrator/agent-owner.mjs';
9
+ import { AGENT_MODE, sessionModeOf } from '../../runtime/agent/orchestrator/session/agent-mode.mjs';
10
+ import {
11
+ conversationHolds,
12
+ promptWorkflowOf,
13
+ } from '../../runtime/agent/orchestrator/session/manager/workflow-switch-notice.mjs';
14
+ import { sessionTailCacheExpired } from '../../runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs';
15
+ import { mergePendingDeferredToolDelta } from '../../runtime/agent/orchestrator/runtime-core/deferred-tool-delta.mjs';
16
+ import {
17
+ agentMcpToolPermission,
18
+ connectorPolicyAgentOf,
19
+ } from '../../runtime/agent/orchestrator/mcp/agent-connectors.mjs';
20
+ import { agentListEntries } from '../../runtime/agent/orchestrator/session/manager/prompt-utils.mjs';
21
+ import { markToolSurfaceMigrated } from '../../runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs';
22
+ import {
23
+ agentProfileRevision,
24
+ leadRosterRevision,
25
+ } from '../../runtime/agent/orchestrator/context/role-instructions.mjs';
26
+ import {
27
+ configForSession,
28
+ currentMode,
29
+ leadPartsFor,
30
+ presentedBp3Core,
31
+ promptMode,
32
+ rewriteConversationBp3Core,
33
+ schemaTools,
34
+ toolName,
35
+ } from './surface-helpers.mjs';
36
+
37
+ const AGENT_PROFILE_INTENT = 'agent_profile';
38
+ // Pending prompt changes folded in where the cache is cold anyway.
39
+ const PROMPT_FOLD_INTENT = 'prompt_fold';
40
+ // Cache-break intents that already rebuild the conversation's cached prefix.
41
+ const COLD_INTENTS = new Set(['post_turn_compaction', 'manual_compaction']);
42
+
43
+ // What the next request sends ahead of the conversation: the system blocks and tools.
44
+ const promptPrefix = (session) =>
45
+ JSON.stringify([
46
+ (Array.isArray(session.messages) ? session.messages : [])
47
+ .filter((message) => message?.role === 'system')
48
+ .map((message) => message.content),
49
+ session.tools,
50
+ ]);
51
+
52
+ // A bot thread built from other shipped rules than these (a release changed one).
53
+ const rulesStale = (session) =>
54
+ sessionModeOf(session) === AGENT_MODE && session.rulesRevision !== promptRulesRevision();
55
+
56
+ // Before session-local modes were used by profile refreshes, changing the
57
+ // roster could replace a coding Lead's mode rules with the configured default
58
+ // while leaving its selected mode intact. This is not a normal mode overlay:
59
+ // repair only a known generated mismatch, with no user switch still pending.
60
+ function orchestrationRecoveryNeeded(session) {
61
+ if (
62
+ !session?.promptIdentity ||
63
+ session.promptIdentity.skipAgentRules ||
64
+ isAgentOwner(session) ||
65
+ sessionModeOf(session) === AGENT_MODE ||
66
+ !ORCHESTRATION_MODES.includes(session.orchestrationMode) ||
67
+ session.workflowOverlay ||
68
+ session.orchestrationModeOverlay ||
69
+ session.pendingWorkflowId !== undefined ||
70
+ session.pendingOrchestrationMode !== undefined
71
+ )
72
+ return false;
73
+ const presented = orchestrationModeFromPrompt(session);
74
+ return presented !== null && presented !== session.orchestrationMode;
75
+ }
76
+
77
+ // Changes the prompt does not carry yet: a workflow switched mid-conversation,
78
+ // a bot's tool gates that moved, or shipped rules a release changed.
79
+ const foldPending = (session) =>
80
+ Boolean(
81
+ session.workflowOverlay || session.orchestrationModeOverlay || session.promptFoldPending || rulesStale(session)
82
+ );
83
+
84
+ // A switch's reminder that is neither pending nor still in the conversation.
85
+ const reminderDropped = (session, overlay, notice) =>
86
+ Boolean(overlay && !notice && !conversationHolds(session, overlay.content));
87
+
88
+ // The cached prefix is cold anyway, so folding pending changes costs nothing
89
+ // extra: a compaction (tagged, or one that dropped a delivered workflow
90
+ // reminder), a cleared conversation, or a message tail the provider's cache
91
+ // already let expire (sessionTailCacheExpired; never for openai-oauth).
92
+ function cacheCold(session) {
93
+ if (COLD_INTENTS.has(session.pendingCacheBreakIntent)) return true;
94
+ if (!sessionHasConversationMessages(session)) return true;
95
+ if (sessionTailCacheExpired(session)) return true;
96
+ return (
97
+ reminderDropped(session, session.workflowOverlay, session.workflowSwitch) ||
98
+ reminderDropped(session, session.orchestrationModeOverlay, session.orchestrationModeSwitch)
99
+ );
100
+ }
101
+
102
+ // The connector tools among `names` the session's agent may run now.
103
+ function connectorTools(session, names) {
104
+ const agent = connectorPolicyAgentOf(session);
105
+ return [...names]
106
+ .filter((name) => name.startsWith('mcp__') && agentMcpToolPermission(agent, name) !== 'disabled')
107
+ .sort();
108
+ }
109
+
110
+ // A bot thread's tools that changed without its prompt: feature gates that
111
+ // opened (or closed) and connectors added or removed. Nothing in the request
112
+ // prefix moves. An opened tool joins the deferred catalog — reachable by
113
+ // deferred loading, which brings its schema into the conversation — and a
114
+ // gone one is refused at call time; the next turn's deferred_tools_delta
115
+ // notice names both. Gate changes are folded into the prompt at the next
116
+ // cold point (promptFoldPending). Connectors live in the bot's agent.json,
117
+ // so they are compared only when its profile stamp moved (`edited`).
118
+ // Returns true when anything changed.
119
+ function stageLiveToolChanges({ liveDeniedTools, modelStandaloneTools }, session, workflow, { edited = false } = {}) {
120
+ const added = [];
121
+ const removed = [];
122
+ const known = new Map(schemaTools(session).map((tool) => [toolName(tool), tool]));
123
+ const live = new Set(liveDeniedTools(session, workflow));
124
+ const disallowed = (session.disallowedTools || []).map(String);
125
+ const opened = disallowed.filter((name) => !live.has(name));
126
+ const closed = [...live].filter((name) => known.has(name) && !disallowed.includes(name));
127
+ if (opened.length || closed.length) {
128
+ const fresh = modelStandaloneTools().filter(
129
+ (tool) => opened.includes(toolName(tool)) && !known.has(toolName(tool))
130
+ );
131
+ if (fresh.length) session.deferredToolCatalog = [...(session.deferredToolCatalog || []), ...fresh];
132
+ for (const tool of fresh) known.set(toolName(tool), tool);
133
+ session.disallowedTools = [...live];
134
+ added.push(...opened.filter((name) => known.has(name)));
135
+ removed.push(...closed);
136
+ session.promptFoldPending = true;
137
+ }
138
+ // Connectors gate MCP tools at call time only (pre-dispatch-deny.mjs).
139
+ const previous = session.agentConnectorTools;
140
+ const permitted = edited || !Array.isArray(previous) ? connectorTools(session, known.keys()) : previous;
141
+ session.agentConnectorTools = permitted;
142
+ if (edited && Array.isArray(previous)) {
143
+ added.push(...permitted.filter((name) => !previous.includes(name)));
144
+ removed.push(...previous.filter((name) => !permitted.includes(name)));
145
+ }
146
+ if (!added.length && !removed.length) {
147
+ return opened.length + closed.length > 0 || !Array.isArray(previous);
148
+ }
149
+ mergePendingDeferredToolDelta(session, {
150
+ added: added.map((name) => ({ name, description: known.get(name)?.description || '' })),
151
+ removed,
152
+ });
153
+ session.updatedAt = Date.now();
154
+ return true;
155
+ }
156
+
157
+ // A coding Lead keeps `agent` whichever agents exist (workflow.mjs
158
+ // workflowDisallowsAgentTool); a denial a session recorded under the older
159
+ // rule, because no agent was enabled, is lifted as the live policy no longer
160
+ // holds it: the tool becomes reachable by deferred loading and the next
161
+ // turn's deferred_tools_delta names it. Nothing in the request prefix moves.
162
+ // Returns true when the session changed.
163
+ function liftAgentDenial({ liveDeniedTools, modelStandaloneTools }, session) {
164
+ const disallowed = (session.disallowedTools || []).map(String);
165
+ const overlayDenied = (session.workflowOverlay?.deniedTools || []).includes('agent');
166
+ if (!disallowed.includes('agent') && !overlayDenied) return false;
167
+ if (liveDeniedTools(session, session.workflow).includes('agent')) return false;
168
+ const known = new Map(schemaTools(session).map((tool) => [toolName(tool), tool]));
169
+ if (!known.has('agent')) {
170
+ const fresh = modelStandaloneTools().filter((tool) => toolName(tool) === 'agent');
171
+ if (!fresh.length) return false;
172
+ session.deferredToolCatalog = [...(session.deferredToolCatalog || []), ...fresh];
173
+ known.set('agent', fresh[0]);
174
+ }
175
+ session.disallowedTools = disallowed.filter((name) => name !== 'agent');
176
+ if (overlayDenied) {
177
+ session.workflowOverlay.deniedTools = session.workflowOverlay.deniedTools.filter((name) => name !== 'agent');
178
+ }
179
+ mergePendingDeferredToolDelta(session, {
180
+ added: [{ name: 'agent', description: known.get('agent')?.description || '' }],
181
+ });
182
+ session.updatedAt = Date.now();
183
+ return true;
184
+ }
185
+
186
+ export function createAgentProfileFold({
187
+ getSession,
188
+ getConfig,
189
+ getDataDir,
190
+ modelStandaloneTools,
191
+ activeWorkflowContext,
192
+ liveDeniedTools,
193
+ stagePolicy,
194
+ applyPolicy,
195
+ turnInFlight,
196
+ }) {
197
+ // An agent profile edit that met a running turn: the next turn applies it.
198
+ let agentProfilePending = false;
199
+
200
+ // Fold every pending change into the prompt: the session's own workflow,
201
+ // its tool gates and the shipped rules as they stand now, with every stamp
202
+ // moved. One cache break, tagged with the intent already pending (a
203
+ // compaction) or `intent`. Returns true when the request prefix changed.
204
+ async function foldPrompt(session, intent) {
205
+ const identity = session.promptIdentity;
206
+ if (!identity) return false;
207
+ const agentMode = sessionModeOf(session) === AGENT_MODE;
208
+ const config = configForSession(getConfig(), session.workflow?.id, currentMode(session));
209
+ const staged = await stagePolicy(session, identity, config, { conversation: true });
210
+ if (getSession?.() !== session) return false;
211
+ const before = promptPrefix(session);
212
+ applyPolicy(session, staged);
213
+ rewriteConversationBp3Core(session, staged.core);
214
+ if (session.agentProfileRevision !== undefined) {
215
+ session.agentProfileRevision = agentProfileRevision(identity.agent, { mixy: agentMode });
216
+ const { leadPromptParts } = activeWorkflowContext(config, getDataDir());
217
+ session.agentRosterRevision = leadRosterRevision(leadPartsFor(session, leadPromptParts));
218
+ }
219
+ if (agentMode) session.rulesRevision = promptRulesRevision();
220
+ session.updatedAt = Date.now();
221
+ if (promptPrefix(session) === before) return false;
222
+ markToolSurfaceMigrated(session, session.pendingCacheBreakIntent || intent);
223
+ return true;
224
+ }
225
+
226
+ /** Fold pending prompt changes (a switched workflow, a bot's moved tool
227
+ * gates, changed shipped rules) when the cache is cold anyway. */
228
+ async function foldPromptIfCold() {
229
+ const session = getSession?.();
230
+ if (!session?.id || !session.promptIdentity || isAgentOwner(session)) return false;
231
+ if (!foldPending(session) || !cacheCold(session)) return false;
232
+ return foldPrompt(session, PROMPT_FOLD_INTENT);
233
+ }
234
+
235
+ /**
236
+ * Bring a Lead session's prompt to the saved bots — its own agent's
237
+ * persona, AGENT.md and name, and the bot roster its catalogs list — after
238
+ * a bot was saved, created, renamed, archived or restored
239
+ * (agent-profile-changes.mjs), on resume, or at the start of the turn after
240
+ * one that ran through the change (`trigger`: 'save' | 'resume' | 'turn').
241
+ * Two stamps (agentProfileRevision, agentRosterRevision) tell whether
242
+ * anything it embeds changed; a delegated worker keeps its prompt. The core
243
+ * is rebuilt like a workflow switch's (the session's own workflow, the
244
+ * workspace slices the model was told) and replaces the stored one, so the
245
+ * next turn sends it with one provider cache break. The prompt is not re-embedded
246
+ * per turn, but currentAgents() does resolve the agent catalog at each
247
+ * turn's preparation (for the listing reminder). That rewrite is immediate
248
+ * (one tagged cache break) and takes every pending fold with it
249
+ * (foldPrompt), moving all stamps.
250
+ * What is not an edit never touches the prefix: a bot thread's feature gates
251
+ * and connectors are staged live (stageLiveToolChanges), and shipped rules a
252
+ * release changed wait silently; both are folded in at the next cold point
253
+ * (foldPromptIfCold). Returns true when the session changed (save it).
254
+ */
255
+ async function refreshAgentProfile({ trigger = 'save' } = {}) {
256
+ const session = getSession?.();
257
+ const identity = session?.promptIdentity;
258
+ const agent = identity?.agent;
259
+ if (!session?.id || !agent || isAgentOwner(session)) return false;
260
+ // Only Mixy's own (agent-mode) thread embeds Mixy's profile.
261
+ const agentMode = sessionModeOf(session) === AGENT_MODE;
262
+ const revision = agentProfileRevision(agent, { mixy: agentMode });
263
+ // The roster the prompt lists is the prompt's workflow's (a switched
264
+ // workflow is not an edit).
265
+ const workflowConfig = configForSession(getConfig(), promptWorkflowOf(session)?.id, promptMode(session));
266
+ const { leadPromptParts, summary: workflow } = activeWorkflowContext(workflowConfig, getDataDir());
267
+ const roster = leadRosterRevision(leadPartsFor(session, leadPromptParts));
268
+ const recoverMode = orchestrationRecoveryNeeded(session);
269
+ // A coding Lead hears of its agents through the listing reminder each
270
+ // turn carries (agent-listing-notice.mjs), never a rewritten prompt;
271
+ // syncAgentListing only lifts a stale `agent` denial.
272
+ const edited =
273
+ recoverMode || session.agentProfileRevision !== revision || (agentMode && session.agentRosterRevision !== roster);
274
+ // At a turn's start its own turn is the one counted; nothing runs yet.
275
+ const busy = () => getSession?.() !== session || (trigger !== 'turn' && turnInFlight(session));
276
+ if (busy()) {
277
+ agentProfilePending = true;
278
+ return false;
279
+ }
280
+ const toolsChanged = agentMode
281
+ ? stageLiveToolChanges({ liveDeniedTools, modelStandaloneTools }, session, workflow, {
282
+ edited: session.agentProfileRevision !== revision,
283
+ })
284
+ : trigger === 'resume' && syncAgentListing(session);
285
+ if (!edited) return (trigger === 'resume' && (await foldPromptIfCold())) || toolsChanged;
286
+ // A coding session from before profile stamps keeps its prompt when it
287
+ // is reopened; a saved edit still reaches it.
288
+ if (session.agentProfileRevision === undefined && trigger === 'resume' && !agentMode && !recoverMode) {
289
+ return toolsChanged;
290
+ }
291
+ if (foldPending(session)) {
292
+ await foldPrompt(session, AGENT_PROFILE_INTENT);
293
+ return true;
294
+ }
295
+ const staged = await stagePolicy(session, identity, workflowConfig, { conversation: true });
296
+ if (busy()) {
297
+ agentProfilePending = true;
298
+ return toolsChanged;
299
+ }
300
+ session.agentProfileRevision = revision;
301
+ session.agentRosterRevision = roster;
302
+ session.updatedAt = Date.now();
303
+ if (staged.core === presentedBp3Core(session)) return toolsChanged;
304
+ rewriteConversationBp3Core(session, staged.core);
305
+ // The request prefix changed: one cache break, tagged on the next send.
306
+ markToolSurfaceMigrated(session, recoverMode ? PROMPT_FOLD_INTENT : AGENT_PROFILE_INTENT);
307
+ return true;
308
+ }
309
+
310
+ /** Turn start: apply an edit that arrived while the previous turn ran, then
311
+ * fold pending prompt changes if the cache is cold anyway. */
312
+ async function applyPendingAgentProfile() {
313
+ let changed = false;
314
+ // A bot thread's connector baseline, before any edit can be compared to it.
315
+ const session = getSession?.();
316
+ if (session?.id && sessionModeOf(session) === AGENT_MODE && !Array.isArray(session.agentConnectorTools)) {
317
+ session.agentConnectorTools = connectorTools(session, schemaTools(session).map(toolName));
318
+ }
319
+ if (agentProfilePending || orchestrationRecoveryNeeded(session)) {
320
+ agentProfilePending = false;
321
+ changed = await refreshAgentProfile({ trigger: 'turn' });
322
+ }
323
+ changed = (await foldPromptIfCold()) || changed;
324
+ return syncAgentListing(session) || changed;
325
+ }
326
+
327
+ // A coding Lead hears of its agents through the agent list reminder.
328
+ const codingLead = (session) =>
329
+ Boolean(session?.id && session.promptIdentity && !isAgentOwner(session) && sessionModeOf(session) !== AGENT_MODE);
330
+
331
+ /** A coding Lead keeps `agent` reachable (liftAgentDenial). Returns true
332
+ * when the session changed. */
333
+ function syncAgentListing(session) {
334
+ return codingLead(session) && liftAgentDenial({ liveDeniedTools, modelStandaloneTools }, session);
335
+ }
336
+
337
+ /** The agents a coding Lead may delegate to now, as its prompt would list
338
+ * them: the turn's input to the agent list reminder (manager/
339
+ * agent-listing-notice.mjs); undefined for any other session. */
340
+ function currentAgents() {
341
+ const session = getSession?.();
342
+ if (!codingLead(session)) return undefined;
343
+ const config = configForSession(getConfig(), session.workflow?.id, currentMode(session));
344
+ const { leadPromptParts } = activeWorkflowContext(config, getDataDir());
345
+ return agentListEntries(leadPartsFor(session, leadPromptParts).agentCatalogContext) || [];
346
+ }
347
+
348
+ return { refreshAgentProfile, applyPendingAgentProfile, currentAgents };
349
+ }
@@ -0,0 +1,54 @@
1
+ // Applying an orchestration (delegation) mode switch to a session: the
2
+ // overlay that carries the new mode's rules while the prompt keeps its own,
3
+ // and the transcript boundary.
4
+ import {
5
+ orchestrationModeNoticeContent,
6
+ stageOrchestrationModeSwitchNotice,
7
+ } from '../../runtime/agent/orchestrator/session/manager/orchestration-mode-switch-notice.mjs';
8
+ import { recordTranscriptBoundary } from '../model-route/set-route.mjs';
9
+ import { currentMode, promptMode, toolNames } from './surface-helpers.mjs';
10
+
11
+ // `agent` when `mode` delegates and the session can run it but holds it only
12
+ // as a deferred tool the model has not loaded.
13
+ function modeLoadableTools(session, mode) {
14
+ if (mode === 'none') return [];
15
+ const reached = new Set([
16
+ ...toolNames(session.tools),
17
+ ...toolNames(session.deferredCallableTools),
18
+ ...toolNames(session.deferredDiscoveredTools),
19
+ ]);
20
+ const deferred = new Set(toolNames(session.deferredToolCatalog));
21
+ const denied = new Set(
22
+ [...(session.disallowedTools || []), ...(session.workflowOverlay?.deniedTools || [])].map(String)
23
+ );
24
+ return ['agent'].filter((name) => deferred.has(name) && !reached.has(name) && !denied.has(name));
25
+ }
26
+
27
+ export function applyOrchestrationModeSwitch(session, mode) {
28
+ const from = currentMode(session);
29
+ const prompt = promptMode(session);
30
+ session.orchestrationMode = mode;
31
+ delete session.orchestrationModeOverlay;
32
+ if (mode !== prompt) {
33
+ const loadableTools = modeLoadableTools(session, mode);
34
+ session.orchestrationModeOverlay = {
35
+ prompt,
36
+ mode,
37
+ loadableTools,
38
+ content: orchestrationModeNoticeContent({ mode, loadableTools }),
39
+ };
40
+ }
41
+ session.updatedAt = Date.now();
42
+ stageOrchestrationModeSwitchNotice(session, from, mode);
43
+ let orchestrationModeSwitch = null;
44
+ if (from !== mode) {
45
+ orchestrationModeSwitch = { from, to: mode, at: Date.now() };
46
+ recordTranscriptBoundary(
47
+ session,
48
+ 'orchestrationModeSwitches',
49
+ orchestrationModeSwitch,
50
+ (entry) => entry?.at === orchestrationModeSwitch.at && entry?.from === from && entry?.to === mode
51
+ );
52
+ }
53
+ return { appliedToCurrentSession: true, mode, orchestrationModeSwitch };
54
+ }
@@ -0,0 +1,59 @@
1
+ // Applying the orchestration mode and workflow choices made while a turn ran.
2
+ import { recordTranscriptBoundary } from '../model-route/set-route.mjs';
3
+ import { applyOrchestrationModeSwitch } from './mode-switch.mjs';
4
+ import { currentMode } from './surface-helpers.mjs';
5
+
6
+ // The transcript note of a pending workflow that could not be applied: the
7
+ // conversation keeps the workflow it runs.
8
+ function unavailableWorkflowBoundary(session, workflowId, error) {
9
+ const current = session.workflow;
10
+ const boundary = {
11
+ fromId: current?.id || '',
12
+ from: current?.name || current?.id || '',
13
+ toId: workflowId,
14
+ to: workflowId,
15
+ unavailable: true,
16
+ reason: String(error?.message || error),
17
+ at: Date.now(),
18
+ };
19
+ recordTranscriptBoundary(
20
+ session,
21
+ 'workflowSwitches',
22
+ boundary,
23
+ (entry) => entry?.at === boundary.at && entry?.toId === workflowId && entry?.unavailable === true
24
+ );
25
+ return boundary;
26
+ }
27
+
28
+ export function createPendingSwitchApplier({ getSession, resolveWorkflow, applyWorkflowSwitch }) {
29
+ /** Turn start: apply the orchestration mode and workflow chosen while the
30
+ * previous turn ran (mode first, so a workflow reminder carries it). Both
31
+ * are resolved before anything changes; a workflow that is gone (or cannot
32
+ * be read) is dropped alone with a transcript note and the turn runs on the
33
+ * current workflow. The pending choices are cleared only once applied.
34
+ * Returns the transcript boundaries, or null when nothing switched. */
35
+ return function applyPendingSessionSwitches() {
36
+ const session = getSession?.();
37
+ if (!session?.id) return null;
38
+ const { pendingOrchestrationMode: mode, pendingWorkflowId: workflowId } = session;
39
+ if (mode === undefined && workflowId === undefined) return null;
40
+ let resolved = null;
41
+ let unavailable = null;
42
+ if (workflowId !== undefined) {
43
+ try {
44
+ resolved = resolveWorkflow(session, workflowId, mode ?? currentMode(session));
45
+ } catch (error) {
46
+ unavailable = unavailableWorkflowBoundary(session, workflowId, error);
47
+ }
48
+ }
49
+ const switches = {};
50
+ if (mode !== undefined) {
51
+ switches.orchestrationModeSwitch = applyOrchestrationModeSwitch(session, mode).orchestrationModeSwitch;
52
+ }
53
+ if (resolved) switches.workflowSwitch = applyWorkflowSwitch(session, resolved).workflowSwitch;
54
+ else if (unavailable) switches.workflowSwitch = unavailable;
55
+ delete session.pendingOrchestrationMode;
56
+ delete session.pendingWorkflowId;
57
+ return switches.orchestrationModeSwitch || switches.workflowSwitch ? switches : null;
58
+ };
59
+ }
@@ -0,0 +1,183 @@
1
+ // Staging and applying the tool/prompt policy a config gives a Lead session:
2
+ // the tools it is denied, its BP1 rules and its BP3 core.
3
+ import {
4
+ toSessionWorkflowMeta,
5
+ workflowDisallowsAgentTool,
6
+ } from '../../runtime/agent/orchestrator/runtime-core/workflow.mjs';
7
+ import {
8
+ applyDeferredToolSurface,
9
+ filterDisallowedTools,
10
+ } from '../../runtime/agent/orchestrator/runtime-core/tool-catalog.mjs';
11
+ import { deferredSurfaceModeForLead } from '../../runtime/agent/orchestrator/runtime-core/effort.mjs';
12
+ import {
13
+ applyInitialDeferredToolManifestToBp2,
14
+ composeSystemPrompt,
15
+ } from '../../runtime/agent/orchestrator/context/collect.mjs';
16
+ import { _buildBaseRules } from '../../runtime/agent/orchestrator/session/manager/rules-cache.mjs';
17
+ import { sessionRolePromptFields } from '../../runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs';
18
+ import {
19
+ delegationDisabled,
20
+ honoredSchemaAllowlist,
21
+ } from '../../runtime/agent/orchestrator/session/manager/session-tool-surface.mjs';
22
+ import { finalizeSessionToolList } from '../../runtime/agent/orchestrator/session/manager/tool-resolution.mjs';
23
+ import { isAgentOwner } from '../../runtime/agent/orchestrator/agent-owner.mjs';
24
+ import { AGENT_MODE, sessionModeOf } from '../../runtime/agent/orchestrator/session/agent-mode.mjs';
25
+ import { unusedModelEditToolName } from '../../runtime/shared/edit-tool-dialect.mjs';
26
+ import {
27
+ presentedAgentCatalogSlice,
28
+ withPresentedWorkspaceSlices,
29
+ } from '../../runtime/agent/orchestrator/session/manager/prompt-utils.mjs';
30
+ import { leadPartsFor, rewriteSystemHeading, toolNames } from './surface-helpers.mjs';
31
+
32
+ export function createPolicyStage({
33
+ getRoute,
34
+ getMode,
35
+ getDataDir,
36
+ modelStandaloneTools,
37
+ featureDisallowedTools,
38
+ loadCoreMemoryContext,
39
+ loadInstructionFilesContext,
40
+ activeWorkflowContext,
41
+ }) {
42
+ // The tools `session` is denied now: its caller's denials, the feature gates
43
+ // as they stand, and an agent-mode Lead's agent tool when its workflow
44
+ // delegates to no one (a coding Lead keeps it: workflow.mjs
45
+ // workflowDisallowsAgentTool).
46
+ function liveDeniedTools(session, workflow) {
47
+ return [
48
+ ...session.callerDisallowedTools,
49
+ ...featureDisallowedTools(),
50
+ ...(workflowDisallowsAgentTool(workflow, { agentMode: sessionModeOf(session) === AGENT_MODE }) ? ['agent'] : []),
51
+ ]
52
+ .map((name) => String(name || ''))
53
+ .filter(Boolean);
54
+ }
55
+
56
+ // Denied tools leave every surface, then the deferred surface is rebuilt
57
+ // for the lead's current mode.
58
+ function applyToolDenials(session, denied, schemaAllowedTools, ownerIsAgent) {
59
+ session.disallowedTools = denied;
60
+ session.tools = filterDisallowedTools(session.tools, denied);
61
+ if (Array.isArray(session.deferredToolCatalog)) {
62
+ session.deferredToolCatalog = filterDisallowedTools(session.deferredToolCatalog, denied);
63
+ }
64
+ const catalogTools = finalizeSessionToolList(modelStandaloneTools(), {
65
+ schemaAllowedTools,
66
+ disallowedTools: denied,
67
+ ownerIsAgent,
68
+ });
69
+ session.tools = finalizeSessionToolList(session.tools, {
70
+ schemaAllowedTools,
71
+ disallowedTools: denied,
72
+ ownerIsAgent,
73
+ });
74
+ applyDeferredToolSurface(session, deferredSurfaceModeForLead(getMode()), catalogTools, {
75
+ provider: getRoute()?.provider,
76
+ });
77
+ const catalog = Array.isArray(session.deferredToolCatalog) ? session.deferredToolCatalog : [];
78
+ const active = new Set(toolNames(session.tools).concat(toolNames(session.deferredCallableTools)));
79
+ const pool = catalog.map((tool) => String(tool?.name || '')).filter((name) => name && !active.has(name));
80
+ applyInitialDeferredToolManifestToBp2(session, pool, { rebuild: true });
81
+ }
82
+
83
+ async function leadCoreMemoryContext() {
84
+ try {
85
+ return await loadCoreMemoryContext();
86
+ } catch {
87
+ return '';
88
+ }
89
+ }
90
+
91
+ // The policy `config` gives `session`, computed without touching the
92
+ // session, so a turn that starts during the async rebuild cannot lose tools
93
+ // to it. `conversation`: the rebuilt BP3 core keeps the instruction files
94
+ // and core memory the prompt presents now (withPresentedWorkspaceSlices).
95
+ async function stagePolicy(session, identity, config, { conversation = false } = {}) {
96
+ const ownerIsAgent = isAgentOwner(session);
97
+ const schemaAllowedTools = honoredSchemaAllowlist(session.schemaAllowedTools, {
98
+ ownerIsAgent,
99
+ agent: identity.agent,
100
+ });
101
+ const toolFreeRole = ownerIsAgent && schemaAllowedTools?.length === 0;
102
+
103
+ const {
104
+ summary: workflow,
105
+ leadPromptParts,
106
+ packContext: workflowContext,
107
+ orchestrationMode,
108
+ } = activeWorkflowContext(config, getDataDir());
109
+ const sessionMode = sessionModeOf(session);
110
+ const agentMode = sessionMode === AGENT_MODE;
111
+ // A coding Lead's conversation keeps the agent list it was built with, as
112
+ // it keeps the workspace slices: agents switched on or off since reach it
113
+ // as reminders on top of that list (agent-listing-notice.mjs). A slice
114
+ // that is not one generated list is rebuilt as before.
115
+ const presentedCatalog = conversation && !agentMode ? presentedAgentCatalogSlice(session) : null;
116
+ const leadWorkflowParts = ownerIsAgent
117
+ ? {}
118
+ : {
119
+ ...leadPartsFor(session, leadPromptParts),
120
+ ...(presentedCatalog !== null ? { agentCatalogContext: presentedCatalog } : {}),
121
+ };
122
+ const denied = liveDeniedTools(session, workflow);
123
+
124
+ const baseRules =
125
+ identity.skipAgentRules || toolFreeRole
126
+ ? ''
127
+ : _buildBaseRules({
128
+ omitTools: [...denied, unusedModelEditToolName(getRoute()?.model)],
129
+ allowTools: schemaAllowedTools,
130
+ provider: getRoute()?.provider,
131
+ model: getRoute()?.model,
132
+ });
133
+ const coreMemoryContext = conversation ? '' : await leadCoreMemoryContext();
134
+ const { sessionMarkerCore } = composeSystemPrompt({
135
+ ...sessionRolePromptFields(identity, {
136
+ ownerIsAgent,
137
+ toolFreeRole,
138
+ delegationFree: delegationDisabled(session, ownerIsAgent),
139
+ sessionMode,
140
+ }),
141
+ provider: getRoute()?.provider,
142
+ workflowContext,
143
+ ...leadWorkflowParts,
144
+ coreMemoryContext,
145
+ // The rebuilt core keeps (or newly applies) the instruction-files
146
+ // setting; agent mode carries none.
147
+ instructionFilesContext:
148
+ conversation || toolFreeRole || agentMode ? null : loadInstructionFilesContext?.(session) || null,
149
+ });
150
+ return {
151
+ workflow,
152
+ orchestrationMode,
153
+ sessionMode,
154
+ denied,
155
+ schemaAllowedTools,
156
+ ownerIsAgent,
157
+ baseRules,
158
+ core: conversation ? withPresentedWorkspaceSlices(session, sessionMarkerCore) : sessionMarkerCore,
159
+ };
160
+ }
161
+
162
+ // Apply a staged policy synchronously; the BP3 core is the caller's. The
163
+ // prompt then carries the session's workflow and tools as they stand.
164
+ function applyPolicy(session, staged) {
165
+ delete session.workflowOverlay;
166
+ delete session.orchestrationModeOverlay;
167
+ delete session.workflowOpenedTools;
168
+ delete session.promptFoldPending;
169
+ session.workflow = toSessionWorkflowMeta(staged.workflow);
170
+ session.orchestrationMode = staged.orchestrationMode;
171
+ session.sessionMode = staged.sessionMode;
172
+ applyToolDenials(session, staged.denied, staged.schemaAllowedTools, staged.ownerIsAgent);
173
+ // BP1 opens with its first rule file's heading (`# Tool Calls`); older
174
+ // prompts opened with `# Tool Use`.
175
+ const heading = String(staged.baseRules || '').split('\n', 1)[0];
176
+ for (const candidate of new Set(['# Tool Use', heading].filter(Boolean))) {
177
+ rewriteSystemHeading(session, candidate, staged.baseRules);
178
+ }
179
+ session.updatedAt = Date.now();
180
+ }
181
+
182
+ return { liveDeniedTools, stagePolicy, applyPolicy };
183
+ }