@vellumai/assistant 0.8.8 → 0.8.9-staging.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 (360) hide show
  1. package/ARCHITECTURE.md +6 -6
  2. package/bun.lock +2 -2
  3. package/examples/plugins/echo/README.md +61 -60
  4. package/examples/plugins/echo/hooks/post-tool-use.ts +18 -0
  5. package/examples/plugins/echo/hooks/stop.ts +16 -0
  6. package/examples/plugins/echo/hooks/user-prompt-submit.ts +18 -0
  7. package/examples/plugins/echo/package.json +1 -2
  8. package/examples/plugins/echo/src/emit.ts +19 -0
  9. package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +7 -6
  10. package/openapi.yaml +235 -6
  11. package/package.json +2 -2
  12. package/src/__tests__/agent-loop-callsite-precedence.test.ts +69 -14
  13. package/src/__tests__/agent-loop-exit-reason.test.ts +204 -144
  14. package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +50 -35
  15. package/src/__tests__/agent-loop-output-hooks.test.ts +357 -0
  16. package/src/__tests__/agent-loop-override-profile.test.ts +25 -6
  17. package/src/__tests__/agent-loop-provider-error-recording.test.ts +41 -21
  18. package/src/__tests__/agent-loop-thinking.test.ts +36 -20
  19. package/src/__tests__/agent-loop.test.ts +441 -96
  20. package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +14 -14
  21. package/src/__tests__/agent-wake-override-profile.test.ts +17 -21
  22. package/src/__tests__/anthropic-provider.test.ts +1 -1
  23. package/src/__tests__/app-builder-tool-scripts.test.ts +21 -0
  24. package/src/__tests__/app-control-flow.test.ts +1 -1
  25. package/src/__tests__/app-dir-path-guard.test.ts +1 -0
  26. package/src/__tests__/app-executors.test.ts +132 -0
  27. package/src/__tests__/approval-cascade.test.ts +5 -4
  28. package/src/__tests__/approval-routes-http.test.ts +4 -1
  29. package/src/__tests__/background-workers-disk-pressure.test.ts +1 -1
  30. package/src/__tests__/channel-approval-routes.test.ts +1 -1
  31. package/src/__tests__/channel-approvals.test.ts +1 -1
  32. package/src/__tests__/compaction-circuit.test.ts +258 -0
  33. package/src/__tests__/compaction-direct.test.ts +132 -0
  34. package/src/__tests__/compaction-events.test.ts +5 -5
  35. package/src/__tests__/compactor-web-search-strip.test.ts +213 -0
  36. package/src/__tests__/context-overflow-reducer.test.ts +1 -1
  37. package/src/__tests__/conversation-abort-tool-results.test.ts +6 -4
  38. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +7 -10
  39. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +78 -119
  40. package/src/__tests__/conversation-agent-loop-overflow.test.ts +142 -218
  41. package/src/__tests__/conversation-agent-loop.test.ts +297 -586
  42. package/src/__tests__/conversation-clean-command.test.ts +5 -2
  43. package/src/__tests__/conversation-confirmation-signals.test.ts +5 -4
  44. package/src/__tests__/conversation-crud-inference-profile.test.ts +7 -9
  45. package/src/__tests__/conversation-history-web-search.test.ts +1 -1
  46. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +4 -4
  47. package/src/__tests__/conversation-process-callsite.test.ts +14 -14
  48. package/src/__tests__/conversation-provider-retry-repair.test.ts +70 -65
  49. package/src/__tests__/conversation-queue.test.ts +9 -9
  50. package/src/__tests__/conversation-runtime-assembly.test.ts +923 -231
  51. package/src/__tests__/conversation-runtime-workspace.test.ts +115 -20
  52. package/src/__tests__/conversation-slash-queue.test.ts +6 -4
  53. package/src/__tests__/conversation-slash-unknown.test.ts +6 -4
  54. package/src/__tests__/conversation-speed-override.test.ts +10 -9
  55. package/src/__tests__/conversation-starter-routes.test.ts +14 -6
  56. package/src/__tests__/conversation-workspace-cache-state.test.ts +23 -20
  57. package/src/__tests__/conversation-workspace-injection.test.ts +68 -6
  58. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +14 -11
  59. package/src/__tests__/conversations-import-system-filter.test.ts +101 -0
  60. package/src/__tests__/credential-security-invariants.test.ts +0 -1
  61. package/src/__tests__/db-acp-history.test.ts +101 -0
  62. package/src/__tests__/dynamic-page-surface.test.ts +31 -0
  63. package/src/__tests__/empty-response-hook.test.ts +1 -1
  64. package/src/__tests__/file-write-tool.test.ts +63 -0
  65. package/src/__tests__/gateway-only-guard.test.ts +12 -2
  66. package/src/__tests__/guardian-grant-minting.test.ts +1 -1
  67. package/src/__tests__/guardian-routing-invariants.test.ts +2 -4
  68. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +1 -1
  69. package/src/__tests__/heartbeat-disk-pressure.test.ts +1 -0
  70. package/src/__tests__/heartbeat-service.test.ts +1 -0
  71. package/src/__tests__/history-repair-hook.test.ts +1 -1
  72. package/src/__tests__/host-app-control-routes.test.ts +1 -1
  73. package/src/__tests__/host-cu-routes-targeted.test.ts +3 -3
  74. package/src/__tests__/inference-profile-reaper.test.ts +62 -0
  75. package/src/__tests__/inference-profile-session-handler.test.ts +86 -0
  76. package/src/__tests__/injector-background-turn.test.ts +13 -23
  77. package/src/__tests__/injector-chain.test.ts +268 -44
  78. package/src/__tests__/injector-disk-pressure.test.ts +210 -52
  79. package/src/__tests__/injector-document-comments.test.ts +97 -114
  80. package/src/__tests__/injector-pkb-v2-silenced.test.ts +2 -2
  81. package/src/__tests__/injector-v3-suppression.test.ts +4 -4
  82. package/src/__tests__/list-messages-client-message-id.test.ts +91 -0
  83. package/src/__tests__/list-messages-hidden-metadata.test.ts +38 -0
  84. package/src/__tests__/memory-retrieval-hook.test.ts +131 -26
  85. package/src/__tests__/memory-v2-static-injector.test.ts +86 -8
  86. package/src/__tests__/parallel-tool.benchmark.test.ts +35 -8
  87. package/src/__tests__/plugin-api-shim.test.ts +6 -9
  88. package/src/__tests__/plugin-bootstrap.test.ts +12 -23
  89. package/src/__tests__/plugin-registry.test.ts +3 -49
  90. package/src/__tests__/plugin-types.test.ts +0 -70
  91. package/src/__tests__/pre-model-call-sanitize.test.ts +109 -0
  92. package/src/__tests__/reaction-persistence.test.ts +1 -1
  93. package/src/__tests__/send-endpoint-busy.test.ts +4 -1
  94. package/src/__tests__/skill-feature-flags-integration.test.ts +33 -0
  95. package/src/__tests__/steer-tool-repair.test.ts +1 -1
  96. package/src/__tests__/subagent-call-site-routing.test.ts +1 -1
  97. package/src/__tests__/subagent-detail.test.ts +25 -7
  98. package/src/__tests__/subagent-fork-notifications.test.ts +1 -3
  99. package/src/__tests__/subagent-fork-spawn.test.ts +1 -1
  100. package/src/__tests__/subagent-manager-notify.test.ts +1 -3
  101. package/src/__tests__/subagent-notify-parent.test.ts +1 -3
  102. package/src/__tests__/subagent-spawn-tool-fork.test.ts +1 -1
  103. package/src/__tests__/title-generate-hook.test.ts +1 -1
  104. package/src/__tests__/tool-error-hook.test.ts +1 -1
  105. package/src/__tests__/tool-result-truncate-hook.test.ts +1 -1
  106. package/src/__tests__/user-plugin-loader.test.ts +54 -286
  107. package/src/acp/__tests__/agent-process.test.ts +161 -0
  108. package/src/acp/__tests__/client-handler.test.ts +40 -0
  109. package/src/acp/__tests__/helpers/acp-history-db.ts +82 -0
  110. package/src/acp/__tests__/helpers/exec-file-stub.ts +106 -0
  111. package/src/acp/__tests__/prepare-agent-env.test.ts +97 -0
  112. package/src/acp/__tests__/session-manager-persistence.test.ts +95 -28
  113. package/src/acp/__tests__/session-manager-resume.test.ts +888 -0
  114. package/src/acp/agent-process.ts +61 -1
  115. package/src/acp/auto-install.test.ts +280 -0
  116. package/src/acp/auto-install.ts +232 -0
  117. package/src/acp/client-handler.ts +31 -0
  118. package/src/acp/feature-gate.test.ts +48 -0
  119. package/src/acp/feature-gate.ts +34 -0
  120. package/src/acp/prepare-agent-env.ts +80 -27
  121. package/src/acp/resolve-agent.test.ts +225 -9
  122. package/src/acp/resolve-agent.ts +122 -17
  123. package/src/acp/resume-hint.ts +23 -0
  124. package/src/acp/session-manager.ts +507 -73
  125. package/src/agent/compaction-circuit.ts +60 -102
  126. package/src/agent/loop.ts +414 -248
  127. package/src/api/responses/conversation-message.ts +14 -1
  128. package/src/approvals/guardian-request-resolvers.ts +1 -1
  129. package/src/background-wake/next-wake.ts +1 -0
  130. package/src/cli/commands/db/__tests__/repair.test.ts +3 -1
  131. package/src/cli/commands/plugins.ts +43 -37
  132. package/src/cli/lib/__tests__/install-from-github.test.ts +429 -111
  133. package/src/cli/lib/__tests__/plugin-catalog-cache.test.ts +196 -0
  134. package/src/cli/lib/__tests__/plugin-details.test.ts +372 -0
  135. package/src/cli/lib/__tests__/plugin-marketplace.test.ts +220 -0
  136. package/src/cli/lib/__tests__/search-plugins.test.ts +226 -32
  137. package/src/cli/lib/install-from-github.ts +464 -55
  138. package/src/cli/lib/plugin-catalog-cache.ts +84 -0
  139. package/src/cli/lib/plugin-details.ts +409 -0
  140. package/src/cli/lib/plugin-marketplace.ts +197 -0
  141. package/src/cli/lib/search-plugins.ts +195 -29
  142. package/src/config/__tests__/feature-flag-registry-guard.test.ts +2 -2
  143. package/src/config/acp-defaults.test.ts +10 -0
  144. package/src/config/acp-defaults.ts +6 -0
  145. package/src/config/bundled-skills/acp/SKILL.md +85 -33
  146. package/src/config/bundled-skills/acp/TOOLS.json +4 -4
  147. package/src/config/bundled-skills/app-builder/SKILL.md +224 -381
  148. package/src/config/bundled-skills/app-builder/TOOLS.json +72 -2
  149. package/src/config/bundled-skills/app-builder/references/DESIGN_SYSTEM.md +48 -0
  150. package/src/config/bundled-skills/app-builder/references/RESPONSIVE.md +57 -0
  151. package/src/config/bundled-skills/app-builder/references/SLIDES.md +38 -0
  152. package/src/config/bundled-skills/app-builder/tools/app-list.ts +62 -0
  153. package/src/config/bundled-skills/app-builder/tools/app-update.ts +18 -0
  154. package/src/config/bundled-skills/document-editor/SKILL.md +28 -23
  155. package/src/config/bundled-skills/document-editor/TOOLS.json +1 -1
  156. package/src/config/bundled-tool-registry.ts +4 -0
  157. package/src/config/call-site-defaults.ts +0 -2
  158. package/src/config/feature-flag-registry.json +15 -6
  159. package/src/config/schemas/call-site-catalog.ts +0 -14
  160. package/src/config/schemas/heartbeat.ts +9 -0
  161. package/src/config/schemas/llm.ts +0 -2
  162. package/src/context/compactor.ts +22 -4
  163. package/src/context/strip-injections.ts +8 -2
  164. package/src/context/window-manager.ts +27 -13
  165. package/src/daemon/conversation-agent-loop-handlers.ts +10 -35
  166. package/src/daemon/conversation-agent-loop.ts +175 -1055
  167. package/src/daemon/conversation-lifecycle.ts +11 -255
  168. package/src/daemon/conversation-process.ts +8 -136
  169. package/src/daemon/conversation-registry.ts +159 -0
  170. package/src/daemon/conversation-runtime-assembly.ts +293 -392
  171. package/src/daemon/conversation-store.ts +9 -90
  172. package/src/daemon/conversation-surfaces.ts +24 -8
  173. package/src/daemon/conversation-workspace.ts +17 -0
  174. package/src/daemon/conversation.ts +404 -57
  175. package/src/daemon/disk-pressure-policy.ts +0 -1
  176. package/src/daemon/external-plugins-bootstrap.ts +14 -19
  177. package/src/daemon/handlers/conversations.ts +3 -1
  178. package/src/daemon/handlers/skills.ts +4 -1
  179. package/src/daemon/host-proxy-preactivation.ts +1 -3
  180. package/src/daemon/lifecycle.ts +21 -7
  181. package/src/daemon/server.ts +2 -0
  182. package/src/daemon/wake-conversation-ops.ts +269 -0
  183. package/src/embedded/plugin-api.ts +2 -2
  184. package/src/export/__tests__/transcript-formatter.test.ts +5 -0
  185. package/src/heartbeat/__tests__/heartbeat-service.test.ts +3 -0
  186. package/src/heartbeat/heartbeat-run-store.ts +23 -1
  187. package/src/heartbeat/heartbeat-service.ts +26 -0
  188. package/src/ipc/__tests__/browser-ipc.test.ts +1 -1
  189. package/src/ipc/__tests__/ui-request-route.test.ts +3 -3
  190. package/src/ipc/skill-routes/__tests__/memory.test.ts +15 -0
  191. package/src/ipc/skill-routes/memory.ts +4 -2
  192. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +87 -0
  193. package/src/memory/conversation-crud.ts +29 -19
  194. package/src/memory/conversation-starter-checkpoints.ts +1 -0
  195. package/src/memory/db-init.ts +2 -0
  196. package/src/memory/job-handlers/conversation-starters.ts +13 -2
  197. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +5 -4
  198. package/src/memory/jobs-worker.ts +25 -1
  199. package/src/memory/migrations/272-acp-session-history-cwd.ts +36 -0
  200. package/src/memory/migrations/index.ts +1 -0
  201. package/src/memory/schema/acp.ts +4 -0
  202. package/src/memory/v2/__tests__/consolidation-job.test.ts +3 -3
  203. package/src/memory/v2/consolidation-job.ts +13 -4
  204. package/src/plugin-api/constants.ts +4 -0
  205. package/src/plugin-api/index.ts +6 -5
  206. package/src/plugin-api/types.ts +75 -0
  207. package/src/plugins/defaults/compaction/compact.ts +59 -0
  208. package/src/{daemon → plugins/defaults/compaction}/context-overflow-reducer.ts +7 -7
  209. package/src/plugins/defaults/compaction/manager-store.ts +57 -0
  210. package/src/plugins/defaults/compaction/package.json +1 -2
  211. package/src/plugins/defaults/empty-response/package.json +0 -1
  212. package/src/plugins/defaults/history-repair/package.json +0 -1
  213. package/src/plugins/defaults/index.ts +135 -26
  214. package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +100 -52
  215. package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit-temp.ts +184 -74
  216. package/src/plugins/defaults/memory-retrieval/injector-chain.ts +2 -2
  217. package/src/plugins/defaults/{injectors/register.ts → memory-retrieval/injectors.ts} +148 -73
  218. package/src/plugins/defaults/memory-retrieval/unified-turn-context.ts +223 -0
  219. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/assign.test.ts +4 -4
  220. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/live-integration.test.ts +9 -6
  221. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/maintain-job.test.ts +5 -5
  222. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/orchestrate.test.ts +8 -5
  223. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/reconcile.test.ts +2 -2
  224. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/render-injection.test.ts +1 -1
  225. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/router.test.ts +10 -5
  226. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/selection-log-store.test.ts +8 -8
  227. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/selector.test.ts +5 -5
  228. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/shadow-plugin.test.ts +16 -17
  229. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/types.test.ts +2 -2
  230. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/assign.ts +9 -5
  231. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/capabilities.ts +5 -2
  232. package/src/plugins/defaults/memory-v3-shadow/hooks/post-compact.ts +14 -0
  233. package/src/plugins/defaults/memory-v3-shadow/hooks/user-prompt-submit.ts +19 -0
  234. package/src/plugins/defaults/memory-v3-shadow/injector.ts +75 -0
  235. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/maintain-job.ts +15 -8
  236. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/orchestrate.ts +2 -2
  237. package/src/plugins/defaults/memory-v3-shadow/package.json +14 -0
  238. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/page-content.ts +2 -2
  239. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/provider-blocks.ts +1 -1
  240. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/reconcile.ts +7 -3
  241. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/render-injection.ts +1 -1
  242. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/router.ts +5 -5
  243. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/selection-log-store.ts +4 -4
  244. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/selector.ts +7 -7
  245. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/shadow-plugin.ts +32 -94
  246. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/tree.ts +1 -1
  247. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/types.ts +1 -1
  248. package/src/plugins/defaults/title-generate/package.json +0 -1
  249. package/src/plugins/defaults/tool-error/package.json +0 -1
  250. package/src/plugins/defaults/tool-result-truncate/package.json +0 -1
  251. package/src/plugins/pipeline.ts +6 -293
  252. package/src/plugins/registry.ts +9 -37
  253. package/src/plugins/types.ts +76 -381
  254. package/src/plugins/user-loader.ts +30 -127
  255. package/src/prompts/__tests__/system-prompt.test.ts +6 -0
  256. package/src/prompts/templates/BOOTSTRAP-ACTIVATION-RAIL.md +35 -3
  257. package/src/runtime/__tests__/agent-wake.test.ts +555 -691
  258. package/src/runtime/__tests__/interactive-ui.test.ts +1 -1
  259. package/src/runtime/agent-wake.ts +108 -209
  260. package/src/runtime/assistant-event-hub.ts +1 -1
  261. package/src/runtime/channel-approvals.ts +1 -1
  262. package/src/runtime/interactive-ui.ts +1 -1
  263. package/src/runtime/routes/__tests__/acp-routes.test.ts +315 -55
  264. package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +1 -1
  265. package/src/runtime/routes/__tests__/plugins-routes.test.ts +423 -73
  266. package/src/runtime/routes/__tests__/surface-action-routes.test.ts +5 -4
  267. package/src/runtime/routes/__tests__/surface-content-routes.test.ts +4 -1
  268. package/src/runtime/routes/acp-routes.test.ts +89 -25
  269. package/src/runtime/routes/acp-routes.ts +81 -29
  270. package/src/runtime/routes/approval-routes.ts +1 -1
  271. package/src/runtime/routes/browser-routes.ts +1 -1
  272. package/src/runtime/routes/browser-tabs-routes.ts +6 -10
  273. package/src/runtime/routes/conversation-cli-routes.ts +1 -1
  274. package/src/runtime/routes/conversation-list-routes.ts +1 -1
  275. package/src/runtime/routes/conversation-query-routes.ts +1 -1
  276. package/src/runtime/routes/conversation-routes.ts +28 -2
  277. package/src/runtime/routes/conversation-starter-routes.ts +13 -7
  278. package/src/runtime/routes/conversations-import-routes.ts +24 -7
  279. package/src/runtime/routes/host-app-control-routes.ts +1 -1
  280. package/src/runtime/routes/host-cu-routes.ts +1 -1
  281. package/src/runtime/routes/identity-routes.ts +18 -3
  282. package/src/runtime/routes/inbound-message-handler.ts +1 -1
  283. package/src/runtime/routes/inference-profile-session-handler.ts +11 -0
  284. package/src/runtime/routes/inference-profile-session-reaper.ts +6 -0
  285. package/src/runtime/routes/memory-v3-routes.ts +16 -6
  286. package/src/runtime/routes/playground/helpers.ts +1 -1
  287. package/src/runtime/routes/plugins-routes.ts +337 -35
  288. package/src/runtime/routes/surface-conversation-resolver.ts +4 -3
  289. package/src/runtime/routes/work-items-routes.ts +2 -4
  290. package/src/runtime/services/conversation-serializer.ts +1 -1
  291. package/src/signals/cancel.ts +2 -4
  292. package/src/subagent/manager.ts +21 -5
  293. package/src/tools/acp/context.ts +20 -0
  294. package/src/tools/acp/list-agents.test.ts +8 -2
  295. package/src/tools/acp/spawn.test.ts +176 -195
  296. package/src/tools/acp/spawn.ts +37 -172
  297. package/src/tools/acp/steer.test.ts +105 -8
  298. package/src/tools/acp/steer.ts +48 -17
  299. package/src/tools/apps/executors.ts +166 -50
  300. package/src/tools/filesystem/write.ts +34 -0
  301. package/src/tools/subagent/spawn.ts +2 -4
  302. package/src/tools/ui-surface/definitions.ts +25 -5
  303. package/src/workspace/migrations/051-seed-conversation-summarization-callsite.ts +4 -5
  304. package/src/workspace/migrations/097-enable-adaptive-thinking-managed-profiles.ts +69 -45
  305. package/docs/plugins.md +0 -832
  306. package/examples/plugins/echo/register.ts +0 -143
  307. package/src/__tests__/circuit-breaker-pipeline.test.ts +0 -405
  308. package/src/__tests__/compaction-pipeline.test.ts +0 -210
  309. package/src/__tests__/compaction-timeout-recovery.test.ts +0 -251
  310. package/src/__tests__/overflow-reduce-pipeline.test.ts +0 -667
  311. package/src/__tests__/pipeline-runner.test.ts +0 -554
  312. package/src/__tests__/plugin-external-api.test.ts +0 -68
  313. package/src/daemon/wake-target-adapter.ts +0 -253
  314. package/src/plugins/defaults/circuit-breaker/middlewares/circuitBreaker.ts +0 -93
  315. package/src/plugins/defaults/circuit-breaker/package.json +0 -15
  316. package/src/plugins/defaults/circuit-breaker/register.ts +0 -39
  317. package/src/plugins/defaults/compaction/middlewares/compaction.ts +0 -25
  318. package/src/plugins/defaults/compaction/register.ts +0 -35
  319. package/src/plugins/defaults/compaction/terminal.ts +0 -73
  320. package/src/plugins/defaults/empty-response/register.ts +0 -23
  321. package/src/plugins/defaults/history-repair/register.ts +0 -24
  322. package/src/plugins/defaults/overflow-reduce/middlewares/overflowReduce.ts +0 -126
  323. package/src/plugins/defaults/overflow-reduce/package.json +0 -15
  324. package/src/plugins/defaults/overflow-reduce/register.ts +0 -42
  325. package/src/plugins/defaults/title-generate/register.ts +0 -35
  326. package/src/plugins/defaults/tool-error/register.ts +0 -23
  327. package/src/plugins/defaults/tool-result-truncate/register.ts +0 -24
  328. package/src/plugins/external-api.ts +0 -104
  329. package/src/proactive-artifact/aux-message-injector.ts +0 -97
  330. package/src/proactive-artifact/decision.test.ts +0 -226
  331. package/src/proactive-artifact/decision.ts +0 -165
  332. package/src/proactive-artifact/index.ts +0 -7
  333. package/src/proactive-artifact/job.test.ts +0 -962
  334. package/src/proactive-artifact/job.ts +0 -372
  335. package/src/proactive-artifact/message-copy.ts +0 -58
  336. package/src/proactive-artifact/trigger-state.test.ts +0 -286
  337. package/src/proactive-artifact/trigger-state.ts +0 -123
  338. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/capabilities.test.ts +0 -0
  339. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/core.test.ts +0 -0
  340. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/fixtures/eval-turns.json +0 -0
  341. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/fixtures/live-turns.json +0 -0
  342. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/health.test.ts +0 -0
  343. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/needle.test.ts +0 -0
  344. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/provider-blocks.test.ts +0 -0
  345. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/snapshot.test.ts +0 -0
  346. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/tree.test.ts +0 -0
  347. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/working-set-eviction.test.ts +0 -0
  348. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/working-set-skeleton.test.ts +0 -0
  349. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/core.ts +0 -0
  350. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/README.md +0 -0
  351. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/assignments.json +0 -0
  352. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/core.json +0 -0
  353. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-a/topic-x.md +0 -0
  354. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-a/topic-y.md +0 -0
  355. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-b/topic-z.md +0 -0
  356. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/health.ts +0 -0
  357. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/llm-retry.ts +0 -0
  358. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/needle.ts +0 -0
  359. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/snapshot.ts +0 -0
  360. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/working-set.ts +0 -0
@@ -50,7 +50,7 @@ let surfaceCalls: Array<{
50
50
  surfaceId: string;
51
51
  }> = [];
52
52
 
53
- mock.module("../../daemon/conversation-store.js", () => ({
53
+ mock.module("../../daemon/conversation-registry.js", () => ({
54
54
  findConversation: (_conversationId: string) => {
55
55
  return mockConversation ?? undefined;
56
56
  },
@@ -27,7 +27,7 @@
27
27
  * conversation, the wake is queued behind it (single-flight per
28
28
  * `conversationId`).
29
29
  * - While the wake's agent loop is running, the conversation is marked
30
- * as processing (via {@link WakeTarget.markProcessing}) so a user send
30
+ * as processing (via the conversation's processing marker) so a user send
31
31
  * that arrives mid-wake is queued by `enqueueMessage` instead of
32
32
  * launching a concurrent `agentLoop.run()` on the same conversation.
33
33
  *
@@ -43,7 +43,6 @@
43
43
 
44
44
  import type {
45
45
  AgentEvent,
46
- AgentLoop,
47
46
  CheckpointDecision,
48
47
  CheckpointInfo,
49
48
  } from "../agent/loop.js";
@@ -51,19 +50,25 @@ import type { InterfaceId } from "../channels/types.js";
51
50
  import { resolveEffectiveContextWindow } from "../config/llm-context-resolution.js";
52
51
  import { getConfig } from "../config/loader.js";
53
52
  import type { LLMCallSite } from "../config/schemas/llm.js";
53
+ import type { Conversation } from "../daemon/conversation.js";
54
54
  import { getDiskPressureStatus } from "../daemon/disk-pressure-guard.js";
55
55
  import {
56
56
  classifyDiskPressureTurnPolicy,
57
57
  type DiskPressureTurnPolicyDecision,
58
58
  } from "../daemon/disk-pressure-policy.js";
59
59
  import type { TrustContext } from "../daemon/trust-context.js";
60
+ import {
61
+ broadcastWakeSurface,
62
+ emitWakeAgentEvent,
63
+ persistWakeTailMessage,
64
+ scopeWakeAllowedTools,
65
+ } from "../daemon/wake-conversation-ops.js";
60
66
  import { getConversationOverrideProfile } from "../memory/conversation-crud.js";
61
67
  import {
62
68
  buildProviderErrorResponsePayload,
63
69
  recordRequestLog,
64
70
  setAgentLoopExitReasonOnLatestLog,
65
71
  } from "../memory/llm-request-log-store.js";
66
- import type { TurnContext } from "../plugins/types.js";
67
72
  import type { Message } from "../providers/types.js";
68
73
  import { getLogger } from "../util/logger.js";
69
74
 
@@ -77,102 +82,6 @@ const WAKE_PREAMBLE =
77
82
  const WAKE_POSTAMBLE =
78
83
  "[system] End of message from external system, continue the conversation.";
79
84
 
80
- /**
81
- * Minimum surface area of a conversation needed to wake it. Defined as an
82
- * interface rather than importing `Conversation` directly so the wake
83
- * helper stays decoupled from the heavyweight conversation class and is
84
- * easy to exercise under unit tests.
85
- *
86
- * Translation note: the wake deliberately hands the adapter a raw
87
- * {@link AgentEvent} via {@link emitAgentEvent} rather than a
88
- * `ServerMessage`. The normal user-turn path translates `AgentEvent` into
89
- * the correctly-shaped wire protocol frames (e.g.
90
- * `text_delta` → `assistant_text_delta` with `conversationId`) via the
91
- * canonical handler in `conversation-agent-loop-handlers.ts`. Passing raw
92
- * events means the adapter can reuse that translation rather than the
93
- * wake helper shipping malformed frames.
94
- */
95
- export interface WakeTarget {
96
- readonly conversationId: string;
97
- readonly agentLoop: Pick<AgentLoop, "run">;
98
- /**
99
- * Live LLM-visible history. We read a snapshot, append the internal hint
100
- * for the run, and then (on non-empty output) append the resulting
101
- * assistant message(s) to this array so subsequent turns see them.
102
- */
103
- getMessages(): Message[];
104
- pushMessage(message: Message): void;
105
- /**
106
- * Forward a raw agent event so the adapter can translate it to the
107
- * correct `ServerMessage` shape (e.g. stamping `conversationId`,
108
- * renaming `text_delta` → `assistant_text_delta`) before emission.
109
- *
110
- * Only called when the wake produces output worth emitting — silent
111
- * no-op wakes never flush buffered events.
112
- */
113
- emitAgentEvent(event: AgentEvent): void;
114
- /** True if the conversation is already processing a turn. */
115
- isProcessing(): boolean;
116
- /**
117
- * Toggle the conversation's in-flight processing marker. The wake
118
- * wraps its `agentLoop.run()` invocation in
119
- * `markProcessing(true) … markProcessing(false)` so a concurrent user
120
- * send sees `isProcessing() === true` and queues the message instead
121
- * of spawning a parallel agent loop.
122
- */
123
- markProcessing(on: boolean): void;
124
- /**
125
- * Persist a single tail message produced by the wake (assistant
126
- * outputs and intervening tool_result user messages). The daemon
127
- * adapter is responsible for building channel/interface metadata and
128
- * syncing the persisted message to the disk view so wake-produced
129
- * messages match the canonical user-turn persistence path. Kept as a
130
- * hook so `runtime/agent-wake.ts` stays decoupled from daemon
131
- * internals (trust context, turn channel/interface contexts,
132
- * disk-view layout).
133
- */
134
- persistTailMessage(message: Message): Promise<void>;
135
- /**
136
- * Drain any messages that arrived (and were queued) while the wake
137
- * was running. Optional because not every wake target has a queue —
138
- * unit-test stubs typically omit it.
139
- *
140
- * The wake invokes this in its `finally` block AFTER
141
- * `markProcessing(false)`. Order matters: if drain ran while
142
- * processing was still true, `enqueueMessage`'s gate
143
- * (`if (!ctx.isProcessing()) return ...`) would still see processing=true
144
- * and the drain itself would be a no-op against any racy late sends.
145
- * Running drain after processing is released matches the canonical
146
- * user-turn finally path in `conversation-agent-loop.ts`.
147
- */
148
- drainQueue?(): Promise<void>;
149
- /**
150
- * Called after a wake produces visible output (text or tool calls).
151
- * The daemon adapter uses this to emit a live SSE event so connected
152
- * clients see the wake indicator immediately. The `surfaceId` matches
153
- * the `ui_surface` content block already injected into the first
154
- * assistant tail message — both must share the same ID so the client
155
- * doesn't render duplicates. Optional because unit-test stubs
156
- * typically omit it.
157
- */
158
- onWakeProducedOutput?(source: string, hint: string, surfaceId: string): void;
159
- /**
160
- * Apply a trust context to the underlying conversation before the agent
161
- * loop runs. Internal background jobs (memory consolidation, update
162
- * bulletin) use this to declare guardian trust so side-effect tools
163
- * (file_edit, file_write, bash) clear the approval gate. Inbound message
164
- * conversations populate trust via `processMessage()` and don't pass
165
- * `trustContext` through the wake.
166
- */
167
- setTrustContext?(ctx: TrustContext): void;
168
- /**
169
- * Temporarily restrict the tools visible/executable during this wake.
170
- * Returns a restore callback so the wake can release the scope before any
171
- * queued user turn is drained.
172
- */
173
- setWakeAllowedTools?(tools: ReadonlySet<string>): () => void;
174
- }
175
-
176
85
  export interface WakeOptions {
177
86
  conversationId: string;
178
87
  hint: string;
@@ -214,7 +123,7 @@ export interface WakeOptions {
214
123
  * Documented intent: this wake must not trigger auto-threshold compaction.
215
124
  *
216
125
  * Today this is automatically satisfied because the wake invokes
217
- * `target.agentLoop.run()` directly, bypassing the daemon orchestrator
126
+ * `conversation.agentLoop.run()` directly, bypassing the daemon orchestrator
218
127
  * (`conversation-agent-loop.ts`) where the compaction pipeline lives. The
219
128
  * flag is recorded in the wake's structured log line so operators can
220
129
  * verify the contract holds across refactors. If compaction is ever moved
@@ -279,9 +188,9 @@ export interface WakeResult {
279
188
  */
280
189
  export interface WakeDeps {
281
190
  /**
282
- * Resolve the wake target for a wake invocation.
191
+ * Resolve the live {@link Conversation} for a wake invocation.
283
192
  * Returns `null` if the conversation doesn't exist, `"archived"` if it
284
- * exists but is archived, or a `WakeTarget` to proceed with the wake.
193
+ * exists but is archived, or the `Conversation` to proceed with the wake.
285
194
  *
286
195
  * Receives the full {@link WakeOptions} so the default resolver can
287
196
  * thread `trustContext` into `getOrCreateConversation`. Without that
@@ -290,7 +199,9 @@ export interface WakeDeps {
290
199
  * out every guardian-provenance message — fatal for fork-based memory
291
200
  * retrospectives.
292
201
  */
293
- resolveTarget: (opts: WakeOptions) => Promise<WakeTarget | null | "archived">;
202
+ resolveTarget: (
203
+ opts: WakeOptions,
204
+ ) => Promise<Conversation | null | "archived">;
294
205
  /** Timestamp source (for deterministic tests). */
295
206
  now?: () => number;
296
207
  }
@@ -298,12 +209,12 @@ export interface WakeDeps {
298
209
  // ── Default resolution ────────────────────────────────────────────────
299
210
  //
300
211
  // When `wakeAgentForOpportunity()` is called without explicit `deps`,
301
- // it resolves the target directly by importing `getConversation`,
302
- // `getOrCreateConversation`, and `conversationToWakeTarget`.
212
+ // it resolves the live conversation directly via `getConversation` and
213
+ // `getOrCreateConversation`.
303
214
 
304
215
  async function defaultResolveTarget(
305
216
  opts: WakeOptions,
306
- ): Promise<WakeTarget | null | "archived"> {
217
+ ): Promise<Conversation | null | "archived"> {
307
218
  const { conversationId } = opts;
308
219
  // Lazy-import daemon modules to avoid pulling heavyweight transitive
309
220
  // deps (conversation store → config/loader → provider catalogs) at
@@ -313,8 +224,6 @@ async function defaultResolveTarget(
313
224
  const { getConversation } = await import("../memory/conversation-crud.js");
314
225
  const { getOrCreateConversation } =
315
226
  await import("../daemon/conversation-store.js");
316
- const { conversationToWakeTarget } =
317
- await import("../daemon/wake-target-adapter.js");
318
227
  try {
319
228
  const existing = getConversation(conversationId);
320
229
  if (!existing) return null;
@@ -334,7 +243,7 @@ async function defaultResolveTarget(
334
243
  const conversation = await getOrCreateConversation(conversationId, {
335
244
  trustContext: opts.trustContext,
336
245
  });
337
- return conversationToWakeTarget(conversation);
246
+ return conversation;
338
247
  } catch (err) {
339
248
  log.warn(
340
249
  { err, conversationId },
@@ -385,15 +294,15 @@ async function runSingleFlight<T>(
385
294
  * while our wake was queued.
386
295
  */
387
296
  async function waitUntilIdle(
388
- target: WakeTarget,
297
+ conversation: Conversation,
389
298
  nowFn: () => number,
390
299
  timeoutMs = 30_000,
391
300
  ): Promise<boolean> {
392
301
  const deadline = nowFn() + timeoutMs;
393
- while (target.isProcessing() && nowFn() < deadline) {
302
+ while (conversation.isProcessing() && nowFn() < deadline) {
394
303
  await new Promise((resolve) => setTimeout(resolve, 50));
395
304
  }
396
- return !target.isProcessing();
305
+ return !conversation.isProcessing();
397
306
  }
398
307
 
399
308
  function classifyWakeDiskPressurePolicy(opts: WakeOptions): {
@@ -417,25 +326,30 @@ function classifyWakeDiskPressurePolicy(opts: WakeOptions): {
417
326
  return { decision, status };
418
327
  }
419
328
 
420
- function buildWakeTurnContext(
329
+ /**
330
+ * Trust snapshot the wake hands to the agent loop. A wake has no compaction
331
+ * path (it runs with overflow recovery disabled), so this snapshot is unread
332
+ * except on the disk-pressure cleanup-mode path, whose guardian value scopes
333
+ * the compactor's image manifest if cleanup ever compacts. Other wakes pass an
334
+ * `unknown`-class snapshot so a missing actor cannot grant elevated trust.
335
+ */
336
+ function buildWakeTrust(
421
337
  opts: WakeOptions,
422
338
  decision: DiskPressureTurnPolicyDecision,
423
- ): TurnContext | undefined {
424
- if (decision.action !== "allow-cleanup-mode") return undefined;
425
- return {
426
- requestId: `wake:${opts.source}`,
427
- conversationId: opts.conversationId,
428
- turnIndex: 0,
429
- trust:
430
- opts.trustContext ??
431
- ({
432
- sourceChannel: opts.sourceChannel ?? "vellum",
433
- trustClass: "guardian",
434
- } satisfies TrustContext),
435
- injectionInputs: {
436
- diskPressureContext: { cleanupModeActive: true },
437
- },
438
- };
339
+ ): TrustContext {
340
+ if (decision.action !== "allow-cleanup-mode") {
341
+ return {
342
+ sourceChannel: opts.sourceChannel ?? "vellum",
343
+ trustClass: "unknown",
344
+ };
345
+ }
346
+ return (
347
+ opts.trustContext ??
348
+ ({
349
+ sourceChannel: opts.sourceChannel ?? "vellum",
350
+ trustClass: "guardian",
351
+ } satisfies TrustContext)
352
+ );
439
353
  }
440
354
 
441
355
  /**
@@ -492,9 +406,10 @@ function inspectWakeOutput(
492
406
  * are serialized per `conversationId`.
493
407
  *
494
408
  * The `deps` argument is optional in production — when omitted, the
495
- * default resolver imports `getConversation`, `getOrCreateConversation`,
496
- * and `conversationToWakeTarget` directly. Tests that want tight
497
- * control over resolution continue to pass explicit deps.
409
+ * default resolver imports `getConversation` and
410
+ * `getOrCreateConversation` directly to return the live conversation.
411
+ * Tests that want tight control over resolution continue to pass
412
+ * explicit deps.
498
413
  */
499
414
  export async function wakeAgentForOpportunity(
500
415
  opts: WakeOptions,
@@ -525,7 +440,7 @@ export async function wakeAgentForOpportunity(
525
440
  );
526
441
  return { invoked: false, producedToolCalls: false, reason: "not_found" };
527
442
  }
528
- const target = resolved;
443
+ const conversation = resolved;
529
444
 
530
445
  const { decision: diskPressureDecision, status: diskPressureStatus } =
531
446
  classifyWakeDiskPressurePolicy(opts);
@@ -551,7 +466,7 @@ export async function wakeAgentForOpportunity(
551
466
  };
552
467
  }
553
468
 
554
- const idle = await waitUntilIdle(target, nowFn);
469
+ const idle = await waitUntilIdle(conversation, nowFn);
555
470
  if (!idle) {
556
471
  log.warn(
557
472
  { conversationId, source },
@@ -563,18 +478,18 @@ export async function wakeAgentForOpportunity(
563
478
  // Apply caller-supplied trust before the agent loop reads its per-turn
564
479
  // snapshot. Background jobs without an inbound message use this to
565
480
  // declare guardian trust so side-effect tools clear the approval gate.
566
- if (opts.trustContext && target.setTrustContext) {
567
- target.setTrustContext(opts.trustContext);
481
+ if (opts.trustContext) {
482
+ conversation.setTrustContext(opts.trustContext);
568
483
  }
569
484
 
570
- const baseline = target.getMessages();
485
+ const baseline = conversation.getMessages();
571
486
  // Snapshot the baseline length BEFORE the run starts. Incremental
572
- // persistence calls `target.pushMessage` mid-run, which grows the
487
+ // persistence pushes onto `conversation.messages` mid-run, which grows the
573
488
  // live history array `baseline` aliases. Reading `baseline.length`
574
489
  // post-run would therefore include the tail we just pushed and the
575
490
  // tail-slice math would skip every message.
576
491
  const baselineLength = baseline.length;
577
- const wakeTurnContext = buildWakeTurnContext(opts, diskPressureDecision);
492
+ const wakeTrust = buildWakeTrust(opts, diskPressureDecision);
578
493
  // Build the hint injection. Three modes:
579
494
  // - `skipHintInjection`: caller has already persisted an instruction
580
495
  // message into the conversation history (typical for fork-based
@@ -674,7 +589,7 @@ export async function wakeAgentForOpportunity(
674
589
  };
675
590
  const safeEmit = (event: AgentEvent): void => {
676
591
  try {
677
- target.emitAgentEvent(event);
592
+ emitWakeAgentEvent(conversation, event);
678
593
  } catch (err) {
679
594
  log.warn(
680
595
  { conversationId, source, err },
@@ -744,8 +659,8 @@ export async function wakeAgentForOpportunity(
744
659
  // Transition from buffered to live emission. Idempotent — only the
745
660
  // first call has an effect. Mutates the first assistant message in
746
661
  // the tail to prepend the ui_surface block, emits the live
747
- // ui_surface event, then drains the buffered events through the
748
- // target's translator. The translator is what stamps `conversationId`
662
+ // ui_surface event, then drains the buffered events through
663
+ // `emitWakeAgentEvent`. The translator is what stamps `conversationId`
749
664
  // and renames `text_delta` → `assistant_text_delta`; bypassing it
750
665
  // would ship malformed wire frames.
751
666
  const goLive = (currentHistory: Message[]): void => {
@@ -772,13 +687,13 @@ export async function wakeAgentForOpportunity(
772
687
  }
773
688
  surfaceInjected = true;
774
689
  }
775
- if (!opts.suppressWakeSurface && target.onWakeProducedOutput) {
690
+ if (!opts.suppressWakeSurface) {
776
691
  try {
777
- target.onWakeProducedOutput(source, hint, wakeSurfaceId);
692
+ broadcastWakeSurface(conversation, source, hint, wakeSurfaceId);
778
693
  } catch (err) {
779
694
  log.warn(
780
695
  { conversationId, source, err },
781
- "agent-wake: onWakeProducedOutput threw; continuing",
696
+ "agent-wake: broadcastWakeSurface threw; continuing",
782
697
  );
783
698
  }
784
699
  }
@@ -815,11 +730,11 @@ export async function wakeAgentForOpportunity(
815
730
  if (start >= currentHistory.length) return;
816
731
  const newMessages = currentHistory.slice(start);
817
732
  for (const msg of newMessages) {
818
- target.pushMessage(msg);
733
+ conversation.messages.push(msg);
819
734
  }
820
735
  for (const msg of newMessages) {
821
736
  try {
822
- await target.persistTailMessage(msg);
737
+ await persistWakeTailMessage(conversation, msg);
823
738
  } catch (err) {
824
739
  log.warn(
825
740
  { conversationId, source, err, role: msg.role },
@@ -836,7 +751,7 @@ export async function wakeAgentForOpportunity(
836
751
  // silently violating the user's pinned preference. Resolve the effective
837
752
  // context budget here as well because wakes bypass the normal user-turn
838
753
  // path that computes it for tool-result truncation. Read before
839
- // `markProcessing(true)` so a thrown DB/config read can't strand the
754
+ // `setProcessing(true)` so a thrown DB/config read can't strand the
840
755
  // processing flag.
841
756
  const overrideProfile = getConversationOverrideProfile(conversationId);
842
757
  const callSite = opts.callSite ?? "mainAgent";
@@ -864,15 +779,9 @@ export async function wakeAgentForOpportunity(
864
779
  };
865
780
  const applyWakeAllowedTools = (): boolean => {
866
781
  if (!opts.allowedTools) return true;
867
- if (!target.setWakeAllowedTools) {
868
- log.warn(
869
- { conversationId, source, allowedTools: opts.allowedTools },
870
- "agent-wake: target cannot apply requested tool allowlist; skipping",
871
- );
872
- return false;
873
- }
874
782
  try {
875
- restoreWakeToolScope = target.setWakeAllowedTools(
783
+ restoreWakeToolScope = scopeWakeAllowedTools(
784
+ conversation,
876
785
  new Set(opts.allowedTools),
877
786
  );
878
787
  return true;
@@ -891,11 +800,7 @@ export async function wakeAgentForOpportunity(
891
800
  // interleave writes to `conversation.messages`). This happens before
892
801
  // applying a wake-scoped tool allowlist so a concurrent user turn cannot
893
802
  // start under the wake's restricted tool set.
894
- try {
895
- target.markProcessing(true);
896
- } catch (err) {
897
- throw err;
898
- }
803
+ conversation.setProcessing(true);
899
804
 
900
805
  // Fires after each tool-execution turn finalizes (assistant message
901
806
  // + matching tool_result user message both in history). A single
@@ -927,31 +832,29 @@ export async function wakeAgentForOpportunity(
927
832
 
928
833
  let updatedHistory: Message[];
929
834
  try {
930
- ({ history: updatedHistory } = await target.agentLoop.run(
931
- runInput,
835
+ ({ history: updatedHistory } = await conversation.agentLoop.run({
836
+ messages: runInput,
932
837
  onEvent,
933
- {
934
- requestId: `wake:${source}`,
935
- onCheckpoint,
936
- // Route through the caller-supplied call site (defaults to
937
- // `mainAgent` so a normal user-turn wake shares the user's chat
938
- // selection). Without an explicit callSite, the resolver in
939
- // `RetryProvider` and the routing in `CallSiteRoutingProvider`
940
- // short-circuit and silently drop both per-callsite config and the
941
- // pinned `overrideProfile` below.
942
- callSite,
943
- turnContext: wakeTurnContext,
944
- overrideProfile,
945
- // Wake runs have no orchestrator-side mid-loop compaction path,
946
- // so the budget gate stays disabled (`overflowRecovery.enabled =
947
- // false`); `maxInputTokens` is still supplied for tool-result
948
- // truncation.
949
- resolveContextWindow: () => ({
950
- maxInputTokens: effectiveContextWindow.maxInputTokens,
951
- overflowRecovery: { enabled: false, safetyMarginRatio: 0 },
952
- }),
953
- },
954
- ));
838
+ requestId: `wake:${source}`,
839
+ onCheckpoint,
840
+ // Route through the caller-supplied call site (defaults to
841
+ // `mainAgent` so a normal user-turn wake shares the user's chat
842
+ // selection). Without an explicit callSite, the resolver in
843
+ // `RetryProvider` and the routing in `CallSiteRoutingProvider`
844
+ // short-circuit and silently drop both per-callsite config and the
845
+ // pinned `overrideProfile` below.
846
+ callSite,
847
+ trust: wakeTrust,
848
+ overrideProfile,
849
+ // Wake runs have no orchestrator-side mid-loop compaction path,
850
+ // so the budget gate stays disabled (`overflowRecovery.enabled =
851
+ // false`); `maxInputTokens` is still supplied for tool-result
852
+ // truncation.
853
+ resolveContextWindow: () => ({
854
+ maxInputTokens: effectiveContextWindow.maxInputTokens,
855
+ overflowRecovery: { enabled: false, safetyMarginRatio: 0 },
856
+ }),
857
+ }));
955
858
  } catch (err) {
956
859
  // Capture the error for post-finally logging, then short-circuit
957
860
  // the rest of the try body — no tail to push/persist when the
@@ -1004,34 +907,32 @@ export async function wakeAgentForOpportunity(
1004
907
 
1005
908
  // Drain queued messages AFTER tail is pushed + persisted so the
1006
909
  // next dequeued user message sees the complete, up-to-date
1007
- // history. markProcessing(false) must come first (the queue only
910
+ // history. setProcessing(false) must come first (the queue only
1008
911
  // accepts entries while processing === true, and drain expects
1009
912
  // processing to already be false). The finally block handles the
1010
913
  // error/early-return paths where no tail was produced.
1011
914
  restoreWakeAllowedTools();
1012
915
  try {
1013
- target.markProcessing(false);
916
+ conversation.setProcessing(false);
1014
917
  } catch (err) {
1015
918
  log.warn(
1016
919
  { conversationId, source, err },
1017
- "agent-wake: markProcessing(false) threw; continuing",
920
+ "agent-wake: setProcessing(false) threw; continuing",
1018
921
  );
1019
922
  }
1020
- if (target.drainQueue) {
1021
- try {
1022
- await target.drainQueue();
1023
- } catch (err) {
1024
- log.warn(
1025
- { conversationId, source, err },
1026
- "agent-wake: drainQueue threw; continuing",
1027
- );
1028
- }
923
+ try {
924
+ await conversation.drainQueue();
925
+ } catch (err) {
926
+ log.warn(
927
+ { conversationId, source, err },
928
+ "agent-wake: drainQueue threw; continuing",
929
+ );
1029
930
  }
1030
931
  drainedInTry = true;
1031
932
 
1032
933
  return { invoked: true, producedToolCalls };
1033
934
  } finally {
1034
- // The success path (above) already called markProcessing(false)
935
+ // The success path (above) already called setProcessing(false)
1035
936
  // + drainQueue after tail persist. This catch-all handles the
1036
937
  // error and early-return paths where no tail was produced — those
1037
938
  // exit the try body before reaching the drain block, so
@@ -1039,22 +940,20 @@ export async function wakeAgentForOpportunity(
1039
940
  if (!drainedInTry) {
1040
941
  restoreWakeAllowedTools();
1041
942
  try {
1042
- target.markProcessing(false);
943
+ conversation.setProcessing(false);
1043
944
  } catch (err) {
1044
945
  log.warn(
1045
946
  { conversationId, source, err },
1046
- "agent-wake: markProcessing(false) threw; continuing",
947
+ "agent-wake: setProcessing(false) threw; continuing",
1047
948
  );
1048
949
  }
1049
- if (target.drainQueue) {
1050
- try {
1051
- await target.drainQueue();
1052
- } catch (err) {
1053
- log.warn(
1054
- { conversationId, source, err },
1055
- "agent-wake: drainQueue threw; continuing",
1056
- );
1057
- }
950
+ try {
951
+ await conversation.drainQueue();
952
+ } catch (err) {
953
+ log.warn(
954
+ { conversationId, source, err },
955
+ "agent-wake: drainQueue threw; continuing",
956
+ );
1058
957
  }
1059
958
  }
1060
959
 
@@ -708,7 +708,7 @@ async function createCanonicalRequestForConfirmation(
708
708
  { DAEMON_INTERNAL_ASSISTANT_ID },
709
709
  { bridgeConfirmationRequestToGuardian },
710
710
  ] = await Promise.all([
711
- import("../daemon/conversation-store.js"),
711
+ import("../daemon/conversation-registry.js"),
712
712
  import("../memory/canonical-guardian-store.js"),
713
713
  import("../security/secret-scanner.js"),
714
714
  import("../tools/tool-input-summary.js"),
@@ -9,7 +9,7 @@
9
9
  * 3. Consume user decisions and apply them to the underlying session
10
10
  */
11
11
 
12
- import { findConversation } from "../daemon/conversation-store.js";
12
+ import { findConversation } from "../daemon/conversation-registry.js";
13
13
  import type { UserDecision } from "../permissions/types.js";
14
14
  import { composeApprovalMessage } from "./approval-message-composer.js";
15
15
  import type {
@@ -30,7 +30,7 @@
30
30
  * `"timed_out"`.
31
31
  */
32
32
 
33
- import { findConversation } from "../daemon/conversation-store.js";
33
+ import { findConversation } from "../daemon/conversation-registry.js";
34
34
  import { showStandaloneSurface } from "../daemon/conversation-surfaces.js";
35
35
  import { getLogger } from "../util/logger.js";
36
36
  import { mintDecisionToken } from "./decision-token.js";