@vellumai/assistant 0.8.8 → 0.8.9-staging.1

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 (340) hide show
  1. package/bun.lock +2 -2
  2. package/examples/plugins/echo/README.md +61 -60
  3. package/examples/plugins/echo/hooks/post-tool-use.ts +18 -0
  4. package/examples/plugins/echo/hooks/stop.ts +16 -0
  5. package/examples/plugins/echo/hooks/user-prompt-submit.ts +18 -0
  6. package/examples/plugins/echo/package.json +1 -2
  7. package/examples/plugins/echo/src/emit.ts +19 -0
  8. package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +7 -6
  9. package/openapi.yaml +236 -6
  10. package/package.json +2 -2
  11. package/src/__tests__/agent-loop-callsite-precedence.test.ts +69 -14
  12. package/src/__tests__/agent-loop-exit-reason.test.ts +185 -140
  13. package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +50 -35
  14. package/src/__tests__/agent-loop-output-hooks.test.ts +357 -0
  15. package/src/__tests__/agent-loop-override-profile.test.ts +25 -6
  16. package/src/__tests__/agent-loop-provider-error-recording.test.ts +41 -21
  17. package/src/__tests__/agent-loop-thinking.test.ts +36 -20
  18. package/src/__tests__/agent-loop.test.ts +441 -96
  19. package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +14 -14
  20. package/src/__tests__/agent-wake-override-profile.test.ts +17 -21
  21. package/src/__tests__/anthropic-provider.test.ts +1 -1
  22. package/src/__tests__/app-control-flow.test.ts +1 -1
  23. package/src/__tests__/app-dir-path-guard.test.ts +1 -0
  24. package/src/__tests__/approval-cascade.test.ts +5 -4
  25. package/src/__tests__/approval-routes-http.test.ts +4 -1
  26. package/src/__tests__/background-workers-disk-pressure.test.ts +1 -1
  27. package/src/__tests__/channel-approval-routes.test.ts +1 -1
  28. package/src/__tests__/channel-approvals.test.ts +1 -1
  29. package/src/__tests__/compaction-circuit.test.ts +258 -0
  30. package/src/__tests__/compaction-direct.test.ts +132 -0
  31. package/src/__tests__/compaction-events.test.ts +5 -5
  32. package/src/__tests__/conversation-abort-tool-results.test.ts +6 -4
  33. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +7 -10
  34. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +59 -103
  35. package/src/__tests__/conversation-agent-loop-overflow.test.ts +94 -189
  36. package/src/__tests__/conversation-agent-loop.test.ts +249 -490
  37. package/src/__tests__/conversation-clean-command.test.ts +5 -2
  38. package/src/__tests__/conversation-confirmation-signals.test.ts +5 -4
  39. package/src/__tests__/conversation-crud-inference-profile.test.ts +7 -9
  40. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +4 -4
  41. package/src/__tests__/conversation-process-callsite.test.ts +14 -14
  42. package/src/__tests__/conversation-provider-retry-repair.test.ts +18 -16
  43. package/src/__tests__/conversation-queue.test.ts +9 -9
  44. package/src/__tests__/conversation-runtime-assembly.test.ts +923 -231
  45. package/src/__tests__/conversation-runtime-workspace.test.ts +115 -20
  46. package/src/__tests__/conversation-slash-queue.test.ts +6 -4
  47. package/src/__tests__/conversation-slash-unknown.test.ts +6 -4
  48. package/src/__tests__/conversation-speed-override.test.ts +10 -9
  49. package/src/__tests__/conversation-starter-routes.test.ts +14 -6
  50. package/src/__tests__/conversation-workspace-cache-state.test.ts +23 -20
  51. package/src/__tests__/conversation-workspace-injection.test.ts +68 -6
  52. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +14 -11
  53. package/src/__tests__/conversations-import-system-filter.test.ts +101 -0
  54. package/src/__tests__/credential-security-invariants.test.ts +0 -1
  55. package/src/__tests__/db-acp-history.test.ts +101 -0
  56. package/src/__tests__/dynamic-page-surface.test.ts +31 -0
  57. package/src/__tests__/empty-response-hook.test.ts +1 -1
  58. package/src/__tests__/file-write-tool.test.ts +63 -0
  59. package/src/__tests__/gateway-only-guard.test.ts +12 -2
  60. package/src/__tests__/guardian-grant-minting.test.ts +1 -1
  61. package/src/__tests__/guardian-routing-invariants.test.ts +2 -4
  62. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +1 -1
  63. package/src/__tests__/heartbeat-disk-pressure.test.ts +1 -0
  64. package/src/__tests__/heartbeat-service.test.ts +1 -0
  65. package/src/__tests__/history-repair-hook.test.ts +1 -1
  66. package/src/__tests__/host-app-control-routes.test.ts +1 -1
  67. package/src/__tests__/host-cu-routes-targeted.test.ts +3 -3
  68. package/src/__tests__/inference-profile-reaper.test.ts +62 -0
  69. package/src/__tests__/inference-profile-session-handler.test.ts +86 -0
  70. package/src/__tests__/injector-background-turn.test.ts +13 -23
  71. package/src/__tests__/injector-chain.test.ts +268 -44
  72. package/src/__tests__/injector-disk-pressure.test.ts +210 -52
  73. package/src/__tests__/injector-document-comments.test.ts +97 -114
  74. package/src/__tests__/injector-pkb-v2-silenced.test.ts +2 -2
  75. package/src/__tests__/injector-v3-suppression.test.ts +4 -4
  76. package/src/__tests__/list-messages-client-message-id.test.ts +91 -0
  77. package/src/__tests__/list-messages-hidden-metadata.test.ts +38 -0
  78. package/src/__tests__/memory-retrieval-hook.test.ts +73 -6
  79. package/src/__tests__/memory-v2-static-injector.test.ts +86 -8
  80. package/src/__tests__/parallel-tool.benchmark.test.ts +35 -8
  81. package/src/__tests__/plugin-api-shim.test.ts +6 -9
  82. package/src/__tests__/plugin-bootstrap.test.ts +12 -23
  83. package/src/__tests__/plugin-registry.test.ts +3 -49
  84. package/src/__tests__/plugin-types.test.ts +0 -70
  85. package/src/__tests__/reaction-persistence.test.ts +1 -1
  86. package/src/__tests__/send-endpoint-busy.test.ts +4 -1
  87. package/src/__tests__/skill-feature-flags-integration.test.ts +33 -0
  88. package/src/__tests__/steer-tool-repair.test.ts +1 -1
  89. package/src/__tests__/subagent-call-site-routing.test.ts +1 -1
  90. package/src/__tests__/subagent-detail.test.ts +25 -7
  91. package/src/__tests__/subagent-fork-notifications.test.ts +1 -3
  92. package/src/__tests__/subagent-fork-spawn.test.ts +1 -1
  93. package/src/__tests__/subagent-manager-notify.test.ts +1 -3
  94. package/src/__tests__/subagent-notify-parent.test.ts +1 -3
  95. package/src/__tests__/subagent-spawn-tool-fork.test.ts +1 -1
  96. package/src/__tests__/title-generate-hook.test.ts +1 -1
  97. package/src/__tests__/tool-error-hook.test.ts +1 -1
  98. package/src/__tests__/tool-result-truncate-hook.test.ts +1 -1
  99. package/src/__tests__/user-plugin-loader.test.ts +54 -286
  100. package/src/acp/__tests__/agent-process.test.ts +161 -0
  101. package/src/acp/__tests__/client-handler.test.ts +40 -0
  102. package/src/acp/__tests__/helpers/acp-history-db.ts +82 -0
  103. package/src/acp/__tests__/helpers/exec-file-stub.ts +101 -0
  104. package/src/acp/__tests__/prepare-agent-env.test.ts +137 -0
  105. package/src/acp/__tests__/session-manager-persistence.test.ts +95 -28
  106. package/src/acp/__tests__/session-manager-resume.test.ts +736 -0
  107. package/src/acp/agent-process.ts +61 -1
  108. package/src/acp/auto-install.test.ts +196 -0
  109. package/src/acp/auto-install.ts +177 -0
  110. package/src/acp/client-handler.ts +31 -0
  111. package/src/acp/feature-gate.test.ts +48 -0
  112. package/src/acp/feature-gate.ts +34 -0
  113. package/src/acp/prepare-agent-env.ts +83 -29
  114. package/src/acp/resolve-agent.test.ts +320 -7
  115. package/src/acp/resolve-agent.ts +182 -18
  116. package/src/acp/resume-hint.ts +25 -0
  117. package/src/acp/session-manager.ts +495 -73
  118. package/src/acp/types.ts +8 -0
  119. package/src/agent/compaction-circuit.ts +60 -102
  120. package/src/agent/loop.ts +390 -240
  121. package/src/api/responses/conversation-message.ts +14 -1
  122. package/src/approvals/guardian-request-resolvers.ts +1 -1
  123. package/src/background-wake/next-wake.ts +1 -0
  124. package/src/cli/commands/db/__tests__/repair.test.ts +3 -1
  125. package/src/cli/commands/plugins.ts +43 -37
  126. package/src/cli/lib/__tests__/install-from-github.test.ts +429 -111
  127. package/src/cli/lib/__tests__/plugin-catalog-cache.test.ts +196 -0
  128. package/src/cli/lib/__tests__/plugin-details.test.ts +372 -0
  129. package/src/cli/lib/__tests__/plugin-marketplace.test.ts +220 -0
  130. package/src/cli/lib/__tests__/search-plugins.test.ts +226 -32
  131. package/src/cli/lib/install-from-github.ts +464 -55
  132. package/src/cli/lib/plugin-catalog-cache.ts +84 -0
  133. package/src/cli/lib/plugin-details.ts +409 -0
  134. package/src/cli/lib/plugin-marketplace.ts +197 -0
  135. package/src/cli/lib/search-plugins.ts +195 -29
  136. package/src/config/__tests__/feature-flag-registry-guard.test.ts +2 -2
  137. package/src/config/acp-defaults.test.ts +10 -0
  138. package/src/config/acp-defaults.ts +6 -0
  139. package/src/config/bundled-skills/acp/SKILL.md +83 -31
  140. package/src/config/bundled-skills/acp/TOOLS.json +4 -4
  141. package/src/config/bundled-skills/app-builder/SKILL.md +224 -381
  142. package/src/config/bundled-skills/app-builder/TOOLS.json +29 -0
  143. package/src/config/bundled-skills/app-builder/references/DESIGN_SYSTEM.md +48 -0
  144. package/src/config/bundled-skills/app-builder/references/RESPONSIVE.md +57 -0
  145. package/src/config/bundled-skills/app-builder/references/SLIDES.md +38 -0
  146. package/src/config/bundled-skills/app-builder/tools/app-list.ts +62 -0
  147. package/src/config/bundled-skills/document-editor/SKILL.md +28 -23
  148. package/src/config/bundled-skills/document-editor/TOOLS.json +1 -1
  149. package/src/config/bundled-tool-registry.ts +2 -0
  150. package/src/config/feature-flag-registry.json +14 -5
  151. package/src/config/schemas/heartbeat.ts +9 -0
  152. package/src/context/strip-injections.ts +8 -2
  153. package/src/context/window-manager.ts +27 -13
  154. package/src/daemon/conversation-agent-loop-handlers.ts +10 -35
  155. package/src/daemon/conversation-agent-loop.ts +167 -1005
  156. package/src/daemon/conversation-lifecycle.ts +11 -255
  157. package/src/daemon/conversation-process.ts +8 -136
  158. package/src/daemon/conversation-registry.ts +159 -0
  159. package/src/daemon/conversation-runtime-assembly.ts +293 -392
  160. package/src/daemon/conversation-store.ts +9 -90
  161. package/src/daemon/conversation-surfaces.ts +24 -8
  162. package/src/daemon/conversation-workspace.ts +17 -0
  163. package/src/daemon/conversation.ts +383 -56
  164. package/src/daemon/external-plugins-bootstrap.ts +14 -19
  165. package/src/daemon/handlers/conversations.ts +3 -1
  166. package/src/daemon/handlers/skills.ts +4 -1
  167. package/src/daemon/host-proxy-preactivation.ts +1 -3
  168. package/src/daemon/lifecycle.ts +21 -0
  169. package/src/daemon/server.ts +2 -0
  170. package/src/daemon/wake-conversation-ops.ts +269 -0
  171. package/src/embedded/plugin-api.ts +2 -2
  172. package/src/export/__tests__/transcript-formatter.test.ts +5 -0
  173. package/src/heartbeat/__tests__/heartbeat-service.test.ts +3 -0
  174. package/src/heartbeat/heartbeat-run-store.ts +23 -1
  175. package/src/heartbeat/heartbeat-service.ts +26 -0
  176. package/src/ipc/__tests__/browser-ipc.test.ts +1 -1
  177. package/src/ipc/__tests__/ui-request-route.test.ts +3 -3
  178. package/src/ipc/skill-routes/__tests__/memory.test.ts +15 -0
  179. package/src/ipc/skill-routes/memory.ts +4 -2
  180. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +87 -0
  181. package/src/memory/conversation-crud.ts +29 -19
  182. package/src/memory/conversation-starter-checkpoints.ts +1 -0
  183. package/src/memory/db-init.ts +2 -0
  184. package/src/memory/job-handlers/conversation-starters.ts +13 -2
  185. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +5 -4
  186. package/src/memory/jobs-worker.ts +25 -1
  187. package/src/memory/migrations/272-acp-session-history-cwd.ts +36 -0
  188. package/src/memory/migrations/index.ts +1 -0
  189. package/src/memory/schema/acp.ts +4 -0
  190. package/src/memory/v2/__tests__/consolidation-job.test.ts +3 -3
  191. package/src/memory/v2/consolidation-job.ts +13 -4
  192. package/src/plugin-api/constants.ts +4 -0
  193. package/src/plugin-api/index.ts +6 -5
  194. package/src/plugin-api/types.ts +75 -0
  195. package/src/plugins/defaults/compaction/compact.ts +59 -0
  196. package/src/plugins/defaults/compaction/manager-store.ts +44 -0
  197. package/src/plugins/defaults/compaction/package.json +1 -2
  198. package/src/plugins/defaults/empty-response/package.json +0 -1
  199. package/src/plugins/defaults/history-repair/package.json +0 -1
  200. package/src/plugins/defaults/index.ts +135 -26
  201. package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +103 -38
  202. package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit-temp.ts +167 -56
  203. package/src/plugins/defaults/memory-retrieval/injector-chain.ts +2 -2
  204. package/src/plugins/defaults/{injectors/register.ts → memory-retrieval/injectors.ts} +148 -73
  205. package/src/plugins/defaults/memory-retrieval/unified-turn-context.ts +223 -0
  206. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/assign.test.ts +4 -4
  207. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/live-integration.test.ts +9 -6
  208. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/maintain-job.test.ts +5 -5
  209. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/orchestrate.test.ts +8 -5
  210. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/reconcile.test.ts +2 -2
  211. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/render-injection.test.ts +1 -1
  212. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/router.test.ts +10 -5
  213. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/selection-log-store.test.ts +8 -8
  214. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/selector.test.ts +5 -5
  215. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/shadow-plugin.test.ts +16 -17
  216. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/types.test.ts +2 -2
  217. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/assign.ts +9 -5
  218. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/capabilities.ts +5 -2
  219. package/src/plugins/defaults/memory-v3-shadow/hooks/post-compact.ts +14 -0
  220. package/src/plugins/defaults/memory-v3-shadow/hooks/user-prompt-submit.ts +19 -0
  221. package/src/plugins/defaults/memory-v3-shadow/injector.ts +75 -0
  222. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/maintain-job.ts +15 -8
  223. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/orchestrate.ts +2 -2
  224. package/src/plugins/defaults/memory-v3-shadow/package.json +14 -0
  225. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/page-content.ts +2 -2
  226. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/provider-blocks.ts +1 -1
  227. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/reconcile.ts +7 -3
  228. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/render-injection.ts +1 -1
  229. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/router.ts +5 -5
  230. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/selection-log-store.ts +4 -4
  231. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/selector.ts +7 -7
  232. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/shadow-plugin.ts +32 -94
  233. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/tree.ts +1 -1
  234. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/types.ts +1 -1
  235. package/src/plugins/defaults/title-generate/package.json +0 -1
  236. package/src/plugins/defaults/tool-error/package.json +0 -1
  237. package/src/plugins/defaults/tool-result-truncate/package.json +0 -1
  238. package/src/plugins/pipeline.ts +6 -293
  239. package/src/plugins/registry.ts +9 -37
  240. package/src/plugins/types.ts +76 -381
  241. package/src/plugins/user-loader.ts +30 -127
  242. package/src/proactive-artifact/aux-message-injector.ts +1 -1
  243. package/src/proactive-artifact/job.test.ts +1 -1
  244. package/src/prompts/__tests__/system-prompt.test.ts +6 -0
  245. package/src/prompts/templates/BOOTSTRAP-ACTIVATION-RAIL.md +35 -3
  246. package/src/runtime/__tests__/agent-wake.test.ts +555 -691
  247. package/src/runtime/__tests__/interactive-ui.test.ts +1 -1
  248. package/src/runtime/agent-wake.ts +108 -209
  249. package/src/runtime/assistant-event-hub.ts +1 -1
  250. package/src/runtime/channel-approvals.ts +1 -1
  251. package/src/runtime/interactive-ui.ts +1 -1
  252. package/src/runtime/routes/__tests__/acp-routes.test.ts +283 -55
  253. package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +1 -1
  254. package/src/runtime/routes/__tests__/plugins-routes.test.ts +398 -73
  255. package/src/runtime/routes/__tests__/surface-action-routes.test.ts +5 -4
  256. package/src/runtime/routes/__tests__/surface-content-routes.test.ts +4 -1
  257. package/src/runtime/routes/acp-routes.test.ts +89 -25
  258. package/src/runtime/routes/acp-routes.ts +81 -29
  259. package/src/runtime/routes/approval-routes.ts +1 -1
  260. package/src/runtime/routes/browser-routes.ts +1 -1
  261. package/src/runtime/routes/browser-tabs-routes.ts +6 -10
  262. package/src/runtime/routes/conversation-cli-routes.ts +1 -1
  263. package/src/runtime/routes/conversation-list-routes.ts +1 -1
  264. package/src/runtime/routes/conversation-query-routes.ts +1 -1
  265. package/src/runtime/routes/conversation-routes.ts +28 -2
  266. package/src/runtime/routes/conversation-starter-routes.ts +13 -7
  267. package/src/runtime/routes/conversations-import-routes.ts +24 -7
  268. package/src/runtime/routes/host-app-control-routes.ts +1 -1
  269. package/src/runtime/routes/host-cu-routes.ts +1 -1
  270. package/src/runtime/routes/identity-routes.ts +18 -3
  271. package/src/runtime/routes/inbound-message-handler.ts +1 -1
  272. package/src/runtime/routes/inference-profile-session-handler.ts +11 -0
  273. package/src/runtime/routes/inference-profile-session-reaper.ts +6 -0
  274. package/src/runtime/routes/memory-v3-routes.ts +16 -6
  275. package/src/runtime/routes/playground/helpers.ts +1 -1
  276. package/src/runtime/routes/plugins-routes.ts +336 -35
  277. package/src/runtime/routes/surface-conversation-resolver.ts +4 -3
  278. package/src/runtime/routes/work-items-routes.ts +2 -4
  279. package/src/runtime/services/conversation-serializer.ts +1 -1
  280. package/src/signals/cancel.ts +2 -4
  281. package/src/subagent/manager.ts +21 -5
  282. package/src/tools/acp/context.ts +20 -0
  283. package/src/tools/acp/list-agents.test.ts +7 -1
  284. package/src/tools/acp/spawn.test.ts +158 -55
  285. package/src/tools/acp/spawn.ts +47 -72
  286. package/src/tools/acp/steer.test.ts +105 -8
  287. package/src/tools/acp/steer.ts +48 -17
  288. package/src/tools/apps/executors.ts +13 -8
  289. package/src/tools/filesystem/write.ts +34 -0
  290. package/src/tools/subagent/spawn.ts +2 -4
  291. package/src/tools/ui-surface/definitions.ts +25 -5
  292. package/src/workspace/migrations/051-seed-conversation-summarization-callsite.ts +4 -5
  293. package/src/workspace/migrations/097-enable-adaptive-thinking-managed-profiles.ts +69 -45
  294. package/docs/plugins.md +0 -832
  295. package/examples/plugins/echo/register.ts +0 -143
  296. package/src/__tests__/circuit-breaker-pipeline.test.ts +0 -405
  297. package/src/__tests__/compaction-pipeline.test.ts +0 -210
  298. package/src/__tests__/compaction-timeout-recovery.test.ts +0 -251
  299. package/src/__tests__/overflow-reduce-pipeline.test.ts +0 -667
  300. package/src/__tests__/pipeline-runner.test.ts +0 -554
  301. package/src/__tests__/plugin-external-api.test.ts +0 -68
  302. package/src/daemon/wake-target-adapter.ts +0 -253
  303. package/src/plugins/defaults/circuit-breaker/middlewares/circuitBreaker.ts +0 -93
  304. package/src/plugins/defaults/circuit-breaker/package.json +0 -15
  305. package/src/plugins/defaults/circuit-breaker/register.ts +0 -39
  306. package/src/plugins/defaults/compaction/middlewares/compaction.ts +0 -25
  307. package/src/plugins/defaults/compaction/register.ts +0 -35
  308. package/src/plugins/defaults/compaction/terminal.ts +0 -73
  309. package/src/plugins/defaults/empty-response/register.ts +0 -23
  310. package/src/plugins/defaults/history-repair/register.ts +0 -24
  311. package/src/plugins/defaults/overflow-reduce/middlewares/overflowReduce.ts +0 -126
  312. package/src/plugins/defaults/overflow-reduce/package.json +0 -15
  313. package/src/plugins/defaults/overflow-reduce/register.ts +0 -42
  314. package/src/plugins/defaults/title-generate/register.ts +0 -35
  315. package/src/plugins/defaults/tool-error/register.ts +0 -23
  316. package/src/plugins/defaults/tool-result-truncate/register.ts +0 -24
  317. package/src/plugins/external-api.ts +0 -104
  318. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/capabilities.test.ts +0 -0
  319. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/core.test.ts +0 -0
  320. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/fixtures/eval-turns.json +0 -0
  321. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/fixtures/live-turns.json +0 -0
  322. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/health.test.ts +0 -0
  323. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/needle.test.ts +0 -0
  324. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/provider-blocks.test.ts +0 -0
  325. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/snapshot.test.ts +0 -0
  326. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/tree.test.ts +0 -0
  327. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/working-set-eviction.test.ts +0 -0
  328. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/working-set-skeleton.test.ts +0 -0
  329. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/core.ts +0 -0
  330. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/README.md +0 -0
  331. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/assignments.json +0 -0
  332. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/core.json +0 -0
  333. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-a/topic-x.md +0 -0
  334. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-a/topic-y.md +0 -0
  335. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-b/topic-z.md +0 -0
  336. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/health.ts +0 -0
  337. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/llm-retry.ts +0 -0
  338. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/needle.ts +0 -0
  339. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/snapshot.ts +0 -0
  340. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/working-set.ts +0 -0
@@ -25,20 +25,20 @@
25
25
 
26
26
  import { beforeEach, describe, expect, mock, test } from "bun:test";
27
27
 
28
+ import { stripAllMemoryInjections } from "../../../../memory/graph/conversation-graph-memory.js";
28
29
  import type {
29
30
  ContentBlock,
30
31
  Message,
31
32
  Provider,
32
33
  ProviderResponse,
33
- } from "../../../providers/types.js";
34
- import { stripAllMemoryInjections } from "../../graph/conversation-graph-memory.js";
34
+ } from "../../../../providers/types.js";
35
35
  import type { NeedleIndex } from "../needle.js";
36
36
  import type {
37
37
  LeafNode,
38
38
  LeafPath,
39
39
  LeafTree,
40
+ MemoryRoutingTurn,
40
41
  Slug,
41
- TurnContext,
42
42
  } from "../types.js";
43
43
  import liveTurns from "./fixtures/live-turns.json" with { type: "json" };
44
44
 
@@ -49,13 +49,13 @@ import liveTurns from "./fixtures/live-turns.json" with { type: "json" };
49
49
 
50
50
  let providerStub: Provider | null = null;
51
51
 
52
- mock.module("../../../providers/provider-send-message.js", () => ({
52
+ mock.module("../../../../providers/provider-send-message.js", () => ({
53
53
  getConfiguredProvider: async () => providerStub,
54
54
  extractToolUse: (response: ProviderResponse) =>
55
55
  response.content.find((b) => b.type === "tool_use"),
56
56
  }));
57
57
 
58
- mock.module("../../../util/logger.js", () => ({
58
+ mock.module("../../../../util/logger.js", () => ({
59
59
  getLogger: () =>
60
60
  new Proxy({} as Record<string, unknown>, {
61
61
  get: (_t, prop) => (prop === "child" ? () => ({}) : () => {}),
@@ -117,7 +117,10 @@ const contentOf = async (slug: Slug): Promise<string> => `body for ${slug}`;
117
117
  /** Needle that never hits — routing alone drives the open set in this fixture. */
118
118
  const emptyNeedle: NeedleIndex = { query: () => [] };
119
119
 
120
- function makeTurn(turnNumber: number, currentMessage: string): TurnContext {
120
+ function makeTurn(
121
+ turnNumber: number,
122
+ currentMessage: string,
123
+ ): MemoryRoutingTurn {
121
124
  return {
122
125
  conversationId: "conv-xyz",
123
126
  turnNumber,
@@ -3,11 +3,11 @@ import { tmpdir } from "node:os";
3
3
  import { join } from "node:path";
4
4
  import { afterEach, beforeEach, describe, expect, test } from "bun:test";
5
5
 
6
- import { setOverridesForTesting } from "../../../__tests__/feature-flag-test-helpers.js";
7
- import type { AssistantConfig } from "../../../config/types.js";
8
- import type { MemoryJob } from "../../jobs-store.js";
9
- import { readPage, writePage } from "../../v2/page-store.js";
10
- import type { ConceptPage } from "../../v2/types.js";
6
+ import { setOverridesForTesting } from "../../../../__tests__/feature-flag-test-helpers.js";
7
+ import type { AssistantConfig } from "../../../../config/types.js";
8
+ import type { MemoryJob } from "../../../../memory/jobs-store.js";
9
+ import { readPage, writePage } from "../../../../memory/v2/page-store.js";
10
+ import type { ConceptPage } from "../../../../memory/v2/types.js";
11
11
  import type { AssignPageResult, AssignPagesOptions } from "../assign.js";
12
12
  import {
13
13
  type ClassifyCandidate,
@@ -17,14 +17,14 @@ import type {
17
17
  Message,
18
18
  Provider,
19
19
  ProviderResponse,
20
- } from "../../../providers/types.js";
20
+ } from "../../../../providers/types.js";
21
21
  import type { NeedleIndex } from "../needle.js";
22
22
  import type {
23
23
  LeafNode,
24
24
  LeafPath,
25
25
  LeafTree,
26
+ MemoryRoutingTurn,
26
27
  Slug,
27
- TurnContext,
28
28
  } from "../types.js";
29
29
  import evalTurns from "./fixtures/eval-turns.json" with { type: "json" };
30
30
 
@@ -35,13 +35,13 @@ import evalTurns from "./fixtures/eval-turns.json" with { type: "json" };
35
35
 
36
36
  let providerStub: Provider | null = null;
37
37
 
38
- mock.module("../../../providers/provider-send-message.js", () => ({
38
+ mock.module("../../../../providers/provider-send-message.js", () => ({
39
39
  getConfiguredProvider: async () => providerStub,
40
40
  extractToolUse: (response: ProviderResponse) =>
41
41
  response.content.find((b) => b.type === "tool_use"),
42
42
  }));
43
43
 
44
- mock.module("../../../util/logger.js", () => ({
44
+ mock.module("../../../../util/logger.js", () => ({
45
45
  getLogger: () =>
46
46
  new Proxy({} as Record<string, unknown>, {
47
47
  get: (_t, prop) => (prop === "child" ? () => ({}) : () => {}),
@@ -104,7 +104,10 @@ function fakeNeedle(hits: Slug[]): NeedleIndex {
104
104
  return { query: (_text, k) => hits.slice(0, k) };
105
105
  }
106
106
 
107
- function makeTurn(turnNumber: number, currentMessage: string): TurnContext {
107
+ function makeTurn(
108
+ turnNumber: number,
109
+ currentMessage: string,
110
+ ): MemoryRoutingTurn {
108
111
  return {
109
112
  conversationId: "conv-xyz",
110
113
  turnNumber,
@@ -3,8 +3,8 @@ import { tmpdir } from "node:os";
3
3
  import { join } from "node:path";
4
4
  import { afterEach, beforeEach, describe, expect, test } from "bun:test";
5
5
 
6
- import type { Provider } from "../../../providers/types.js";
7
- import { readPage, writePage } from "../../v2/page-store.js";
6
+ import { readPage, writePage } from "../../../../memory/v2/page-store.js";
7
+ import type { Provider } from "../../../../providers/types.js";
8
8
  import { type LeafRef, reconcileTree } from "../reconcile.js";
9
9
 
10
10
  /**
@@ -1,6 +1,6 @@
1
1
  import { describe, expect, test } from "bun:test";
2
2
 
3
- import { wrapMemoryBlock } from "../../memory-marker.js";
3
+ import { wrapMemoryBlock } from "../../../../memory/memory-marker.js";
4
4
  import { renderMemoryBlock } from "../render-injection.js";
5
5
  import { Slug } from "../types.js";
6
6
 
@@ -25,8 +25,13 @@ import type {
25
25
  ProviderResponse,
26
26
  SendMessageOptions,
27
27
  ToolUseContent,
28
- } from "../../../providers/types.js";
29
- import type { LeafNode, LeafPath, LeafTree, TurnContext } from "../types.js";
28
+ } from "../../../../providers/types.js";
29
+ import type {
30
+ LeafNode,
31
+ LeafPath,
32
+ LeafTree,
33
+ MemoryRoutingTurn,
34
+ } from "../types.js";
30
35
 
31
36
  // ---------------------------------------------------------------------------
32
37
  // Mocks installed BEFORE the router import so the module observes them at
@@ -41,13 +46,13 @@ interface ProviderCall {
41
46
  }
42
47
  const providerCalls: ProviderCall[] = [];
43
48
 
44
- mock.module("../../../providers/provider-send-message.js", () => ({
49
+ mock.module("../../../../providers/provider-send-message.js", () => ({
45
50
  getConfiguredProvider: async () => providerStub,
46
51
  extractToolUse: (response: ProviderResponse) =>
47
52
  response.content.find((b): b is ToolUseContent => b.type === "tool_use"),
48
53
  }));
49
54
 
50
- mock.module("../../../util/logger.js", () => ({
55
+ mock.module("../../../../util/logger.js", () => ({
51
56
  getLogger: () =>
52
57
  new Proxy({} as Record<string, unknown>, {
53
58
  get: (_t, prop) => (prop === "child" ? () => ({}) : () => {}),
@@ -143,7 +148,7 @@ function makeTree(): LeafTree {
143
148
  };
144
149
  }
145
150
 
146
- function makeTurn(currentMessage: string): TurnContext {
151
+ function makeTurn(currentMessage: string): MemoryRoutingTurn {
147
152
  return {
148
153
  conversationId: "conv-xyz",
149
154
  turnNumber: 1,
@@ -20,14 +20,14 @@ import { afterAll, beforeEach, describe, expect, mock, test } from "bun:test";
20
20
 
21
21
  import { drizzle } from "drizzle-orm/bun-sqlite";
22
22
 
23
- import { migrateAddMemoryV3Selections } from "../../migrations/268-add-memory-v3-selections.js";
24
- import * as schema from "../../schema.js";
23
+ import { migrateAddMemoryV3Selections } from "../../../../memory/migrations/268-add-memory-v3-selections.js";
24
+ import * as schema from "../../../../memory/schema.js";
25
25
 
26
26
  const realFlags = {
27
- ...(await import("../../../config/assistant-feature-flags.js")),
27
+ ...(await import("../../../../config/assistant-feature-flags.js")),
28
28
  };
29
- const realLoader = { ...(await import("../../../config/loader.js")) };
30
- const realDb = { ...(await import("../../db-connection.js")) };
29
+ const realLoader = { ...(await import("../../../../config/loader.js")) };
30
+ const realDb = { ...(await import("../../../../memory/db-connection.js")) };
31
31
  const realPageContent = { ...(await import("../page-content.js")) };
32
32
 
33
33
  let storeMockActive = false;
@@ -64,7 +64,7 @@ function seed(
64
64
  }
65
65
  }
66
66
 
67
- mock.module("../../../config/assistant-feature-flags.js", () => ({
67
+ mock.module("../../../../config/assistant-feature-flags.js", () => ({
68
68
  ...realFlags,
69
69
  isAssistantFeatureFlagEnabled: (key: string, config: unknown) =>
70
70
  storeMockActive
@@ -81,12 +81,12 @@ mock.module("../../../config/assistant-feature-flags.js", () => ({
81
81
  ),
82
82
  }));
83
83
 
84
- mock.module("../../../config/loader.js", () => ({
84
+ mock.module("../../../../config/loader.js", () => ({
85
85
  ...realLoader,
86
86
  getConfig: () => (storeMockActive ? {} : realLoader.getConfig()),
87
87
  }));
88
88
 
89
- mock.module("../../db-connection.js", () => ({
89
+ mock.module("../../../../memory/db-connection.js", () => ({
90
90
  ...realDb,
91
91
  getDb: () => (storeMockActive ? testDb : realDb.getDb()),
92
92
  getSqliteFrom: (db: unknown) =>
@@ -26,13 +26,13 @@ import type {
26
26
  ProviderResponse,
27
27
  SendMessageOptions,
28
28
  ToolUseContent,
29
- } from "../../../providers/types.js";
29
+ } from "../../../../providers/types.js";
30
30
  import type {
31
31
  LeafNode,
32
32
  LeafPath,
33
33
  LeafTree,
34
+ MemoryRoutingTurn,
34
35
  Slug,
35
- TurnContext,
36
36
  } from "../types.js";
37
37
 
38
38
  // ---------------------------------------------------------------------------
@@ -48,13 +48,13 @@ interface ProviderCall {
48
48
  }
49
49
  const providerCalls: ProviderCall[] = [];
50
50
 
51
- mock.module("../../../providers/provider-send-message.js", () => ({
51
+ mock.module("../../../../providers/provider-send-message.js", () => ({
52
52
  getConfiguredProvider: async () => providerStub,
53
53
  extractToolUse: (response: ProviderResponse) =>
54
54
  response.content.find((b): b is ToolUseContent => b.type === "tool_use"),
55
55
  }));
56
56
 
57
- mock.module("../../../util/logger.js", () => ({
57
+ mock.module("../../../../util/logger.js", () => ({
58
58
  getLogger: () =>
59
59
  new Proxy({} as Record<string, unknown>, {
60
60
  get: (_t, prop) => (prop === "child" ? () => ({}) : () => {}),
@@ -155,7 +155,7 @@ function makeTree(): LeafTree {
155
155
 
156
156
  const ALICE_MEMBERS = ["alice-bio", "alice-1on1", "alice-feedback"];
157
157
 
158
- function makeTurn(currentMessage: string): TurnContext {
158
+ function makeTurn(currentMessage: string): MemoryRoutingTurn {
159
159
  return {
160
160
  conversationId: "conv-xyz",
161
161
  turnNumber: 1,
@@ -22,8 +22,8 @@ import { afterAll, beforeEach, describe, expect, mock, test } from "bun:test";
22
22
 
23
23
  import { drizzle } from "drizzle-orm/bun-sqlite";
24
24
 
25
- import { migrateAddMemoryV3Selections } from "../../migrations/268-add-memory-v3-selections.js";
26
- import * as schema from "../../schema.js";
25
+ import { migrateAddMemoryV3Selections } from "../../../../memory/migrations/268-add-memory-v3-selections.js";
26
+ import * as schema from "../../../../memory/schema.js";
27
27
  import type { LeafTree, SelectionSource } from "../types.js";
28
28
 
29
29
  // `mock.module` is process-global and, in Bun, neither `mock.restore()` nor a
@@ -41,10 +41,12 @@ const realTree = { ...(await import("../tree.js")) };
41
41
  const realCore = { ...(await import("../core.js")) };
42
42
  const realNeedle = { ...(await import("../needle.js")) };
43
43
  const realOrchestrate = { ...(await import("../orchestrate.js")) };
44
- const realPlatform = { ...(await import("../../../util/platform.js")) };
45
- const realPageStore = { ...(await import("../../v2/page-store.js")) };
44
+ const realPlatform = { ...(await import("../../../../util/platform.js")) };
45
+ const realPageStore = {
46
+ ...(await import("../../../../memory/v2/page-store.js")),
47
+ };
46
48
  const realConversationCrud = {
47
- ...(await import("../../conversation-crud.js")),
49
+ ...(await import("../../../../memory/conversation-crud.js")),
48
50
  };
49
51
 
50
52
  let shadowMockActive = false;
@@ -95,7 +97,7 @@ const FAKE_TREE = {
95
97
 
96
98
  // ─── module mocks (installed before the plugin import) ──────────────────────
97
99
 
98
- mock.module("../../../config/assistant-feature-flags.js", () => ({
100
+ mock.module("../../../../config/assistant-feature-flags.js", () => ({
99
101
  isAssistantFeatureFlagEnabled: (key: string) =>
100
102
  key === "memory-v3-live"
101
103
  ? liveEnabled
@@ -104,7 +106,7 @@ mock.module("../../../config/assistant-feature-flags.js", () => ({
104
106
  : false,
105
107
  }));
106
108
 
107
- mock.module("../../../config/loader.js", () => ({
109
+ mock.module("../../../../config/loader.js", () => ({
108
110
  getConfig: () => ({
109
111
  memory: {
110
112
  v3: {
@@ -119,12 +121,12 @@ mock.module("../../../config/loader.js", () => ({
119
121
  // (e.g. `getMessageById` via page-content.ts) stays present — replacing the
120
122
  // whole module with a bare `{ getMessages }` made those consumers fail to load.
121
123
  // Only `getMessages` is overridden, since that's the one the plugin reads.
122
- mock.module("../../conversation-crud.js", () => ({
124
+ mock.module("../../../../memory/conversation-crud.js", () => ({
123
125
  ...realConversationCrud,
124
126
  getMessages: () => messages.map((m, i) => ({ ...m, id: `m${i}` })),
125
127
  }));
126
128
 
127
- mock.module("../../db-connection.js", () => ({
129
+ mock.module("../../../../memory/db-connection.js", () => ({
128
130
  getDb: () => testDb,
129
131
  getSqliteFrom: () => testSqlite,
130
132
  }));
@@ -136,7 +138,7 @@ mock.module("../v2/page-index.js", () => ({
136
138
  // `pageContent` (live mode) reads the full page via `readPage`/`renderPageContent`.
137
139
  // Stub them to return a deterministic body per slug so the rendered `<memory>`
138
140
  // block is assertable without touching the filesystem.
139
- mock.module("../../v2/page-store.js", () => ({
141
+ mock.module("../../../../memory/v2/page-store.js", () => ({
140
142
  ...realPageStore,
141
143
  readPage: async (workspaceDir: string, slug: string) =>
142
144
  shadowMockActive
@@ -150,7 +152,7 @@ mock.module("../../v2/page-store.js", () => ({
150
152
  ),
151
153
  }));
152
154
 
153
- mock.module("../../../util/platform.js", () => ({
155
+ mock.module("../../../../util/platform.js", () => ({
154
156
  ...realPlatform,
155
157
  getWorkspaceDir: () =>
156
158
  shadowMockActive
@@ -205,12 +207,9 @@ mock.module("../orchestrate.js", () => ({
205
207
  }));
206
208
 
207
209
  // Import AFTER mocks so the plugin binds to them.
208
- const {
209
- runShadowObservation,
210
- resetShadowLanesForTests,
211
- invalidateLanes,
212
- memoryV3Injector,
213
- } = await import("../shadow-plugin.js");
210
+ const { runShadowObservation, resetShadowLanesForTests, invalidateLanes } =
211
+ await import("../shadow-plugin.js");
212
+ const { memoryV3Injector } = await import("../injector.js");
214
213
 
215
214
  // The module stubs above stay installed for the rest of the process (Bun can't
216
215
  // reliably uninstall them), but `shadowMockActive` gates their fake behavior to
@@ -5,9 +5,9 @@ import type {
5
5
  LeafNode,
6
6
  LeafPath,
7
7
  LeafTree,
8
+ MemoryRoutingTurn,
8
9
  SelectionSource,
9
10
  Slug,
10
- TurnContext,
11
11
  WorkingSetEntry,
12
12
  } from "../types.js";
13
13
 
@@ -37,7 +37,7 @@ test("v3 core types instantiate", () => {
37
37
  lastSeenTurn: 2,
38
38
  };
39
39
 
40
- const turnContext: TurnContext = {
40
+ const turnContext: MemoryRoutingTurn = {
41
41
  conversationId: "conv-xyz",
42
42
  turnNumber: 3,
43
43
  currentMessage: "hello",
@@ -18,15 +18,19 @@
18
18
  * omitted, resolves the `memoryV3RouteL1` callsite provider.
19
19
  */
20
20
 
21
+ import {
22
+ listPages,
23
+ readPage,
24
+ writePage,
25
+ } from "../../../memory/v2/page-store.js";
26
+ import type { ConceptPage } from "../../../memory/v2/types.js";
21
27
  import {
22
28
  extractToolUse,
23
29
  getConfiguredProvider,
24
30
  userMessage,
25
- } from "../../providers/provider-send-message.js";
26
- import type { Provider, ToolDefinition } from "../../providers/types.js";
27
- import { getLogger } from "../../util/logger.js";
28
- import { listPages, readPage, writePage } from "../v2/page-store.js";
29
- import type { ConceptPage } from "../v2/types.js";
31
+ } from "../../../providers/provider-send-message.js";
32
+ import type { Provider, ToolDefinition } from "../../../providers/types.js";
33
+ import { getLogger } from "../../../util/logger.js";
30
34
  import type { LeafPath, LeafTree, Slug } from "./types.js";
31
35
 
32
36
  const log = getLogger("memory-v3-assign");
@@ -28,8 +28,11 @@
28
28
  import {
29
29
  getCliCommandCapability,
30
30
  isCliCommandSlug,
31
- } from "../v2/cli-command-store.js";
32
- import { getSkillCapability, isSkillSlug } from "../v2/skill-store.js";
31
+ } from "../../../memory/v2/cli-command-store.js";
32
+ import {
33
+ getSkillCapability,
34
+ isSkillSlug,
35
+ } from "../../../memory/v2/skill-store.js";
33
36
  import type { LeafNode, LeafPath, LeafTree, Slug } from "./types.js";
34
37
 
35
38
  /** Path of the always-on synthetic leaf that owns skill + CLI capability rows. */
@@ -0,0 +1,14 @@
1
+ /**
2
+ * No-op `post-compact` scaffolding for the memory-v3-shadow plugin.
3
+ *
4
+ * v3 re-injection after mid-turn compaction is not yet owned by this plugin —
5
+ * the active injector still runs through the static chain. Once the
6
+ * post-compaction hook API stabilizes we will import `memoryV3Injector` from
7
+ * `../injector.js` and re-apply it here. Until then this hook does nothing.
8
+ */
9
+
10
+ import type { PluginHookFn } from "@vellumai/plugin-api";
11
+
12
+ const postCompact: PluginHookFn = async () => {};
13
+
14
+ export default postCompact;
@@ -0,0 +1,19 @@
1
+ /**
2
+ * No-op `user-prompt-submit` scaffolding for the memory-v3-shadow plugin.
3
+ *
4
+ * The v3 injector currently runs through the static injector chain
5
+ * (`memory-retrieval/injector-chain.ts`), not through this hook. Once the
6
+ * prompt-submit hook API stabilizes we will import `memoryV3Injector` from
7
+ * `../injector.js` and run it here, so v3 injection is owned by the plugin's
8
+ * own lifecycle rather than the loop-driven chain. Until then this hook
9
+ * intentionally does nothing.
10
+ */
11
+
12
+ import type {
13
+ PluginHookFn,
14
+ UserPromptSubmitContext,
15
+ } from "@vellumai/plugin-api";
16
+
17
+ const userPromptSubmit: PluginHookFn<UserPromptSubmitContext> = async () => {};
18
+
19
+ export default userPromptSubmit;
@@ -0,0 +1,75 @@
1
+ /**
2
+ * The memory-v3 {@link Injector}. Reads both v3 flags:
3
+ * - `memory-v3-live` on → orchestrate, log, render the working-set selection
4
+ * into a `<memory>` block, and return it at v2's dynamic-memory placement.
5
+ * - `memory-v3-shadow` on (live off) → orchestrate + log only, return `null`.
6
+ * - both off → return `null` (no orchestration).
7
+ *
8
+ * Empty selection and any failure return `null` (no v3 injection). v2
9
+ * suppression keys off BOTH the flag AND this return value, so a `null` here
10
+ * (failure or empty selection) falls back to v2 memory rather than dropping all
11
+ * memory.
12
+ *
13
+ * Orchestration and telemetry live in {@link observeTurn}; this module is the
14
+ * thin injector wrapper that renders the result for live injection.
15
+ */
16
+
17
+ import { isAssistantFeatureFlagEnabled } from "../../../config/assistant-feature-flags.js";
18
+ import { getConfig } from "../../../config/loader.js";
19
+ import { getLogger } from "../../../util/logger.js";
20
+ import {
21
+ type InjectionBlock,
22
+ type Injector,
23
+ type TurnContext,
24
+ } from "../../types.js";
25
+ import { renderV3PageContent } from "./page-content.js";
26
+ import { renderMemoryBlock } from "./render-injection.js";
27
+ import {
28
+ MEMORY_V3_LIVE,
29
+ MEMORY_V3_SHADOW,
30
+ observeTurn,
31
+ } from "./shadow-plugin.js";
32
+ import { MEMORY_V3_BLOCK_ID } from "./types.js";
33
+
34
+ const log = getLogger("memory-v3-shadow");
35
+
36
+ export const memoryV3Injector: Injector = {
37
+ name: "memory-v3-shadow",
38
+ // High order so it sorts last; the live `<memory>` block uses the
39
+ // after-memory-prefix placement so it lands at the memory boundary regardless
40
+ // of this sort key, which only orders content-producing injectors.
41
+ order: 1000,
42
+ async produce(ctx: TurnContext): Promise<InjectionBlock | null> {
43
+ const config = getConfig();
44
+ const live = isAssistantFeatureFlagEnabled(MEMORY_V3_LIVE, config);
45
+ const shadow = isAssistantFeatureFlagEnabled(MEMORY_V3_SHADOW, config);
46
+ if (!live && !shadow) return null;
47
+
48
+ const result = await observeTurn(ctx.conversationId, ctx.turnIndex);
49
+ if (!live || !result) return null;
50
+
51
+ try {
52
+ // `renderMemoryBlock` returns "" for an empty selection; inject nothing.
53
+ const text = await renderMemoryBlock(
54
+ result.finalInjection,
55
+ renderV3PageContent,
56
+ );
57
+ if (text.length === 0) return null;
58
+ return {
59
+ id: MEMORY_V3_BLOCK_ID,
60
+ text,
61
+ // Mirror v2's dynamic `<memory>` block placement.
62
+ placement: "after-memory-prefix",
63
+ };
64
+ } catch (err) {
65
+ log.warn(
66
+ {
67
+ err: err instanceof Error ? err.message : String(err),
68
+ conversationId: ctx.conversationId,
69
+ },
70
+ "memory-v3 live render failed (non-fatal) — falling back to v2",
71
+ );
72
+ return null;
73
+ }
74
+ },
75
+ };
@@ -25,14 +25,21 @@
25
25
  * `assignPages`, and `invalidateLanes` without process-global module mocks.
26
26
  */
27
27
 
28
- import { isAssistantFeatureFlagEnabled } from "../../config/assistant-feature-flags.js";
29
- import type { AssistantConfig } from "../../config/types.js";
30
- import { getLogger } from "../../util/logger.js";
31
- import { getWorkspaceDir } from "../../util/platform.js";
32
- import { getMemoryCheckpoint, setMemoryCheckpoint } from "../checkpoints.js";
33
- import type { MemoryJob } from "../jobs-store.js";
34
- import { getPageIndex } from "../v2/page-index.js";
35
- import { listPages, readPage, writePage } from "../v2/page-store.js";
28
+ import { isAssistantFeatureFlagEnabled } from "../../../config/assistant-feature-flags.js";
29
+ import type { AssistantConfig } from "../../../config/types.js";
30
+ import {
31
+ getMemoryCheckpoint,
32
+ setMemoryCheckpoint,
33
+ } from "../../../memory/checkpoints.js";
34
+ import type { MemoryJob } from "../../../memory/jobs-store.js";
35
+ import { getPageIndex } from "../../../memory/v2/page-index.js";
36
+ import {
37
+ listPages,
38
+ readPage,
39
+ writePage,
40
+ } from "../../../memory/v2/page-store.js";
41
+ import { getLogger } from "../../../util/logger.js";
42
+ import { getWorkspaceDir } from "../../../util/platform.js";
36
43
  import { assignPages as realAssignPages } from "./assign.js";
37
44
  import { invalidateLanes as realInvalidateLanes } from "./shadow-plugin.js";
38
45
  import { loadLeafTree as realLoadLeafTree, resolveDataDir } from "./tree.js";
@@ -30,7 +30,7 @@ import { routeL1 } from "./router.js";
30
30
  import type { SelectedPage } from "./selector.js";
31
31
  import { selectAcrossLeaves } from "./selector.js";
32
32
  import { coreSlugs, leavesOf } from "./tree.js";
33
- import type { LeafPath, LeafTree, Slug, TurnContext } from "./types.js";
33
+ import type { LeafPath, LeafTree, MemoryRoutingTurn, Slug } from "./types.js";
34
34
  import { WorkingSet } from "./working-set.js";
35
35
 
36
36
  /** Default number of needle hits to fold into the open set when unspecified. */
@@ -66,7 +66,7 @@ function unique<T>(items: Iterable<T>): T[] {
66
66
  }
67
67
 
68
68
  export async function orchestrate(
69
- turn: TurnContext,
69
+ turn: MemoryRoutingTurn,
70
70
  deps: OrchestrateDeps,
71
71
  ): Promise<OrchestrateResult> {
72
72
  // Step 1: routing (LLM) and needle (sync BM25) run in parallel.
@@ -0,0 +1,14 @@
1
+ {
2
+ "name": "default-memory-v3-shadow",
3
+ "version": "1.0.0",
4
+ "description": "First-party default plugin housing the memory-v3 shadow/live orchestration engine and its injector.",
5
+ "private": true,
6
+ "license": "MIT",
7
+ "type": "module",
8
+ "engines": {
9
+ "node": ">=20.12.0"
10
+ },
11
+ "peerDependencies": {
12
+ "@vellumai/plugin-api": "^0.8.0"
13
+ }
14
+ }
@@ -1,5 +1,5 @@
1
- import { getWorkspaceDir } from "../../util/platform.js";
2
- import { readPage, renderPageContent } from "../v2/page-store.js";
1
+ import { readPage, renderPageContent } from "../../../memory/v2/page-store.js";
2
+ import { getWorkspaceDir } from "../../../util/platform.js";
3
3
  import { renderCapabilityContent } from "./capabilities.js";
4
4
  import type { Slug } from "./types.js";
5
5
 
@@ -1,4 +1,4 @@
1
- import type { ContentBlock } from "../../providers/types.js";
1
+ import type { ContentBlock } from "../../../providers/types.js";
2
2
 
3
3
  /**
4
4
  * Text content block carrying a `cache_control` breakpoint with a 1-hour TTL.
@@ -38,9 +38,13 @@ import { join, relative, sep } from "node:path";
38
38
 
39
39
  import { parse as parseYaml } from "yaml";
40
40
 
41
- import type { Provider } from "../../providers/types.js";
42
- import { getLogger } from "../../util/logger.js";
43
- import { listPages, readPage, writePage } from "../v2/page-store.js";
41
+ import {
42
+ listPages,
43
+ readPage,
44
+ writePage,
45
+ } from "../../../memory/v2/page-store.js";
46
+ import type { Provider } from "../../../providers/types.js";
47
+ import { getLogger } from "../../../util/logger.js";
44
48
  import { assignPages } from "./assign.js";
45
49
  import { loadCore } from "./core.js";
46
50
  import { invalidateLanes } from "./shadow-plugin.js";
@@ -1,4 +1,4 @@
1
- import { wrapMemoryBlock } from "../memory-marker.js";
1
+ import { wrapMemoryBlock } from "../../../memory/memory-marker.js";
2
2
  import { Slug } from "./types.js";
3
3
 
4
4
  /**