@vellumai/assistant 0.8.8 → 0.8.9-staging.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (360) hide show
  1. package/ARCHITECTURE.md +6 -6
  2. package/bun.lock +2 -2
  3. package/examples/plugins/echo/README.md +61 -60
  4. package/examples/plugins/echo/hooks/post-tool-use.ts +18 -0
  5. package/examples/plugins/echo/hooks/stop.ts +16 -0
  6. package/examples/plugins/echo/hooks/user-prompt-submit.ts +18 -0
  7. package/examples/plugins/echo/package.json +1 -2
  8. package/examples/plugins/echo/src/emit.ts +19 -0
  9. package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +7 -6
  10. package/openapi.yaml +235 -6
  11. package/package.json +2 -2
  12. package/src/__tests__/agent-loop-callsite-precedence.test.ts +69 -14
  13. package/src/__tests__/agent-loop-exit-reason.test.ts +204 -144
  14. package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +50 -35
  15. package/src/__tests__/agent-loop-output-hooks.test.ts +357 -0
  16. package/src/__tests__/agent-loop-override-profile.test.ts +25 -6
  17. package/src/__tests__/agent-loop-provider-error-recording.test.ts +41 -21
  18. package/src/__tests__/agent-loop-thinking.test.ts +36 -20
  19. package/src/__tests__/agent-loop.test.ts +441 -96
  20. package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +14 -14
  21. package/src/__tests__/agent-wake-override-profile.test.ts +17 -21
  22. package/src/__tests__/anthropic-provider.test.ts +1 -1
  23. package/src/__tests__/app-builder-tool-scripts.test.ts +21 -0
  24. package/src/__tests__/app-control-flow.test.ts +1 -1
  25. package/src/__tests__/app-dir-path-guard.test.ts +1 -0
  26. package/src/__tests__/app-executors.test.ts +132 -0
  27. package/src/__tests__/approval-cascade.test.ts +5 -4
  28. package/src/__tests__/approval-routes-http.test.ts +4 -1
  29. package/src/__tests__/background-workers-disk-pressure.test.ts +1 -1
  30. package/src/__tests__/channel-approval-routes.test.ts +1 -1
  31. package/src/__tests__/channel-approvals.test.ts +1 -1
  32. package/src/__tests__/compaction-circuit.test.ts +258 -0
  33. package/src/__tests__/compaction-direct.test.ts +132 -0
  34. package/src/__tests__/compaction-events.test.ts +5 -5
  35. package/src/__tests__/compactor-web-search-strip.test.ts +213 -0
  36. package/src/__tests__/context-overflow-reducer.test.ts +1 -1
  37. package/src/__tests__/conversation-abort-tool-results.test.ts +6 -4
  38. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +7 -10
  39. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +78 -119
  40. package/src/__tests__/conversation-agent-loop-overflow.test.ts +142 -218
  41. package/src/__tests__/conversation-agent-loop.test.ts +297 -586
  42. package/src/__tests__/conversation-clean-command.test.ts +5 -2
  43. package/src/__tests__/conversation-confirmation-signals.test.ts +5 -4
  44. package/src/__tests__/conversation-crud-inference-profile.test.ts +7 -9
  45. package/src/__tests__/conversation-history-web-search.test.ts +1 -1
  46. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +4 -4
  47. package/src/__tests__/conversation-process-callsite.test.ts +14 -14
  48. package/src/__tests__/conversation-provider-retry-repair.test.ts +70 -65
  49. package/src/__tests__/conversation-queue.test.ts +9 -9
  50. package/src/__tests__/conversation-runtime-assembly.test.ts +923 -231
  51. package/src/__tests__/conversation-runtime-workspace.test.ts +115 -20
  52. package/src/__tests__/conversation-slash-queue.test.ts +6 -4
  53. package/src/__tests__/conversation-slash-unknown.test.ts +6 -4
  54. package/src/__tests__/conversation-speed-override.test.ts +10 -9
  55. package/src/__tests__/conversation-starter-routes.test.ts +14 -6
  56. package/src/__tests__/conversation-workspace-cache-state.test.ts +23 -20
  57. package/src/__tests__/conversation-workspace-injection.test.ts +68 -6
  58. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +14 -11
  59. package/src/__tests__/conversations-import-system-filter.test.ts +101 -0
  60. package/src/__tests__/credential-security-invariants.test.ts +0 -1
  61. package/src/__tests__/db-acp-history.test.ts +101 -0
  62. package/src/__tests__/dynamic-page-surface.test.ts +31 -0
  63. package/src/__tests__/empty-response-hook.test.ts +1 -1
  64. package/src/__tests__/file-write-tool.test.ts +63 -0
  65. package/src/__tests__/gateway-only-guard.test.ts +12 -2
  66. package/src/__tests__/guardian-grant-minting.test.ts +1 -1
  67. package/src/__tests__/guardian-routing-invariants.test.ts +2 -4
  68. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +1 -1
  69. package/src/__tests__/heartbeat-disk-pressure.test.ts +1 -0
  70. package/src/__tests__/heartbeat-service.test.ts +1 -0
  71. package/src/__tests__/history-repair-hook.test.ts +1 -1
  72. package/src/__tests__/host-app-control-routes.test.ts +1 -1
  73. package/src/__tests__/host-cu-routes-targeted.test.ts +3 -3
  74. package/src/__tests__/inference-profile-reaper.test.ts +62 -0
  75. package/src/__tests__/inference-profile-session-handler.test.ts +86 -0
  76. package/src/__tests__/injector-background-turn.test.ts +13 -23
  77. package/src/__tests__/injector-chain.test.ts +268 -44
  78. package/src/__tests__/injector-disk-pressure.test.ts +210 -52
  79. package/src/__tests__/injector-document-comments.test.ts +97 -114
  80. package/src/__tests__/injector-pkb-v2-silenced.test.ts +2 -2
  81. package/src/__tests__/injector-v3-suppression.test.ts +4 -4
  82. package/src/__tests__/list-messages-client-message-id.test.ts +91 -0
  83. package/src/__tests__/list-messages-hidden-metadata.test.ts +38 -0
  84. package/src/__tests__/memory-retrieval-hook.test.ts +131 -26
  85. package/src/__tests__/memory-v2-static-injector.test.ts +86 -8
  86. package/src/__tests__/parallel-tool.benchmark.test.ts +35 -8
  87. package/src/__tests__/plugin-api-shim.test.ts +6 -9
  88. package/src/__tests__/plugin-bootstrap.test.ts +12 -23
  89. package/src/__tests__/plugin-registry.test.ts +3 -49
  90. package/src/__tests__/plugin-types.test.ts +0 -70
  91. package/src/__tests__/pre-model-call-sanitize.test.ts +109 -0
  92. package/src/__tests__/reaction-persistence.test.ts +1 -1
  93. package/src/__tests__/send-endpoint-busy.test.ts +4 -1
  94. package/src/__tests__/skill-feature-flags-integration.test.ts +33 -0
  95. package/src/__tests__/steer-tool-repair.test.ts +1 -1
  96. package/src/__tests__/subagent-call-site-routing.test.ts +1 -1
  97. package/src/__tests__/subagent-detail.test.ts +25 -7
  98. package/src/__tests__/subagent-fork-notifications.test.ts +1 -3
  99. package/src/__tests__/subagent-fork-spawn.test.ts +1 -1
  100. package/src/__tests__/subagent-manager-notify.test.ts +1 -3
  101. package/src/__tests__/subagent-notify-parent.test.ts +1 -3
  102. package/src/__tests__/subagent-spawn-tool-fork.test.ts +1 -1
  103. package/src/__tests__/title-generate-hook.test.ts +1 -1
  104. package/src/__tests__/tool-error-hook.test.ts +1 -1
  105. package/src/__tests__/tool-result-truncate-hook.test.ts +1 -1
  106. package/src/__tests__/user-plugin-loader.test.ts +54 -286
  107. package/src/acp/__tests__/agent-process.test.ts +161 -0
  108. package/src/acp/__tests__/client-handler.test.ts +40 -0
  109. package/src/acp/__tests__/helpers/acp-history-db.ts +82 -0
  110. package/src/acp/__tests__/helpers/exec-file-stub.ts +106 -0
  111. package/src/acp/__tests__/prepare-agent-env.test.ts +97 -0
  112. package/src/acp/__tests__/session-manager-persistence.test.ts +95 -28
  113. package/src/acp/__tests__/session-manager-resume.test.ts +888 -0
  114. package/src/acp/agent-process.ts +61 -1
  115. package/src/acp/auto-install.test.ts +280 -0
  116. package/src/acp/auto-install.ts +232 -0
  117. package/src/acp/client-handler.ts +31 -0
  118. package/src/acp/feature-gate.test.ts +48 -0
  119. package/src/acp/feature-gate.ts +34 -0
  120. package/src/acp/prepare-agent-env.ts +80 -27
  121. package/src/acp/resolve-agent.test.ts +225 -9
  122. package/src/acp/resolve-agent.ts +122 -17
  123. package/src/acp/resume-hint.ts +23 -0
  124. package/src/acp/session-manager.ts +507 -73
  125. package/src/agent/compaction-circuit.ts +60 -102
  126. package/src/agent/loop.ts +414 -248
  127. package/src/api/responses/conversation-message.ts +14 -1
  128. package/src/approvals/guardian-request-resolvers.ts +1 -1
  129. package/src/background-wake/next-wake.ts +1 -0
  130. package/src/cli/commands/db/__tests__/repair.test.ts +3 -1
  131. package/src/cli/commands/plugins.ts +43 -37
  132. package/src/cli/lib/__tests__/install-from-github.test.ts +429 -111
  133. package/src/cli/lib/__tests__/plugin-catalog-cache.test.ts +196 -0
  134. package/src/cli/lib/__tests__/plugin-details.test.ts +372 -0
  135. package/src/cli/lib/__tests__/plugin-marketplace.test.ts +220 -0
  136. package/src/cli/lib/__tests__/search-plugins.test.ts +226 -32
  137. package/src/cli/lib/install-from-github.ts +464 -55
  138. package/src/cli/lib/plugin-catalog-cache.ts +84 -0
  139. package/src/cli/lib/plugin-details.ts +409 -0
  140. package/src/cli/lib/plugin-marketplace.ts +197 -0
  141. package/src/cli/lib/search-plugins.ts +195 -29
  142. package/src/config/__tests__/feature-flag-registry-guard.test.ts +2 -2
  143. package/src/config/acp-defaults.test.ts +10 -0
  144. package/src/config/acp-defaults.ts +6 -0
  145. package/src/config/bundled-skills/acp/SKILL.md +85 -33
  146. package/src/config/bundled-skills/acp/TOOLS.json +4 -4
  147. package/src/config/bundled-skills/app-builder/SKILL.md +224 -381
  148. package/src/config/bundled-skills/app-builder/TOOLS.json +72 -2
  149. package/src/config/bundled-skills/app-builder/references/DESIGN_SYSTEM.md +48 -0
  150. package/src/config/bundled-skills/app-builder/references/RESPONSIVE.md +57 -0
  151. package/src/config/bundled-skills/app-builder/references/SLIDES.md +38 -0
  152. package/src/config/bundled-skills/app-builder/tools/app-list.ts +62 -0
  153. package/src/config/bundled-skills/app-builder/tools/app-update.ts +18 -0
  154. package/src/config/bundled-skills/document-editor/SKILL.md +28 -23
  155. package/src/config/bundled-skills/document-editor/TOOLS.json +1 -1
  156. package/src/config/bundled-tool-registry.ts +4 -0
  157. package/src/config/call-site-defaults.ts +0 -2
  158. package/src/config/feature-flag-registry.json +15 -6
  159. package/src/config/schemas/call-site-catalog.ts +0 -14
  160. package/src/config/schemas/heartbeat.ts +9 -0
  161. package/src/config/schemas/llm.ts +0 -2
  162. package/src/context/compactor.ts +22 -4
  163. package/src/context/strip-injections.ts +8 -2
  164. package/src/context/window-manager.ts +27 -13
  165. package/src/daemon/conversation-agent-loop-handlers.ts +10 -35
  166. package/src/daemon/conversation-agent-loop.ts +175 -1055
  167. package/src/daemon/conversation-lifecycle.ts +11 -255
  168. package/src/daemon/conversation-process.ts +8 -136
  169. package/src/daemon/conversation-registry.ts +159 -0
  170. package/src/daemon/conversation-runtime-assembly.ts +293 -392
  171. package/src/daemon/conversation-store.ts +9 -90
  172. package/src/daemon/conversation-surfaces.ts +24 -8
  173. package/src/daemon/conversation-workspace.ts +17 -0
  174. package/src/daemon/conversation.ts +404 -57
  175. package/src/daemon/disk-pressure-policy.ts +0 -1
  176. package/src/daemon/external-plugins-bootstrap.ts +14 -19
  177. package/src/daemon/handlers/conversations.ts +3 -1
  178. package/src/daemon/handlers/skills.ts +4 -1
  179. package/src/daemon/host-proxy-preactivation.ts +1 -3
  180. package/src/daemon/lifecycle.ts +21 -7
  181. package/src/daemon/server.ts +2 -0
  182. package/src/daemon/wake-conversation-ops.ts +269 -0
  183. package/src/embedded/plugin-api.ts +2 -2
  184. package/src/export/__tests__/transcript-formatter.test.ts +5 -0
  185. package/src/heartbeat/__tests__/heartbeat-service.test.ts +3 -0
  186. package/src/heartbeat/heartbeat-run-store.ts +23 -1
  187. package/src/heartbeat/heartbeat-service.ts +26 -0
  188. package/src/ipc/__tests__/browser-ipc.test.ts +1 -1
  189. package/src/ipc/__tests__/ui-request-route.test.ts +3 -3
  190. package/src/ipc/skill-routes/__tests__/memory.test.ts +15 -0
  191. package/src/ipc/skill-routes/memory.ts +4 -2
  192. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +87 -0
  193. package/src/memory/conversation-crud.ts +29 -19
  194. package/src/memory/conversation-starter-checkpoints.ts +1 -0
  195. package/src/memory/db-init.ts +2 -0
  196. package/src/memory/job-handlers/conversation-starters.ts +13 -2
  197. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +5 -4
  198. package/src/memory/jobs-worker.ts +25 -1
  199. package/src/memory/migrations/272-acp-session-history-cwd.ts +36 -0
  200. package/src/memory/migrations/index.ts +1 -0
  201. package/src/memory/schema/acp.ts +4 -0
  202. package/src/memory/v2/__tests__/consolidation-job.test.ts +3 -3
  203. package/src/memory/v2/consolidation-job.ts +13 -4
  204. package/src/plugin-api/constants.ts +4 -0
  205. package/src/plugin-api/index.ts +6 -5
  206. package/src/plugin-api/types.ts +75 -0
  207. package/src/plugins/defaults/compaction/compact.ts +59 -0
  208. package/src/{daemon → plugins/defaults/compaction}/context-overflow-reducer.ts +7 -7
  209. package/src/plugins/defaults/compaction/manager-store.ts +57 -0
  210. package/src/plugins/defaults/compaction/package.json +1 -2
  211. package/src/plugins/defaults/empty-response/package.json +0 -1
  212. package/src/plugins/defaults/history-repair/package.json +0 -1
  213. package/src/plugins/defaults/index.ts +135 -26
  214. package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +100 -52
  215. package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit-temp.ts +184 -74
  216. package/src/plugins/defaults/memory-retrieval/injector-chain.ts +2 -2
  217. package/src/plugins/defaults/{injectors/register.ts → memory-retrieval/injectors.ts} +148 -73
  218. package/src/plugins/defaults/memory-retrieval/unified-turn-context.ts +223 -0
  219. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/assign.test.ts +4 -4
  220. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/live-integration.test.ts +9 -6
  221. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/maintain-job.test.ts +5 -5
  222. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/orchestrate.test.ts +8 -5
  223. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/reconcile.test.ts +2 -2
  224. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/render-injection.test.ts +1 -1
  225. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/router.test.ts +10 -5
  226. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/selection-log-store.test.ts +8 -8
  227. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/selector.test.ts +5 -5
  228. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/shadow-plugin.test.ts +16 -17
  229. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/types.test.ts +2 -2
  230. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/assign.ts +9 -5
  231. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/capabilities.ts +5 -2
  232. package/src/plugins/defaults/memory-v3-shadow/hooks/post-compact.ts +14 -0
  233. package/src/plugins/defaults/memory-v3-shadow/hooks/user-prompt-submit.ts +19 -0
  234. package/src/plugins/defaults/memory-v3-shadow/injector.ts +75 -0
  235. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/maintain-job.ts +15 -8
  236. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/orchestrate.ts +2 -2
  237. package/src/plugins/defaults/memory-v3-shadow/package.json +14 -0
  238. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/page-content.ts +2 -2
  239. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/provider-blocks.ts +1 -1
  240. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/reconcile.ts +7 -3
  241. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/render-injection.ts +1 -1
  242. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/router.ts +5 -5
  243. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/selection-log-store.ts +4 -4
  244. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/selector.ts +7 -7
  245. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/shadow-plugin.ts +32 -94
  246. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/tree.ts +1 -1
  247. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/types.ts +1 -1
  248. package/src/plugins/defaults/title-generate/package.json +0 -1
  249. package/src/plugins/defaults/tool-error/package.json +0 -1
  250. package/src/plugins/defaults/tool-result-truncate/package.json +0 -1
  251. package/src/plugins/pipeline.ts +6 -293
  252. package/src/plugins/registry.ts +9 -37
  253. package/src/plugins/types.ts +76 -381
  254. package/src/plugins/user-loader.ts +30 -127
  255. package/src/prompts/__tests__/system-prompt.test.ts +6 -0
  256. package/src/prompts/templates/BOOTSTRAP-ACTIVATION-RAIL.md +35 -3
  257. package/src/runtime/__tests__/agent-wake.test.ts +555 -691
  258. package/src/runtime/__tests__/interactive-ui.test.ts +1 -1
  259. package/src/runtime/agent-wake.ts +108 -209
  260. package/src/runtime/assistant-event-hub.ts +1 -1
  261. package/src/runtime/channel-approvals.ts +1 -1
  262. package/src/runtime/interactive-ui.ts +1 -1
  263. package/src/runtime/routes/__tests__/acp-routes.test.ts +315 -55
  264. package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +1 -1
  265. package/src/runtime/routes/__tests__/plugins-routes.test.ts +423 -73
  266. package/src/runtime/routes/__tests__/surface-action-routes.test.ts +5 -4
  267. package/src/runtime/routes/__tests__/surface-content-routes.test.ts +4 -1
  268. package/src/runtime/routes/acp-routes.test.ts +89 -25
  269. package/src/runtime/routes/acp-routes.ts +81 -29
  270. package/src/runtime/routes/approval-routes.ts +1 -1
  271. package/src/runtime/routes/browser-routes.ts +1 -1
  272. package/src/runtime/routes/browser-tabs-routes.ts +6 -10
  273. package/src/runtime/routes/conversation-cli-routes.ts +1 -1
  274. package/src/runtime/routes/conversation-list-routes.ts +1 -1
  275. package/src/runtime/routes/conversation-query-routes.ts +1 -1
  276. package/src/runtime/routes/conversation-routes.ts +28 -2
  277. package/src/runtime/routes/conversation-starter-routes.ts +13 -7
  278. package/src/runtime/routes/conversations-import-routes.ts +24 -7
  279. package/src/runtime/routes/host-app-control-routes.ts +1 -1
  280. package/src/runtime/routes/host-cu-routes.ts +1 -1
  281. package/src/runtime/routes/identity-routes.ts +18 -3
  282. package/src/runtime/routes/inbound-message-handler.ts +1 -1
  283. package/src/runtime/routes/inference-profile-session-handler.ts +11 -0
  284. package/src/runtime/routes/inference-profile-session-reaper.ts +6 -0
  285. package/src/runtime/routes/memory-v3-routes.ts +16 -6
  286. package/src/runtime/routes/playground/helpers.ts +1 -1
  287. package/src/runtime/routes/plugins-routes.ts +337 -35
  288. package/src/runtime/routes/surface-conversation-resolver.ts +4 -3
  289. package/src/runtime/routes/work-items-routes.ts +2 -4
  290. package/src/runtime/services/conversation-serializer.ts +1 -1
  291. package/src/signals/cancel.ts +2 -4
  292. package/src/subagent/manager.ts +21 -5
  293. package/src/tools/acp/context.ts +20 -0
  294. package/src/tools/acp/list-agents.test.ts +8 -2
  295. package/src/tools/acp/spawn.test.ts +176 -195
  296. package/src/tools/acp/spawn.ts +37 -172
  297. package/src/tools/acp/steer.test.ts +105 -8
  298. package/src/tools/acp/steer.ts +48 -17
  299. package/src/tools/apps/executors.ts +166 -50
  300. package/src/tools/filesystem/write.ts +34 -0
  301. package/src/tools/subagent/spawn.ts +2 -4
  302. package/src/tools/ui-surface/definitions.ts +25 -5
  303. package/src/workspace/migrations/051-seed-conversation-summarization-callsite.ts +4 -5
  304. package/src/workspace/migrations/097-enable-adaptive-thinking-managed-profiles.ts +69 -45
  305. package/docs/plugins.md +0 -832
  306. package/examples/plugins/echo/register.ts +0 -143
  307. package/src/__tests__/circuit-breaker-pipeline.test.ts +0 -405
  308. package/src/__tests__/compaction-pipeline.test.ts +0 -210
  309. package/src/__tests__/compaction-timeout-recovery.test.ts +0 -251
  310. package/src/__tests__/overflow-reduce-pipeline.test.ts +0 -667
  311. package/src/__tests__/pipeline-runner.test.ts +0 -554
  312. package/src/__tests__/plugin-external-api.test.ts +0 -68
  313. package/src/daemon/wake-target-adapter.ts +0 -253
  314. package/src/plugins/defaults/circuit-breaker/middlewares/circuitBreaker.ts +0 -93
  315. package/src/plugins/defaults/circuit-breaker/package.json +0 -15
  316. package/src/plugins/defaults/circuit-breaker/register.ts +0 -39
  317. package/src/plugins/defaults/compaction/middlewares/compaction.ts +0 -25
  318. package/src/plugins/defaults/compaction/register.ts +0 -35
  319. package/src/plugins/defaults/compaction/terminal.ts +0 -73
  320. package/src/plugins/defaults/empty-response/register.ts +0 -23
  321. package/src/plugins/defaults/history-repair/register.ts +0 -24
  322. package/src/plugins/defaults/overflow-reduce/middlewares/overflowReduce.ts +0 -126
  323. package/src/plugins/defaults/overflow-reduce/package.json +0 -15
  324. package/src/plugins/defaults/overflow-reduce/register.ts +0 -42
  325. package/src/plugins/defaults/title-generate/register.ts +0 -35
  326. package/src/plugins/defaults/tool-error/register.ts +0 -23
  327. package/src/plugins/defaults/tool-result-truncate/register.ts +0 -24
  328. package/src/plugins/external-api.ts +0 -104
  329. package/src/proactive-artifact/aux-message-injector.ts +0 -97
  330. package/src/proactive-artifact/decision.test.ts +0 -226
  331. package/src/proactive-artifact/decision.ts +0 -165
  332. package/src/proactive-artifact/index.ts +0 -7
  333. package/src/proactive-artifact/job.test.ts +0 -962
  334. package/src/proactive-artifact/job.ts +0 -372
  335. package/src/proactive-artifact/message-copy.ts +0 -58
  336. package/src/proactive-artifact/trigger-state.test.ts +0 -286
  337. package/src/proactive-artifact/trigger-state.ts +0 -123
  338. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/capabilities.test.ts +0 -0
  339. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/core.test.ts +0 -0
  340. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/fixtures/eval-turns.json +0 -0
  341. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/fixtures/live-turns.json +0 -0
  342. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/health.test.ts +0 -0
  343. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/needle.test.ts +0 -0
  344. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/provider-blocks.test.ts +0 -0
  345. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/snapshot.test.ts +0 -0
  346. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/tree.test.ts +0 -0
  347. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/working-set-eviction.test.ts +0 -0
  348. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/working-set-skeleton.test.ts +0 -0
  349. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/core.ts +0 -0
  350. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/README.md +0 -0
  351. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/assignments.json +0 -0
  352. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/core.json +0 -0
  353. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-a/topic-x.md +0 -0
  354. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-a/topic-y.md +0 -0
  355. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-b/topic-z.md +0 -0
  356. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/health.ts +0 -0
  357. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/llm-retry.ts +0 -0
  358. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/needle.ts +0 -0
  359. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/snapshot.ts +0 -0
  360. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/working-set.ts +0 -0
@@ -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);