mixdog 1.3.0 → 1.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (423) hide show
  1. package/NOTICE.md +52 -9
  2. package/README.md +8 -4
  3. package/package.json +2 -2
  4. package/scripts/native-release-status.mjs +238 -0
  5. package/src/defaults/shipped-history.json +8 -1
  6. package/src/defaults/skills/pptx/scripts/qc-pages.mjs +3 -2
  7. package/src/defaults/skills/setup/SKILL.md +23 -1
  8. package/src/defaults/skills/setup/references/actions.md +54 -4
  9. package/src/defaults/skills/setup/references/surfaces.md +23 -3
  10. package/src/defaults/skills/setup-guide/SKILL.md +17 -10
  11. package/src/defaults/skills/visualize/SKILL.md +9 -6
  12. package/src/defaults/skills/visualize/references/craft.md +8 -1
  13. package/src/help.mjs +1 -1
  14. package/src/lib/keychain-cjs.cjs +4 -1
  15. package/src/lib/rules-builder.cjs +14 -7
  16. package/src/output-styles/common.md +13 -8
  17. package/src/rules/agent-mode/AGENT_MODE.md +9 -6
  18. package/src/rules/agent-mode/MIXY.md +11 -6
  19. package/src/rules/lead/LEAD.md +2 -2
  20. package/src/rules/shared/10-tool-workflow.md +4 -0
  21. package/src/rules/shared/20-research.md +2 -0
  22. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/preset.mjs +5 -0
  23. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/session-prep.mjs +8 -0
  24. package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +6 -1
  25. package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +114 -26
  26. package/src/runtime/agent/orchestrator/agent-runtime/maintenance-route.mjs +8 -0
  27. package/src/runtime/agent/orchestrator/agent-runtime/room-supervisor-completion.mjs +5 -4
  28. package/src/runtime/agent/orchestrator/agent-trace.mjs +3 -0
  29. package/src/runtime/agent/orchestrator/cache-break-trace.mjs +4 -0
  30. package/src/runtime/agent/orchestrator/config-presets.mjs +2 -0
  31. package/src/runtime/agent/orchestrator/config-storage.mjs +10 -3
  32. package/src/runtime/agent/orchestrator/config.mjs +11 -0
  33. package/src/runtime/agent/orchestrator/context/role-instructions.mjs +81 -16
  34. package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +97 -4
  35. package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +6 -10
  36. package/src/runtime/agent/orchestrator/mcp/client.mjs +7 -4
  37. package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +80 -31
  38. package/src/runtime/agent/orchestrator/providers/anthropic-model-resolve.mjs +1 -1
  39. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
  40. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +67 -38
  41. package/src/runtime/agent/orchestrator/providers/anthropic-turn-result.mjs +2 -0
  42. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-catalog.mjs +7 -2
  43. package/src/runtime/agent/orchestrator/providers/antigravity-request.mjs +6 -2
  44. package/src/runtime/agent/orchestrator/providers/auto-effort.mjs +34 -16
  45. package/src/runtime/agent/orchestrator/providers/cursor-wire.mjs +31 -4
  46. package/src/runtime/agent/orchestrator/providers/cursor.mjs +4 -1
  47. package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +11 -8
  48. package/src/runtime/agent/orchestrator/providers/lib/anthropic-prefix-trace.mjs +76 -0
  49. package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +19 -1
  50. package/src/runtime/agent/orchestrator/providers/lib/tail-reminder-split.mjs +13 -0
  51. package/src/runtime/agent/orchestrator/providers/lib/tool-call-wire-ids.mjs +65 -0
  52. package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +16 -1
  53. package/src/runtime/agent/orchestrator/providers/mixdog-local.mjs +3 -1
  54. package/src/runtime/agent/orchestrator/providers/model-proxy-provider.mjs +1 -0
  55. package/src/runtime/agent/orchestrator/providers/openai-codex-metadata.mjs +5 -5
  56. package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +9 -5
  57. package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +9 -1
  58. package/src/runtime/agent/orchestrator/providers/openai-compat-retry-profile.mjs +8 -2
  59. package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +10 -2
  60. package/src/runtime/agent/orchestrator/providers/openai-direct-request.mjs +30 -3
  61. package/src/runtime/agent/orchestrator/providers/openai-model-capabilities.mjs +1 -1
  62. package/src/runtime/agent/orchestrator/providers/openai-responses-input.mjs +3 -1
  63. package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +3 -1
  64. package/src/runtime/agent/orchestrator/providers/opencode-go-oauth.mjs +61 -8
  65. package/src/runtime/agent/orchestrator/providers/provider-error-kind.mjs +14 -2
  66. package/src/runtime/agent/orchestrator/providers/registry.mjs +9 -0
  67. package/src/runtime/agent/orchestrator/providers/retry-executor.mjs +17 -0
  68. package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +90 -24
  69. package/src/runtime/agent/orchestrator/runtime-core/fs-utils.mjs +8 -1
  70. package/src/runtime/agent/orchestrator/runtime-core/goal-mutations.mjs +1 -1
  71. package/src/runtime/agent/orchestrator/runtime-core/goal-storage.mjs +68 -22
  72. package/src/runtime/agent/orchestrator/runtime-core/goal-tool-exec.mjs +1 -1
  73. package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +5 -5
  74. package/src/runtime/agent/orchestrator/runtime-core/route-context-state.mjs +81 -0
  75. package/src/runtime/agent/orchestrator/runtime-core/session-text.mjs +2 -1
  76. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +12 -1
  77. package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +17 -6
  78. package/src/runtime/agent/orchestrator/runtime-core/workflow/agents.mjs +41 -10
  79. package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +6 -4
  80. package/src/runtime/agent/orchestrator/runtime-core/workflow/packs.mjs +8 -4
  81. package/src/runtime/agent/orchestrator/runtime-core/workflow.mjs +2 -0
  82. package/src/runtime/agent/orchestrator/session/agent-mode.mjs +0 -6
  83. package/src/runtime/agent/orchestrator/session/agent-room-supervisor.d.mts +1 -1
  84. package/src/runtime/agent/orchestrator/session/agent-room-supervisor.mjs +22 -4
  85. package/src/runtime/agent/orchestrator/session/agent-room.d.mts +21 -2
  86. package/src/runtime/agent/orchestrator/session/agent-room.mjs +149 -45
  87. package/src/runtime/agent/orchestrator/session/attachment-preflight.mjs +80 -0
  88. package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +4 -1
  89. package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +14 -11
  90. package/src/runtime/agent/orchestrator/session/compact/forked-summary.mjs +3 -0
  91. package/src/runtime/agent/orchestrator/session/compact/runner.mjs +68 -18
  92. package/src/runtime/agent/orchestrator/session/compact/summary-mode.mjs +16 -0
  93. package/src/runtime/agent/orchestrator/session/compact/summary-route.mjs +87 -0
  94. package/src/runtime/agent/orchestrator/session/compact/summary.mjs +2 -0
  95. package/src/runtime/agent/orchestrator/session/compact/text-utils.mjs +5 -1
  96. package/src/runtime/agent/orchestrator/session/compact/user-message-kind.mjs +1 -1
  97. package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +1 -1
  98. package/src/runtime/agent/orchestrator/session/context-utils.mjs +41 -10
  99. package/src/runtime/agent/orchestrator/session/human-gate/delegation.mjs +230 -0
  100. package/src/runtime/agent/orchestrator/session/human-gate/gate.mjs +156 -25
  101. package/src/runtime/agent/orchestrator/session/human-gate/outbound-policy.mjs +20 -0
  102. package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +21 -9
  103. package/src/runtime/agent/orchestrator/session/human-gate/run-policy.mjs +73 -0
  104. package/src/runtime/agent/orchestrator/session/human-gate/store.mjs +55 -27
  105. package/src/runtime/agent/orchestrator/session/human-gate/unattended-port.mjs +15 -0
  106. package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +4 -1
  107. package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +189 -105
  108. package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +9 -0
  109. package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +6 -2
  110. package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +111 -9
  111. package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +11 -14
  112. package/src/runtime/agent/orchestrator/session/loop/steering.mjs +3 -0
  113. package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +38 -5
  114. package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +21 -0
  115. package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +2 -1
  116. package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +12 -0
  117. package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +11 -5
  118. package/src/runtime/agent/orchestrator/session/loop/usage.mjs +46 -4
  119. package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +13 -2
  120. package/src/runtime/agent/orchestrator/session/manager/ask-turn-commit.mjs +18 -8
  121. package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +4 -0
  122. package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +6 -0
  123. package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +4 -0
  124. package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +44 -18
  125. package/src/runtime/agent/orchestrator/session/manager/orchestration-mode-switch-notice.mjs +99 -0
  126. package/src/runtime/agent/orchestrator/session/manager/owner-route-fallbacks.mjs +42 -0
  127. package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +3 -9
  128. package/src/runtime/agent/orchestrator/session/manager/pending-spool-file.mjs +1 -1
  129. package/src/runtime/agent/orchestrator/session/manager/pending-spool-shard.mjs +5 -3
  130. package/src/runtime/agent/orchestrator/session/manager/provider-replay.mjs +50 -0
  131. package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +40 -1
  132. package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +12 -0
  133. package/src/runtime/agent/orchestrator/session/manager/runtime-state.mjs +20 -0
  134. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +62 -47
  135. package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +6 -8
  136. package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +12 -1
  137. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-journal.mjs +6 -15
  138. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint.mjs +7 -1
  139. package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +24 -8
  140. package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +1 -1
  141. package/src/runtime/agent/orchestrator/session/manager/workflow-switch-notice.mjs +94 -13
  142. package/src/runtime/agent/orchestrator/session/mixy-name.mjs +5 -2
  143. package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +42 -10
  144. package/src/runtime/agent/orchestrator/session/provider-prefix-guard.mjs +21 -3
  145. package/src/runtime/agent/orchestrator/session/routine-result.d.mts +35 -4
  146. package/src/runtime/agent/orchestrator/session/routine-result.mjs +179 -16
  147. package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +5 -1
  148. package/src/runtime/agent/orchestrator/session/side-question-store.mjs +3 -1
  149. package/src/runtime/agent/orchestrator/session/store/canonical-reader.mjs +41 -7
  150. package/src/runtime/agent/orchestrator/session/store/lifecycle-barriers.mjs +10 -2
  151. package/src/runtime/agent/orchestrator/session/store/load-cache.mjs +14 -2
  152. package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +15 -1
  153. package/src/runtime/agent/orchestrator/session/store/sweep/sweep-record.mjs +8 -3
  154. package/src/runtime/agent/orchestrator/session/store/sweep/sweep-row.mjs +36 -1
  155. package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +4 -1
  156. package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +40 -5
  157. package/src/runtime/agent/orchestrator/session/store-summary-last-message.mjs +47 -2
  158. package/src/runtime/agent/orchestrator/session/tail-reminder-rules.mjs +125 -0
  159. package/src/runtime/agent/orchestrator/session/tool-batch/finalize.mjs +4 -0
  160. package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +78 -43
  161. package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +49 -14
  162. package/src/runtime/agent/orchestrator/session/transcript-restore/user-text.mjs +134 -17
  163. package/src/runtime/agent/orchestrator/tools/builtin/advisory-lock.mjs +35 -13
  164. package/src/runtime/agent/orchestrator/tools/builtin/atomic-write.mjs +25 -5
  165. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/backgrounded-result.mjs +4 -3
  166. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/completed-result.mjs +13 -14
  167. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/transport-artifacts.mjs +9 -0
  168. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +19 -14
  169. package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +7 -1
  170. package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +6 -14
  171. package/src/runtime/agent/orchestrator/tools/builtin/pdf-test-fixtures.mjs +5 -3
  172. package/src/runtime/agent/orchestrator/tools/builtin/read-image.mjs +4 -2
  173. package/src/runtime/agent/orchestrator/tools/builtin/read-single-media.mjs +47 -2
  174. package/src/runtime/agent/orchestrator/tools/builtin/read-special-files.mjs +264 -87
  175. package/src/runtime/agent/orchestrator/tools/builtin/shell-analysis.mjs +10 -4
  176. package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +34 -21
  177. package/src/runtime/agent/orchestrator/tools/code-graph/constants.mjs +8 -4
  178. package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +9 -30
  179. package/src/runtime/agent/orchestrator/tools/lib/shell-run-settle.mjs +24 -12
  180. package/src/runtime/agent/orchestrator/tools/lib/shell-run-spawn.mjs +3 -2
  181. package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +6 -2
  182. package/src/runtime/agent/orchestrator/tools/patch/delete-quarantine.mjs +2 -1
  183. package/src/runtime/agent/orchestrator/tools/patch/replay-capture.mjs +4 -2
  184. package/src/runtime/agent/orchestrator/tools/patch/rollback-state.mjs +33 -2
  185. package/src/runtime/agent/orchestrator/tools/patch-manifest.json +13 -13
  186. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +5 -3
  187. package/src/runtime/agent/orchestrator/tools/shell-exec-output.mjs +3 -1
  188. package/src/runtime/attachments/attachment-reference.mjs +155 -0
  189. package/src/runtime/attachments/limits.mjs +5 -1
  190. package/src/runtime/attachments/office-extract.mjs +3 -6
  191. package/src/runtime/attachments/pdf-extract.mjs +84 -10
  192. package/src/runtime/attachments/store.mjs +55 -30
  193. package/src/runtime/browser-bridge/client.mjs +73 -20
  194. package/src/runtime/channels/lib/runtime-paths.mjs +1 -1
  195. package/src/runtime/channels/lib/scheduler.mjs +14 -7
  196. package/src/runtime/channels/lib/state-file.mjs +15 -15
  197. package/src/runtime/channels/lib/voice-runtime-fetcher.mjs +14 -13
  198. package/src/runtime/channels/lib/webhook/relay-tunnel.mjs +22 -18
  199. package/src/runtime/channels/lib/webhook/session-dispatch.mjs +14 -36
  200. package/src/runtime/channels/lib/worker-main.mjs +3 -2
  201. package/src/runtime/effort-judge/compact-tokenizer.mjs +8 -2
  202. package/src/runtime/effort-judge/judge-client.mjs +6 -3
  203. package/src/runtime/effort-judge/model-install.mjs +16 -8
  204. package/src/runtime/effort-judge/model-manifest.json +7 -7
  205. package/src/runtime/local-provider/asset-installer.mjs +10 -4
  206. package/src/runtime/local-provider/catalog.mjs +5 -2
  207. package/src/runtime/local-provider/registered-models.mjs +64 -27
  208. package/src/runtime/local-provider/server.mjs +2 -3
  209. package/src/runtime/media/adapters/image-api.mjs +89 -0
  210. package/src/runtime/media/auth.mjs +64 -1
  211. package/src/runtime/media/catalog.mjs +66 -4
  212. package/src/runtime/media/jobs.mjs +4 -0
  213. package/src/runtime/media/lanes.mjs +46 -5
  214. package/src/runtime/media/media-usage.mjs +17 -0
  215. package/src/runtime/media/renditions.mjs +15 -15
  216. package/src/runtime/media/store.mjs +36 -35
  217. package/src/runtime/media/tool.mjs +8 -1
  218. package/src/runtime/memory/lib/cycle-scheduler/health-ledger.mjs +8 -2
  219. package/src/runtime/memory/lib/embedding-model-files.mjs +30 -7
  220. package/src/runtime/memory/lib/ingest/transcript-tail.mjs +16 -7
  221. package/src/runtime/memory/lib/pg/process.mjs +8 -4
  222. package/src/runtime/memory/lib/project-id-resolver.mjs +5 -1
  223. package/src/runtime/memory/lib/runtime-fetcher.mjs +6 -1
  224. package/src/runtime/office/core/journal.mjs +7 -14
  225. package/src/runtime/office/design/library/design-library-core.mjs +4 -16
  226. package/src/runtime/office/pdf/ocr-engine-worker.mjs +37 -0
  227. package/src/runtime/office/pdf/ocr-engine.mjs +146 -0
  228. package/src/runtime/office/pdf/pdf-ocr.mjs +51 -21
  229. package/src/runtime/office/pdf/pdf-render.mjs +30 -18
  230. package/src/runtime/office/portable/ooxml-validator.mjs +2 -2
  231. package/src/runtime/office/portable/portable-soffice.mjs +4 -0
  232. package/src/runtime/shared/agent-kind-migration.mjs +200 -0
  233. package/src/runtime/shared/agent-kind.mjs +152 -0
  234. package/src/runtime/shared/agent-message-envelope.d.mts +6 -0
  235. package/src/runtime/shared/agent-message-envelope.mjs +44 -0
  236. package/src/runtime/shared/agent-reap-state.d.mts +4 -0
  237. package/src/runtime/shared/agent-route-config.d.mts +1 -0
  238. package/src/runtime/shared/agent-route-config.mjs +22 -8
  239. package/src/runtime/shared/agent-store.mjs +149 -0
  240. package/src/runtime/shared/agent-task-starts.mjs +27 -0
  241. package/src/runtime/shared/atomic-file.d.mts +50 -0
  242. package/src/runtime/shared/atomic-file.mjs +394 -132
  243. package/src/runtime/shared/background-tasks.mjs +7 -4
  244. package/src/runtime/shared/bot-hops.mjs +30 -0
  245. package/src/runtime/shared/bot-split-migration.mjs +457 -0
  246. package/src/runtime/shared/bounded-download.mjs +4 -2
  247. package/src/runtime/shared/config-patch.mjs +20 -1
  248. package/src/runtime/shared/config.mjs +39 -9
  249. package/src/runtime/shared/connector-catalog.d.mts +1 -2
  250. package/src/runtime/shared/connector-catalog.mjs +2 -4
  251. package/src/runtime/shared/connector-triggers.mjs +2 -0
  252. package/src/runtime/shared/defaults-separation.mjs +6 -2
  253. package/src/runtime/shared/delegated-approval-host.mjs +74 -0
  254. package/src/runtime/shared/err-text.mjs +7 -1
  255. package/src/runtime/shared/error-presentation.mjs +113 -10
  256. package/src/runtime/shared/file-has-data.mjs +28 -0
  257. package/src/runtime/shared/handoff-artifacts.d.mts +20 -0
  258. package/src/runtime/shared/handoff-artifacts.mjs +61 -0
  259. package/src/runtime/shared/llm/provider-model-identities.mjs +6 -1
  260. package/src/runtime/shared/llm/usage-accounting.mjs +7 -1
  261. package/src/runtime/shared/llm/usage-ledger-import.mjs +37 -18
  262. package/src/runtime/shared/model-route-fallback.mjs +79 -7
  263. package/src/runtime/shared/pending-agent-work.mjs +54 -0
  264. package/src/runtime/shared/plain-preview.mjs +22 -17
  265. package/src/runtime/shared/process-lifecycle.mjs +8 -12
  266. package/src/runtime/shared/projects.mjs +50 -41
  267. package/src/runtime/shared/provider-accounts.mjs +17 -12
  268. package/src/runtime/shared/routine-trigger.d.mts +6 -1
  269. package/src/runtime/shared/routine-trigger.mjs +14 -6
  270. package/src/runtime/shared/run-child.d.mts +3 -0
  271. package/src/runtime/shared/run-child.mjs +24 -3
  272. package/src/runtime/shared/sensitive-path-rules.d.mts +15 -0
  273. package/src/runtime/shared/sensitive-path-rules.mjs +256 -0
  274. package/src/runtime/shared/session-baseline-store.mjs +8 -2
  275. package/src/runtime/shared/singleton-owner.mjs +7 -6
  276. package/src/runtime/shared/skill-tool-dependencies.mjs +4 -10
  277. package/src/runtime/shared/staged-update.mjs +4 -2
  278. package/src/runtime/shared/statusline/statusline-segments.mjs +4 -15
  279. package/src/runtime/shared/tool-execution-contract.mjs +6 -0
  280. package/src/runtime/shared/transcript-metadata.mjs +28 -3
  281. package/src/runtime/shared/transcript-writer/session-record.mjs +7 -6
  282. package/src/runtime/shared/turn-snapshot-store.mjs +5 -4
  283. package/src/runtime/shared/turn-snapshot.mjs +44 -2
  284. package/src/runtime/shared/usage-readout-totals.mjs +15 -13
  285. package/src/runtime/shared/user-cwd.mjs +9 -4
  286. package/src/runtime/shared/user-data-guard.mjs +46 -44
  287. package/src/runtime/shared/utf8-cut.mjs +10 -0
  288. package/src/runtime/shared/worktrees/activity-gate.mjs +269 -61
  289. package/src/runtime/shared/worktrees/registry.mjs +26 -26
  290. package/src/runtime/tidy/core-install.mjs +26 -4
  291. package/src/runtime/tidy/install.mjs +91 -23
  292. package/src/runtime/web-search/lib/config.mjs +4 -16
  293. package/src/session-runtime/agent-home-delivery.mjs +859 -136
  294. package/src/session-runtime/agent-room-delivery.mjs +167 -19
  295. package/src/session-runtime/agent-task-sessions.mjs +831 -69
  296. package/src/session-runtime/agent-tool-routing.mjs +1 -0
  297. package/src/session-runtime/boot/apis.mjs +58 -24
  298. package/src/session-runtime/boot/config.mjs +1 -0
  299. package/src/session-runtime/boot/facade.mjs +11 -1
  300. package/src/session-runtime/boot/infrastructure.mjs +14 -2
  301. package/src/session-runtime/boot/providers.mjs +16 -6
  302. package/src/session-runtime/boot/shared.mjs +12 -6
  303. package/src/session-runtime/boot/tools.mjs +2 -2
  304. package/src/session-runtime/bot-status.mjs +432 -0
  305. package/src/session-runtime/config-lifecycle/lead-route-sync.mjs +29 -0
  306. package/src/session-runtime/config-lifecycle.mjs +78 -32
  307. package/src/session-runtime/cwd-plugins/core-memory-context.mjs +2 -4
  308. package/src/session-runtime/handoff-attachments.mjs +593 -0
  309. package/src/session-runtime/held-requests.mjs +36 -33
  310. package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +10 -1
  311. package/src/session-runtime/internal-tool-executor/feature-tools.mjs +2 -2
  312. package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +45 -6
  313. package/src/session-runtime/lifecycle/session-catalog.mjs +12 -2
  314. package/src/session-runtime/lifecycle/teardown.mjs +11 -3
  315. package/src/session-runtime/mcp-glue/connect.mjs +100 -186
  316. package/src/session-runtime/mcp-glue/initial-connect-gate.mjs +57 -0
  317. package/src/session-runtime/mcp-glue/server-connection.mjs +71 -0
  318. package/src/session-runtime/media-api.mjs +5 -2
  319. package/src/session-runtime/model-route/route-persist.mjs +2 -2
  320. package/src/session-runtime/model-route/route-tuning.mjs +11 -2
  321. package/src/session-runtime/model-route/set-route.mjs +82 -2
  322. package/src/session-runtime/native-web-search.mjs +2 -2
  323. package/src/session-runtime/new-session-config.mjs +6 -1
  324. package/src/session-runtime/owned-automation-run.mjs +8 -1
  325. package/src/session-runtime/room-member-gate.mjs +16 -3
  326. package/src/session-runtime/route-resolution.mjs +21 -19
  327. package/src/session-runtime/route-state.mjs +1 -59
  328. package/src/session-runtime/routine-home-turn.mjs +5 -3
  329. package/src/session-runtime/runtime-bootstrap.mjs +5 -3
  330. package/src/session-runtime/runtime-paths.mjs +11 -5
  331. package/src/session-runtime/runtime-tunables.mjs +6 -0
  332. package/src/session-runtime/services/agent-tool/close-flow/close-all.mjs +11 -2
  333. package/src/session-runtime/services/agent-tool/close-flow.mjs +4 -2
  334. package/src/session-runtime/services/agent-tool/execute-send.mjs +1 -0
  335. package/src/session-runtime/services/agent-tool/execute-spawn.mjs +1 -0
  336. package/src/session-runtime/services/agent-tool/helpers.mjs +24 -5
  337. package/src/session-runtime/services/agent-tool/restart-notify.mjs +10 -0
  338. package/src/session-runtime/services/agent-tool/send-flow.mjs +36 -24
  339. package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +4 -0
  340. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +6 -3
  341. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +12 -6
  342. package/src/session-runtime/services/agent-tool/spawn-preset.mjs +5 -8
  343. package/src/session-runtime/services/agent-tool/tool-def.mjs +7 -0
  344. package/src/session-runtime/services/agent-tool/worker-index/row-liveness.mjs +22 -2
  345. package/src/session-runtime/services/agent-tool/worker-index.mjs +4 -6
  346. package/src/session-runtime/services/agent-tool.mjs +6 -0
  347. package/src/session-runtime/services/daemon-crash-capture/daemon-exit-record.mjs +1 -1
  348. package/src/session-runtime/services/daemon-crash-capture/retention.mjs +4 -3
  349. package/src/session-runtime/services/hook-bus/config-loader.mjs +14 -5
  350. package/src/session-runtime/services/hook-bus/rule-file.mjs +49 -11
  351. package/src/session-runtime/services/plugin-admin.mjs +26 -26
  352. package/src/session-runtime/services/provider-admin.mjs +14 -4
  353. package/src/session-runtime/services/schedule-access.mjs +33 -4
  354. package/src/session-runtime/services/seeds.mjs +4 -3
  355. package/src/session-runtime/services/usage-dashboard.mjs +1 -1
  356. package/src/session-runtime/services/usage-stats-model.mjs +2 -1
  357. package/src/session-runtime/session-create/materialize.mjs +2 -3
  358. package/src/session-runtime/session-create/session-options.mjs +15 -2
  359. package/src/session-runtime/settings-builtin-tools-api.mjs +63 -1
  360. package/src/session-runtime/settings-compaction-api.mjs +86 -39
  361. package/src/session-runtime/setup-tool/executor.mjs +20 -3
  362. package/src/session-runtime/setup-tool/extended-actions.mjs +19 -7
  363. package/src/session-runtime/setup-tool/settings-contract.mjs +37 -1
  364. package/src/session-runtime/setup-tool/tool-defs.mjs +20 -3
  365. package/src/session-runtime/skills-api.mjs +12 -5
  366. package/src/session-runtime/tool-policy/agent-profile-fold.mjs +265 -0
  367. package/src/session-runtime/tool-policy/mode-switch.mjs +54 -0
  368. package/src/session-runtime/tool-policy/pending-switches.mjs +59 -0
  369. package/src/session-runtime/tool-policy/policy-stage.mjs +165 -0
  370. package/src/session-runtime/tool-policy/session-switches.mjs +169 -0
  371. package/src/session-runtime/tool-policy/surface-helpers.mjs +114 -0
  372. package/src/session-runtime/tool-policy/workflow-overlay.mjs +145 -0
  373. package/src/session-runtime/tool-policy-refresh.mjs +47 -358
  374. package/src/session-runtime/tool-surface.mjs +5 -3
  375. package/src/session-runtime/turn/turn-run/turn-prepare.mjs +99 -81
  376. package/src/session-runtime/turn/turn-run/turn-timing.mjs +4 -3
  377. package/src/session-runtime/turn/turn-run.mjs +2 -1
  378. package/src/session-runtime/workflow-agents-api/agent-connectors.mjs +54 -7
  379. package/src/session-runtime/workflow-agents-api/agent-editor.mjs +578 -301
  380. package/src/session-runtime/workflow-agents-api/agent-route.mjs +113 -53
  381. package/src/session-runtime/workflow-agents-api/onboarding.mjs +11 -4
  382. package/src/session-runtime/workflow-agents-api/shared.mjs +5 -1
  383. package/src/session-runtime/workflow-agents-api/style-and-mode.mjs +14 -1
  384. package/src/session-runtime/workflow-agents-api/workflow-packs.mjs +6 -3
  385. package/src/session-runtime/workspace/workspace-state.mjs +7 -6
  386. package/src/standalone/daemon-agent-control.mjs +4 -1
  387. package/src/standalone/daemon-session-control.mjs +60 -11
  388. package/src/standalone/daemon.mjs +34 -4
  389. package/src/standalone/local-session-runtime.mjs +22 -14
  390. package/src/standalone/session-client.mjs +7 -2
  391. package/src/standalone/session-protocol.mjs +7 -0
  392. package/src/standalone/session-service/agent-tree/agent-turns.mjs +46 -3
  393. package/src/standalone/session-service/agent-tree.mjs +4 -3
  394. package/src/standalone/session-service/session-calls/session-turns.mjs +19 -0
  395. package/src/standalone/session-service.mjs +11 -0
  396. package/src/standalone/session-state-projection.mjs +19 -9
  397. package/src/standalone/session-tool-output.mjs +35 -9
  398. package/src/tui/app/maintenance-pickers/auto-clear-picker.mjs +19 -13
  399. package/src/tui/app/settings-picker/settings-rows.mjs +2 -2
  400. package/src/tui/app/slash-commands.mjs +1 -1
  401. package/src/tui/app/usage-context-panels/context-model.mjs +8 -2
  402. package/src/tui/dist/index.mjs +599 -342
  403. package/src/tui/prompt-history-store.mjs +16 -21
  404. package/src/tui/session/context-state.mjs +4 -0
  405. package/src/tui/session/notice-surface.mjs +3 -4
  406. package/src/tui/session/session-api/intake/abort.mjs +19 -1
  407. package/src/tui/session/session-api/media.mjs +2 -1
  408. package/src/tui/session/session-api/routes-agent-definitions.mjs +75 -0
  409. package/src/tui/session/session-api/routes-write.mjs +203 -0
  410. package/src/tui/session/session-api/routes.mjs +23 -236
  411. package/src/tui/session/session-api/settings.mjs +14 -1
  412. package/src/tui/session/session-flow/drain.mjs +28 -3
  413. package/src/tui/session/session-flow/failed-turn-rewind.mjs +4 -2
  414. package/src/tui/session/session-flow/queue/take-entries.mjs +8 -0
  415. package/src/tui/session/session-flow/steering.mjs +8 -3
  416. package/src/tui/session/tool-approval.mjs +185 -20
  417. package/src/tui/session/transcript-intake.mjs +4 -0
  418. package/src/tui/session/turn-live-call.mjs +11 -3
  419. package/src/tui/session/turn.mjs +36 -17
  420. package/src/tui/transcript-tool-failures.mjs +8 -2
  421. package/src/vendor/statusline/src/gateway/route-meta.mjs +7 -8
  422. package/src/vendor/statusline/src/gateway/session-routes.mjs +6 -7
  423. package/src/rules/agent-mode/ROUTINE.md +0 -6
@@ -0,0 +1,265 @@
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 { promptRulesRevision } from '../../runtime/agent/orchestrator/session/manager/rules-cache.mjs';
6
+ import { isAgentOwner } from '../../runtime/agent/orchestrator/agent-owner.mjs';
7
+ import { AGENT_MODE, sessionModeOf } from '../../runtime/agent/orchestrator/session/agent-mode.mjs';
8
+ import {
9
+ conversationHolds,
10
+ promptWorkflowOf,
11
+ } from '../../runtime/agent/orchestrator/session/manager/workflow-switch-notice.mjs';
12
+ import { sessionTailCacheExpired } from '../../runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs';
13
+ import { mergePendingDeferredToolDelta } from '../../runtime/agent/orchestrator/runtime-core/deferred-tool-delta.mjs';
14
+ import {
15
+ agentMcpToolPermission,
16
+ connectorPolicyAgentOf,
17
+ } from '../../runtime/agent/orchestrator/mcp/agent-connectors.mjs';
18
+ import { markToolSurfaceMigrated } from '../../runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs';
19
+ import {
20
+ agentProfileRevision,
21
+ leadRosterRevision,
22
+ } from '../../runtime/agent/orchestrator/context/role-instructions.mjs';
23
+ import {
24
+ configForSession,
25
+ currentMode,
26
+ leadPartsFor,
27
+ presentedBp3Core,
28
+ promptMode,
29
+ rewriteConversationBp3Core,
30
+ schemaTools,
31
+ toolName,
32
+ } from './surface-helpers.mjs';
33
+
34
+ const AGENT_PROFILE_INTENT = 'agent_profile';
35
+ // Pending prompt changes folded in where the cache is cold anyway.
36
+ const PROMPT_FOLD_INTENT = 'prompt_fold';
37
+ // Cache-break intents that already rebuild the conversation's cached prefix.
38
+ const COLD_INTENTS = new Set(['post_turn_compaction', 'manual_compaction']);
39
+
40
+ // What the next request sends ahead of the conversation: the system blocks and tools.
41
+ const promptPrefix = (session) =>
42
+ JSON.stringify([
43
+ (Array.isArray(session.messages) ? session.messages : [])
44
+ .filter((message) => message?.role === 'system')
45
+ .map((message) => message.content),
46
+ session.tools,
47
+ ]);
48
+
49
+ // A bot thread built from other shipped rules than these (a release changed one).
50
+ const rulesStale = (session) =>
51
+ sessionModeOf(session) === AGENT_MODE && session.rulesRevision !== promptRulesRevision();
52
+
53
+ // Changes the prompt does not carry yet: a workflow switched mid-conversation,
54
+ // a bot's tool gates that moved, or shipped rules a release changed.
55
+ const foldPending = (session) =>
56
+ Boolean(
57
+ session.workflowOverlay || session.orchestrationModeOverlay || session.promptFoldPending || rulesStale(session)
58
+ );
59
+
60
+ // A switch's reminder that is neither pending nor still in the conversation.
61
+ const reminderDropped = (session, overlay, notice) =>
62
+ Boolean(overlay && !notice && !conversationHolds(session, overlay.content));
63
+
64
+ // The cached prefix is cold anyway, so folding pending changes costs nothing
65
+ // extra: a compaction (tagged, or one that dropped a delivered workflow
66
+ // reminder), a cleared conversation, or a message tail the provider's cache
67
+ // already let expire (sessionTailCacheExpired; never for openai-oauth).
68
+ function cacheCold(session) {
69
+ if (COLD_INTENTS.has(session.pendingCacheBreakIntent)) return true;
70
+ if (!sessionHasConversationMessages(session)) return true;
71
+ if (sessionTailCacheExpired(session)) return true;
72
+ return (
73
+ reminderDropped(session, session.workflowOverlay, session.workflowSwitch) ||
74
+ reminderDropped(session, session.orchestrationModeOverlay, session.orchestrationModeSwitch)
75
+ );
76
+ }
77
+
78
+ // The connector tools among `names` the session's agent may run now.
79
+ function connectorTools(session, names) {
80
+ const agent = connectorPolicyAgentOf(session);
81
+ return [...names]
82
+ .filter((name) => name.startsWith('mcp__') && agentMcpToolPermission(agent, name) !== 'disabled')
83
+ .sort();
84
+ }
85
+
86
+ // A bot thread's tools that changed without its prompt: feature gates that
87
+ // opened (or closed) and connectors added or removed. Nothing in the request
88
+ // prefix moves. An opened tool joins the deferred catalog — reachable by
89
+ // deferred loading, which brings its schema into the conversation — and a
90
+ // gone one is refused at call time; the next turn's deferred_tools_delta
91
+ // notice names both. Gate changes are folded into the prompt at the next
92
+ // cold point (promptFoldPending). Connectors live in the bot's agent.json,
93
+ // so they are compared only when its profile stamp moved (`edited`).
94
+ // Returns true when anything changed.
95
+ function stageLiveToolChanges({ liveDeniedTools, modelStandaloneTools }, session, workflow, { edited = false } = {}) {
96
+ const added = [];
97
+ const removed = [];
98
+ const known = new Map(schemaTools(session).map((tool) => [toolName(tool), tool]));
99
+ const live = new Set(liveDeniedTools(session, workflow));
100
+ const disallowed = (session.disallowedTools || []).map(String);
101
+ const opened = disallowed.filter((name) => !live.has(name));
102
+ const closed = [...live].filter((name) => known.has(name) && !disallowed.includes(name));
103
+ if (opened.length || closed.length) {
104
+ const fresh = modelStandaloneTools().filter(
105
+ (tool) => opened.includes(toolName(tool)) && !known.has(toolName(tool))
106
+ );
107
+ if (fresh.length) session.deferredToolCatalog = [...(session.deferredToolCatalog || []), ...fresh];
108
+ for (const tool of fresh) known.set(toolName(tool), tool);
109
+ session.disallowedTools = [...live];
110
+ added.push(...opened.filter((name) => known.has(name)));
111
+ removed.push(...closed);
112
+ session.promptFoldPending = true;
113
+ }
114
+ // Connectors gate MCP tools at call time only (pre-dispatch-deny.mjs).
115
+ const previous = session.agentConnectorTools;
116
+ const permitted = edited || !Array.isArray(previous) ? connectorTools(session, known.keys()) : previous;
117
+ session.agentConnectorTools = permitted;
118
+ if (edited && Array.isArray(previous)) {
119
+ added.push(...permitted.filter((name) => !previous.includes(name)));
120
+ removed.push(...previous.filter((name) => !permitted.includes(name)));
121
+ }
122
+ if (!added.length && !removed.length) {
123
+ return opened.length + closed.length > 0 || !Array.isArray(previous);
124
+ }
125
+ mergePendingDeferredToolDelta(session, {
126
+ added: added.map((name) => ({ name, description: known.get(name)?.description || '' })),
127
+ removed,
128
+ });
129
+ session.updatedAt = Date.now();
130
+ return true;
131
+ }
132
+
133
+ export function createAgentProfileFold({
134
+ getSession,
135
+ getConfig,
136
+ getDataDir,
137
+ modelStandaloneTools,
138
+ activeWorkflowContext,
139
+ liveDeniedTools,
140
+ stagePolicy,
141
+ applyPolicy,
142
+ turnInFlight,
143
+ }) {
144
+ // An agent profile edit that met a running turn: the next turn applies it.
145
+ let agentProfilePending = false;
146
+
147
+ // Fold every pending change into the prompt: the session's own workflow,
148
+ // its tool gates and the shipped rules as they stand now, with every stamp
149
+ // moved. One cache break, tagged with the intent already pending (a
150
+ // compaction) or `intent`. Returns true when the request prefix changed.
151
+ async function foldPrompt(session, intent) {
152
+ const identity = session.promptIdentity;
153
+ if (!identity) return false;
154
+ const agentMode = sessionModeOf(session) === AGENT_MODE;
155
+ const config = configForSession(getConfig(), session.workflow?.id, currentMode(session));
156
+ const staged = await stagePolicy(session, identity, config, { conversation: true });
157
+ if (getSession?.() !== session) return false;
158
+ const before = promptPrefix(session);
159
+ applyPolicy(session, staged);
160
+ rewriteConversationBp3Core(session, staged.core);
161
+ if (session.agentProfileRevision !== undefined) {
162
+ session.agentProfileRevision = agentProfileRevision(identity.agent, { mixy: agentMode });
163
+ const { leadPromptParts } = activeWorkflowContext(config, getDataDir());
164
+ session.agentRosterRevision = leadRosterRevision(leadPartsFor(session, leadPromptParts));
165
+ }
166
+ if (agentMode) session.rulesRevision = promptRulesRevision();
167
+ session.updatedAt = Date.now();
168
+ if (promptPrefix(session) === before) return false;
169
+ markToolSurfaceMigrated(session, session.pendingCacheBreakIntent || intent);
170
+ return true;
171
+ }
172
+
173
+ /** Fold pending prompt changes (a switched workflow, a bot's moved tool
174
+ * gates, changed shipped rules) when the cache is cold anyway. */
175
+ async function foldPromptIfCold() {
176
+ const session = getSession?.();
177
+ if (!session?.id || !session.promptIdentity || isAgentOwner(session)) return false;
178
+ if (!foldPending(session) || !cacheCold(session)) return false;
179
+ return foldPrompt(session, PROMPT_FOLD_INTENT);
180
+ }
181
+
182
+ /**
183
+ * Bring a Lead session's prompt to the saved bots — its own agent's
184
+ * persona, AGENT.md and name, and the bot roster its catalogs list — after
185
+ * a bot was saved, created, renamed, archived or restored
186
+ * (agent-profile-changes.mjs), on resume, or at the start of the turn after
187
+ * one that ran through the change (`trigger`: 'save' | 'resume' | 'turn').
188
+ * Two stamps (agentProfileRevision, agentRosterRevision) tell whether
189
+ * anything it embeds changed; a delegated worker keeps its prompt. The core
190
+ * is rebuilt like a workflow switch's (the session's own workflow, the
191
+ * workspace slices the model was told) and replaces the stored one, so the
192
+ * next turn sends it with one provider cache break; nothing is re-read per
193
+ * turn. That rewrite is immediate (one tagged cache break) and takes every
194
+ * pending fold with it (foldPrompt), moving all stamps.
195
+ * What is not an edit never touches the prefix: a bot thread's feature gates
196
+ * and connectors are staged live (stageLiveToolChanges), and shipped rules a
197
+ * release changed wait silently; both are folded in at the next cold point
198
+ * (foldPromptIfCold). Returns true when the session changed (save it).
199
+ */
200
+ async function refreshAgentProfile({ trigger = 'save' } = {}) {
201
+ const session = getSession?.();
202
+ const identity = session?.promptIdentity;
203
+ const agent = identity?.agent;
204
+ if (!session?.id || !agent || isAgentOwner(session)) return false;
205
+ // Only Mixy's own (agent-mode) thread embeds Mixy's profile.
206
+ const agentMode = sessionModeOf(session) === AGENT_MODE;
207
+ const revision = agentProfileRevision(agent, { mixy: agentMode });
208
+ // The roster the prompt lists is the prompt's workflow's (a switched
209
+ // workflow is not an edit).
210
+ const workflowConfig = configForSession(getConfig(), promptWorkflowOf(session)?.id, promptMode(session));
211
+ const { leadPromptParts, summary: workflow } = activeWorkflowContext(workflowConfig, getDataDir());
212
+ const roster = leadRosterRevision(leadPartsFor(session, leadPromptParts));
213
+ const edited = session.agentProfileRevision !== revision || session.agentRosterRevision !== roster;
214
+ // At a turn's start its own turn is the one counted; nothing runs yet.
215
+ const busy = () => getSession?.() !== session || (trigger !== 'turn' && turnInFlight(session));
216
+ if (busy()) {
217
+ agentProfilePending = true;
218
+ return false;
219
+ }
220
+ const toolsChanged =
221
+ agentMode &&
222
+ stageLiveToolChanges({ liveDeniedTools, modelStandaloneTools }, session, workflow, {
223
+ edited: session.agentProfileRevision !== revision,
224
+ });
225
+ if (!edited) return (trigger === 'resume' && (await foldPromptIfCold())) || toolsChanged;
226
+ // A coding session from before profile stamps keeps its prompt when it
227
+ // is reopened; a saved edit still reaches it.
228
+ if (session.agentProfileRevision === undefined && trigger === 'resume' && !agentMode) return toolsChanged;
229
+ if (foldPending(session)) {
230
+ await foldPrompt(session, AGENT_PROFILE_INTENT);
231
+ return true;
232
+ }
233
+ const staged = await stagePolicy(session, identity, workflowConfig, { conversation: true });
234
+ if (busy()) {
235
+ agentProfilePending = true;
236
+ return toolsChanged;
237
+ }
238
+ session.agentProfileRevision = revision;
239
+ session.agentRosterRevision = roster;
240
+ session.updatedAt = Date.now();
241
+ if (staged.core === presentedBp3Core(session)) return toolsChanged;
242
+ rewriteConversationBp3Core(session, staged.core);
243
+ // The request prefix changed: one cache break, tagged on the next send.
244
+ markToolSurfaceMigrated(session, AGENT_PROFILE_INTENT);
245
+ return true;
246
+ }
247
+
248
+ /** Turn start: apply an edit that arrived while the previous turn ran, then
249
+ * fold pending prompt changes if the cache is cold anyway. */
250
+ async function applyPendingAgentProfile() {
251
+ let changed = false;
252
+ // A bot thread's connector baseline, before any edit can be compared to it.
253
+ const session = getSession?.();
254
+ if (session?.id && sessionModeOf(session) === AGENT_MODE && !Array.isArray(session.agentConnectorTools)) {
255
+ session.agentConnectorTools = connectorTools(session, schemaTools(session).map(toolName));
256
+ }
257
+ if (agentProfilePending) {
258
+ agentProfilePending = false;
259
+ changed = await refreshAgentProfile({ trigger: 'turn' });
260
+ }
261
+ return (await foldPromptIfCold()) || changed;
262
+ }
263
+
264
+ return { refreshAgentProfile, applyPendingAgentProfile };
265
+ }
@@ -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,165 @@
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 { toSessionWorkflowMeta } from '../../runtime/agent/orchestrator/runtime-core/workflow.mjs';
4
+ import {
5
+ applyDeferredToolSurface,
6
+ filterDisallowedTools,
7
+ } from '../../runtime/agent/orchestrator/runtime-core/tool-catalog.mjs';
8
+ import { deferredSurfaceModeForLead } from '../../runtime/agent/orchestrator/runtime-core/effort.mjs';
9
+ import {
10
+ applyInitialDeferredToolManifestToBp2,
11
+ composeSystemPrompt,
12
+ } from '../../runtime/agent/orchestrator/context/collect.mjs';
13
+ import { _buildBaseRules } from '../../runtime/agent/orchestrator/session/manager/rules-cache.mjs';
14
+ import { sessionRolePromptFields } from '../../runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs';
15
+ import {
16
+ delegationDisabled,
17
+ honoredSchemaAllowlist,
18
+ } from '../../runtime/agent/orchestrator/session/manager/session-tool-surface.mjs';
19
+ import { finalizeSessionToolList } from '../../runtime/agent/orchestrator/session/manager/tool-resolution.mjs';
20
+ import { isAgentOwner } from '../../runtime/agent/orchestrator/agent-owner.mjs';
21
+ import { AGENT_MODE, sessionModeOf } from '../../runtime/agent/orchestrator/session/agent-mode.mjs';
22
+ import { unusedModelEditToolName } from '../../runtime/shared/edit-tool-dialect.mjs';
23
+ import { withPresentedWorkspaceSlices } from '../../runtime/agent/orchestrator/session/manager/prompt-utils.mjs';
24
+ import { leadPartsFor, rewriteSystemHeading, toolNames } from './surface-helpers.mjs';
25
+
26
+ export function createPolicyStage({
27
+ getRoute,
28
+ getMode,
29
+ getDataDir,
30
+ modelStandaloneTools,
31
+ featureDisallowedTools,
32
+ loadCoreMemoryContext,
33
+ loadInstructionFilesContext,
34
+ activeWorkflowContext,
35
+ }) {
36
+ // The tools `session` is denied now: its caller's denials, the feature gates
37
+ // as they stand, and the agent tool when its workflow delegates to no one.
38
+ function liveDeniedTools(session, workflow) {
39
+ return [
40
+ ...session.callerDisallowedTools,
41
+ ...featureDisallowedTools(),
42
+ ...(workflow?.delegatesAgents === false ? ['agent'] : []),
43
+ ]
44
+ .map((name) => String(name || ''))
45
+ .filter(Boolean);
46
+ }
47
+
48
+ // Denied tools leave every surface, then the deferred surface is rebuilt
49
+ // for the lead's current mode.
50
+ function applyToolDenials(session, denied, schemaAllowedTools, ownerIsAgent) {
51
+ session.disallowedTools = denied;
52
+ session.tools = filterDisallowedTools(session.tools, denied);
53
+ if (Array.isArray(session.deferredToolCatalog)) {
54
+ session.deferredToolCatalog = filterDisallowedTools(session.deferredToolCatalog, denied);
55
+ }
56
+ const catalogTools = finalizeSessionToolList(modelStandaloneTools(), {
57
+ schemaAllowedTools,
58
+ disallowedTools: denied,
59
+ ownerIsAgent,
60
+ });
61
+ session.tools = finalizeSessionToolList(session.tools, {
62
+ schemaAllowedTools,
63
+ disallowedTools: denied,
64
+ ownerIsAgent,
65
+ });
66
+ applyDeferredToolSurface(session, deferredSurfaceModeForLead(getMode()), catalogTools, {
67
+ provider: getRoute()?.provider,
68
+ });
69
+ const catalog = Array.isArray(session.deferredToolCatalog) ? session.deferredToolCatalog : [];
70
+ const active = new Set(toolNames(session.tools).concat(toolNames(session.deferredCallableTools)));
71
+ const pool = catalog.map((tool) => String(tool?.name || '')).filter((name) => name && !active.has(name));
72
+ applyInitialDeferredToolManifestToBp2(session, pool, { rebuild: true });
73
+ }
74
+
75
+ async function leadCoreMemoryContext() {
76
+ try {
77
+ return await loadCoreMemoryContext();
78
+ } catch {
79
+ return '';
80
+ }
81
+ }
82
+
83
+ // The policy `config` gives `session`, computed without touching the
84
+ // session, so a turn that starts during the async rebuild cannot lose tools
85
+ // to it. `conversation`: the rebuilt BP3 core keeps the instruction files
86
+ // and core memory the prompt presents now (withPresentedWorkspaceSlices).
87
+ async function stagePolicy(session, identity, config, { conversation = false } = {}) {
88
+ const ownerIsAgent = isAgentOwner(session);
89
+ const schemaAllowedTools = honoredSchemaAllowlist(session.schemaAllowedTools, {
90
+ ownerIsAgent,
91
+ agent: identity.agent,
92
+ });
93
+ const toolFreeRole = ownerIsAgent && schemaAllowedTools?.length === 0;
94
+
95
+ const {
96
+ summary: workflow,
97
+ leadPromptParts,
98
+ packContext: workflowContext,
99
+ orchestrationMode,
100
+ } = activeWorkflowContext(config, getDataDir());
101
+ const sessionMode = sessionModeOf(session);
102
+ const agentMode = sessionMode === AGENT_MODE;
103
+ const leadWorkflowParts = ownerIsAgent ? {} : leadPartsFor(session, leadPromptParts);
104
+ const denied = liveDeniedTools(session, workflow);
105
+
106
+ const baseRules =
107
+ identity.skipAgentRules || toolFreeRole
108
+ ? ''
109
+ : _buildBaseRules({
110
+ omitTools: [...denied, unusedModelEditToolName(getRoute()?.model)],
111
+ allowTools: schemaAllowedTools,
112
+ provider: getRoute()?.provider,
113
+ model: getRoute()?.model,
114
+ });
115
+ const coreMemoryContext = conversation ? '' : await leadCoreMemoryContext();
116
+ const { sessionMarkerCore } = composeSystemPrompt({
117
+ ...sessionRolePromptFields(identity, {
118
+ ownerIsAgent,
119
+ toolFreeRole,
120
+ delegationFree: delegationDisabled(session, ownerIsAgent),
121
+ sessionMode,
122
+ }),
123
+ provider: getRoute()?.provider,
124
+ workflowContext,
125
+ ...leadWorkflowParts,
126
+ coreMemoryContext,
127
+ // The rebuilt core keeps (or newly applies) the instruction-files
128
+ // setting; agent mode carries none.
129
+ instructionFilesContext:
130
+ conversation || toolFreeRole || agentMode ? null : loadInstructionFilesContext?.(session) || null,
131
+ });
132
+ return {
133
+ workflow,
134
+ orchestrationMode,
135
+ sessionMode,
136
+ denied,
137
+ schemaAllowedTools,
138
+ ownerIsAgent,
139
+ baseRules,
140
+ core: conversation ? withPresentedWorkspaceSlices(session, sessionMarkerCore) : sessionMarkerCore,
141
+ };
142
+ }
143
+
144
+ // Apply a staged policy synchronously; the BP3 core is the caller's. The
145
+ // prompt then carries the session's workflow and tools as they stand.
146
+ function applyPolicy(session, staged) {
147
+ delete session.workflowOverlay;
148
+ delete session.orchestrationModeOverlay;
149
+ delete session.workflowOpenedTools;
150
+ delete session.promptFoldPending;
151
+ session.workflow = toSessionWorkflowMeta(staged.workflow);
152
+ session.orchestrationMode = staged.orchestrationMode;
153
+ session.sessionMode = staged.sessionMode;
154
+ applyToolDenials(session, staged.denied, staged.schemaAllowedTools, staged.ownerIsAgent);
155
+ // BP1 opens with its first rule file's heading (`# Tool Calls`); older
156
+ // prompts opened with `# Tool Use`.
157
+ const heading = String(staged.baseRules || '').split('\n', 1)[0];
158
+ for (const candidate of new Set(['# Tool Use', heading].filter(Boolean))) {
159
+ rewriteSystemHeading(session, candidate, staged.baseRules);
160
+ }
161
+ session.updatedAt = Date.now();
162
+ }
163
+
164
+ return { liveDeniedTools, stagePolicy, applyPolicy };
165
+ }