@vellumai/assistant 0.8.8 → 0.8.9-dev.202606091926.ebb2d62

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 (490) hide show
  1. package/ARCHITECTURE.md +6 -6
  2. package/bun.lock +2 -2
  3. package/docs/activation-funnel-telemetry.md +310 -0
  4. package/examples/plugins/echo/README.md +61 -60
  5. package/examples/plugins/echo/hooks/post-tool-use.ts +18 -0
  6. package/examples/plugins/echo/hooks/stop.ts +16 -0
  7. package/examples/plugins/echo/hooks/user-prompt-submit.ts +18 -0
  8. package/examples/plugins/echo/package.json +1 -2
  9. package/examples/plugins/echo/src/emit.ts +19 -0
  10. package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +7 -6
  11. package/openapi.yaml +273 -121
  12. package/package.json +2 -2
  13. package/scripts/sync-llm-catalog.ts +2 -0
  14. package/src/__tests__/activation-early-marking.test.ts +120 -0
  15. package/src/__tests__/agent-loop-callsite-precedence.test.ts +69 -14
  16. package/src/__tests__/agent-loop-exit-reason.test.ts +204 -144
  17. package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +50 -35
  18. package/src/__tests__/agent-loop-output-hooks.test.ts +357 -0
  19. package/src/__tests__/agent-loop-override-profile.test.ts +25 -6
  20. package/src/__tests__/agent-loop-provider-error-recording.test.ts +41 -21
  21. package/src/__tests__/agent-loop-thinking.test.ts +36 -20
  22. package/src/__tests__/agent-loop.test.ts +441 -96
  23. package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +14 -14
  24. package/src/__tests__/agent-wake-override-profile.test.ts +17 -21
  25. package/src/__tests__/anthropic-provider.test.ts +23 -8
  26. package/src/__tests__/app-builder-tool-scripts.test.ts +21 -0
  27. package/src/__tests__/app-control-flow.test.ts +1 -1
  28. package/src/__tests__/app-dir-path-guard.test.ts +1 -0
  29. package/src/__tests__/app-executors.test.ts +132 -0
  30. package/src/__tests__/approval-cascade.test.ts +6 -5
  31. package/src/__tests__/approval-routes-http.test.ts +4 -1
  32. package/src/__tests__/background-workers-disk-pressure.test.ts +1 -1
  33. package/src/__tests__/build-persisted-content.test.ts +75 -1
  34. package/src/__tests__/channel-approval-routes.test.ts +1 -1
  35. package/src/__tests__/channel-approvals.test.ts +1 -1
  36. package/src/__tests__/compaction-circuit.test.ts +258 -0
  37. package/src/__tests__/compaction-direct.test.ts +146 -0
  38. package/src/__tests__/compaction-events.test.ts +7 -7
  39. package/src/__tests__/compaction.benchmark.test.ts +1 -1
  40. package/src/__tests__/compactor-web-search-strip.test.ts +213 -0
  41. package/src/__tests__/config-managed-gemini-defaults.test.ts +2 -46
  42. package/src/__tests__/context-overflow-reducer.test.ts +265 -125
  43. package/src/__tests__/context-window-manager-compact-retry.test.ts +121 -15
  44. package/src/__tests__/conversation-abort-tool-results.test.ts +7 -5
  45. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +7 -10
  46. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +78 -119
  47. package/src/__tests__/conversation-agent-loop-overflow.test.ts +158 -234
  48. package/src/__tests__/conversation-agent-loop.test.ts +342 -623
  49. package/src/__tests__/conversation-clean-command.test.ts +5 -2
  50. package/src/__tests__/conversation-confirmation-signals.test.ts +6 -5
  51. package/src/__tests__/conversation-crud-inference-profile.test.ts +7 -9
  52. package/src/__tests__/conversation-error.test.ts +15 -1
  53. package/src/__tests__/conversation-history-web-search.test.ts +6 -1
  54. package/src/__tests__/conversation-media-retry.test.ts +1 -1
  55. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +44 -4
  56. package/src/__tests__/conversation-process-callsite.test.ts +15 -15
  57. package/src/__tests__/conversation-provider-retry-repair.test.ts +66 -65
  58. package/src/__tests__/conversation-queue.test.ts +10 -10
  59. package/src/__tests__/conversation-runtime-assembly.test.ts +1059 -231
  60. package/src/__tests__/conversation-runtime-workspace.test.ts +115 -20
  61. package/src/__tests__/conversation-slash-queue.test.ts +7 -5
  62. package/src/__tests__/conversation-slash-unknown.test.ts +7 -5
  63. package/src/__tests__/conversation-speed-override.test.ts +11 -10
  64. package/src/__tests__/conversation-starter-routes.test.ts +14 -6
  65. package/src/__tests__/conversation-surfaces-activation-emit.test.ts +395 -0
  66. package/src/__tests__/conversation-surfaces-app-control.test.ts +48 -1
  67. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +73 -4
  68. package/src/__tests__/conversation-undo.test.ts +2 -2
  69. package/src/__tests__/conversation-workspace-cache-state.test.ts +24 -21
  70. package/src/__tests__/conversation-workspace-injection.test.ts +69 -7
  71. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +15 -12
  72. package/src/__tests__/conversations-import-system-filter.test.ts +101 -0
  73. package/src/__tests__/corrected-target.test.ts +93 -0
  74. package/src/__tests__/credential-execution-feature-gates.test.ts +5 -4
  75. package/src/__tests__/credential-security-invariants.test.ts +1 -0
  76. package/src/__tests__/cu-unified-flow.test.ts +36 -0
  77. package/src/__tests__/db-acp-history.test.ts +101 -0
  78. package/src/__tests__/dynamic-page-surface.test.ts +31 -0
  79. package/src/__tests__/embedding-managed-proxy-selection.test.ts +6 -40
  80. package/src/__tests__/empty-response-hook.test.ts +1 -1
  81. package/src/__tests__/file-write-tool.test.ts +63 -0
  82. package/src/__tests__/gateway-only-guard.test.ts +17 -2
  83. package/src/__tests__/guardian-grant-minting.test.ts +1 -1
  84. package/src/__tests__/guardian-routing-invariants.test.ts +93 -4
  85. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +1 -1
  86. package/src/__tests__/heartbeat-disk-pressure.test.ts +1 -0
  87. package/src/__tests__/heartbeat-service.test.ts +1 -0
  88. package/src/__tests__/history-repair-hook.test.ts +5 -1
  89. package/src/__tests__/host-app-control-proxy.test.ts +45 -0
  90. package/src/__tests__/host-app-control-routes.test.ts +1 -1
  91. package/src/__tests__/host-cu-routes-targeted.test.ts +3 -3
  92. package/src/__tests__/inference-profile-reaper.test.ts +62 -0
  93. package/src/__tests__/inference-profile-session-handler.test.ts +86 -0
  94. package/src/__tests__/injector-background-turn.test.ts +13 -23
  95. package/src/__tests__/injector-chain.test.ts +268 -44
  96. package/src/__tests__/injector-disk-pressure.test.ts +210 -52
  97. package/src/__tests__/injector-document-comments.test.ts +97 -114
  98. package/src/__tests__/injector-pkb-v2-silenced.test.ts +2 -2
  99. package/src/__tests__/injector-v3-suppression.test.ts +4 -4
  100. package/src/__tests__/list-messages-client-message-id.test.ts +91 -0
  101. package/src/__tests__/list-messages-hidden-metadata.test.ts +38 -0
  102. package/src/__tests__/llm-catalog-parity.test.ts +4 -0
  103. package/src/__tests__/llm-resolver.test.ts +73 -0
  104. package/src/__tests__/memory-retrieval-hook.test.ts +156 -38
  105. package/src/__tests__/memory-v2-static-injector.test.ts +86 -8
  106. package/src/__tests__/notification-decision-strategy.test.ts +3 -3
  107. package/src/__tests__/parallel-tool.benchmark.test.ts +35 -8
  108. package/src/__tests__/persist-unsendable-image-downscale.test.ts +145 -0
  109. package/src/__tests__/persist-unsendable-image.test.ts +97 -1
  110. package/src/__tests__/persistence-secret-redaction.test.ts +78 -0
  111. package/src/__tests__/plugin-api-shim.test.ts +6 -9
  112. package/src/__tests__/plugin-bootstrap.test.ts +91 -81
  113. package/src/__tests__/plugin-registry.test.ts +3 -49
  114. package/src/__tests__/plugin-skill-contribution.test.ts +15 -14
  115. package/src/__tests__/plugin-tool-contribution.test.ts +7 -4
  116. package/src/__tests__/plugin-types.test.ts +0 -70
  117. package/src/__tests__/post-turn-tool-result-truncation.test.ts +69 -0
  118. package/src/__tests__/pre-model-call-sanitize.test.ts +109 -0
  119. package/src/__tests__/published-app-updater.test.ts +138 -0
  120. package/src/__tests__/reaction-persistence.test.ts +1 -1
  121. package/src/__tests__/retry-thinking-adaptive-only.test.ts +245 -0
  122. package/src/__tests__/send-endpoint-busy.test.ts +4 -1
  123. package/src/__tests__/server-history-render.test.ts +39 -0
  124. package/src/__tests__/skill-feature-flags-integration.test.ts +31 -0
  125. package/src/__tests__/steer-tool-repair.test.ts +1 -1
  126. package/src/__tests__/subagent-call-site-routing.test.ts +1 -1
  127. package/src/__tests__/subagent-detail.test.ts +25 -7
  128. package/src/__tests__/subagent-fork-notifications.test.ts +1 -3
  129. package/src/__tests__/subagent-fork-spawn.test.ts +1 -1
  130. package/src/__tests__/subagent-manager-notify.test.ts +1 -3
  131. package/src/__tests__/subagent-notify-parent.test.ts +1 -3
  132. package/src/__tests__/subagent-spawn-tool-fork.test.ts +1 -1
  133. package/src/__tests__/title-generate-hook.test.ts +5 -1
  134. package/src/__tests__/tool-error-hook.test.ts +1 -1
  135. package/src/__tests__/tool-result-truncate-hook.test.ts +1 -1
  136. package/src/__tests__/tool-start-timestamp.test.ts +218 -0
  137. package/src/__tests__/user-plugin-loader.test.ts +54 -286
  138. package/src/__tests__/web-fetch.test.ts +45 -0
  139. package/src/acp/__tests__/agent-process.test.ts +161 -0
  140. package/src/acp/__tests__/client-handler.test.ts +40 -0
  141. package/src/acp/__tests__/helpers/acp-config-stub.ts +0 -2
  142. package/src/acp/__tests__/helpers/acp-history-db.ts +82 -0
  143. package/src/acp/__tests__/helpers/exec-file-stub.ts +106 -0
  144. package/src/acp/__tests__/prepare-agent-env.test.ts +97 -0
  145. package/src/acp/__tests__/session-manager-persistence.test.ts +95 -28
  146. package/src/acp/__tests__/session-manager-resume.test.ts +888 -0
  147. package/src/acp/agent-process.ts +61 -1
  148. package/src/acp/auto-install.test.ts +280 -0
  149. package/src/acp/auto-install.ts +232 -0
  150. package/src/acp/client-handler.ts +31 -0
  151. package/src/acp/prepare-agent-env.ts +80 -27
  152. package/src/acp/resolve-agent.test.ts +188 -28
  153. package/src/acp/resolve-agent.ts +119 -42
  154. package/src/acp/resume-hint.ts +23 -0
  155. package/src/acp/session-manager.ts +507 -73
  156. package/src/agent/compaction-circuit.ts +60 -102
  157. package/src/agent/loop.ts +403 -251
  158. package/src/api/events/tool-result.ts +9 -0
  159. package/src/api/events/tool-use-start.ts +7 -0
  160. package/src/api/responses/conversation-message.ts +72 -13
  161. package/src/api/responses/memory-v3-selection-log.ts +19 -10
  162. package/src/approvals/guardian-request-resolvers.ts +27 -1
  163. package/src/background-wake/next-wake.ts +1 -0
  164. package/src/cli/commands/__tests__/memory-v3.test.ts +191 -210
  165. package/src/cli/commands/channel-verification-sessions.ts +6 -6
  166. package/src/cli/commands/db/__tests__/repair.test.ts +3 -1
  167. package/src/cli/commands/memory-v3.ts +57 -199
  168. package/src/cli/commands/plugins.ts +43 -37
  169. package/src/cli/lib/__tests__/install-from-github.test.ts +790 -111
  170. package/src/cli/lib/__tests__/plugin-catalog-cache.test.ts +196 -0
  171. package/src/cli/lib/__tests__/plugin-details.test.ts +381 -0
  172. package/src/cli/lib/__tests__/plugin-marketplace.test.ts +270 -0
  173. package/src/cli/lib/__tests__/search-plugins.test.ts +233 -32
  174. package/src/cli/lib/install-from-github.ts +797 -60
  175. package/src/cli/lib/plugin-catalog-cache.ts +84 -0
  176. package/src/cli/lib/plugin-details.ts +416 -0
  177. package/src/cli/lib/plugin-marketplace.ts +215 -0
  178. package/src/cli/lib/search-plugins.ts +201 -29
  179. package/src/config/__tests__/feature-flag-registry-guard.test.ts +2 -2
  180. package/src/config/acp-defaults.test.ts +10 -0
  181. package/src/config/acp-defaults.ts +9 -3
  182. package/src/config/acp-schema.ts +1 -7
  183. package/src/config/bundled-skills/acp/SKILL.md +80 -41
  184. package/src/config/bundled-skills/acp/TOOLS.json +4 -4
  185. package/src/config/bundled-skills/app-builder/SKILL.md +224 -381
  186. package/src/config/bundled-skills/app-builder/TOOLS.json +72 -2
  187. package/src/config/bundled-skills/app-builder/references/DESIGN_SYSTEM.md +48 -0
  188. package/src/config/bundled-skills/app-builder/references/RESPONSIVE.md +57 -0
  189. package/src/config/bundled-skills/app-builder/references/SLIDES.md +38 -0
  190. package/src/config/bundled-skills/app-builder/tools/app-list.ts +62 -0
  191. package/src/config/bundled-skills/app-builder/tools/app-update.ts +18 -0
  192. package/src/config/bundled-skills/document-editor/SKILL.md +28 -23
  193. package/src/config/bundled-skills/document-editor/TOOLS.json +1 -1
  194. package/src/config/bundled-tool-registry.ts +4 -0
  195. package/src/config/call-site-defaults.ts +0 -3
  196. package/src/config/feature-flag-registry.json +10 -56
  197. package/src/config/llm-resolver.ts +39 -7
  198. package/src/config/loader.ts +5 -22
  199. package/src/config/schemas/__tests__/memory-v3.test.ts +25 -9
  200. package/src/config/schemas/call-site-catalog.ts +0 -21
  201. package/src/config/schemas/heartbeat.ts +9 -0
  202. package/src/config/schemas/llm.ts +17 -3
  203. package/src/config/schemas/memory-v3.ts +58 -8
  204. package/src/config/seed-inference-profiles.ts +18 -0
  205. package/src/context/compactor.ts +22 -4
  206. package/src/context/post-turn-tool-result-truncation.ts +39 -1
  207. package/src/context/strip-injections.ts +8 -2
  208. package/src/daemon/conversation-agent-loop-handlers.ts +120 -42
  209. package/src/daemon/conversation-agent-loop.ts +308 -1297
  210. package/src/daemon/conversation-error.ts +31 -4
  211. package/src/daemon/conversation-history.ts +1 -1
  212. package/src/daemon/conversation-lifecycle.ts +11 -255
  213. package/src/daemon/conversation-media-retry.ts +19 -6
  214. package/src/daemon/conversation-messaging.ts +17 -0
  215. package/src/daemon/conversation-process.ts +22 -141
  216. package/src/daemon/conversation-queue-manager.ts +8 -0
  217. package/src/daemon/conversation-registry.ts +159 -0
  218. package/src/daemon/conversation-runtime-assembly.ts +361 -393
  219. package/src/daemon/conversation-store.ts +9 -90
  220. package/src/daemon/conversation-surfaces.ts +165 -11
  221. package/src/daemon/conversation-workspace.ts +17 -0
  222. package/src/daemon/conversation.ts +444 -62
  223. package/src/daemon/disk-pressure-policy.ts +0 -1
  224. package/src/daemon/external-plugins-bootstrap.ts +36 -46
  225. package/src/daemon/handlers/config-channels.ts +11 -2
  226. package/src/daemon/handlers/conversations.ts +3 -1
  227. package/src/daemon/handlers/shared.ts +9 -1
  228. package/src/daemon/handlers/skills.ts +4 -1
  229. package/src/daemon/host-app-control-proxy.ts +72 -57
  230. package/src/daemon/host-proxy-preactivation.ts +1 -3
  231. package/src/daemon/lifecycle.ts +21 -7
  232. package/src/daemon/persist-unsendable-image.ts +62 -25
  233. package/src/daemon/process-message.ts +1 -1
  234. package/src/daemon/server.ts +2 -0
  235. package/src/daemon/tool-side-effects.ts +15 -0
  236. package/src/daemon/wake-conversation-ops.ts +269 -0
  237. package/src/embedded/plugin-api.ts +2 -2
  238. package/src/export/__tests__/transcript-formatter.test.ts +5 -0
  239. package/src/heartbeat/__tests__/heartbeat-service.test.ts +3 -0
  240. package/src/heartbeat/heartbeat-run-store.ts +23 -1
  241. package/src/heartbeat/heartbeat-service.ts +26 -0
  242. package/src/ipc/__tests__/browser-ipc.test.ts +1 -1
  243. package/src/ipc/__tests__/ui-request-route.test.ts +3 -3
  244. package/src/ipc/skill-routes/__tests__/memory.test.ts +15 -0
  245. package/src/ipc/skill-routes/memory.ts +4 -2
  246. package/src/memory/__tests__/activation-session-store.test.ts +41 -0
  247. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +87 -0
  248. package/src/memory/__tests__/onboarding-events-store.test.ts +80 -0
  249. package/src/memory/activation-session-store.ts +43 -0
  250. package/src/memory/conversation-crud.ts +29 -19
  251. package/src/memory/conversation-starter-checkpoints.ts +1 -0
  252. package/src/memory/db-init.ts +6 -0
  253. package/src/memory/embedding-backend.ts +5 -22
  254. package/src/memory/job-handlers/conversation-starters.ts +13 -2
  255. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +5 -4
  256. package/src/memory/jobs-worker.ts +25 -1
  257. package/src/memory/migrations/272-acp-session-history-cwd.ts +36 -0
  258. package/src/memory/migrations/273-onboarding-events-funnel-columns.ts +46 -0
  259. package/src/memory/migrations/274-create-activation-sessions.ts +15 -0
  260. package/src/memory/migrations/index.ts +3 -0
  261. package/src/memory/onboarding-events-store.ts +66 -18
  262. package/src/memory/schema/acp.ts +4 -0
  263. package/src/memory/schema/infrastructure.ts +13 -0
  264. package/src/memory/v2/__tests__/consolidation-job.test.ts +4 -97
  265. package/src/memory/v2/__tests__/page-store.test.ts +22 -0
  266. package/src/memory/v2/consolidation-job.ts +2 -63
  267. package/src/memory/v2/types.ts +5 -0
  268. package/src/messaging/providers/telegram-bot/api.ts +14 -5
  269. package/src/notifications/__tests__/copy-composer.test.ts +244 -0
  270. package/src/notifications/access-request-copy.ts +298 -0
  271. package/src/notifications/adapters/slack.ts +3 -3
  272. package/src/notifications/adapters/telegram.ts +9 -2
  273. package/src/notifications/copy-composer.ts +49 -267
  274. package/src/notifications/decision-engine.ts +16 -35
  275. package/src/notifications/home-feed-side-effect.ts +1 -6
  276. package/src/plugin-api/constants.ts +4 -0
  277. package/src/plugin-api/index.ts +40 -11
  278. package/src/plugin-api/types.ts +108 -0
  279. package/src/plugins/defaults/compaction/compact.ts +106 -0
  280. package/src/{daemon → plugins/defaults/compaction}/context-overflow-reducer.ts +250 -42
  281. package/src/plugins/defaults/compaction/corrected-target.ts +53 -0
  282. package/src/plugins/defaults/compaction/manager-store.ts +57 -0
  283. package/src/plugins/defaults/compaction/package.json +1 -2
  284. package/src/{context → plugins/defaults/compaction}/window-manager.ts +95 -25
  285. package/src/plugins/defaults/empty-response/package.json +0 -1
  286. package/src/plugins/defaults/history-repair/package.json +0 -1
  287. package/src/plugins/defaults/index.ts +156 -26
  288. package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +100 -52
  289. package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit.ts +285 -0
  290. package/src/plugins/defaults/memory-retrieval/injector-chain.ts +2 -2
  291. package/src/plugins/defaults/{injectors/register.ts → memory-retrieval/injectors.ts} +148 -73
  292. package/src/plugins/defaults/memory-retrieval/package.json +14 -0
  293. package/src/plugins/defaults/memory-retrieval/unified-turn-context.ts +223 -0
  294. package/src/plugins/defaults/memory-v3-shadow/__tests__/capabilities.test.ts +71 -0
  295. package/src/plugins/defaults/memory-v3-shadow/__tests__/dense.test.ts +181 -0
  296. package/src/plugins/defaults/memory-v3-shadow/__tests__/edge.test.ts +247 -0
  297. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/live-integration.test.ts +147 -134
  298. package/src/plugins/defaults/memory-v3-shadow/__tests__/maintain-job.test.ts +456 -0
  299. package/src/plugins/defaults/memory-v3-shadow/__tests__/orchestrate.test.ts +662 -0
  300. package/src/plugins/defaults/memory-v3-shadow/__tests__/pool-select.test.ts +306 -0
  301. package/src/plugins/defaults/memory-v3-shadow/__tests__/render-injection.test.ts +91 -0
  302. package/src/plugins/defaults/memory-v3-shadow/__tests__/section-dense-store.test.ts +402 -0
  303. package/src/plugins/defaults/memory-v3-shadow/__tests__/section-needle.test.ts +135 -0
  304. package/src/plugins/defaults/memory-v3-shadow/__tests__/sections.test.ts +125 -0
  305. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/selection-log-store.test.ts +74 -19
  306. package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-integration.test.ts +446 -0
  307. package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +592 -0
  308. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/types.test.ts +2 -24
  309. package/src/plugins/defaults/memory-v3-shadow/capabilities.ts +91 -0
  310. package/src/plugins/defaults/memory-v3-shadow/dense.ts +97 -0
  311. package/src/plugins/defaults/memory-v3-shadow/edge.ts +252 -0
  312. package/src/plugins/defaults/memory-v3-shadow/hooks/post-compact.ts +14 -0
  313. package/src/plugins/defaults/memory-v3-shadow/hooks/user-prompt-submit.ts +19 -0
  314. package/src/plugins/defaults/memory-v3-shadow/injector.ts +76 -0
  315. package/src/plugins/defaults/memory-v3-shadow/maintain-job.ts +555 -0
  316. package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +266 -0
  317. package/src/plugins/defaults/memory-v3-shadow/package.json +14 -0
  318. package/src/plugins/defaults/memory-v3-shadow/page-content.ts +71 -0
  319. package/src/plugins/defaults/memory-v3-shadow/pool-select.ts +204 -0
  320. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/render-injection.ts +16 -8
  321. package/src/plugins/defaults/memory-v3-shadow/section-dense-store.ts +236 -0
  322. package/src/plugins/defaults/memory-v3-shadow/section-needle.ts +200 -0
  323. package/src/plugins/defaults/memory-v3-shadow/sections.ts +115 -0
  324. package/src/plugins/defaults/memory-v3-shadow/selection-log-store.ts +156 -0
  325. package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +382 -0
  326. package/src/plugins/defaults/memory-v3-shadow/types.ts +92 -0
  327. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/working-set.ts +4 -1
  328. package/src/plugins/defaults/title-generate/package.json +0 -1
  329. package/src/plugins/defaults/tool-error/package.json +0 -1
  330. package/src/plugins/defaults/tool-result-truncate/package.json +0 -1
  331. package/src/plugins/external-api.ts +12 -2
  332. package/src/plugins/pipeline.ts +6 -293
  333. package/src/plugins/registry.ts +9 -37
  334. package/src/plugins/types.ts +76 -381
  335. package/src/plugins/user-loader.ts +30 -127
  336. package/src/prompts/__tests__/system-prompt.test.ts +6 -0
  337. package/src/prompts/system-prompt.ts +61 -10
  338. package/src/prompts/templates/BOOTSTRAP-ACTIVATION-RAIL.md +71 -4
  339. package/src/providers/anthropic/client.ts +9 -10
  340. package/src/providers/inference/kimi-cjk-token-ids.ts +493 -0
  341. package/src/providers/inference/logit-bias.ts +55 -0
  342. package/src/providers/model-catalog.ts +57 -0
  343. package/src/providers/openai/__tests__/vision-not-supported.test.ts +75 -0
  344. package/src/providers/openai/chat-completions-provider.ts +44 -1
  345. package/src/providers/retry.ts +57 -7
  346. package/src/providers/types.ts +6 -0
  347. package/src/runtime/__tests__/agent-wake.test.ts +555 -691
  348. package/src/runtime/__tests__/interactive-ui.test.ts +1 -1
  349. package/src/runtime/agent-wake.ts +108 -209
  350. package/src/runtime/assistant-event-hub.ts +1 -1
  351. package/src/runtime/channel-approvals.ts +1 -1
  352. package/src/runtime/interactive-ui.ts +1 -1
  353. package/src/runtime/routes/__tests__/acp-routes.test.ts +466 -55
  354. package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +1 -1
  355. package/src/runtime/routes/__tests__/plugins-routes.test.ts +423 -73
  356. package/src/runtime/routes/__tests__/stt-routes.test.ts +112 -0
  357. package/src/runtime/routes/__tests__/surface-action-routes.test.ts +5 -4
  358. package/src/runtime/routes/__tests__/surface-content-routes.test.ts +4 -1
  359. package/src/runtime/routes/acp-routes.test.ts +185 -32
  360. package/src/runtime/routes/acp-routes.ts +328 -30
  361. package/src/runtime/routes/app-management-routes.ts +3 -0
  362. package/src/runtime/routes/approval-routes.ts +1 -1
  363. package/src/runtime/routes/browser-routes.ts +1 -1
  364. package/src/runtime/routes/browser-tabs-routes.ts +6 -10
  365. package/src/runtime/routes/channel-verification-routes.ts +14 -5
  366. package/src/runtime/routes/conversation-cli-routes.ts +1 -1
  367. package/src/runtime/routes/conversation-list-routes.ts +1 -1
  368. package/src/runtime/routes/conversation-query-routes.ts +1 -1
  369. package/src/runtime/routes/conversation-routes.ts +30 -2
  370. package/src/runtime/routes/conversation-starter-routes.ts +13 -7
  371. package/src/runtime/routes/conversations-import-routes.ts +24 -7
  372. package/src/runtime/routes/host-app-control-routes.ts +1 -1
  373. package/src/runtime/routes/host-cu-routes.ts +1 -1
  374. package/src/runtime/routes/identity-routes.ts +18 -3
  375. package/src/runtime/routes/inbound-message-handler.ts +1 -1
  376. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +33 -34
  377. package/src/runtime/routes/inference-profile-session-handler.ts +11 -0
  378. package/src/runtime/routes/inference-profile-session-reaper.ts +6 -0
  379. package/src/runtime/routes/memory-v3-routes.ts +65 -305
  380. package/src/runtime/routes/playground/__tests__/force-compact.test.ts +1 -1
  381. package/src/runtime/routes/playground/helpers.ts +1 -1
  382. package/src/runtime/routes/plugins-routes.ts +337 -35
  383. package/src/runtime/routes/stt-routes.ts +45 -12
  384. package/src/runtime/routes/surface-conversation-resolver.ts +4 -3
  385. package/src/runtime/routes/work-items-routes.ts +2 -4
  386. package/src/runtime/routes/workspace-routes.ts +50 -15
  387. package/src/runtime/services/conversation-serializer.ts +1 -1
  388. package/src/runtime/verification-outbound-actions.ts +147 -2
  389. package/src/runtime/verification-templates.ts +29 -3
  390. package/src/services/published-app-updater.ts +30 -8
  391. package/src/signals/cancel.ts +2 -4
  392. package/src/subagent/manager.ts +21 -5
  393. package/src/telemetry/__tests__/activation-funnel.test.ts +95 -0
  394. package/src/telemetry/activation-funnel.ts +167 -0
  395. package/src/telemetry/types.ts +13 -0
  396. package/src/telemetry/usage-telemetry-reporter.test.ts +154 -0
  397. package/src/telemetry/usage-telemetry-reporter.ts +26 -1
  398. package/src/tools/acp/context.ts +20 -0
  399. package/src/tools/acp/list-agents.test.ts +9 -19
  400. package/src/tools/acp/list-agents.ts +3 -15
  401. package/src/tools/acp/spawn.test.ts +173 -202
  402. package/src/tools/acp/spawn.ts +37 -172
  403. package/src/tools/acp/steer.test.ts +105 -8
  404. package/src/tools/acp/steer.ts +48 -17
  405. package/src/tools/apps/executors.ts +166 -50
  406. package/src/tools/browser/browser-execution.ts +12 -2
  407. package/src/tools/filesystem/write.ts +34 -0
  408. package/src/tools/network/web-fetch.ts +65 -24
  409. package/src/tools/skills/load.ts +1 -1
  410. package/src/tools/subagent/spawn.ts +2 -4
  411. package/src/tools/ui-surface/definitions.ts +32 -5
  412. package/src/workspace/migrations/051-seed-conversation-summarization-callsite.ts +4 -5
  413. package/src/workspace/migrations/097-enable-adaptive-thinking-managed-profiles.ts +69 -45
  414. package/docs/plugins.md +0 -832
  415. package/examples/plugins/echo/register.ts +0 -143
  416. package/src/__tests__/circuit-breaker-pipeline.test.ts +0 -405
  417. package/src/__tests__/compaction-pipeline.test.ts +0 -210
  418. package/src/__tests__/compaction-timeout-recovery.test.ts +0 -251
  419. package/src/__tests__/overflow-reduce-pipeline.test.ts +0 -667
  420. package/src/__tests__/pipeline-runner.test.ts +0 -554
  421. package/src/daemon/wake-target-adapter.ts +0 -253
  422. package/src/memory/v3/__tests__/assign.test.ts +0 -242
  423. package/src/memory/v3/__tests__/capabilities.test.ts +0 -118
  424. package/src/memory/v3/__tests__/core.test.ts +0 -39
  425. package/src/memory/v3/__tests__/health.test.ts +0 -219
  426. package/src/memory/v3/__tests__/maintain-job.test.ts +0 -288
  427. package/src/memory/v3/__tests__/needle.test.ts +0 -107
  428. package/src/memory/v3/__tests__/orchestrate.test.ts +0 -436
  429. package/src/memory/v3/__tests__/provider-blocks.test.ts +0 -13
  430. package/src/memory/v3/__tests__/reconcile.test.ts +0 -274
  431. package/src/memory/v3/__tests__/render-injection.test.ts +0 -61
  432. package/src/memory/v3/__tests__/router.test.ts +0 -332
  433. package/src/memory/v3/__tests__/selector.test.ts +0 -470
  434. package/src/memory/v3/__tests__/shadow-plugin.test.ts +0 -432
  435. package/src/memory/v3/__tests__/snapshot.test.ts +0 -168
  436. package/src/memory/v3/__tests__/tree.test.ts +0 -192
  437. package/src/memory/v3/assign.ts +0 -268
  438. package/src/memory/v3/capabilities.ts +0 -124
  439. package/src/memory/v3/core.ts +0 -26
  440. package/src/memory/v3/health.ts +0 -0
  441. package/src/memory/v3/maintain-job.ts +0 -314
  442. package/src/memory/v3/needle.ts +0 -115
  443. package/src/memory/v3/orchestrate.ts +0 -126
  444. package/src/memory/v3/page-content.ts +0 -34
  445. package/src/memory/v3/provider-blocks.ts +0 -26
  446. package/src/memory/v3/reconcile.ts +0 -523
  447. package/src/memory/v3/router.ts +0 -190
  448. package/src/memory/v3/selection-log-store.ts +0 -84
  449. package/src/memory/v3/selector.ts +0 -226
  450. package/src/memory/v3/shadow-plugin.ts +0 -411
  451. package/src/memory/v3/snapshot.ts +0 -209
  452. package/src/memory/v3/tree.ts +0 -174
  453. package/src/memory/v3/types.ts +0 -59
  454. package/src/notifications/__tests__/emit-signal-home-feed.test.ts +0 -187
  455. package/src/plugins/defaults/circuit-breaker/middlewares/circuitBreaker.ts +0 -93
  456. package/src/plugins/defaults/circuit-breaker/package.json +0 -15
  457. package/src/plugins/defaults/circuit-breaker/register.ts +0 -39
  458. package/src/plugins/defaults/compaction/middlewares/compaction.ts +0 -25
  459. package/src/plugins/defaults/compaction/register.ts +0 -35
  460. package/src/plugins/defaults/compaction/terminal.ts +0 -73
  461. package/src/plugins/defaults/empty-response/register.ts +0 -23
  462. package/src/plugins/defaults/history-repair/register.ts +0 -24
  463. package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit-temp.ts +0 -216
  464. package/src/plugins/defaults/overflow-reduce/middlewares/overflowReduce.ts +0 -126
  465. package/src/plugins/defaults/overflow-reduce/package.json +0 -15
  466. package/src/plugins/defaults/overflow-reduce/register.ts +0 -42
  467. package/src/plugins/defaults/title-generate/register.ts +0 -35
  468. package/src/plugins/defaults/tool-error/register.ts +0 -23
  469. package/src/plugins/defaults/tool-result-truncate/register.ts +0 -24
  470. package/src/proactive-artifact/aux-message-injector.ts +0 -97
  471. package/src/proactive-artifact/decision.test.ts +0 -226
  472. package/src/proactive-artifact/decision.ts +0 -165
  473. package/src/proactive-artifact/index.ts +0 -7
  474. package/src/proactive-artifact/job.test.ts +0 -962
  475. package/src/proactive-artifact/job.ts +0 -372
  476. package/src/proactive-artifact/message-copy.ts +0 -58
  477. package/src/proactive-artifact/trigger-state.test.ts +0 -286
  478. package/src/proactive-artifact/trigger-state.ts +0 -123
  479. package/src/util/map-limit.ts +0 -27
  480. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/fixtures/eval-turns.json +0 -0
  481. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/fixtures/live-turns.json +0 -0
  482. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/working-set-eviction.test.ts +0 -0
  483. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/working-set-skeleton.test.ts +0 -0
  484. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/README.md +0 -0
  485. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/assignments.json +0 -0
  486. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/core.json +0 -0
  487. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-a/topic-x.md +0 -0
  488. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-a/topic-y.md +0 -0
  489. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-b/topic-z.md +0 -0
  490. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/llm-retry.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);