@vellumai/assistant 0.8.8 → 0.8.9-dev.202606091853.fbaa2ae

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 (475) hide show
  1. package/ARCHITECTURE.md +6 -6
  2. package/bun.lock +2 -2
  3. package/docs/activation-funnel-telemetry.md +310 -0
  4. package/examples/plugins/echo/README.md +61 -60
  5. package/examples/plugins/echo/hooks/post-tool-use.ts +18 -0
  6. package/examples/plugins/echo/hooks/stop.ts +16 -0
  7. package/examples/plugins/echo/hooks/user-prompt-submit.ts +18 -0
  8. package/examples/plugins/echo/package.json +1 -2
  9. package/examples/plugins/echo/src/emit.ts +19 -0
  10. package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +7 -6
  11. package/openapi.yaml +263 -121
  12. package/package.json +2 -2
  13. package/src/__tests__/activation-early-marking.test.ts +120 -0
  14. package/src/__tests__/agent-loop-callsite-precedence.test.ts +69 -14
  15. package/src/__tests__/agent-loop-exit-reason.test.ts +204 -144
  16. package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +50 -35
  17. package/src/__tests__/agent-loop-output-hooks.test.ts +357 -0
  18. package/src/__tests__/agent-loop-override-profile.test.ts +25 -6
  19. package/src/__tests__/agent-loop-provider-error-recording.test.ts +41 -21
  20. package/src/__tests__/agent-loop-thinking.test.ts +36 -20
  21. package/src/__tests__/agent-loop.test.ts +441 -96
  22. package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +14 -14
  23. package/src/__tests__/agent-wake-override-profile.test.ts +17 -21
  24. package/src/__tests__/anthropic-provider.test.ts +23 -8
  25. package/src/__tests__/app-builder-tool-scripts.test.ts +21 -0
  26. package/src/__tests__/app-control-flow.test.ts +1 -1
  27. package/src/__tests__/app-dir-path-guard.test.ts +1 -0
  28. package/src/__tests__/app-executors.test.ts +132 -0
  29. package/src/__tests__/approval-cascade.test.ts +6 -5
  30. package/src/__tests__/approval-routes-http.test.ts +4 -1
  31. package/src/__tests__/background-workers-disk-pressure.test.ts +1 -1
  32. package/src/__tests__/channel-approval-routes.test.ts +1 -1
  33. package/src/__tests__/channel-approvals.test.ts +1 -1
  34. package/src/__tests__/compaction-circuit.test.ts +258 -0
  35. package/src/__tests__/compaction-direct.test.ts +146 -0
  36. package/src/__tests__/compaction-events.test.ts +7 -7
  37. package/src/__tests__/compaction.benchmark.test.ts +1 -1
  38. package/src/__tests__/compactor-web-search-strip.test.ts +213 -0
  39. package/src/__tests__/context-overflow-reducer.test.ts +265 -125
  40. package/src/__tests__/context-window-manager-compact-retry.test.ts +121 -15
  41. package/src/__tests__/conversation-abort-tool-results.test.ts +7 -5
  42. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +7 -10
  43. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +78 -119
  44. package/src/__tests__/conversation-agent-loop-overflow.test.ts +158 -234
  45. package/src/__tests__/conversation-agent-loop.test.ts +342 -623
  46. package/src/__tests__/conversation-clean-command.test.ts +5 -2
  47. package/src/__tests__/conversation-confirmation-signals.test.ts +6 -5
  48. package/src/__tests__/conversation-crud-inference-profile.test.ts +7 -9
  49. package/src/__tests__/conversation-error.test.ts +15 -1
  50. package/src/__tests__/conversation-history-web-search.test.ts +6 -1
  51. package/src/__tests__/conversation-media-retry.test.ts +1 -1
  52. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +44 -4
  53. package/src/__tests__/conversation-process-callsite.test.ts +15 -15
  54. package/src/__tests__/conversation-provider-retry-repair.test.ts +66 -65
  55. package/src/__tests__/conversation-queue.test.ts +10 -10
  56. package/src/__tests__/conversation-runtime-assembly.test.ts +1059 -231
  57. package/src/__tests__/conversation-runtime-workspace.test.ts +115 -20
  58. package/src/__tests__/conversation-slash-queue.test.ts +7 -5
  59. package/src/__tests__/conversation-slash-unknown.test.ts +7 -5
  60. package/src/__tests__/conversation-speed-override.test.ts +11 -10
  61. package/src/__tests__/conversation-starter-routes.test.ts +14 -6
  62. package/src/__tests__/conversation-surfaces-activation-emit.test.ts +395 -0
  63. package/src/__tests__/conversation-surfaces-app-control.test.ts +48 -1
  64. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +73 -4
  65. package/src/__tests__/conversation-undo.test.ts +2 -2
  66. package/src/__tests__/conversation-workspace-cache-state.test.ts +24 -21
  67. package/src/__tests__/conversation-workspace-injection.test.ts +69 -7
  68. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +15 -12
  69. package/src/__tests__/conversations-import-system-filter.test.ts +101 -0
  70. package/src/__tests__/corrected-target.test.ts +93 -0
  71. package/src/__tests__/credential-security-invariants.test.ts +1 -0
  72. package/src/__tests__/cu-unified-flow.test.ts +36 -0
  73. package/src/__tests__/db-acp-history.test.ts +101 -0
  74. package/src/__tests__/dynamic-page-surface.test.ts +31 -0
  75. package/src/__tests__/empty-response-hook.test.ts +1 -1
  76. package/src/__tests__/file-write-tool.test.ts +63 -0
  77. package/src/__tests__/gateway-only-guard.test.ts +17 -2
  78. package/src/__tests__/guardian-grant-minting.test.ts +1 -1
  79. package/src/__tests__/guardian-routing-invariants.test.ts +93 -4
  80. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +1 -1
  81. package/src/__tests__/heartbeat-disk-pressure.test.ts +1 -0
  82. package/src/__tests__/heartbeat-service.test.ts +1 -0
  83. package/src/__tests__/history-repair-hook.test.ts +5 -1
  84. package/src/__tests__/host-app-control-proxy.test.ts +45 -0
  85. package/src/__tests__/host-app-control-routes.test.ts +1 -1
  86. package/src/__tests__/host-cu-routes-targeted.test.ts +3 -3
  87. package/src/__tests__/inference-profile-reaper.test.ts +62 -0
  88. package/src/__tests__/inference-profile-session-handler.test.ts +86 -0
  89. package/src/__tests__/injector-background-turn.test.ts +13 -23
  90. package/src/__tests__/injector-chain.test.ts +268 -44
  91. package/src/__tests__/injector-disk-pressure.test.ts +210 -52
  92. package/src/__tests__/injector-document-comments.test.ts +97 -114
  93. package/src/__tests__/injector-pkb-v2-silenced.test.ts +2 -2
  94. package/src/__tests__/injector-v3-suppression.test.ts +4 -4
  95. package/src/__tests__/list-messages-client-message-id.test.ts +91 -0
  96. package/src/__tests__/list-messages-hidden-metadata.test.ts +38 -0
  97. package/src/__tests__/llm-resolver.test.ts +73 -0
  98. package/src/__tests__/memory-retrieval-hook.test.ts +156 -38
  99. package/src/__tests__/memory-v2-static-injector.test.ts +86 -8
  100. package/src/__tests__/notification-decision-strategy.test.ts +3 -3
  101. package/src/__tests__/parallel-tool.benchmark.test.ts +35 -8
  102. package/src/__tests__/persist-unsendable-image-downscale.test.ts +145 -0
  103. package/src/__tests__/persist-unsendable-image.test.ts +97 -1
  104. package/src/__tests__/plugin-api-shim.test.ts +6 -9
  105. package/src/__tests__/plugin-bootstrap.test.ts +91 -81
  106. package/src/__tests__/plugin-registry.test.ts +3 -49
  107. package/src/__tests__/plugin-skill-contribution.test.ts +15 -14
  108. package/src/__tests__/plugin-tool-contribution.test.ts +7 -4
  109. package/src/__tests__/plugin-types.test.ts +0 -70
  110. package/src/__tests__/post-turn-tool-result-truncation.test.ts +69 -0
  111. package/src/__tests__/pre-model-call-sanitize.test.ts +109 -0
  112. package/src/__tests__/published-app-updater.test.ts +138 -0
  113. package/src/__tests__/reaction-persistence.test.ts +1 -1
  114. package/src/__tests__/send-endpoint-busy.test.ts +4 -1
  115. package/src/__tests__/skill-feature-flags-integration.test.ts +31 -0
  116. package/src/__tests__/steer-tool-repair.test.ts +1 -1
  117. package/src/__tests__/subagent-call-site-routing.test.ts +1 -1
  118. package/src/__tests__/subagent-detail.test.ts +25 -7
  119. package/src/__tests__/subagent-fork-notifications.test.ts +1 -3
  120. package/src/__tests__/subagent-fork-spawn.test.ts +1 -1
  121. package/src/__tests__/subagent-manager-notify.test.ts +1 -3
  122. package/src/__tests__/subagent-notify-parent.test.ts +1 -3
  123. package/src/__tests__/subagent-spawn-tool-fork.test.ts +1 -1
  124. package/src/__tests__/title-generate-hook.test.ts +5 -1
  125. package/src/__tests__/tool-error-hook.test.ts +1 -1
  126. package/src/__tests__/tool-result-truncate-hook.test.ts +1 -1
  127. package/src/__tests__/user-plugin-loader.test.ts +54 -286
  128. package/src/__tests__/web-fetch.test.ts +45 -0
  129. package/src/acp/__tests__/agent-process.test.ts +161 -0
  130. package/src/acp/__tests__/client-handler.test.ts +40 -0
  131. package/src/acp/__tests__/helpers/acp-config-stub.ts +0 -2
  132. package/src/acp/__tests__/helpers/acp-history-db.ts +82 -0
  133. package/src/acp/__tests__/helpers/exec-file-stub.ts +106 -0
  134. package/src/acp/__tests__/prepare-agent-env.test.ts +97 -0
  135. package/src/acp/__tests__/session-manager-persistence.test.ts +95 -28
  136. package/src/acp/__tests__/session-manager-resume.test.ts +888 -0
  137. package/src/acp/agent-process.ts +61 -1
  138. package/src/acp/auto-install.test.ts +280 -0
  139. package/src/acp/auto-install.ts +232 -0
  140. package/src/acp/client-handler.ts +31 -0
  141. package/src/acp/prepare-agent-env.ts +80 -27
  142. package/src/acp/resolve-agent.test.ts +188 -28
  143. package/src/acp/resolve-agent.ts +119 -42
  144. package/src/acp/resume-hint.ts +23 -0
  145. package/src/acp/session-manager.ts +507 -73
  146. package/src/agent/compaction-circuit.ts +60 -102
  147. package/src/agent/loop.ts +403 -251
  148. package/src/api/responses/conversation-message.ts +22 -2
  149. package/src/api/responses/memory-v3-selection-log.ts +19 -10
  150. package/src/approvals/guardian-request-resolvers.ts +27 -1
  151. package/src/background-wake/next-wake.ts +1 -0
  152. package/src/cli/commands/__tests__/memory-v3.test.ts +191 -210
  153. package/src/cli/commands/channel-verification-sessions.ts +6 -6
  154. package/src/cli/commands/db/__tests__/repair.test.ts +3 -1
  155. package/src/cli/commands/memory-v3.ts +57 -199
  156. package/src/cli/commands/plugins.ts +43 -37
  157. package/src/cli/lib/__tests__/install-from-github.test.ts +790 -111
  158. package/src/cli/lib/__tests__/plugin-catalog-cache.test.ts +196 -0
  159. package/src/cli/lib/__tests__/plugin-details.test.ts +381 -0
  160. package/src/cli/lib/__tests__/plugin-marketplace.test.ts +270 -0
  161. package/src/cli/lib/__tests__/search-plugins.test.ts +233 -32
  162. package/src/cli/lib/install-from-github.ts +797 -60
  163. package/src/cli/lib/plugin-catalog-cache.ts +84 -0
  164. package/src/cli/lib/plugin-details.ts +416 -0
  165. package/src/cli/lib/plugin-marketplace.ts +215 -0
  166. package/src/cli/lib/search-plugins.ts +201 -29
  167. package/src/config/__tests__/feature-flag-registry-guard.test.ts +2 -2
  168. package/src/config/acp-defaults.test.ts +10 -0
  169. package/src/config/acp-defaults.ts +9 -3
  170. package/src/config/acp-schema.ts +1 -7
  171. package/src/config/bundled-skills/acp/SKILL.md +80 -41
  172. package/src/config/bundled-skills/acp/TOOLS.json +4 -4
  173. package/src/config/bundled-skills/app-builder/SKILL.md +224 -381
  174. package/src/config/bundled-skills/app-builder/TOOLS.json +72 -2
  175. package/src/config/bundled-skills/app-builder/references/DESIGN_SYSTEM.md +48 -0
  176. package/src/config/bundled-skills/app-builder/references/RESPONSIVE.md +57 -0
  177. package/src/config/bundled-skills/app-builder/references/SLIDES.md +38 -0
  178. package/src/config/bundled-skills/app-builder/tools/app-list.ts +62 -0
  179. package/src/config/bundled-skills/app-builder/tools/app-update.ts +18 -0
  180. package/src/config/bundled-skills/document-editor/SKILL.md +28 -23
  181. package/src/config/bundled-skills/document-editor/TOOLS.json +1 -1
  182. package/src/config/bundled-tool-registry.ts +4 -0
  183. package/src/config/call-site-defaults.ts +0 -3
  184. package/src/config/feature-flag-registry.json +10 -16
  185. package/src/config/llm-resolver.ts +39 -7
  186. package/src/config/schemas/__tests__/memory-v3.test.ts +25 -9
  187. package/src/config/schemas/call-site-catalog.ts +0 -21
  188. package/src/config/schemas/heartbeat.ts +9 -0
  189. package/src/config/schemas/llm.ts +17 -3
  190. package/src/config/schemas/memory-v3.ts +58 -8
  191. package/src/config/seed-inference-profiles.ts +18 -0
  192. package/src/context/compactor.ts +22 -4
  193. package/src/context/post-turn-tool-result-truncation.ts +39 -1
  194. package/src/context/strip-injections.ts +8 -2
  195. package/src/daemon/conversation-agent-loop-handlers.ts +18 -36
  196. package/src/daemon/conversation-agent-loop.ts +308 -1297
  197. package/src/daemon/conversation-error.ts +31 -4
  198. package/src/daemon/conversation-history.ts +1 -1
  199. package/src/daemon/conversation-lifecycle.ts +11 -255
  200. package/src/daemon/conversation-media-retry.ts +19 -6
  201. package/src/daemon/conversation-messaging.ts +17 -0
  202. package/src/daemon/conversation-process.ts +22 -141
  203. package/src/daemon/conversation-queue-manager.ts +8 -0
  204. package/src/daemon/conversation-registry.ts +159 -0
  205. package/src/daemon/conversation-runtime-assembly.ts +361 -393
  206. package/src/daemon/conversation-store.ts +9 -90
  207. package/src/daemon/conversation-surfaces.ts +165 -11
  208. package/src/daemon/conversation-workspace.ts +17 -0
  209. package/src/daemon/conversation.ts +444 -62
  210. package/src/daemon/disk-pressure-policy.ts +0 -1
  211. package/src/daemon/external-plugins-bootstrap.ts +36 -46
  212. package/src/daemon/handlers/config-channels.ts +11 -2
  213. package/src/daemon/handlers/conversations.ts +3 -1
  214. package/src/daemon/handlers/skills.ts +4 -1
  215. package/src/daemon/host-app-control-proxy.ts +72 -57
  216. package/src/daemon/host-proxy-preactivation.ts +1 -3
  217. package/src/daemon/lifecycle.ts +21 -7
  218. package/src/daemon/persist-unsendable-image.ts +62 -25
  219. package/src/daemon/process-message.ts +1 -1
  220. package/src/daemon/server.ts +2 -0
  221. package/src/daemon/tool-side-effects.ts +15 -0
  222. package/src/daemon/wake-conversation-ops.ts +269 -0
  223. package/src/embedded/plugin-api.ts +2 -2
  224. package/src/export/__tests__/transcript-formatter.test.ts +5 -0
  225. package/src/heartbeat/__tests__/heartbeat-service.test.ts +3 -0
  226. package/src/heartbeat/heartbeat-run-store.ts +23 -1
  227. package/src/heartbeat/heartbeat-service.ts +26 -0
  228. package/src/ipc/__tests__/browser-ipc.test.ts +1 -1
  229. package/src/ipc/__tests__/ui-request-route.test.ts +3 -3
  230. package/src/ipc/skill-routes/__tests__/memory.test.ts +15 -0
  231. package/src/ipc/skill-routes/memory.ts +4 -2
  232. package/src/memory/__tests__/activation-session-store.test.ts +41 -0
  233. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +87 -0
  234. package/src/memory/__tests__/onboarding-events-store.test.ts +80 -0
  235. package/src/memory/activation-session-store.ts +43 -0
  236. package/src/memory/conversation-crud.ts +29 -19
  237. package/src/memory/conversation-starter-checkpoints.ts +1 -0
  238. package/src/memory/db-init.ts +6 -0
  239. package/src/memory/job-handlers/conversation-starters.ts +13 -2
  240. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +5 -4
  241. package/src/memory/jobs-worker.ts +25 -1
  242. package/src/memory/migrations/272-acp-session-history-cwd.ts +36 -0
  243. package/src/memory/migrations/273-onboarding-events-funnel-columns.ts +46 -0
  244. package/src/memory/migrations/274-create-activation-sessions.ts +15 -0
  245. package/src/memory/migrations/index.ts +3 -0
  246. package/src/memory/onboarding-events-store.ts +66 -18
  247. package/src/memory/schema/acp.ts +4 -0
  248. package/src/memory/schema/infrastructure.ts +13 -0
  249. package/src/memory/v2/__tests__/consolidation-job.test.ts +4 -97
  250. package/src/memory/v2/__tests__/page-store.test.ts +22 -0
  251. package/src/memory/v2/consolidation-job.ts +2 -63
  252. package/src/memory/v2/types.ts +5 -0
  253. package/src/messaging/providers/telegram-bot/api.ts +14 -5
  254. package/src/notifications/__tests__/copy-composer.test.ts +244 -0
  255. package/src/notifications/access-request-copy.ts +298 -0
  256. package/src/notifications/adapters/slack.ts +3 -3
  257. package/src/notifications/adapters/telegram.ts +9 -2
  258. package/src/notifications/copy-composer.ts +49 -267
  259. package/src/notifications/decision-engine.ts +16 -35
  260. package/src/notifications/home-feed-side-effect.ts +1 -6
  261. package/src/plugin-api/constants.ts +4 -0
  262. package/src/plugin-api/index.ts +40 -11
  263. package/src/plugin-api/types.ts +108 -0
  264. package/src/plugins/defaults/compaction/compact.ts +106 -0
  265. package/src/{daemon → plugins/defaults/compaction}/context-overflow-reducer.ts +250 -42
  266. package/src/plugins/defaults/compaction/corrected-target.ts +53 -0
  267. package/src/plugins/defaults/compaction/manager-store.ts +57 -0
  268. package/src/plugins/defaults/compaction/package.json +1 -2
  269. package/src/{context → plugins/defaults/compaction}/window-manager.ts +95 -25
  270. package/src/plugins/defaults/empty-response/package.json +0 -1
  271. package/src/plugins/defaults/history-repair/package.json +0 -1
  272. package/src/plugins/defaults/index.ts +156 -26
  273. package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +100 -52
  274. package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit.ts +285 -0
  275. package/src/plugins/defaults/memory-retrieval/injector-chain.ts +2 -2
  276. package/src/plugins/defaults/{injectors/register.ts → memory-retrieval/injectors.ts} +148 -73
  277. package/src/plugins/defaults/memory-retrieval/package.json +14 -0
  278. package/src/plugins/defaults/memory-retrieval/unified-turn-context.ts +223 -0
  279. package/src/plugins/defaults/memory-v3-shadow/__tests__/capabilities.test.ts +71 -0
  280. package/src/plugins/defaults/memory-v3-shadow/__tests__/dense.test.ts +181 -0
  281. package/src/plugins/defaults/memory-v3-shadow/__tests__/edge.test.ts +247 -0
  282. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/live-integration.test.ts +147 -134
  283. package/src/plugins/defaults/memory-v3-shadow/__tests__/maintain-job.test.ts +456 -0
  284. package/src/plugins/defaults/memory-v3-shadow/__tests__/orchestrate.test.ts +662 -0
  285. package/src/plugins/defaults/memory-v3-shadow/__tests__/pool-select.test.ts +306 -0
  286. package/src/plugins/defaults/memory-v3-shadow/__tests__/render-injection.test.ts +91 -0
  287. package/src/plugins/defaults/memory-v3-shadow/__tests__/section-dense-store.test.ts +402 -0
  288. package/src/plugins/defaults/memory-v3-shadow/__tests__/section-needle.test.ts +135 -0
  289. package/src/plugins/defaults/memory-v3-shadow/__tests__/sections.test.ts +125 -0
  290. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/selection-log-store.test.ts +74 -19
  291. package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-integration.test.ts +446 -0
  292. package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +592 -0
  293. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/types.test.ts +2 -24
  294. package/src/plugins/defaults/memory-v3-shadow/capabilities.ts +91 -0
  295. package/src/plugins/defaults/memory-v3-shadow/dense.ts +97 -0
  296. package/src/plugins/defaults/memory-v3-shadow/edge.ts +252 -0
  297. package/src/plugins/defaults/memory-v3-shadow/hooks/post-compact.ts +14 -0
  298. package/src/plugins/defaults/memory-v3-shadow/hooks/user-prompt-submit.ts +19 -0
  299. package/src/plugins/defaults/memory-v3-shadow/injector.ts +76 -0
  300. package/src/plugins/defaults/memory-v3-shadow/maintain-job.ts +555 -0
  301. package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +266 -0
  302. package/src/plugins/defaults/memory-v3-shadow/package.json +14 -0
  303. package/src/plugins/defaults/memory-v3-shadow/page-content.ts +71 -0
  304. package/src/plugins/defaults/memory-v3-shadow/pool-select.ts +204 -0
  305. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/render-injection.ts +16 -8
  306. package/src/plugins/defaults/memory-v3-shadow/section-dense-store.ts +236 -0
  307. package/src/plugins/defaults/memory-v3-shadow/section-needle.ts +200 -0
  308. package/src/plugins/defaults/memory-v3-shadow/sections.ts +115 -0
  309. package/src/plugins/defaults/memory-v3-shadow/selection-log-store.ts +156 -0
  310. package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +382 -0
  311. package/src/plugins/defaults/memory-v3-shadow/types.ts +92 -0
  312. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/working-set.ts +4 -1
  313. package/src/plugins/defaults/title-generate/package.json +0 -1
  314. package/src/plugins/defaults/tool-error/package.json +0 -1
  315. package/src/plugins/defaults/tool-result-truncate/package.json +0 -1
  316. package/src/plugins/external-api.ts +12 -2
  317. package/src/plugins/pipeline.ts +6 -293
  318. package/src/plugins/registry.ts +9 -37
  319. package/src/plugins/types.ts +76 -381
  320. package/src/plugins/user-loader.ts +30 -127
  321. package/src/prompts/__tests__/system-prompt.test.ts +6 -0
  322. package/src/prompts/system-prompt.ts +61 -10
  323. package/src/prompts/templates/BOOTSTRAP-ACTIVATION-RAIL.md +71 -4
  324. package/src/providers/anthropic/client.ts +9 -10
  325. package/src/providers/inference/kimi-cjk-token-ids.ts +493 -0
  326. package/src/providers/inference/logit-bias.ts +55 -0
  327. package/src/providers/model-catalog.ts +34 -0
  328. package/src/providers/openai/__tests__/vision-not-supported.test.ts +75 -0
  329. package/src/providers/openai/chat-completions-provider.ts +44 -1
  330. package/src/providers/retry.ts +22 -0
  331. package/src/providers/types.ts +6 -0
  332. package/src/runtime/__tests__/agent-wake.test.ts +555 -691
  333. package/src/runtime/__tests__/interactive-ui.test.ts +1 -1
  334. package/src/runtime/agent-wake.ts +108 -209
  335. package/src/runtime/assistant-event-hub.ts +1 -1
  336. package/src/runtime/channel-approvals.ts +1 -1
  337. package/src/runtime/interactive-ui.ts +1 -1
  338. package/src/runtime/routes/__tests__/acp-routes.test.ts +466 -55
  339. package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +1 -1
  340. package/src/runtime/routes/__tests__/plugins-routes.test.ts +423 -73
  341. package/src/runtime/routes/__tests__/stt-routes.test.ts +112 -0
  342. package/src/runtime/routes/__tests__/surface-action-routes.test.ts +5 -4
  343. package/src/runtime/routes/__tests__/surface-content-routes.test.ts +4 -1
  344. package/src/runtime/routes/acp-routes.test.ts +185 -32
  345. package/src/runtime/routes/acp-routes.ts +328 -30
  346. package/src/runtime/routes/app-management-routes.ts +3 -0
  347. package/src/runtime/routes/approval-routes.ts +1 -1
  348. package/src/runtime/routes/browser-routes.ts +1 -1
  349. package/src/runtime/routes/browser-tabs-routes.ts +6 -10
  350. package/src/runtime/routes/channel-verification-routes.ts +14 -5
  351. package/src/runtime/routes/conversation-cli-routes.ts +1 -1
  352. package/src/runtime/routes/conversation-list-routes.ts +1 -1
  353. package/src/runtime/routes/conversation-query-routes.ts +1 -1
  354. package/src/runtime/routes/conversation-routes.ts +30 -2
  355. package/src/runtime/routes/conversation-starter-routes.ts +13 -7
  356. package/src/runtime/routes/conversations-import-routes.ts +24 -7
  357. package/src/runtime/routes/host-app-control-routes.ts +1 -1
  358. package/src/runtime/routes/host-cu-routes.ts +1 -1
  359. package/src/runtime/routes/identity-routes.ts +18 -3
  360. package/src/runtime/routes/inbound-message-handler.ts +1 -1
  361. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +33 -34
  362. package/src/runtime/routes/inference-profile-session-handler.ts +11 -0
  363. package/src/runtime/routes/inference-profile-session-reaper.ts +6 -0
  364. package/src/runtime/routes/memory-v3-routes.ts +65 -305
  365. package/src/runtime/routes/playground/__tests__/force-compact.test.ts +1 -1
  366. package/src/runtime/routes/playground/helpers.ts +1 -1
  367. package/src/runtime/routes/plugins-routes.ts +337 -35
  368. package/src/runtime/routes/stt-routes.ts +45 -12
  369. package/src/runtime/routes/surface-conversation-resolver.ts +4 -3
  370. package/src/runtime/routes/work-items-routes.ts +2 -4
  371. package/src/runtime/routes/workspace-routes.ts +50 -15
  372. package/src/runtime/services/conversation-serializer.ts +1 -1
  373. package/src/runtime/verification-outbound-actions.ts +147 -2
  374. package/src/runtime/verification-templates.ts +29 -3
  375. package/src/services/published-app-updater.ts +30 -8
  376. package/src/signals/cancel.ts +2 -4
  377. package/src/subagent/manager.ts +21 -5
  378. package/src/telemetry/__tests__/activation-funnel.test.ts +95 -0
  379. package/src/telemetry/activation-funnel.ts +167 -0
  380. package/src/telemetry/types.ts +13 -0
  381. package/src/telemetry/usage-telemetry-reporter.test.ts +154 -0
  382. package/src/telemetry/usage-telemetry-reporter.ts +26 -1
  383. package/src/tools/acp/context.ts +20 -0
  384. package/src/tools/acp/list-agents.test.ts +9 -19
  385. package/src/tools/acp/list-agents.ts +3 -15
  386. package/src/tools/acp/spawn.test.ts +173 -202
  387. package/src/tools/acp/spawn.ts +37 -172
  388. package/src/tools/acp/steer.test.ts +105 -8
  389. package/src/tools/acp/steer.ts +48 -17
  390. package/src/tools/apps/executors.ts +166 -50
  391. package/src/tools/browser/browser-execution.ts +12 -2
  392. package/src/tools/filesystem/write.ts +34 -0
  393. package/src/tools/network/web-fetch.ts +65 -24
  394. package/src/tools/skills/load.ts +1 -1
  395. package/src/tools/subagent/spawn.ts +2 -4
  396. package/src/tools/ui-surface/definitions.ts +32 -5
  397. package/src/workspace/migrations/051-seed-conversation-summarization-callsite.ts +4 -5
  398. package/src/workspace/migrations/097-enable-adaptive-thinking-managed-profiles.ts +69 -45
  399. package/docs/plugins.md +0 -832
  400. package/examples/plugins/echo/register.ts +0 -143
  401. package/src/__tests__/circuit-breaker-pipeline.test.ts +0 -405
  402. package/src/__tests__/compaction-pipeline.test.ts +0 -210
  403. package/src/__tests__/compaction-timeout-recovery.test.ts +0 -251
  404. package/src/__tests__/overflow-reduce-pipeline.test.ts +0 -667
  405. package/src/__tests__/pipeline-runner.test.ts +0 -554
  406. package/src/daemon/wake-target-adapter.ts +0 -253
  407. package/src/memory/v3/__tests__/assign.test.ts +0 -242
  408. package/src/memory/v3/__tests__/capabilities.test.ts +0 -118
  409. package/src/memory/v3/__tests__/core.test.ts +0 -39
  410. package/src/memory/v3/__tests__/health.test.ts +0 -219
  411. package/src/memory/v3/__tests__/maintain-job.test.ts +0 -288
  412. package/src/memory/v3/__tests__/needle.test.ts +0 -107
  413. package/src/memory/v3/__tests__/orchestrate.test.ts +0 -436
  414. package/src/memory/v3/__tests__/provider-blocks.test.ts +0 -13
  415. package/src/memory/v3/__tests__/reconcile.test.ts +0 -274
  416. package/src/memory/v3/__tests__/render-injection.test.ts +0 -61
  417. package/src/memory/v3/__tests__/router.test.ts +0 -332
  418. package/src/memory/v3/__tests__/selector.test.ts +0 -470
  419. package/src/memory/v3/__tests__/shadow-plugin.test.ts +0 -432
  420. package/src/memory/v3/__tests__/snapshot.test.ts +0 -168
  421. package/src/memory/v3/__tests__/tree.test.ts +0 -192
  422. package/src/memory/v3/assign.ts +0 -268
  423. package/src/memory/v3/capabilities.ts +0 -124
  424. package/src/memory/v3/core.ts +0 -26
  425. package/src/memory/v3/health.ts +0 -0
  426. package/src/memory/v3/maintain-job.ts +0 -314
  427. package/src/memory/v3/needle.ts +0 -115
  428. package/src/memory/v3/orchestrate.ts +0 -126
  429. package/src/memory/v3/page-content.ts +0 -34
  430. package/src/memory/v3/provider-blocks.ts +0 -26
  431. package/src/memory/v3/reconcile.ts +0 -523
  432. package/src/memory/v3/router.ts +0 -190
  433. package/src/memory/v3/selection-log-store.ts +0 -84
  434. package/src/memory/v3/selector.ts +0 -226
  435. package/src/memory/v3/shadow-plugin.ts +0 -411
  436. package/src/memory/v3/snapshot.ts +0 -209
  437. package/src/memory/v3/tree.ts +0 -174
  438. package/src/memory/v3/types.ts +0 -59
  439. package/src/notifications/__tests__/emit-signal-home-feed.test.ts +0 -187
  440. package/src/plugins/defaults/circuit-breaker/middlewares/circuitBreaker.ts +0 -93
  441. package/src/plugins/defaults/circuit-breaker/package.json +0 -15
  442. package/src/plugins/defaults/circuit-breaker/register.ts +0 -39
  443. package/src/plugins/defaults/compaction/middlewares/compaction.ts +0 -25
  444. package/src/plugins/defaults/compaction/register.ts +0 -35
  445. package/src/plugins/defaults/compaction/terminal.ts +0 -73
  446. package/src/plugins/defaults/empty-response/register.ts +0 -23
  447. package/src/plugins/defaults/history-repair/register.ts +0 -24
  448. package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit-temp.ts +0 -216
  449. package/src/plugins/defaults/overflow-reduce/middlewares/overflowReduce.ts +0 -126
  450. package/src/plugins/defaults/overflow-reduce/package.json +0 -15
  451. package/src/plugins/defaults/overflow-reduce/register.ts +0 -42
  452. package/src/plugins/defaults/title-generate/register.ts +0 -35
  453. package/src/plugins/defaults/tool-error/register.ts +0 -23
  454. package/src/plugins/defaults/tool-result-truncate/register.ts +0 -24
  455. package/src/proactive-artifact/aux-message-injector.ts +0 -97
  456. package/src/proactive-artifact/decision.test.ts +0 -226
  457. package/src/proactive-artifact/decision.ts +0 -165
  458. package/src/proactive-artifact/index.ts +0 -7
  459. package/src/proactive-artifact/job.test.ts +0 -962
  460. package/src/proactive-artifact/job.ts +0 -372
  461. package/src/proactive-artifact/message-copy.ts +0 -58
  462. package/src/proactive-artifact/trigger-state.test.ts +0 -286
  463. package/src/proactive-artifact/trigger-state.ts +0 -123
  464. package/src/util/map-limit.ts +0 -27
  465. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/fixtures/eval-turns.json +0 -0
  466. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/fixtures/live-turns.json +0 -0
  467. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/working-set-eviction.test.ts +0 -0
  468. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/working-set-skeleton.test.ts +0 -0
  469. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/README.md +0 -0
  470. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/assignments.json +0 -0
  471. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/core.json +0 -0
  472. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-a/topic-x.md +0 -0
  473. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-a/topic-y.md +0 -0
  474. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-b/topic-z.md +0 -0
  475. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/llm-retry.ts +0 -0
@@ -0,0 +1,109 @@
1
+ import { describe, expect, test } from "bun:test";
2
+
3
+ import { preModelCallSanitize } from "../agent/loop.js";
4
+ import type { Message } from "../providers/types.js";
5
+
6
+ /**
7
+ * `preModelCallSanitize` is the loop's single pre-send transform: it converts
8
+ * historical `web_search_tool_result` blocks to text alongside the media and
9
+ * AX-tree strips, so every provider call — first call, post-compaction, and
10
+ * recovery reruns — is sanitized in one place. These tests guard that the
11
+ * helper actually performs the web-search conversion and is idempotent.
12
+ */
13
+ describe("preModelCallSanitize", () => {
14
+ test("passes through history with nothing to sanitize", () => {
15
+ // GIVEN a plain conversation with no media, AX trees, or web-search blocks
16
+ const messages: Message[] = [
17
+ { role: "user", content: [{ type: "text", text: "Hello" }] },
18
+ { role: "assistant", content: [{ type: "text", text: "Hi" }] },
19
+ ];
20
+
21
+ // WHEN the loop sanitizes the outbound history
22
+ const result = preModelCallSanitize(messages);
23
+
24
+ // THEN the history is returned unchanged
25
+ expect(result).toEqual(messages);
26
+ });
27
+
28
+ test("converts historical web_search_tool_result blocks to text summaries", () => {
29
+ // GIVEN an assistant turn whose web_search_tool_result carries an opaque
30
+ // encrypted_content token that would be rejected if replayed
31
+ const messages: Message[] = [
32
+ { role: "user", content: [{ type: "text", text: "Search cats" }] },
33
+ {
34
+ role: "assistant",
35
+ content: [
36
+ {
37
+ type: "server_tool_use",
38
+ id: "stu_1",
39
+ name: "web_search",
40
+ input: { query: "cats" },
41
+ },
42
+ {
43
+ type: "web_search_tool_result",
44
+ tool_use_id: "stu_1",
45
+ content: [
46
+ {
47
+ type: "web_search_result",
48
+ url: "https://cats.com",
49
+ title: "Cats!",
50
+ encrypted_content: "expired_token_1",
51
+ },
52
+ ],
53
+ },
54
+ ],
55
+ },
56
+ ];
57
+
58
+ // WHEN the loop sanitizes the outbound history
59
+ const result = preModelCallSanitize(messages);
60
+
61
+ // THEN the opaque block is replaced with a plaintext title+URL summary and
62
+ // the paired server_tool_use is dropped, so no expired token is replayed
63
+ const assistantMsg = result[1];
64
+ expect(assistantMsg.content.map((b) => b.type)).toEqual(["text"]);
65
+ const summary = assistantMsg.content[0];
66
+ expect(summary.type).toBe("text");
67
+ if (summary.type === "text") {
68
+ expect(summary.text).toContain("Cats!");
69
+ expect(summary.text).toContain("https://cats.com");
70
+ expect(summary.text).not.toContain("expired_token_1");
71
+ }
72
+ });
73
+
74
+ test("is idempotent — re-sanitizing already-sanitized history is a no-op", () => {
75
+ // GIVEN history that has already been sanitized once
76
+ const messages: Message[] = [
77
+ {
78
+ role: "assistant",
79
+ content: [
80
+ {
81
+ type: "server_tool_use",
82
+ id: "stu_A",
83
+ name: "web_search",
84
+ input: { query: "alpha" },
85
+ },
86
+ {
87
+ type: "web_search_tool_result",
88
+ tool_use_id: "stu_A",
89
+ content: [
90
+ {
91
+ type: "web_search_result",
92
+ url: "https://a.example",
93
+ title: "A",
94
+ encrypted_content: "tok_A",
95
+ },
96
+ ],
97
+ },
98
+ ],
99
+ },
100
+ ];
101
+ const once = preModelCallSanitize(messages);
102
+
103
+ // WHEN it is sanitized a second time (every outbound call re-runs the helper)
104
+ const twice = preModelCallSanitize(once);
105
+
106
+ // THEN the second pass changes nothing
107
+ expect(twice).toEqual(once);
108
+ });
109
+ });
@@ -0,0 +1,138 @@
1
+ /**
2
+ * Tests that the auto-redeploy path deploys the app's *effective* HTML
3
+ * (dist/index.html for multifile apps) rather than the empty `htmlDefinition`.
4
+ */
5
+
6
+ import { beforeEach, describe, expect, mock, test } from "bun:test";
7
+
8
+ import type { AppDefinition } from "../memory/app-store.js";
9
+
10
+ // ── Mocks ───────────────────────────────────────────────────────────────
11
+
12
+ let mockApp: AppDefinition | null = null;
13
+ let mockIsMultifile = false;
14
+ let mockEffectiveHtml = "";
15
+ // A directory that does not exist on disk, so the multifile dist-existence
16
+ // guard reads `false` from the real fs without mocking node:fs (which would
17
+ // leak across test files).
18
+ let mockAppDir = "/tmp/__vellum_test_nonexistent__/app-1";
19
+
20
+ mock.module("../memory/app-store.js", () => ({
21
+ getApp: () => mockApp,
22
+ getAppDirPath: () => mockAppDir,
23
+ isMultifileApp: () => mockIsMultifile,
24
+ resolveEffectiveAppHtml: () => mockEffectiveHtml,
25
+ }));
26
+
27
+ let mockPublishedPage: {
28
+ id: string;
29
+ projectSlug?: string;
30
+ htmlHash: string;
31
+ } | null = null;
32
+ const updatePublishedPageSpy = mock(() => {});
33
+
34
+ mock.module("../memory/published-pages-store.js", () => ({
35
+ getActivePublishedPageByAppId: () => mockPublishedPage,
36
+ updatePublishedPage: updatePublishedPageSpy,
37
+ }));
38
+
39
+ const deploySpy = mock(async (_args: { html: string; name: string }) => ({
40
+ deploymentId: "dep-1",
41
+ url: "https://example.vercel.app",
42
+ }));
43
+
44
+ mock.module("../services/vercel-deploy.js", () => ({
45
+ deployHtmlToVercel: deploySpy,
46
+ }));
47
+
48
+ // credentialBroker.serverUse invokes execute(token) and reports success.
49
+ mock.module("../tools/credentials/broker.js", () => ({
50
+ credentialBroker: {
51
+ serverUse: async ({
52
+ execute,
53
+ }: {
54
+ execute: (token: string) => Promise<unknown>;
55
+ }) => {
56
+ await execute("test-token");
57
+ return { success: true };
58
+ },
59
+ },
60
+ }));
61
+
62
+ const { updatePublishedAppDeployment } =
63
+ await import("../services/published-app-updater.js");
64
+
65
+ function makeApp(overrides: Partial<AppDefinition> = {}): AppDefinition {
66
+ return {
67
+ id: "app-1",
68
+ name: "App",
69
+ schemaJson: "{}",
70
+ htmlDefinition: "",
71
+ createdAt: 1,
72
+ updatedAt: 2,
73
+ ...overrides,
74
+ };
75
+ }
76
+
77
+ // ── Tests ───────────────────────────────────────────────────────────────
78
+
79
+ describe("updatePublishedAppDeployment", () => {
80
+ beforeEach(() => {
81
+ mockApp = makeApp();
82
+ mockIsMultifile = false;
83
+ mockEffectiveHtml = "";
84
+ mockPublishedPage = { id: "pp-1", projectSlug: "slug", htmlHash: "old" };
85
+ mockAppDir = "/tmp/__vellum_test_nonexistent__/app-1";
86
+ deploySpy.mockClear();
87
+ updatePublishedPageSpy.mockClear();
88
+ });
89
+
90
+ test("deploys the resolved effective HTML, not the empty htmlDefinition", async () => {
91
+ // htmlDefinition is "" (as it is for every multifile app); the real
92
+ // content comes from resolveEffectiveAppHtml. isMultifile=false here keeps
93
+ // the dist guard out of the way so the assertion targets the html source.
94
+ mockApp = makeApp({ htmlDefinition: "" });
95
+ mockEffectiveHtml = "<html><body>real app</body></html>";
96
+
97
+ await updatePublishedAppDeployment("app-1");
98
+
99
+ expect(deploySpy).toHaveBeenCalledTimes(1);
100
+ expect(deploySpy.mock.calls[0][0].html).toBe(
101
+ "<html><body>real app</body></html>",
102
+ );
103
+ });
104
+
105
+ test("skips deploy when a multifile app has no compiled output", async () => {
106
+ mockIsMultifile = true;
107
+ mockApp = makeApp({ formatVersion: 2 });
108
+ mockEffectiveHtml = "<p>App compilation failed.</p>";
109
+ // mockAppDir does not exist → dist/index.html is absent.
110
+
111
+ await updatePublishedAppDeployment("app-1");
112
+
113
+ expect(deploySpy).not.toHaveBeenCalled();
114
+ });
115
+
116
+ test("skips deploy when content hash is unchanged", async () => {
117
+ const html = "<html>same</html>";
118
+ mockEffectiveHtml = html;
119
+ const { createHash } = await import("node:crypto");
120
+ mockPublishedPage = {
121
+ id: "pp-1",
122
+ htmlHash: createHash("sha256").update(html).digest("hex"),
123
+ };
124
+
125
+ await updatePublishedAppDeployment("app-1");
126
+
127
+ expect(deploySpy).not.toHaveBeenCalled();
128
+ });
129
+
130
+ test("skips deploy when the app has no active published page", async () => {
131
+ mockPublishedPage = null;
132
+ mockEffectiveHtml = "<html>x</html>";
133
+
134
+ await updatePublishedAppDeployment("app-1");
135
+
136
+ expect(deploySpy).not.toHaveBeenCalled();
137
+ });
138
+ });
@@ -27,7 +27,7 @@ mock.module("../config/env.js", () => ({
27
27
  }));
28
28
 
29
29
  const _conversationMocks = new Map<string, unknown>();
30
- mock.module("../daemon/conversation-store.js", () => ({
30
+ mock.module("../daemon/conversation-registry.js", () => ({
31
31
  findConversation: (id: string) => _conversationMocks.get(id),
32
32
  }));
33
33
 
@@ -91,11 +91,14 @@ mock.module("../config/loader.js", () => ({
91
91
  let _conversationFactory: (() => Conversation) | undefined;
92
92
  let _approvalGenerator: unknown;
93
93
 
94
- mock.module("../daemon/conversation-store.js", () => ({
94
+ mock.module("../daemon/conversation-registry.js", () => ({
95
95
  findConversation: () => {
96
96
  if (!_conversationFactory) return undefined;
97
97
  return _conversationFactory();
98
98
  },
99
+ }));
100
+
101
+ mock.module("../daemon/conversation-store.js", () => ({
99
102
  getOrCreateConversation: async (..._args: unknown[]) => {
100
103
  if (!_conversationFactory)
101
104
  throw new Error("_conversationFactory not set in test");
@@ -5,6 +5,8 @@
5
5
  * parses it via the real frontmatter parser, and verifies that `skillFlagKey()`
6
6
  * returns the correct key and `resolveSkillStates()` correctly gates the skill.
7
7
  */
8
+ import { readFileSync } from "node:fs";
9
+ import { fileURLToPath } from "node:url";
8
10
  import { afterEach, beforeEach, describe, expect, test } from "bun:test";
9
11
 
10
12
  import { isAssistantFeatureFlagEnabled } from "../config/assistant-feature-flags.js";
@@ -225,3 +227,32 @@ describe("frontmatter feature-flag integration", () => {
225
227
  expect(resolvedOff.length).toBe(0);
226
228
  });
227
229
  });
230
+
231
+ // ---------------------------------------------------------------------------
232
+ // Bundled ACP skill: discoverability when ACP is disabled
233
+ // ---------------------------------------------------------------------------
234
+
235
+ describe("bundled acp skill discoverability", () => {
236
+ test("acp skill resolves with no frontmatter flag gate", () => {
237
+ // The ACP skill carries its own first-time-setup instructions and is
238
+ // always discoverable: it has no frontmatter feature-flag gate.
239
+ const skillMdPath = fileURLToPath(
240
+ new URL("../config/bundled-skills/acp/SKILL.md", import.meta.url),
241
+ );
242
+ const skillMd = readFileSync(skillMdPath, "utf8");
243
+
244
+ const skill = buildSkillSummary("acp", skillMd);
245
+ expect(skill).not.toBeNull();
246
+ expect(skill!.featureFlag).toBeUndefined();
247
+ expect(skillFlagKey(skill!)).toBeUndefined();
248
+
249
+ const config = makeConfig({
250
+ acp: { maxConcurrentSessions: 4, agents: {} },
251
+ });
252
+
253
+ const resolved = resolveSkillStates([skill!], config);
254
+ expect(resolved.length).toBe(1);
255
+ expect(resolved[0].summary.id).toBe("acp");
256
+ expect(resolved[0].state).toBe("enabled");
257
+ });
258
+ });
@@ -14,7 +14,7 @@ import type { Message } from "../providers/types.js";
14
14
  /**
15
15
  * Minimal reproduction of repairPendingToolUseBlocks logic for direct
16
16
  * unit testing. The real implementation lives in conversation-process.ts.
17
- * This mirrors it exactly to avoid needing the full ProcessConversationContext.
17
+ * This mirrors it exactly to avoid needing the full Conversation.
18
18
  */
19
19
  function repairPendingToolUseBlocks(messages: Message[]): Message[] {
20
20
  if (messages.length === 0) return messages;
@@ -174,7 +174,7 @@ import { LLMSchema } from "../config/schemas/llm.js";
174
174
  import {
175
175
  clearConversations,
176
176
  setConversation,
177
- } from "../daemon/conversation-store.js";
177
+ } from "../daemon/conversation-registry.js";
178
178
  import { CallSiteRoutingProvider } from "../providers/call-site-routing.js";
179
179
  import { SubagentManager } from "../subagent/manager.js";
180
180
 
@@ -18,6 +18,7 @@ function msg(role: string, content: unknown[]): MessageRow {
18
18
  content: JSON.stringify(content),
19
19
  createdAt: Date.now(),
20
20
  metadata: null,
21
+ clientMessageId: null,
21
22
  };
22
23
  }
23
24
 
@@ -26,10 +27,19 @@ describe("parseSubagentMessages", () => {
26
27
  const messages = [
27
28
  msg("user", [{ type: "text", text: "Do something" }]),
28
29
  msg("assistant", [
29
- { type: "tool_use", id: "t1", name: "web_search", input: { query: "test" } },
30
+ {
31
+ type: "tool_use",
32
+ id: "t1",
33
+ name: "web_search",
34
+ input: { query: "test" },
35
+ },
30
36
  ]),
31
37
  msg("user", [
32
- { type: "tool_result", tool_use_id: "t1", content: "Search results here" },
38
+ {
39
+ type: "tool_result",
40
+ tool_use_id: "t1",
41
+ content: "Search results here",
42
+ },
33
43
  ]),
34
44
  ];
35
45
 
@@ -44,7 +54,12 @@ describe("parseSubagentMessages", () => {
44
54
  const messages = [
45
55
  msg("user", [{ type: "text", text: "Do something" }]),
46
56
  msg("assistant", [
47
- { type: "tool_use", id: "t2", name: "file_read", input: { file_path: "/tmp/test.txt" } },
57
+ {
58
+ type: "tool_use",
59
+ id: "t2",
60
+ name: "file_read",
61
+ input: { file_path: "/tmp/test.txt" },
62
+ },
48
63
  ]),
49
64
  msg("user", [
50
65
  {
@@ -69,11 +84,14 @@ describe("parseSubagentMessages", () => {
69
84
  const messages = [
70
85
  msg("user", [{ type: "text", text: "Do something" }]),
71
86
  msg("assistant", [
72
- { type: "tool_use", id: "t3", name: "bash", input: { command: "echo hi" } },
73
- ]),
74
- msg("user", [
75
- { type: "tool_result", tool_use_id: "t3", content: null },
87
+ {
88
+ type: "tool_use",
89
+ id: "t3",
90
+ name: "bash",
91
+ input: { command: "echo hi" },
92
+ },
76
93
  ]),
94
+ msg("user", [{ type: "tool_result", tool_use_id: "t3", content: null }]),
77
95
  ];
78
96
 
79
97
  const result = parseSubagentMessages("sub-1", messages);
@@ -11,7 +11,7 @@ const capturedNotifications: {
11
11
  message: string;
12
12
  }[] = [];
13
13
 
14
- mock.module("../daemon/conversation-store.js", () => ({
14
+ mock.module("../daemon/conversation-registry.js", () => ({
15
15
  findConversation: (id: string) => ({
16
16
  enqueueMessage: (options: { content: string }) => {
17
17
  capturedNotifications.push({
@@ -23,8 +23,6 @@ mock.module("../daemon/conversation-store.js", () => ({
23
23
  persistUserMessage: async () => ({ id: "mock-msg", deduplicated: false }),
24
24
  runAgentLoop: async () => {},
25
25
  }),
26
- addConversation: () => {},
27
- removeConversation: () => {},
28
26
  }));
29
27
 
30
28
  mock.module("../runtime/assistant-event-hub.js", () => ({
@@ -4,7 +4,7 @@ import {
4
4
  clearConversations,
5
5
  findConversation,
6
6
  setConversation,
7
- } from "../daemon/conversation-store.js";
7
+ } from "../daemon/conversation-registry.js";
8
8
  import type { ServerMessage } from "../daemon/message-protocol.js";
9
9
  import type { Message } from "../providers/types.js";
10
10
  import { SubagentManager } from "../subagent/manager.js";
@@ -11,7 +11,7 @@ const capturedNotifications: {
11
11
  message: string;
12
12
  }[] = [];
13
13
 
14
- mock.module("../daemon/conversation-store.js", () => ({
14
+ mock.module("../daemon/conversation-registry.js", () => ({
15
15
  findConversation: (id: string) => ({
16
16
  enqueueMessage: (options: { content: string }) => {
17
17
  capturedNotifications.push({
@@ -23,8 +23,6 @@ mock.module("../daemon/conversation-store.js", () => ({
23
23
  persistUserMessage: async () => ({ id: "mock-msg", deduplicated: false }),
24
24
  runAgentLoop: async () => {},
25
25
  }),
26
- addConversation: () => {},
27
- removeConversation: () => {},
28
26
  }));
29
27
 
30
28
  mock.module("../runtime/assistant-event-hub.js", () => ({
@@ -36,7 +36,7 @@ mock.module("../memory/conversation-crud.js", () => ({
36
36
  */
37
37
  const capturedMessages: string[] = [];
38
38
 
39
- mock.module("../daemon/conversation-store.js", () => ({
39
+ mock.module("../daemon/conversation-registry.js", () => ({
40
40
  findConversation: (_id: string) => ({
41
41
  enqueueMessage: (options: { content: string }) => {
42
42
  capturedMessages.push(options.content);
@@ -45,8 +45,6 @@ mock.module("../daemon/conversation-store.js", () => ({
45
45
  persistUserMessage: async () => ({ id: "mock-msg", deduplicated: false }),
46
46
  runAgentLoop: async () => {},
47
47
  }),
48
- addConversation: () => {},
49
- removeConversation: () => {},
50
48
  }));
51
49
 
52
50
  mock.module("../runtime/assistant-event-hub.js", () => ({
@@ -32,7 +32,7 @@ mock.module("../memory/conversation-crud.js", () => ({
32
32
  import {
33
33
  clearConversations,
34
34
  setConversation,
35
- } from "../daemon/conversation-store.js";
35
+ } from "../daemon/conversation-registry.js";
36
36
  import type { Message } from "../providers/types.js";
37
37
  import { getSubagentManager } from "../subagent/index.js";
38
38
  import { executeSubagentSpawn } from "../tools/subagent/spawn.js";
@@ -51,9 +51,9 @@ import type {
51
51
  StopContext,
52
52
  UserPromptSubmitContext,
53
53
  } from "../plugin-api/types.js";
54
+ import { defaultTitleGeneratePlugin } from "../plugins/defaults/index.js";
54
55
  import stop from "../plugins/defaults/title-generate/hooks/stop.js";
55
56
  import userPromptSubmit from "../plugins/defaults/title-generate/hooks/user-prompt-submit.js";
56
- import { defaultTitleGeneratePlugin } from "../plugins/defaults/title-generate/register.js";
57
57
  import { runHook } from "../plugins/pipeline.js";
58
58
  import {
59
59
  registerPlugin,
@@ -76,6 +76,10 @@ function makeCtx(
76
76
  ];
77
77
  return {
78
78
  conversationId: "conv-1",
79
+ userMessageId: "msg-1",
80
+ requestId: "req-1",
81
+ modelProfileKey: null,
82
+ isNonInteractive: false,
79
83
  prompt: "first message",
80
84
  originalMessages: messages,
81
85
  latestMessages: messages,
@@ -18,10 +18,10 @@ import { beforeEach, describe, expect, test } from "bun:test";
18
18
 
19
19
  import { HOOKS } from "../plugin-api/constants.js";
20
20
  import type { PluginLogger, PostToolUseContext } from "../plugin-api/types.js";
21
+ import { defaultToolErrorPlugin } from "../plugins/defaults/index.js";
21
22
  import postToolUse, {
22
23
  TOOL_ERROR_NUDGE_TEXT,
23
24
  } from "../plugins/defaults/tool-error/hooks/post-tool-use.js";
24
- import { defaultToolErrorPlugin } from "../plugins/defaults/tool-error/register.js";
25
25
  import { runHook } from "../plugins/pipeline.js";
26
26
  import {
27
27
  registerPlugin,
@@ -16,8 +16,8 @@ import { beforeEach, describe, expect, test } from "bun:test";
16
16
 
17
17
  import { HOOKS } from "../plugin-api/constants.js";
18
18
  import type { PluginLogger, PostToolUseContext } from "../plugin-api/types.js";
19
+ import { defaultToolResultTruncatePlugin } from "../plugins/defaults/index.js";
19
20
  import postToolUse from "../plugins/defaults/tool-result-truncate/hooks/post-tool-use.js";
20
- import { defaultToolResultTruncatePlugin } from "../plugins/defaults/tool-result-truncate/register.js";
21
21
  import {
22
22
  truncateToolResult,
23
23
  TRUNCATION_SUFFIX,