@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
@@ -0,0 +1,132 @@
1
+ /**
2
+ * Tests for the default compaction plugin (`defaultCompact`).
3
+ *
4
+ * The agent loop calls {@link defaultCompact} directly with a
5
+ * {@link CompactionContext} rather than routing through a middleware pipeline.
6
+ * These tests assert that the default implementation delegates to the
7
+ * supplied {@link ContextWindowManager} and forwards the request's
8
+ * conversational options verbatim. The orchestrator integration path
9
+ * (conversation-agent-loop) is exercised by
10
+ * `conversation-agent-loop-overflow.test.ts`.
11
+ */
12
+
13
+ import { describe, expect, test } from "bun:test";
14
+
15
+ import {
16
+ type CompactionContext,
17
+ defaultCompact,
18
+ } from "../plugins/defaults/compaction/compact.js";
19
+
20
+ type ContextWindowResultShape = {
21
+ compacted: boolean;
22
+ summaryText: string;
23
+ messages: unknown[];
24
+ previousEstimatedInputTokens: number;
25
+ estimatedInputTokens: number;
26
+ maxInputTokens: number;
27
+ thresholdTokens: number;
28
+ compactedMessages: number;
29
+ compactedPersistedMessages: number;
30
+ summaryCalls: number;
31
+ summaryInputTokens: number;
32
+ summaryOutputTokens: number;
33
+ summaryModel: string;
34
+ reason?: string;
35
+ };
36
+
37
+ function makeResult(
38
+ overrides: Partial<ContextWindowResultShape> = {},
39
+ ): ContextWindowResultShape {
40
+ return {
41
+ compacted: true,
42
+ summaryText: "default-summary",
43
+ messages: [],
44
+ previousEstimatedInputTokens: 1000,
45
+ estimatedInputTokens: 100,
46
+ maxInputTokens: 100000,
47
+ thresholdTokens: 80000,
48
+ compactedMessages: 3,
49
+ compactedPersistedMessages: 3,
50
+ summaryCalls: 1,
51
+ summaryInputTokens: 500,
52
+ summaryOutputTokens: 120,
53
+ summaryModel: "default-model",
54
+ ...overrides,
55
+ };
56
+ }
57
+
58
+ function makeManager(result: ContextWindowResultShape) {
59
+ const observed: {
60
+ messages: unknown;
61
+ signal: unknown;
62
+ options: unknown;
63
+ }[] = [];
64
+ const manager = {
65
+ maybeCompact: async (
66
+ messages: unknown,
67
+ signal: unknown,
68
+ options: unknown,
69
+ ) => {
70
+ observed.push({ messages, signal, options });
71
+ return result;
72
+ },
73
+ } as unknown as CompactionContext["manager"];
74
+ return { manager, observed };
75
+ }
76
+
77
+ describe("defaultCompact", () => {
78
+ test("delegates to the manager and returns its result unchanged", async () => {
79
+ // GIVEN a manager whose maybeCompact records its arguments
80
+ const expected = makeResult({
81
+ summaryText: "manager-summary",
82
+ compactedMessages: 7,
83
+ });
84
+ const { manager, observed } = makeManager(expected);
85
+ const messages = [{ role: "user", content: "hi" }] as never;
86
+ const signal = new AbortController().signal;
87
+
88
+ // WHEN defaultCompact runs with those messages and a signal
89
+ const result = (await defaultCompact({
90
+ manager,
91
+ messages,
92
+ signal,
93
+ })) as unknown as ContextWindowResultShape;
94
+
95
+ // THEN the manager saw the same messages and signal
96
+ expect(observed).toHaveLength(1);
97
+ expect(observed[0]!.messages).toBe(messages);
98
+ expect(observed[0]!.signal).toBe(signal);
99
+
100
+ // AND the returned result is the manager's object, unmodified
101
+ expect(result).toBe(expected);
102
+ expect(result.summaryText).toBe("manager-summary");
103
+ expect(result.compactedMessages).toBe(7);
104
+ });
105
+
106
+ test("forwards the request's compaction options to the manager", async () => {
107
+ // GIVEN a manager and a fully-populated compaction context
108
+ const { manager, observed } = makeManager(makeResult());
109
+
110
+ // WHEN defaultCompact runs with force/profile/trust options
111
+ await defaultCompact({
112
+ manager,
113
+ messages: [] as never,
114
+ force: true,
115
+ overrideProfile: "fast-profile",
116
+ precomputedEstimate: 1234,
117
+ minKeepRecentUserTurns: 0,
118
+ actorTrustClass: "guardian",
119
+ });
120
+
121
+ // THEN the manager received exactly those options, and the manager,
122
+ // messages, and signal are not leaked into the options bag
123
+ expect(observed).toHaveLength(1);
124
+ expect(observed[0]!.options).toEqual({
125
+ force: true,
126
+ overrideProfile: "fast-profile",
127
+ precomputedEstimate: 1234,
128
+ minKeepRecentUserTurns: 0,
129
+ actorTrustClass: "guardian",
130
+ });
131
+ });
132
+ });
@@ -190,8 +190,8 @@ let mockCompactResult: ContextWindowResult = {
190
190
  mock.module("../context/window-manager.js", () => ({
191
191
  ContextWindowManager: class {
192
192
  nonPersistedPrefixCount = 0;
193
- summaryIsInjected = false;
194
193
  constructor() {}
194
+ updateConfig() {}
195
195
  shouldCompact() {
196
196
  return { needed: false, estimatedTokens: 0 };
197
197
  }
@@ -228,10 +228,10 @@ mock.module("../agent/loop.js", () => ({
228
228
  getActiveModel() {
229
229
  return undefined;
230
230
  }
231
- async run(
232
- _messages: Message[],
233
- _onEvent: (event: AgentEvent) => void,
234
- ): Promise<Message[]> {
231
+ async run(_options: {
232
+ messages: Message[];
233
+ onEvent: (event: AgentEvent) => void;
234
+ }): Promise<Message[]> {
235
235
  return [];
236
236
  }
237
237
  },
@@ -0,0 +1,213 @@
1
+ import { describe, expect, mock, test } from "bun:test";
2
+
3
+ function makeLoggerStub(): Record<string, unknown> {
4
+ const stub: Record<string, unknown> = {};
5
+ for (const m of [
6
+ "info",
7
+ "warn",
8
+ "error",
9
+ "debug",
10
+ "trace",
11
+ "fatal",
12
+ "silent",
13
+ "child",
14
+ ]) {
15
+ stub[m] = m === "child" ? () => makeLoggerStub() : () => {};
16
+ }
17
+ return stub;
18
+ }
19
+
20
+ mock.module("../util/logger.js", () => ({
21
+ getLogger: () => makeLoggerStub(),
22
+ }));
23
+
24
+ mock.module("../memory/conversation-crud.js", () => ({
25
+ getMessages: () => [],
26
+ reserveMessage: mock(async () => ({ id: "msg-reserve" })),
27
+ }));
28
+
29
+ mock.module("../memory/attachments-store.js", () => ({
30
+ getAttachmentMetadataForMessage: () => [],
31
+ getAttachmentContent: () => null,
32
+ }));
33
+
34
+ import {
35
+ runAssistantDrivenCompaction,
36
+ runEmergencyCompaction,
37
+ } from "../context/compactor.js";
38
+ import type { Message, Provider } from "../providers/types.js";
39
+
40
+ const TAIL_TIMESTAMP =
41
+ "2026-05-21 (Thursday) 10:00:00 -05:00 (America/Chicago)";
42
+
43
+ const compactionResponse = `
44
+ <compaction_result>
45
+ <summary>
46
+ Earlier turns summarized here.
47
+ </summary>
48
+
49
+ <key_state>
50
+ - Nothing critical pending.
51
+ </key_state>
52
+
53
+ <tail_start timestamp="${TAIL_TIMESTAMP}" preview="tail anchor message" />
54
+ </compaction_result>
55
+ `;
56
+
57
+ const ENCRYPTED_TOKEN = "expired_encrypted_token_abc123";
58
+
59
+ const userText = (text: string): Message => ({
60
+ role: "user",
61
+ content: [{ type: "text", text }],
62
+ });
63
+
64
+ const userTextWithTurnContext = (text: string, timestamp: string): Message => ({
65
+ role: "user",
66
+ content: [
67
+ {
68
+ type: "text",
69
+ text: `<turn_context>\ncurrent_time: ${timestamp}\n</turn_context>\n${text}`,
70
+ },
71
+ ],
72
+ });
73
+
74
+ const assistantWithWebSearch = (): Message => ({
75
+ role: "assistant",
76
+ content: [
77
+ {
78
+ type: "server_tool_use",
79
+ id: "stu_1",
80
+ name: "web_search",
81
+ input: { query: "cats" },
82
+ },
83
+ {
84
+ type: "web_search_tool_result",
85
+ tool_use_id: "stu_1",
86
+ content: [
87
+ {
88
+ type: "web_search_result",
89
+ url: "https://cats.example",
90
+ title: "All About Cats",
91
+ encrypted_content: ENCRYPTED_TOKEN,
92
+ },
93
+ ],
94
+ },
95
+ ],
96
+ });
97
+
98
+ const assistantToolUse = (): Message => ({
99
+ role: "assistant",
100
+ content: [
101
+ { type: "tool_use", id: "tu_1", name: "bash", input: { cmd: "ls" } },
102
+ ],
103
+ });
104
+
105
+ const toolResult = (): Message => ({
106
+ role: "user",
107
+ content: [{ type: "tool_result", tool_use_id: "tu_1", content: "ok" }],
108
+ });
109
+
110
+ function serializeBlocks(messages: Message[]): string {
111
+ return JSON.stringify(messages);
112
+ }
113
+
114
+ // Records the exact message list the provider is asked to summarize.
115
+ function recordingProvider(sink: { sent: Message[] }): Provider {
116
+ return {
117
+ name: "mock-provider",
118
+ sendMessage: async (msgs: Message[]) => {
119
+ sink.sent = msgs;
120
+ return {
121
+ content: [{ type: "text", text: compactionResponse }],
122
+ model: "mock-model",
123
+ usage: { inputTokens: 100, outputTokens: 50 },
124
+ stopReason: "end_turn",
125
+ };
126
+ },
127
+ };
128
+ }
129
+
130
+ // Expired Anthropic web-search tokens must never reach the summarization LLM:
131
+ // both compaction provider calls funnel through the same request builder, so
132
+ // each is guarded here.
133
+ describe("compaction summary calls — historical web-search sanitization", () => {
134
+ test("runAssistantDrivenCompaction strips expired encrypted_content from the request while leaving durable history untouched", async () => {
135
+ // GIVEN a history whose older turn contains a native web_search_tool_result
136
+ // block carrying an opaque, expired `encrypted_content` token
137
+ const messages: Message[] = [
138
+ userText("old user turn"),
139
+ assistantWithWebSearch(),
140
+ userTextWithTurnContext("tail anchor message", TAIL_TIMESTAMP),
141
+ assistantWithWebSearch(),
142
+ ];
143
+
144
+ // AND a snapshot of the caller's array so we can assert it is not mutated
145
+ const inputSnapshot = serializeBlocks(messages);
146
+ const sink = { sent: [] as Message[] };
147
+
148
+ // WHEN compaction runs over that history
149
+ const result = await runAssistantDrivenCompaction({
150
+ conversationId: "conv-web-search",
151
+ messages,
152
+ provider: recordingProvider(sink),
153
+ systemPrompt: "system",
154
+ compaction: { enabled: true, autoThreshold: 0.7 },
155
+ maxInputTokens: 1000,
156
+ previousEstimatedInputTokens: 900,
157
+ });
158
+
159
+ // THEN the summary request the provider received carries no expired token
160
+ // and no native web_search blocks, but keeps the search content as text
161
+ const sentSerialized = serializeBlocks(sink.sent);
162
+ expect(sentSerialized).not.toContain(ENCRYPTED_TOKEN);
163
+ expect(sentSerialized).not.toContain("web_search_tool_result");
164
+ expect(sentSerialized).not.toContain("server_tool_use");
165
+ expect(sentSerialized).toContain("All About Cats");
166
+ expect(sentSerialized).toContain("https://cats.example");
167
+
168
+ // AND the caller's durable history array is left byte-for-byte untouched,
169
+ // so persisted messages keep the original rich blocks
170
+ expect(serializeBlocks(messages)).toBe(inputSnapshot);
171
+ expect(result.compacted).toBe(true);
172
+ });
173
+
174
+ test("runEmergencyCompaction strips expired encrypted_content from the prefix request", async () => {
175
+ // GIVEN a mid-turn history whose prefix (before the last tool pair) holds a
176
+ // web_search_tool_result block with an expired token
177
+ const messages: Message[] = [
178
+ userText("old user turn"),
179
+ assistantWithWebSearch(),
180
+ userText("keep going"),
181
+ assistantToolUse(),
182
+ toolResult(),
183
+ ];
184
+
185
+ const inputSnapshot = serializeBlocks(messages);
186
+ const sink = { sent: [] as Message[] };
187
+
188
+ // WHEN emergency compaction splits at the last tool pair and summarizes the
189
+ // prefix
190
+ const result = await runEmergencyCompaction({
191
+ conversationId: "conv-web-search-emergency",
192
+ messages,
193
+ provider: recordingProvider(sink),
194
+ systemPrompt: "system",
195
+ compaction: { enabled: true, autoThreshold: 0.7 },
196
+ // Large budget so the prefix is not front-truncated — this test exercises
197
+ // the web-search sanitizer, not the truncation fallback.
198
+ maxInputTokens: 100000,
199
+ previousEstimatedInputTokens: 90000,
200
+ });
201
+
202
+ // THEN the prefix sent to the provider carries no expired token
203
+ const sentSerialized = serializeBlocks(sink.sent);
204
+ expect(sentSerialized).not.toContain(ENCRYPTED_TOKEN);
205
+ expect(sentSerialized).not.toContain("web_search_tool_result");
206
+ expect(sentSerialized).not.toContain("server_tool_use");
207
+ expect(sentSerialized).toContain("All About Cats");
208
+
209
+ // AND the caller's durable history is untouched
210
+ expect(serializeBlocks(messages)).toBe(inputSnapshot);
211
+ expect(result.compacted).toBe(true);
212
+ });
213
+ });
@@ -11,7 +11,7 @@ import {
11
11
  reduceContextOverflow,
12
12
  type ReducerConfig,
13
13
  type ReducerState,
14
- } from "../daemon/context-overflow-reducer.js";
14
+ } from "../plugins/defaults/compaction/context-overflow-reducer.js";
15
15
  import type { Message } from "../providers/types.js";
16
16
 
17
17
  function msg(role: "user" | "assistant", text: string): Message {
@@ -170,6 +170,7 @@ mock.module("../memory/retriever.js", () => ({
170
170
  mock.module("../context/window-manager.js", () => ({
171
171
  ContextWindowManager: class {
172
172
  constructor() {}
173
+ updateConfig() {}
173
174
  shouldCompact() {
174
175
  return { needed: false, estimatedTokens: 0 };
175
176
  }
@@ -198,10 +199,11 @@ mock.module("../agent/loop.js", () => ({
198
199
  getActiveModel() {
199
200
  return undefined;
200
201
  }
201
- async run(
202
- messages: Message[],
203
- onEvent: (event: AgentEvent) => void,
204
- ): Promise<AgentLoopRunResult> {
202
+ async run(options: {
203
+ messages: Message[];
204
+ onEvent: (event: AgentEvent) => void;
205
+ }): Promise<AgentLoopRunResult> {
206
+ const { messages, onEvent } = options;
205
207
  // Prime the assistant row anchor — production code emits this from
206
208
  // `AgentLoop.run` just before `provider.sendMessage`.
207
209
  await onEvent({ type: "llm_call_started" });
@@ -2,11 +2,11 @@ import { afterAll, beforeEach, describe, expect, mock, test } from "bun:test";
2
2
 
3
3
  import { CompactionCircuit } from "../agent/compaction-circuit.js";
4
4
  import type { AgentLoop } from "../agent/loop.js";
5
- import type { AgentLoopConversationContext } from "../daemon/conversation-agent-loop.js";
5
+ import type { Conversation } from "../daemon/conversation.js";
6
6
  import type { DiskPressureStatus } from "../daemon/disk-pressure-guard.js";
7
7
  import type { ServerMessage } from "../daemon/message-protocol.js";
8
8
 
9
- type Context = AgentLoopConversationContext;
9
+ type Context = Conversation;
10
10
 
11
11
  mock.module("../util/logger.js", () => ({
12
12
  getLogger: () =>
@@ -96,7 +96,7 @@ mock.module("../memory/conversation-crud.js", () => ({
96
96
  getMessageById: () => null,
97
97
  getConversationOriginChannel: () => null,
98
98
  getConversationOriginInterface: () => null,
99
- getConversationOverrideProfileFromRow: () => null,
99
+ resolveOverrideProfile: () => null,
100
100
  provenanceFromTrustContext: () => ({}),
101
101
  setConversationHistoryStrippedAt: () => {},
102
102
  updateConversationContextWindow: () => {},
@@ -106,9 +106,7 @@ mock.module("../memory/conversation-crud.js", () => ({
106
106
 
107
107
  import { runAgentLoopImpl } from "../daemon/conversation-agent-loop.js";
108
108
 
109
- function makeCtx(
110
- overrides: Partial<Context> = {},
111
- ): AgentLoopConversationContext {
109
+ function makeCtx(overrides: Partial<Context> = {}): Conversation {
112
110
  let processing = true;
113
111
  return {
114
112
  conversationId: "conv-123",
@@ -137,6 +135,8 @@ function makeCtx(
137
135
  } as unknown as Context["contextWindowManager"],
138
136
  contextCompactedMessageCount: 0,
139
137
  contextCompactedAt: null,
138
+ conversationType: "background",
139
+ source: "memory",
140
140
  memoryPolicy: { scopeId: "default", includeDefaultFallback: true },
141
141
  currentActiveSurfaceId: undefined,
142
142
  currentPage: undefined,
@@ -145,8 +145,6 @@ function makeCtx(
145
145
  surfaceActionRequestIds: new Set<string>(),
146
146
  currentTurnSurfaces: [],
147
147
  workingDir: "/tmp",
148
- workspaceTopLevelContext: null,
149
- workspaceTopLevelDirty: false,
150
148
  channelCapabilities: undefined,
151
149
  commandIntent: undefined,
152
150
  trustContext: undefined,
@@ -172,7 +170,6 @@ function makeCtx(
172
170
  hasNoClient: false,
173
171
  prompter: {} as Context["prompter"],
174
172
  queue: {} as Context["queue"],
175
- refreshWorkspaceTopLevelContextIfNeeded: () => {},
176
173
  markWorkspaceTopLevelDirty: () => {},
177
174
  emitActivityState: () => {},
178
175
  getQueueDepth: () => 0,
@@ -183,7 +180,7 @@ function makeCtx(
183
180
  getTurnChannelContext: () => null,
184
181
  graphMemory: {} as Context["graphMemory"],
185
182
  ...overrides,
186
- } as AgentLoopConversationContext;
183
+ } as unknown as Conversation;
187
184
  }
188
185
 
189
186
  describe("runAgentLoopImpl disk pressure gate", () => {