@vellumai/assistant 0.8.7-dev.202606052232.2ddc989 → 0.8.8

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 (262) hide show
  1. package/bun.lock +2 -2
  2. package/docs/plugins.md +832 -0
  3. package/examples/plugins/echo/README.md +60 -61
  4. package/examples/plugins/echo/package.json +2 -1
  5. package/examples/plugins/echo/register.ts +143 -0
  6. package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +6 -7
  7. package/openapi.yaml +5 -15
  8. package/package.json +2 -2
  9. package/src/__tests__/agent-loop-exit-reason.test.ts +56 -3
  10. package/src/__tests__/anthropic-provider.test.ts +1 -1
  11. package/src/__tests__/app-control-flow.test.ts +1 -1
  12. package/src/__tests__/app-dir-path-guard.test.ts +0 -1
  13. package/src/__tests__/approval-routes-http.test.ts +1 -4
  14. package/src/__tests__/channel-approval-routes.test.ts +1 -1
  15. package/src/__tests__/channel-approvals.test.ts +1 -1
  16. package/src/__tests__/circuit-breaker-pipeline.test.ts +405 -0
  17. package/src/__tests__/compaction-pipeline.test.ts +210 -0
  18. package/src/__tests__/compaction-timeout-recovery.test.ts +251 -0
  19. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +3 -0
  20. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +3 -0
  21. package/src/__tests__/conversation-agent-loop-overflow.test.ts +7 -3
  22. package/src/__tests__/conversation-agent-loop.test.ts +39 -42
  23. package/src/__tests__/conversation-clean-command.test.ts +2 -5
  24. package/src/__tests__/conversation-provider-retry-repair.test.ts +5 -4
  25. package/src/__tests__/conversation-runtime-assembly.test.ts +71 -140
  26. package/src/__tests__/conversation-runtime-workspace.test.ts +27 -108
  27. package/src/__tests__/conversation-starter-routes.test.ts +6 -14
  28. package/src/__tests__/conversation-workspace-cache-state.test.ts +16 -17
  29. package/src/__tests__/conversation-workspace-injection.test.ts +1 -61
  30. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +6 -7
  31. package/src/__tests__/db-acp-history.test.ts +0 -101
  32. package/src/__tests__/dynamic-page-surface.test.ts +0 -31
  33. package/src/__tests__/file-write-tool.test.ts +0 -63
  34. package/src/__tests__/gateway-only-guard.test.ts +2 -12
  35. package/src/__tests__/guardian-grant-minting.test.ts +1 -1
  36. package/src/__tests__/guardian-routing-invariants.test.ts +4 -2
  37. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +1 -1
  38. package/src/__tests__/heartbeat-disk-pressure.test.ts +0 -1
  39. package/src/__tests__/heartbeat-service.test.ts +0 -1
  40. package/src/__tests__/host-app-control-routes.test.ts +1 -1
  41. package/src/__tests__/host-cu-routes-targeted.test.ts +3 -3
  42. package/src/__tests__/injector-background-turn.test.ts +1 -1
  43. package/src/__tests__/injector-chain.test.ts +6 -34
  44. package/src/__tests__/injector-disk-pressure.test.ts +34 -77
  45. package/src/__tests__/injector-document-comments.test.ts +1 -1
  46. package/src/__tests__/list-messages-hidden-metadata.test.ts +0 -38
  47. package/src/__tests__/memory-v2-static-injector.test.ts +1 -1
  48. package/src/__tests__/{overflow-reduction-loop.test.ts → overflow-reduce-pipeline.test.ts} +284 -64
  49. package/src/__tests__/pipeline-runner.test.ts +554 -0
  50. package/src/__tests__/plugin-api-shim.test.ts +6 -3
  51. package/src/__tests__/plugin-bootstrap.test.ts +23 -12
  52. package/src/__tests__/plugin-registry.test.ts +49 -3
  53. package/src/__tests__/plugin-types.test.ts +70 -0
  54. package/src/__tests__/reaction-persistence.test.ts +1 -1
  55. package/src/__tests__/send-endpoint-busy.test.ts +1 -4
  56. package/src/__tests__/skill-feature-flags-integration.test.ts +0 -33
  57. package/src/__tests__/subagent-call-site-routing.test.ts +1 -1
  58. package/src/__tests__/subagent-fork-notifications.test.ts +3 -1
  59. package/src/__tests__/subagent-fork-spawn.test.ts +1 -1
  60. package/src/__tests__/subagent-manager-notify.test.ts +3 -1
  61. package/src/__tests__/subagent-notify-parent.test.ts +3 -1
  62. package/src/__tests__/subagent-spawn-tool-fork.test.ts +1 -1
  63. package/src/__tests__/user-plugin-loader.test.ts +286 -54
  64. package/src/acp/__tests__/client-handler.test.ts +0 -40
  65. package/src/acp/__tests__/prepare-agent-env.test.ts +0 -137
  66. package/src/acp/__tests__/session-manager-persistence.test.ts +28 -95
  67. package/src/acp/agent-process.ts +1 -61
  68. package/src/acp/client-handler.ts +0 -31
  69. package/src/acp/prepare-agent-env.ts +29 -83
  70. package/src/acp/resolve-agent.test.ts +7 -320
  71. package/src/acp/resolve-agent.ts +18 -182
  72. package/src/acp/session-manager.ts +73 -495
  73. package/src/acp/types.ts +0 -8
  74. package/src/agent/compaction-circuit.ts +102 -60
  75. package/src/agent/loop.ts +59 -32
  76. package/src/api/responses/conversation-message.ts +1 -7
  77. package/src/approvals/guardian-request-resolvers.ts +1 -1
  78. package/src/background-wake/next-wake.ts +0 -1
  79. package/src/config/__tests__/feature-flag-registry-guard.test.ts +2 -2
  80. package/src/config/acp-defaults.test.ts +0 -10
  81. package/src/config/acp-defaults.ts +0 -6
  82. package/src/config/bundled-skills/acp/SKILL.md +31 -83
  83. package/src/config/bundled-skills/acp/TOOLS.json +4 -4
  84. package/src/config/bundled-skills/app-builder/SKILL.md +381 -224
  85. package/src/config/bundled-skills/app-builder/TOOLS.json +0 -29
  86. package/src/config/bundled-skills/document-editor/SKILL.md +23 -28
  87. package/src/config/bundled-skills/document-editor/TOOLS.json +1 -1
  88. package/src/config/bundled-tool-registry.ts +0 -2
  89. package/src/config/feature-flag-registry.json +5 -14
  90. package/src/config/schemas/heartbeat.ts +0 -9
  91. package/src/context/strip-injections.ts +2 -8
  92. package/src/context/window-manager.ts +1 -2
  93. package/src/daemon/conversation-agent-loop-handlers.ts +11 -0
  94. package/src/daemon/conversation-agent-loop.ts +279 -62
  95. package/src/daemon/conversation-runtime-assembly.ts +69 -106
  96. package/src/daemon/conversation-store.ts +90 -9
  97. package/src/daemon/conversation-workspace.ts +0 -17
  98. package/src/daemon/conversation.ts +6 -0
  99. package/src/daemon/external-plugins-bootstrap.ts +11 -11
  100. package/src/daemon/handlers/conversations.ts +1 -3
  101. package/src/daemon/handlers/skills.ts +1 -4
  102. package/src/daemon/lifecycle.ts +0 -21
  103. package/src/daemon/server.ts +0 -2
  104. package/src/heartbeat/__tests__/heartbeat-service.test.ts +0 -3
  105. package/src/heartbeat/heartbeat-run-store.ts +1 -23
  106. package/src/heartbeat/heartbeat-service.ts +0 -26
  107. package/src/ipc/__tests__/browser-ipc.test.ts +1 -1
  108. package/src/ipc/__tests__/ui-request-route.test.ts +3 -3
  109. package/src/ipc/skill-routes/__tests__/memory.test.ts +0 -15
  110. package/src/ipc/skill-routes/memory.ts +2 -4
  111. package/src/memory/conversation-starter-checkpoints.ts +0 -1
  112. package/src/memory/db-init.ts +0 -2
  113. package/src/memory/job-handlers/conversation-starters.ts +2 -13
  114. package/src/memory/jobs-worker.ts +1 -1
  115. package/src/memory/migrations/index.ts +0 -1
  116. package/src/memory/schema/acp.ts +0 -4
  117. package/src/memory/v2/__tests__/consolidation-job.test.ts +3 -3
  118. package/src/memory/v2/consolidation-job.ts +4 -13
  119. package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/assign.test.ts +4 -4
  120. package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/live-integration.test.ts +4 -4
  121. package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/maintain-job.test.ts +5 -5
  122. package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/orchestrate.test.ts +3 -3
  123. package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/reconcile.test.ts +2 -2
  124. package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/render-injection.test.ts +1 -1
  125. package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/router.test.ts +3 -3
  126. package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/selection-log-store.test.ts +8 -8
  127. package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/selector.test.ts +3 -3
  128. package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/shadow-plugin.test.ts +12 -12
  129. package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/assign.ts +5 -5
  130. package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/capabilities.ts +2 -2
  131. package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/maintain-job.ts +8 -8
  132. package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/page-content.ts +2 -2
  133. package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/provider-blocks.ts +1 -1
  134. package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/reconcile.ts +3 -3
  135. package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/render-injection.ts +1 -1
  136. package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/router.ts +3 -3
  137. package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/selection-log-store.ts +4 -4
  138. package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/selector.ts +4 -4
  139. package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/shadow-plugin.ts +90 -28
  140. package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/tree.ts +1 -1
  141. package/src/plugin-api/index.ts +5 -0
  142. package/src/plugins/defaults/circuit-breaker/middlewares/circuitBreaker.ts +93 -0
  143. package/src/plugins/defaults/{memory-v3-shadow → circuit-breaker}/package.json +2 -2
  144. package/src/plugins/defaults/circuit-breaker/register.ts +39 -0
  145. package/src/plugins/defaults/compaction/middlewares/compaction.ts +25 -0
  146. package/src/plugins/defaults/compaction/package.json +1 -1
  147. package/src/plugins/defaults/compaction/register.ts +19 -8
  148. package/src/plugins/defaults/compaction/terminal.ts +73 -0
  149. package/src/plugins/defaults/index.ts +5 -3
  150. package/src/plugins/defaults/{memory-retrieval/injectors.ts → injectors/register.ts} +7 -45
  151. package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +7 -11
  152. package/src/plugins/defaults/memory-retrieval/injector-chain.ts +2 -2
  153. package/src/plugins/defaults/overflow-reduce/middlewares/overflowReduce.ts +126 -0
  154. package/src/plugins/defaults/overflow-reduce/package.json +15 -0
  155. package/src/plugins/defaults/overflow-reduce/register.ts +42 -0
  156. package/src/plugins/external-api.ts +2 -2
  157. package/src/plugins/pipeline.ts +293 -6
  158. package/src/plugins/registry.ts +37 -9
  159. package/src/plugins/types.ts +336 -32
  160. package/src/plugins/user-loader.ts +127 -30
  161. package/src/proactive-artifact/aux-message-injector.ts +1 -1
  162. package/src/proactive-artifact/job.test.ts +1 -1
  163. package/src/prompts/__tests__/system-prompt.test.ts +0 -6
  164. package/src/prompts/templates/BOOTSTRAP-ACTIVATION-RAIL.md +2 -4
  165. package/src/runtime/__tests__/agent-wake.test.ts +5 -5
  166. package/src/runtime/__tests__/interactive-ui.test.ts +1 -1
  167. package/src/runtime/agent-wake.ts +3 -0
  168. package/src/runtime/assistant-event-hub.ts +1 -1
  169. package/src/runtime/channel-approvals.ts +1 -1
  170. package/src/runtime/interactive-ui.ts +1 -1
  171. package/src/runtime/routes/__tests__/acp-routes.test.ts +55 -283
  172. package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +1 -1
  173. package/src/runtime/routes/__tests__/surface-action-routes.test.ts +4 -5
  174. package/src/runtime/routes/__tests__/surface-content-routes.test.ts +1 -4
  175. package/src/runtime/routes/acp-routes.test.ts +25 -89
  176. package/src/runtime/routes/acp-routes.ts +29 -81
  177. package/src/runtime/routes/approval-routes.ts +1 -1
  178. package/src/runtime/routes/browser-routes.ts +1 -1
  179. package/src/runtime/routes/browser-tabs-routes.ts +10 -6
  180. package/src/runtime/routes/conversation-cli-routes.ts +1 -1
  181. package/src/runtime/routes/conversation-list-routes.ts +1 -1
  182. package/src/runtime/routes/conversation-query-routes.ts +1 -1
  183. package/src/runtime/routes/conversation-routes.ts +2 -15
  184. package/src/runtime/routes/conversation-starter-routes.ts +7 -13
  185. package/src/runtime/routes/conversations-import-routes.ts +7 -24
  186. package/src/runtime/routes/host-app-control-routes.ts +1 -1
  187. package/src/runtime/routes/host-cu-routes.ts +1 -1
  188. package/src/runtime/routes/identity-routes.ts +3 -18
  189. package/src/runtime/routes/inbound-message-handler.ts +1 -1
  190. package/src/runtime/routes/memory-v3-routes.ts +6 -16
  191. package/src/runtime/routes/playground/helpers.ts +1 -1
  192. package/src/runtime/routes/surface-conversation-resolver.ts +3 -4
  193. package/src/runtime/routes/work-items-routes.ts +4 -2
  194. package/src/runtime/services/conversation-serializer.ts +1 -1
  195. package/src/signals/cancel.ts +4 -2
  196. package/src/subagent/manager.ts +5 -17
  197. package/src/tools/acp/list-agents.test.ts +1 -7
  198. package/src/tools/acp/spawn.test.ts +55 -158
  199. package/src/tools/acp/spawn.ts +72 -47
  200. package/src/tools/acp/steer.test.ts +8 -105
  201. package/src/tools/acp/steer.ts +17 -48
  202. package/src/tools/apps/executors.ts +8 -13
  203. package/src/tools/filesystem/write.ts +0 -34
  204. package/src/tools/subagent/spawn.ts +4 -2
  205. package/src/tools/ui-surface/definitions.ts +4 -25
  206. package/src/workspace/migrations/051-seed-conversation-summarization-callsite.ts +5 -4
  207. package/src/workspace/migrations/097-enable-adaptive-thinking-managed-profiles.ts +45 -69
  208. package/examples/plugins/echo/hooks/post-tool-use.ts +0 -18
  209. package/examples/plugins/echo/hooks/stop.ts +0 -16
  210. package/examples/plugins/echo/hooks/user-prompt-submit.ts +0 -18
  211. package/examples/plugins/echo/src/emit.ts +0 -19
  212. package/src/__tests__/compaction-circuit.test.ts +0 -258
  213. package/src/__tests__/compaction-direct.test.ts +0 -132
  214. package/src/__tests__/conversations-import-system-filter.test.ts +0 -101
  215. package/src/acp/__tests__/agent-process.test.ts +0 -161
  216. package/src/acp/__tests__/helpers/acp-history-db.ts +0 -82
  217. package/src/acp/__tests__/helpers/exec-file-stub.ts +0 -101
  218. package/src/acp/__tests__/session-manager-resume.test.ts +0 -736
  219. package/src/acp/auto-install.test.ts +0 -196
  220. package/src/acp/auto-install.ts +0 -177
  221. package/src/acp/feature-gate.test.ts +0 -48
  222. package/src/acp/feature-gate.ts +0 -34
  223. package/src/acp/resume-hint.ts +0 -25
  224. package/src/config/bundled-skills/app-builder/references/DESIGN_SYSTEM.md +0 -48
  225. package/src/config/bundled-skills/app-builder/references/RESPONSIVE.md +0 -57
  226. package/src/config/bundled-skills/app-builder/references/SLIDES.md +0 -38
  227. package/src/config/bundled-skills/app-builder/tools/app-list.ts +0 -62
  228. package/src/daemon/conversation-registry.ts +0 -159
  229. package/src/daemon/overflow-reduction-loop.ts +0 -230
  230. package/src/memory/migrations/272-acp-session-history-cwd.ts +0 -36
  231. package/src/plugins/defaults/compaction/compact.ts +0 -59
  232. package/src/plugins/defaults/memory-v3-shadow/hooks/post-compact.ts +0 -14
  233. package/src/plugins/defaults/memory-v3-shadow/hooks/user-prompt-submit.ts +0 -19
  234. package/src/plugins/defaults/memory-v3-shadow/injector.ts +0 -75
  235. package/src/plugins/defaults/memory-v3-shadow/register.ts +0 -26
  236. package/src/tools/acp/context.ts +0 -20
  237. /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/capabilities.test.ts +0 -0
  238. /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/core.test.ts +0 -0
  239. /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/fixtures/eval-turns.json +0 -0
  240. /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/fixtures/live-turns.json +0 -0
  241. /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/health.test.ts +0 -0
  242. /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/needle.test.ts +0 -0
  243. /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/provider-blocks.test.ts +0 -0
  244. /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/snapshot.test.ts +0 -0
  245. /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/tree.test.ts +0 -0
  246. /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/types.test.ts +0 -0
  247. /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/working-set-eviction.test.ts +0 -0
  248. /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/__tests__/working-set-skeleton.test.ts +0 -0
  249. /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/core.ts +0 -0
  250. /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/data/README.md +0 -0
  251. /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/data/assignments.json +0 -0
  252. /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/data/core.json +0 -0
  253. /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/data/leaves/domain-a/topic-x.md +0 -0
  254. /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/data/leaves/domain-a/topic-y.md +0 -0
  255. /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/data/leaves/domain-b/topic-z.md +0 -0
  256. /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/health.ts +0 -0
  257. /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/llm-retry.ts +0 -0
  258. /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/needle.ts +0 -0
  259. /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/orchestrate.ts +0 -0
  260. /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/snapshot.ts +0 -0
  261. /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/types.ts +0 -0
  262. /package/src/{plugins/defaults/memory-v3-shadow → memory/v3}/working-set.ts +0 -0
@@ -41,28 +41,20 @@ mock.module("../config/loader.js", () => ({
41
41
  const { applyRuntimeInjections, composeInjectorChain } =
42
42
  await import("../daemon/conversation-runtime-assembly.js");
43
43
  const { DEFAULT_INJECTOR_ORDER, defaultInjectors } =
44
- await import("../plugins/defaults/memory-retrieval/injectors.js");
44
+ await import("../plugins/defaults/injectors/register.js");
45
45
  const { getInjectorChain } =
46
46
  await import("../plugins/defaults/memory-retrieval/injector-chain.js");
47
- import {
48
- clearConversations,
49
- setConversation,
50
- } from "../daemon/conversation-registry.js";
51
47
  import { buildPkbReminder } from "../daemon/pkb-reminder-builder.js";
52
48
  import { getPkbRoot } from "../memory/pkb/types.js";
53
49
  import type { TurnContext } from "../plugins/types.js";
54
50
  import type { Message } from "../providers/types.js";
55
51
  import { getWorkspacePromptPath } from "../util/platform.js";
56
52
 
57
- // `makeTurnContext` and the workspace registry seed share this id so the
58
- // `workspace-context` injector resolves the seeded block for the turn.
59
- const TEST_CONVERSATION_ID = "conv-test-1";
60
-
61
53
  /** A fake TurnContext sufficient for driving `composeInjectorChain`. */
62
54
  function makeTurnContext(): TurnContext {
63
55
  return {
64
56
  requestId: "req-test-1",
65
- conversationId: TEST_CONVERSATION_ID,
57
+ conversationId: "conv-test-1",
66
58
  turnIndex: 0,
67
59
  trust: {
68
60
  sourceChannel: "vellum",
@@ -102,25 +94,10 @@ function clearNowScratchpad(): void {
102
94
  rmSync(getWorkspacePromptPath("NOW.md"), { force: true });
103
95
  }
104
96
 
105
- // The workspace-context injector sources its block off the live `Conversation`
106
- // looked up by `conversationId`. Seed a fake instance carrying a non-dirty
107
- // workspace cache under the id `makeTurnContext()` uses so the injector emits
108
- // the block; `clearConversations()` between tests keeps suites that assert the
109
- // workspace block is absent unaffected.
110
- function seedWorkspaceContext(text: string): void {
111
- setConversation(TEST_CONVERSATION_ID, {
112
- conversationId: TEST_CONVERSATION_ID,
113
- workingDir: "/sandbox",
114
- workspaceTopLevelContext: text,
115
- workspaceTopLevelDirty: false,
116
- } as never);
117
- }
118
-
119
97
  describe("injector chain", () => {
120
98
  beforeEach(() => {
121
99
  clearPkbContent();
122
100
  clearNowScratchpad();
123
- clearConversations();
124
101
  });
125
102
 
126
103
  test("defaultInjectors lists the defaults in the documented order", () => {
@@ -276,9 +253,9 @@ describe("injector chain", () => {
276
253
  const subagentBlock =
277
254
  '<active_subagents>\n- [running] "worker" (sub-1) | elapsed: 5s\n</active_subagents>';
278
255
 
279
- seedWorkspaceContext(workspaceText);
280
256
  const result = await applyRuntimeInjections(runMessages, {
281
257
  turnContext: makeTurnContext(),
258
+ workspaceTopLevelContext: workspaceText,
282
259
  unifiedTurnContext: unifiedTurn,
283
260
  subagentStatusBlock: subagentBlock,
284
261
  });
@@ -350,11 +327,8 @@ describe("injector chain", () => {
350
327
  },
351
328
  ];
352
329
 
353
- setConversation(TEST_CONVERSATION_ID, {
354
- conversationId: TEST_CONVERSATION_ID,
355
- workingDir: "/sandbox",
356
- workspaceTopLevelContext: "",
357
- workspaceTopLevelDirty: false,
330
+ const result = await applyRuntimeInjections(originalRun, {
331
+ turnContext: makeTurnContext(),
358
332
  channelCapabilities: {
359
333
  channel: "slack",
360
334
  dashboardCapable: false,
@@ -362,9 +336,6 @@ describe("injector chain", () => {
362
336
  supportsVoiceInput: false,
363
337
  chatType: "channel",
364
338
  },
365
- } as never);
366
- const result = await applyRuntimeInjections(originalRun, {
367
- turnContext: makeTurnContext(),
368
339
  slackChronologicalMessages: slackTranscript,
369
340
  });
370
341
 
@@ -402,6 +373,7 @@ describe("injector chain", () => {
402
373
  {
403
374
  turnContext: makeTurnContext(),
404
375
  mode: "minimal",
376
+ workspaceTopLevelContext: "<workspace>...</workspace>",
405
377
  unifiedTurnContext: "<turn_context>...</turn_context>",
406
378
  subagentStatusBlock: "<active_subagents>...</active_subagents>",
407
379
  },
@@ -1,10 +1,5 @@
1
- import { beforeEach, describe, expect, test } from "bun:test";
1
+ import { describe, expect, test } from "bun:test";
2
2
 
3
- import {
4
- clearConversations,
5
- setConversation,
6
- } from "../daemon/conversation-registry.js";
7
- import type { ChannelCapabilities } from "../daemon/conversation-runtime-assembly.js";
8
3
  import {
9
4
  applyRuntimeInjections,
10
5
  stripInjectionsForCompaction,
@@ -13,14 +8,10 @@ import {
13
8
  DEFAULT_INJECTOR_ORDER,
14
9
  defaultInjectors,
15
10
  DISK_PRESSURE_WARNING_PROMPT,
16
- } from "../plugins/defaults/memory-retrieval/injectors.js";
11
+ } from "../plugins/defaults/injectors/register.js";
17
12
  import type { Injector, TurnContext } from "../plugins/types.js";
18
13
  import type { Message } from "../providers/types.js";
19
14
 
20
- // `makeContext` and the workspace registry seed share this id so the
21
- // `workspace-context` injector resolves the seeded block for the turn.
22
- const TEST_CONVERSATION_ID = "conv-test";
23
-
24
15
  function findInjector(name: string): Injector {
25
16
  const injector = defaultInjectors.find(
26
17
  (candidate) => candidate.name === name,
@@ -34,7 +25,7 @@ function findInjector(name: string): Injector {
34
25
  function makeContext(overrides: Partial<TurnContext> = {}): TurnContext {
35
26
  return {
36
27
  requestId: "req-test",
37
- conversationId: TEST_CONVERSATION_ID,
28
+ conversationId: "conv-test",
38
29
  turnIndex: 0,
39
30
  trust: { sourceChannel: "vellum", trustClass: "guardian" },
40
31
  ...overrides,
@@ -52,58 +43,15 @@ function tailTexts(messages: Message[]): string[] {
52
43
  }
53
44
 
54
45
  const diskPressureInjector = findInjector("disk-pressure-warning");
55
-
56
- // The disk-pressure-warning and workspace-context injectors both read their
57
- // per-conversation state off the live `Conversation` looked up by
58
- // `conversationId`. Seed a single fake instance under the id `makeContext()`
59
- // uses, carrying the disk-pressure flag and the workspace top-level cache, so a
60
- // turn can exercise both; the seed helpers mutate and re-register the same
61
- // instance. An empty (non-dirty) workspace cache resolves to no block, so
62
- // disk-pressure-only tests don't trigger a directory scan.
63
- let liveConversation: {
64
- conversationId: string;
65
- workingDir: string;
66
- workspaceTopLevelContext: string | null;
67
- workspaceTopLevelDirty: boolean;
68
- diskPressureCleanupModeActive: boolean;
69
- channelCapabilities?: ChannelCapabilities;
70
- };
71
-
72
- function resetLiveConversation(): void {
73
- liveConversation = {
74
- conversationId: TEST_CONVERSATION_ID,
75
- workingDir: "/workspace",
76
- workspaceTopLevelContext: "",
77
- workspaceTopLevelDirty: false,
78
- diskPressureCleanupModeActive: false,
79
- };
80
- }
81
-
82
- function seedChannelCapabilities(caps: ChannelCapabilities): void {
83
- liveConversation.channelCapabilities = caps;
84
- setConversation(TEST_CONVERSATION_ID, liveConversation as never);
85
- }
86
-
87
- function seedDiskPressure(cleanupModeActive: boolean): void {
88
- liveConversation.diskPressureCleanupModeActive = cleanupModeActive;
89
- setConversation(TEST_CONVERSATION_ID, liveConversation as never);
90
- }
91
-
92
- function seedWorkspaceContext(text: string): void {
93
- liveConversation.workspaceTopLevelContext = text;
94
- liveConversation.workspaceTopLevelDirty = false;
95
- setConversation(TEST_CONVERSATION_ID, liveConversation as never);
96
- }
46
+ const cleanupContext = { cleanupModeActive: true };
97
47
 
98
48
  describe("disk-pressure-warning injector", () => {
99
- beforeEach(() => {
100
- clearConversations();
101
- resetLiveConversation();
102
- });
103
-
104
49
  test("emits the exact cleanup prompt during disk pressure cleanup mode", async () => {
105
- seedDiskPressure(true);
106
- const block = await diskPressureInjector.produce(makeContext());
50
+ const block = await diskPressureInjector.produce(
51
+ makeContext({
52
+ injectionInputs: { diskPressureContext: cleanupContext },
53
+ }),
54
+ );
107
55
 
108
56
  expect(block).toEqual({
109
57
  id: "disk-pressure-warning",
@@ -124,14 +72,21 @@ Do not work on unrelated tasks until enough space is freed to clear the lock or
124
72
  </disk_pressure_warning>`);
125
73
  });
126
74
 
127
- test("omits the prompt when no cleanup context is registered or it is inactive", async () => {
75
+ test("omits the prompt when cleanup context is null or inactive", async () => {
128
76
  await expect(
129
- diskPressureInjector.produce(makeContext()),
77
+ diskPressureInjector.produce(
78
+ makeContext({ injectionInputs: { diskPressureContext: null } }),
79
+ ),
130
80
  ).resolves.toBeNull();
131
81
 
132
- seedDiskPressure(false);
133
82
  await expect(
134
- diskPressureInjector.produce(makeContext()),
83
+ diskPressureInjector.produce(
84
+ makeContext({
85
+ injectionInputs: {
86
+ diskPressureContext: { cleanupModeActive: false },
87
+ },
88
+ }),
89
+ ),
135
90
  ).resolves.toBeNull();
136
91
  });
137
92
 
@@ -142,10 +97,10 @@ Do not work on unrelated tasks until enough space is freed to clear the lock or
142
97
  const workspace = "<workspace>\nRoot: /workspace\n</workspace>";
143
98
  const turnContext = "<turn_context>\ninterface: macos\n</turn_context>";
144
99
 
145
- seedWorkspaceContext(workspace);
146
- seedDiskPressure(true);
147
100
  const result = await applyRuntimeInjections(runMessages, {
148
101
  turnContext: makeContext(),
102
+ diskPressureContext: cleanupContext,
103
+ workspaceTopLevelContext: workspace,
149
104
  unifiedTurnContext: turnContext,
150
105
  });
151
106
 
@@ -163,12 +118,13 @@ Do not work on unrelated tasks until enough space is freed to clear the lock or
163
118
  });
164
119
 
165
120
  test("survives minimal mode as safety-critical context", async () => {
166
- seedDiskPressure(true);
167
121
  const result = await applyRuntimeInjections(
168
122
  [{ role: "user", content: [{ type: "text", text: "status" }] }],
169
123
  {
170
124
  turnContext: makeContext(),
171
125
  mode: "minimal",
126
+ diskPressureContext: cleanupContext,
127
+ workspaceTopLevelContext: "<workspace>...</workspace>",
172
128
  unifiedTurnContext: "<turn_context>...</turn_context>",
173
129
  },
174
130
  );
@@ -198,16 +154,16 @@ Do not work on unrelated tasks until enough space is freed to clear the lock or
198
154
  },
199
155
  ];
200
156
 
201
- seedDiskPressure(true);
202
- seedChannelCapabilities({
203
- channel: "slack",
204
- dashboardCapable: false,
205
- supportsDynamicUi: false,
206
- supportsVoiceInput: false,
207
- chatType: "channel",
208
- });
209
157
  const result = await applyRuntimeInjections(originalRun, {
210
158
  turnContext: makeContext(),
159
+ diskPressureContext: cleanupContext,
160
+ channelCapabilities: {
161
+ channel: "slack",
162
+ dashboardCapable: false,
163
+ supportsDynamicUi: false,
164
+ supportsVoiceInput: false,
165
+ chatType: "channel",
166
+ },
211
167
  slackChronologicalMessages: slackTranscript,
212
168
  });
213
169
 
@@ -225,15 +181,16 @@ Do not work on unrelated tasks until enough space is freed to clear the lock or
225
181
  { role: "user", content: [{ type: "text", text: "find large files" }] },
226
182
  ];
227
183
 
228
- seedDiskPressure(true);
229
184
  const first = await applyRuntimeInjections(runMessages, {
230
185
  turnContext: makeContext(),
186
+ diskPressureContext: cleanupContext,
231
187
  });
232
188
  const stripped = stripInjectionsForCompaction(first.messages);
233
189
  expect(tailTexts(stripped)).toEqual(["find large files"]);
234
190
 
235
191
  const second = await applyRuntimeInjections(stripped, {
236
192
  turnContext: makeContext(),
193
+ diskPressureContext: cleanupContext,
237
194
  });
238
195
  expect(
239
196
  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/memory-retrieval/injectors.js");
12
+ await import("../plugins/defaults/injectors/register.js");
13
13
  import type { Injector, TurnContext } from "../plugins/types.js";
14
14
 
15
15
  function findInjector(name: string): Injector {
@@ -96,44 +96,6 @@ describe("handleListMessages metadata.hidden filtering", () => {
96
96
  expect(llmRows[1].metadata).toContain('"hidden":true');
97
97
  });
98
98
 
99
- test("UI serializer omits system rows but LLM-side getMessages includes them", async () => {
100
- // GIVEN a conversation with a system row sandwiched between two
101
- // renderable turns (e.g. a skill-authored context message)
102
- const conv = createConversation();
103
- await addMessage(
104
- conv.id,
105
- "user",
106
- JSON.stringify([{ type: "text", text: "first visible" }]),
107
- );
108
- await addMessage(
109
- conv.id,
110
- "system",
111
- JSON.stringify([{ type: "text", text: "system scaffolding" }]),
112
- );
113
- await addMessage(
114
- conv.id,
115
- "assistant",
116
- JSON.stringify([{ type: "text", text: "second visible" }]),
117
- );
118
-
119
- // WHEN the UI history list is serialized
120
- const response = handleListMessages({
121
- queryParams: { conversationId: conv.id },
122
- });
123
- const body = response as { messages: MessagePayload[] };
124
-
125
- // THEN only the user/assistant turns are returned, never the system row
126
- expect(body.messages.map((m) => m.role)).toEqual(["user", "assistant"]);
127
- expect(
128
- body.messages.some((m) => plainText(m).includes("system scaffolding")),
129
- ).toBe(false);
130
-
131
- // AND the LLM-side loader still includes the system row for agent context
132
- const llmRows = getMessages(conv.id);
133
- expect(llmRows).toHaveLength(3);
134
- expect(llmRows[1].role).toBe("system");
135
- });
136
-
137
99
  test("messages without metadata or with hidden=false are returned", async () => {
138
100
  const conv = createConversation();
139
101
  await addMessage(
@@ -35,7 +35,7 @@ mock.module("../config/loader.js", () => ({
35
35
  }));
36
36
 
37
37
  const { defaultInjectors } =
38
- await import("../plugins/defaults/memory-retrieval/injectors.js");
38
+ await import("../plugins/defaults/injectors/register.js");
39
39
  import type { Injector, TurnContext } from "../plugins/types.js";
40
40
  import type { Message } from "../providers/types.js";
41
41
  import { getWorkspacePromptPath } from "../util/platform.js";