@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
@@ -1,17 +1,53 @@
1
- import { describe, expect, test } from "bun:test";
1
+ import { beforeEach, describe, expect, mock, test } from "bun:test";
2
+
3
+ import { eq } from "drizzle-orm";
4
+
5
+ import * as dateContext from "../daemon/date-context.js";
6
+
7
+ // `applyRuntimeInjections` computes the `<turn_context>` `current_time` live via
8
+ // `formatTurnTimestamp`; pin it so the rendered block matches the deterministic
9
+ // `buildUnifiedTurnContextBlock` expectation below. The rest of the module
10
+ // (timezone canonicalization/resolution) keeps its real behavior.
11
+ const FIXED_TURN_TIMESTAMP = "2026-04-02T12:00:00Z";
12
+ mock.module("../daemon/date-context.js", () => ({
13
+ ...dateContext,
14
+ formatTurnTimestamp: () => FIXED_TURN_TIMESTAMP,
15
+ }));
2
16
 
17
+ import {
18
+ clearConversations,
19
+ setConversation,
20
+ } from "../daemon/conversation-registry.js";
21
+ import type { ChannelCapabilities } from "../daemon/conversation-runtime-assembly.js";
3
22
  import {
4
23
  applyRuntimeInjections,
5
24
  stripInjectionsForCompaction,
6
25
  } from "../daemon/conversation-runtime-assembly.js";
26
+ import { getDb } from "../memory/db-connection.js";
27
+ import { initializeDb } from "../memory/db-init.js";
28
+ import { conversations, messages } from "../memory/schema.js";
29
+ import {
30
+ type SlackMessageMetadata,
31
+ writeSlackMetadata,
32
+ } from "../messaging/providers/slack/message-metadata.js";
7
33
  import {
8
34
  DEFAULT_INJECTOR_ORDER,
9
35
  defaultInjectors,
10
36
  DISK_PRESSURE_WARNING_PROMPT,
11
- } from "../plugins/defaults/injectors/register.js";
37
+ } from "../plugins/defaults/memory-retrieval/injectors.js";
38
+ import { buildUnifiedTurnContextBlock } from "../plugins/defaults/memory-retrieval/unified-turn-context.js";
12
39
  import type { Injector, TurnContext } from "../plugins/types.js";
13
40
  import type { Message } from "../providers/types.js";
14
41
 
42
+ // `applyRuntimeInjections` self-resolves the Slack active-thread focus block
43
+ // from the persisted message rows, so the schema must exist for Slack-channel
44
+ // turns; with no seeded rows the focus loader resolves to null.
45
+ initializeDb();
46
+
47
+ // `makeContext` and the workspace registry seed share this id so the
48
+ // `workspace-context` injector resolves the seeded block for the turn.
49
+ const TEST_CONVERSATION_ID = "conv-test";
50
+
15
51
  function findInjector(name: string): Injector {
16
52
  const injector = defaultInjectors.find(
17
53
  (candidate) => candidate.name === name,
@@ -25,7 +61,7 @@ function findInjector(name: string): Injector {
25
61
  function makeContext(overrides: Partial<TurnContext> = {}): TurnContext {
26
62
  return {
27
63
  requestId: "req-test",
28
- conversationId: "conv-test",
64
+ conversationId: TEST_CONVERSATION_ID,
29
65
  turnIndex: 0,
30
66
  trust: { sourceChannel: "vellum", trustClass: "guardian" },
31
67
  ...overrides,
@@ -43,15 +79,134 @@ function tailTexts(messages: Message[]): string[] {
43
79
  }
44
80
 
45
81
  const diskPressureInjector = findInjector("disk-pressure-warning");
46
- const cleanupContext = { cleanupModeActive: true };
82
+
83
+ // The disk-pressure-warning and workspace-context injectors both read their
84
+ // per-conversation state off the live `Conversation` looked up by
85
+ // `conversationId`. Seed a single fake instance under the id `makeContext()`
86
+ // uses, carrying the disk-pressure flag and the workspace top-level cache, so a
87
+ // turn can exercise both; the seed helpers mutate and re-register the same
88
+ // instance. An empty (non-dirty) workspace cache resolves to no block, so
89
+ // disk-pressure-only tests don't trigger a directory scan.
90
+ let liveConversation: {
91
+ conversationId: string;
92
+ workingDir: string;
93
+ workspaceTopLevelContext: string | null;
94
+ workspaceTopLevelDirty: boolean;
95
+ diskPressureCleanupModeActive: boolean;
96
+ channelCapabilities?: ChannelCapabilities;
97
+ trustContext?: { trustClass: string };
98
+ currentTurnTemporalSnapshot?: {
99
+ clientTimezone: string | null;
100
+ };
101
+ currentTurnInterfaceContext?: {
102
+ userMessageInterface: string;
103
+ assistantMessageInterface: string;
104
+ };
105
+ };
106
+
107
+ function resetLiveConversation(): void {
108
+ liveConversation = {
109
+ conversationId: TEST_CONVERSATION_ID,
110
+ workingDir: "/workspace",
111
+ workspaceTopLevelContext: "",
112
+ workspaceTopLevelDirty: false,
113
+ diskPressureCleanupModeActive: false,
114
+ trustContext: { trustClass: "guardian" },
115
+ // The unified-turn-context injector sources the interface label from the
116
+ // live conversation's turn interface context; match the expected blocks.
117
+ currentTurnInterfaceContext: {
118
+ userMessageInterface: "macos",
119
+ assistantMessageInterface: "macos",
120
+ },
121
+ };
122
+ }
123
+
124
+ // `applyRuntimeInjections` gates the `<turn_context>` block on the live
125
+ // conversation's frozen temporal snapshot (computing `current_time` live), so
126
+ // seed it for tests that assert the unified-turn-context block is present.
127
+ function seedTemporalSnapshot(): void {
128
+ liveConversation.currentTurnTemporalSnapshot = {
129
+ clientTimezone: null,
130
+ };
131
+ setConversation(TEST_CONVERSATION_ID, liveConversation as never);
132
+ }
133
+
134
+ function seedChannelCapabilities(caps: ChannelCapabilities): void {
135
+ liveConversation.channelCapabilities = caps;
136
+ setConversation(TEST_CONVERSATION_ID, liveConversation as never);
137
+ }
138
+
139
+ function seedDiskPressure(cleanupModeActive: boolean): void {
140
+ liveConversation.diskPressureCleanupModeActive = cleanupModeActive;
141
+ setConversation(TEST_CONVERSATION_ID, liveConversation as never);
142
+ }
143
+
144
+ function seedWorkspaceContext(text: string): void {
145
+ liveConversation.workspaceTopLevelContext = text;
146
+ liveConversation.workspaceTopLevelDirty = false;
147
+ setConversation(TEST_CONVERSATION_ID, liveConversation as never);
148
+ }
149
+
150
+ // Persist Slack-channel rows for the turn conversation so
151
+ // `applyRuntimeInjections` self-resolves the chronological transcript from
152
+ // conversation state, exactly as production does (the slack-messages injector
153
+ // reads the live conversation rather than receiving a pre-built transcript).
154
+ const SLACK_CHANNEL_ID = "C0123CHANNEL";
155
+ function seedSlackChannelRows(
156
+ rows: Array<{
157
+ id: string;
158
+ text: string;
159
+ channelTs: string;
160
+ displayName: string;
161
+ createdAt: number;
162
+ }>,
163
+ ): void {
164
+ const db = getDb();
165
+ const now = Date.now();
166
+ db.insert(conversations)
167
+ .values({ id: TEST_CONVERSATION_ID, createdAt: now, updatedAt: now })
168
+ .onConflictDoNothing()
169
+ .run();
170
+ for (const r of rows) {
171
+ const meta: SlackMessageMetadata = {
172
+ source: "slack",
173
+ channelId: SLACK_CHANNEL_ID,
174
+ channelTs: r.channelTs,
175
+ eventKind: "message",
176
+ displayName: r.displayName,
177
+ } as SlackMessageMetadata;
178
+ db.insert(messages)
179
+ .values({
180
+ id: r.id,
181
+ conversationId: TEST_CONVERSATION_ID,
182
+ role: "user",
183
+ content: JSON.stringify([{ type: "text", text: r.text }]),
184
+ createdAt: r.createdAt,
185
+ metadata: JSON.stringify({
186
+ provenanceTrustClass: "guardian",
187
+ slackMeta: writeSlackMetadata(meta),
188
+ }),
189
+ })
190
+ .run();
191
+ }
192
+ }
47
193
 
48
194
  describe("disk-pressure-warning injector", () => {
195
+ beforeEach(() => {
196
+ clearConversations();
197
+ resetLiveConversation();
198
+ const db = getDb();
199
+ db.delete(messages)
200
+ .where(eq(messages.conversationId, TEST_CONVERSATION_ID))
201
+ .run();
202
+ db.delete(conversations)
203
+ .where(eq(conversations.id, TEST_CONVERSATION_ID))
204
+ .run();
205
+ });
206
+
49
207
  test("emits the exact cleanup prompt during disk pressure cleanup mode", async () => {
50
- const block = await diskPressureInjector.produce(
51
- makeContext({
52
- injectionInputs: { diskPressureContext: cleanupContext },
53
- }),
54
- );
208
+ seedDiskPressure(true);
209
+ const block = await diskPressureInjector.produce(makeContext());
55
210
 
56
211
  expect(block).toEqual({
57
212
  id: "disk-pressure-warning",
@@ -72,21 +227,14 @@ Do not work on unrelated tasks until enough space is freed to clear the lock or
72
227
  </disk_pressure_warning>`);
73
228
  });
74
229
 
75
- test("omits the prompt when cleanup context is null or inactive", async () => {
230
+ test("omits the prompt when no cleanup context is registered or it is inactive", async () => {
76
231
  await expect(
77
- diskPressureInjector.produce(
78
- makeContext({ injectionInputs: { diskPressureContext: null } }),
79
- ),
232
+ diskPressureInjector.produce(makeContext()),
80
233
  ).resolves.toBeNull();
81
234
 
235
+ seedDiskPressure(false);
82
236
  await expect(
83
- diskPressureInjector.produce(
84
- makeContext({
85
- injectionInputs: {
86
- diskPressureContext: { cleanupModeActive: false },
87
- },
88
- }),
89
- ),
237
+ diskPressureInjector.produce(makeContext()),
90
238
  ).resolves.toBeNull();
91
239
  });
92
240
 
@@ -95,13 +243,16 @@ Do not work on unrelated tasks until enough space is freed to clear the lock or
95
243
  { role: "user", content: [{ type: "text", text: "clean up space" }] },
96
244
  ];
97
245
  const workspace = "<workspace>\nRoot: /workspace\n</workspace>";
98
- const turnContext = "<turn_context>\ninterface: macos\n</turn_context>";
246
+ const turnContext = buildUnifiedTurnContextBlock({
247
+ timestamp: "2026-04-02T12:00:00Z",
248
+ interfaceName: "macos",
249
+ });
99
250
 
251
+ seedWorkspaceContext(workspace);
252
+ seedDiskPressure(true);
253
+ seedTemporalSnapshot();
100
254
  const result = await applyRuntimeInjections(runMessages, {
101
- turnContext: makeContext(),
102
- diskPressureContext: cleanupContext,
103
- workspaceTopLevelContext: workspace,
104
- unifiedTurnContext: turnContext,
255
+ ...makeContext(),
105
256
  });
106
257
 
107
258
  expect(tailTexts(result.messages).slice(0, 4)).toEqual([
@@ -118,20 +269,23 @@ Do not work on unrelated tasks until enough space is freed to clear the lock or
118
269
  });
119
270
 
120
271
  test("survives minimal mode as safety-critical context", async () => {
272
+ const turnContext = buildUnifiedTurnContextBlock({
273
+ timestamp: "2026-04-02T12:00:00Z",
274
+ interfaceName: "macos",
275
+ });
276
+ seedDiskPressure(true);
277
+ seedTemporalSnapshot();
121
278
  const result = await applyRuntimeInjections(
122
279
  [{ role: "user", content: [{ type: "text", text: "status" }] }],
123
280
  {
124
- turnContext: makeContext(),
281
+ ...makeContext(),
125
282
  mode: "minimal",
126
- diskPressureContext: cleanupContext,
127
- workspaceTopLevelContext: "<workspace>...</workspace>",
128
- unifiedTurnContext: "<turn_context>...</turn_context>",
129
283
  },
130
284
  );
131
285
 
132
286
  expect(tailTexts(result.messages)).toEqual([
133
287
  DISK_PRESSURE_WARNING_PROMPT,
134
- "<turn_context>...</turn_context>",
288
+ turnContext,
135
289
  "status",
136
290
  ]);
137
291
  });
@@ -143,28 +297,33 @@ Do not work on unrelated tasks until enough space is freed to clear the lock or
143
297
  content: [{ type: "text", text: "latest raw user text" }],
144
298
  },
145
299
  ];
146
- const slackTranscript: Message[] = [
300
+
301
+ seedSlackChannelRows([
147
302
  {
148
- role: "user",
149
- content: [{ type: "text", text: "[12:00 user]: earlier" }],
303
+ id: "dp-1",
304
+ text: "earlier",
305
+ channelTs: "1700000000.000001",
306
+ displayName: "user",
307
+ createdAt: 1700000000_000,
150
308
  },
151
309
  {
152
- role: "user",
153
- content: [{ type: "text", text: "[12:01 @assistant]: cleanup?" }],
310
+ id: "dp-2",
311
+ text: "cleanup?",
312
+ channelTs: "1700000005.000001",
313
+ displayName: "user",
314
+ createdAt: 1700000005_000,
154
315
  },
155
- ];
156
-
316
+ ]);
317
+ seedDiskPressure(true);
318
+ seedChannelCapabilities({
319
+ channel: "slack",
320
+ dashboardCapable: false,
321
+ supportsDynamicUi: false,
322
+ supportsVoiceInput: false,
323
+ chatType: "channel",
324
+ });
157
325
  const result = await applyRuntimeInjections(originalRun, {
158
- turnContext: makeContext(),
159
- diskPressureContext: cleanupContext,
160
- channelCapabilities: {
161
- channel: "slack",
162
- dashboardCapable: false,
163
- supportsDynamicUi: false,
164
- supportsVoiceInput: false,
165
- chatType: "channel",
166
- },
167
- slackChronologicalMessages: slackTranscript,
326
+ ...makeContext(),
168
327
  });
169
328
 
170
329
  expect(result.messages).toHaveLength(2);
@@ -173,7 +332,7 @@ Do not work on unrelated tasks until enough space is freed to clear the lock or
173
332
  expect(
174
333
  texts.some((text) => text.startsWith("<channel_capabilities>")),
175
334
  ).toBe(true);
176
- expect(texts[texts.length - 1]).toBe("[12:01 @assistant]: cleanup?");
335
+ expect(texts[texts.length - 1]).toContain("cleanup?");
177
336
  });
178
337
 
179
338
  test("compaction strip plus re-apply does not duplicate the warning", async () => {
@@ -181,16 +340,15 @@ Do not work on unrelated tasks until enough space is freed to clear the lock or
181
340
  { role: "user", content: [{ type: "text", text: "find large files" }] },
182
341
  ];
183
342
 
343
+ seedDiskPressure(true);
184
344
  const first = await applyRuntimeInjections(runMessages, {
185
- turnContext: makeContext(),
186
- diskPressureContext: cleanupContext,
345
+ ...makeContext(),
187
346
  });
188
347
  const stripped = stripInjectionsForCompaction(first.messages);
189
348
  expect(tailTexts(stripped)).toEqual(["find large files"]);
190
349
 
191
350
  const second = await applyRuntimeInjections(stripped, {
192
- turnContext: makeContext(),
193
- diskPressureContext: cleanupContext,
351
+ ...makeContext(),
194
352
  });
195
353
  expect(
196
354
  tailTexts(second.messages).filter(
@@ -9,7 +9,7 @@ mock.module("../documents/document-comments-store.js", () => ({
9
9
  }));
10
10
 
11
11
  const { DEFAULT_INJECTOR_ORDER, defaultInjectors } =
12
- await import("../plugins/defaults/injectors/register.js");
12
+ await import("../plugins/defaults/memory-retrieval/injectors.js");
13
13
  import type { Injector, TurnContext } from "../plugins/types.js";
14
14
 
15
15
  function findInjector(name: string): Injector {
@@ -62,7 +62,8 @@ describe("document-comments injector", () => {
62
62
  test("returns null when no active documents exist", async () => {
63
63
  const block = await injector.produce(
64
64
  makeContext({
65
- injectionInputs: { mode: "full", activeDocuments: [] },
65
+ mode: "full",
66
+ activeDocuments: [],
66
67
  }),
67
68
  );
68
69
  expect(block).toBeNull();
@@ -71,7 +72,7 @@ describe("document-comments injector", () => {
71
72
  test("returns null when activeDocuments is undefined", async () => {
72
73
  const block = await injector.produce(
73
74
  makeContext({
74
- injectionInputs: { mode: "full" },
75
+ mode: "full",
75
76
  }),
76
77
  );
77
78
  expect(block).toBeNull();
@@ -80,17 +81,15 @@ describe("document-comments injector", () => {
80
81
  test("returns null when mode is minimal", async () => {
81
82
  const block = await injector.produce(
82
83
  makeContext({
83
- injectionInputs: {
84
- mode: "minimal",
85
- activeDocuments: [
86
- {
87
- surfaceId: "doc-1",
88
- title: "My Doc",
89
- wordCount: 100,
90
- updatedAt: 1000,
91
- },
92
- ],
93
- },
84
+ mode: "minimal",
85
+ activeDocuments: [
86
+ {
87
+ surfaceId: "doc-1",
88
+ title: "My Doc",
89
+ wordCount: 100,
90
+ updatedAt: 1000,
91
+ },
92
+ ],
94
93
  }),
95
94
  );
96
95
  expect(block).toBeNull();
@@ -100,17 +99,15 @@ describe("document-comments injector", () => {
100
99
  listCommentsMock = mock(() => []);
101
100
  const block = await injector.produce(
102
101
  makeContext({
103
- injectionInputs: {
104
- mode: "full",
105
- activeDocuments: [
106
- {
107
- surfaceId: "doc-1",
108
- title: "My Doc",
109
- wordCount: 100,
110
- updatedAt: 1000,
111
- },
112
- ],
113
- },
102
+ mode: "full",
103
+ activeDocuments: [
104
+ {
105
+ surfaceId: "doc-1",
106
+ title: "My Doc",
107
+ wordCount: 100,
108
+ updatedAt: 1000,
109
+ },
110
+ ],
114
111
  }),
115
112
  );
116
113
  expect(block).toBeNull();
@@ -127,17 +124,15 @@ describe("document-comments injector", () => {
127
124
 
128
125
  const block = await injector.produce(
129
126
  makeContext({
130
- injectionInputs: {
131
- mode: "full",
132
- activeDocuments: [
133
- {
134
- surfaceId: "doc-1",
135
- title: "My Doc",
136
- wordCount: 100,
137
- updatedAt: 1000,
138
- },
139
- ],
140
- },
127
+ mode: "full",
128
+ activeDocuments: [
129
+ {
130
+ surfaceId: "doc-1",
131
+ title: "My Doc",
132
+ wordCount: 100,
133
+ updatedAt: 1000,
134
+ },
135
+ ],
141
136
  }),
142
137
  );
143
138
 
@@ -162,17 +157,15 @@ describe("document-comments injector", () => {
162
157
 
163
158
  const block = await injector.produce(
164
159
  makeContext({
165
- injectionInputs: {
166
- mode: "full",
167
- activeDocuments: [
168
- {
169
- surfaceId: "doc-1",
170
- title: "My Doc",
171
- wordCount: 100,
172
- updatedAt: 1000,
173
- },
174
- ],
175
- },
160
+ mode: "full",
161
+ activeDocuments: [
162
+ {
163
+ surfaceId: "doc-1",
164
+ title: "My Doc",
165
+ wordCount: 100,
166
+ updatedAt: 1000,
167
+ },
168
+ ],
176
169
  }),
177
170
  );
178
171
 
@@ -200,17 +193,15 @@ describe("document-comments injector", () => {
200
193
 
201
194
  const block = await injector.produce(
202
195
  makeContext({
203
- injectionInputs: {
204
- mode: "full",
205
- activeDocuments: [
206
- {
207
- surfaceId: "doc-xxx",
208
- title: "Title",
209
- wordCount: 200,
210
- updatedAt: 1000,
211
- },
212
- ],
213
- },
196
+ mode: "full",
197
+ activeDocuments: [
198
+ {
199
+ surfaceId: "doc-xxx",
200
+ title: "Title",
201
+ wordCount: 200,
202
+ updatedAt: 1000,
203
+ },
204
+ ],
214
205
  }),
215
206
  );
216
207
 
@@ -236,17 +227,15 @@ describe("document-comments injector", () => {
236
227
 
237
228
  const block = await injector.produce(
238
229
  makeContext({
239
- injectionInputs: {
240
- mode: "full",
241
- activeDocuments: [
242
- {
243
- surfaceId: "doc-1",
244
- title: "Big Doc",
245
- wordCount: 500,
246
- updatedAt: 1000,
247
- },
248
- ],
249
- },
230
+ mode: "full",
231
+ activeDocuments: [
232
+ {
233
+ surfaceId: "doc-1",
234
+ title: "Big Doc",
235
+ wordCount: 500,
236
+ updatedAt: 1000,
237
+ },
238
+ ],
250
239
  }),
251
240
  );
252
241
 
@@ -282,23 +271,21 @@ describe("document-comments injector", () => {
282
271
 
283
272
  const block = await injector.produce(
284
273
  makeContext({
285
- injectionInputs: {
286
- mode: "full",
287
- activeDocuments: [
288
- {
289
- surfaceId: "doc-1",
290
- title: "Doc A",
291
- wordCount: 100,
292
- updatedAt: 1000,
293
- },
294
- {
295
- surfaceId: "doc-2",
296
- title: "Doc B",
297
- wordCount: 200,
298
- updatedAt: 2000,
299
- },
300
- ],
301
- },
274
+ mode: "full",
275
+ activeDocuments: [
276
+ {
277
+ surfaceId: "doc-1",
278
+ title: "Doc A",
279
+ wordCount: 100,
280
+ updatedAt: 1000,
281
+ },
282
+ {
283
+ surfaceId: "doc-2",
284
+ title: "Doc B",
285
+ wordCount: 200,
286
+ updatedAt: 2000,
287
+ },
288
+ ],
302
289
  }),
303
290
  );
304
291
 
@@ -319,23 +306,21 @@ describe("document-comments injector", () => {
319
306
 
320
307
  const block = await injector.produce(
321
308
  makeContext({
322
- injectionInputs: {
323
- mode: "full",
324
- activeDocuments: [
325
- {
326
- surfaceId: "doc-1",
327
- title: "Empty Doc",
328
- wordCount: 100,
329
- updatedAt: 1000,
330
- },
331
- {
332
- surfaceId: "doc-2",
333
- title: "Commented Doc",
334
- wordCount: 200,
335
- updatedAt: 2000,
336
- },
337
- ],
338
- },
309
+ mode: "full",
310
+ activeDocuments: [
311
+ {
312
+ surfaceId: "doc-1",
313
+ title: "Empty Doc",
314
+ wordCount: 100,
315
+ updatedAt: 1000,
316
+ },
317
+ {
318
+ surfaceId: "doc-2",
319
+ title: "Commented Doc",
320
+ wordCount: 200,
321
+ updatedAt: 2000,
322
+ },
323
+ ],
339
324
  }),
340
325
  );
341
326
 
@@ -356,17 +341,15 @@ describe("document-comments injector", () => {
356
341
 
357
342
  const block = await injector.produce(
358
343
  makeContext({
359
- injectionInputs: {
360
- mode: "full",
361
- activeDocuments: [
362
- {
363
- surfaceId: "doc-1",
364
- title: "My Doc",
365
- wordCount: 100,
366
- updatedAt: 1000,
367
- },
368
- ],
369
- },
344
+ mode: "full",
345
+ activeDocuments: [
346
+ {
347
+ surfaceId: "doc-1",
348
+ title: "My Doc",
349
+ wordCount: 100,
350
+ updatedAt: 1000,
351
+ },
352
+ ],
370
353
  }),
371
354
  );
372
355
 
@@ -90,7 +90,7 @@ describe("PKB injector v2 cutover behavior", () => {
90
90
 
91
91
  test("v2 inactive → pkb-context, pkb-reminder, and now-md all produce blocks", async () => {
92
92
  const result = await applyRuntimeInjections(RUN_MESSAGES, {
93
- turnContext: makeTurnContext(),
93
+ ...makeTurnContext(),
94
94
  });
95
95
 
96
96
  const texts = tailTexts(result.messages);
@@ -102,7 +102,7 @@ describe("PKB injector v2 cutover behavior", () => {
102
102
  test("v2 active → pkb-context and pkb-reminder silenced; now-md still fires", async () => {
103
103
  v2Active = true;
104
104
  const result = await applyRuntimeInjections(RUN_MESSAGES, {
105
- turnContext: makeTurnContext(),
105
+ ...makeTurnContext(),
106
106
  });
107
107
 
108
108
  const texts = tailTexts(result.messages);