@vellumai/assistant 0.8.8 → 0.8.9-dev.202606091853.fbaa2ae

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 (475) 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 +263 -121
  12. package/package.json +2 -2
  13. package/src/__tests__/activation-early-marking.test.ts +120 -0
  14. package/src/__tests__/agent-loop-callsite-precedence.test.ts +69 -14
  15. package/src/__tests__/agent-loop-exit-reason.test.ts +204 -144
  16. package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +50 -35
  17. package/src/__tests__/agent-loop-output-hooks.test.ts +357 -0
  18. package/src/__tests__/agent-loop-override-profile.test.ts +25 -6
  19. package/src/__tests__/agent-loop-provider-error-recording.test.ts +41 -21
  20. package/src/__tests__/agent-loop-thinking.test.ts +36 -20
  21. package/src/__tests__/agent-loop.test.ts +441 -96
  22. package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +14 -14
  23. package/src/__tests__/agent-wake-override-profile.test.ts +17 -21
  24. package/src/__tests__/anthropic-provider.test.ts +23 -8
  25. package/src/__tests__/app-builder-tool-scripts.test.ts +21 -0
  26. package/src/__tests__/app-control-flow.test.ts +1 -1
  27. package/src/__tests__/app-dir-path-guard.test.ts +1 -0
  28. package/src/__tests__/app-executors.test.ts +132 -0
  29. package/src/__tests__/approval-cascade.test.ts +6 -5
  30. package/src/__tests__/approval-routes-http.test.ts +4 -1
  31. package/src/__tests__/background-workers-disk-pressure.test.ts +1 -1
  32. package/src/__tests__/channel-approval-routes.test.ts +1 -1
  33. package/src/__tests__/channel-approvals.test.ts +1 -1
  34. package/src/__tests__/compaction-circuit.test.ts +258 -0
  35. package/src/__tests__/compaction-direct.test.ts +146 -0
  36. package/src/__tests__/compaction-events.test.ts +7 -7
  37. package/src/__tests__/compaction.benchmark.test.ts +1 -1
  38. package/src/__tests__/compactor-web-search-strip.test.ts +213 -0
  39. package/src/__tests__/context-overflow-reducer.test.ts +265 -125
  40. package/src/__tests__/context-window-manager-compact-retry.test.ts +121 -15
  41. package/src/__tests__/conversation-abort-tool-results.test.ts +7 -5
  42. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +7 -10
  43. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +78 -119
  44. package/src/__tests__/conversation-agent-loop-overflow.test.ts +158 -234
  45. package/src/__tests__/conversation-agent-loop.test.ts +342 -623
  46. package/src/__tests__/conversation-clean-command.test.ts +5 -2
  47. package/src/__tests__/conversation-confirmation-signals.test.ts +6 -5
  48. package/src/__tests__/conversation-crud-inference-profile.test.ts +7 -9
  49. package/src/__tests__/conversation-error.test.ts +15 -1
  50. package/src/__tests__/conversation-history-web-search.test.ts +6 -1
  51. package/src/__tests__/conversation-media-retry.test.ts +1 -1
  52. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +44 -4
  53. package/src/__tests__/conversation-process-callsite.test.ts +15 -15
  54. package/src/__tests__/conversation-provider-retry-repair.test.ts +66 -65
  55. package/src/__tests__/conversation-queue.test.ts +10 -10
  56. package/src/__tests__/conversation-runtime-assembly.test.ts +1059 -231
  57. package/src/__tests__/conversation-runtime-workspace.test.ts +115 -20
  58. package/src/__tests__/conversation-slash-queue.test.ts +7 -5
  59. package/src/__tests__/conversation-slash-unknown.test.ts +7 -5
  60. package/src/__tests__/conversation-speed-override.test.ts +11 -10
  61. package/src/__tests__/conversation-starter-routes.test.ts +14 -6
  62. package/src/__tests__/conversation-surfaces-activation-emit.test.ts +395 -0
  63. package/src/__tests__/conversation-surfaces-app-control.test.ts +48 -1
  64. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +73 -4
  65. package/src/__tests__/conversation-undo.test.ts +2 -2
  66. package/src/__tests__/conversation-workspace-cache-state.test.ts +24 -21
  67. package/src/__tests__/conversation-workspace-injection.test.ts +69 -7
  68. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +15 -12
  69. package/src/__tests__/conversations-import-system-filter.test.ts +101 -0
  70. package/src/__tests__/corrected-target.test.ts +93 -0
  71. package/src/__tests__/credential-security-invariants.test.ts +1 -0
  72. package/src/__tests__/cu-unified-flow.test.ts +36 -0
  73. package/src/__tests__/db-acp-history.test.ts +101 -0
  74. package/src/__tests__/dynamic-page-surface.test.ts +31 -0
  75. package/src/__tests__/empty-response-hook.test.ts +1 -1
  76. package/src/__tests__/file-write-tool.test.ts +63 -0
  77. package/src/__tests__/gateway-only-guard.test.ts +17 -2
  78. package/src/__tests__/guardian-grant-minting.test.ts +1 -1
  79. package/src/__tests__/guardian-routing-invariants.test.ts +93 -4
  80. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +1 -1
  81. package/src/__tests__/heartbeat-disk-pressure.test.ts +1 -0
  82. package/src/__tests__/heartbeat-service.test.ts +1 -0
  83. package/src/__tests__/history-repair-hook.test.ts +5 -1
  84. package/src/__tests__/host-app-control-proxy.test.ts +45 -0
  85. package/src/__tests__/host-app-control-routes.test.ts +1 -1
  86. package/src/__tests__/host-cu-routes-targeted.test.ts +3 -3
  87. package/src/__tests__/inference-profile-reaper.test.ts +62 -0
  88. package/src/__tests__/inference-profile-session-handler.test.ts +86 -0
  89. package/src/__tests__/injector-background-turn.test.ts +13 -23
  90. package/src/__tests__/injector-chain.test.ts +268 -44
  91. package/src/__tests__/injector-disk-pressure.test.ts +210 -52
  92. package/src/__tests__/injector-document-comments.test.ts +97 -114
  93. package/src/__tests__/injector-pkb-v2-silenced.test.ts +2 -2
  94. package/src/__tests__/injector-v3-suppression.test.ts +4 -4
  95. package/src/__tests__/list-messages-client-message-id.test.ts +91 -0
  96. package/src/__tests__/list-messages-hidden-metadata.test.ts +38 -0
  97. package/src/__tests__/llm-resolver.test.ts +73 -0
  98. package/src/__tests__/memory-retrieval-hook.test.ts +156 -38
  99. package/src/__tests__/memory-v2-static-injector.test.ts +86 -8
  100. package/src/__tests__/notification-decision-strategy.test.ts +3 -3
  101. package/src/__tests__/parallel-tool.benchmark.test.ts +35 -8
  102. package/src/__tests__/persist-unsendable-image-downscale.test.ts +145 -0
  103. package/src/__tests__/persist-unsendable-image.test.ts +97 -1
  104. package/src/__tests__/plugin-api-shim.test.ts +6 -9
  105. package/src/__tests__/plugin-bootstrap.test.ts +91 -81
  106. package/src/__tests__/plugin-registry.test.ts +3 -49
  107. package/src/__tests__/plugin-skill-contribution.test.ts +15 -14
  108. package/src/__tests__/plugin-tool-contribution.test.ts +7 -4
  109. package/src/__tests__/plugin-types.test.ts +0 -70
  110. package/src/__tests__/post-turn-tool-result-truncation.test.ts +69 -0
  111. package/src/__tests__/pre-model-call-sanitize.test.ts +109 -0
  112. package/src/__tests__/published-app-updater.test.ts +138 -0
  113. package/src/__tests__/reaction-persistence.test.ts +1 -1
  114. package/src/__tests__/send-endpoint-busy.test.ts +4 -1
  115. package/src/__tests__/skill-feature-flags-integration.test.ts +31 -0
  116. package/src/__tests__/steer-tool-repair.test.ts +1 -1
  117. package/src/__tests__/subagent-call-site-routing.test.ts +1 -1
  118. package/src/__tests__/subagent-detail.test.ts +25 -7
  119. package/src/__tests__/subagent-fork-notifications.test.ts +1 -3
  120. package/src/__tests__/subagent-fork-spawn.test.ts +1 -1
  121. package/src/__tests__/subagent-manager-notify.test.ts +1 -3
  122. package/src/__tests__/subagent-notify-parent.test.ts +1 -3
  123. package/src/__tests__/subagent-spawn-tool-fork.test.ts +1 -1
  124. package/src/__tests__/title-generate-hook.test.ts +5 -1
  125. package/src/__tests__/tool-error-hook.test.ts +1 -1
  126. package/src/__tests__/tool-result-truncate-hook.test.ts +1 -1
  127. package/src/__tests__/user-plugin-loader.test.ts +54 -286
  128. package/src/__tests__/web-fetch.test.ts +45 -0
  129. package/src/acp/__tests__/agent-process.test.ts +161 -0
  130. package/src/acp/__tests__/client-handler.test.ts +40 -0
  131. package/src/acp/__tests__/helpers/acp-config-stub.ts +0 -2
  132. package/src/acp/__tests__/helpers/acp-history-db.ts +82 -0
  133. package/src/acp/__tests__/helpers/exec-file-stub.ts +106 -0
  134. package/src/acp/__tests__/prepare-agent-env.test.ts +97 -0
  135. package/src/acp/__tests__/session-manager-persistence.test.ts +95 -28
  136. package/src/acp/__tests__/session-manager-resume.test.ts +888 -0
  137. package/src/acp/agent-process.ts +61 -1
  138. package/src/acp/auto-install.test.ts +280 -0
  139. package/src/acp/auto-install.ts +232 -0
  140. package/src/acp/client-handler.ts +31 -0
  141. package/src/acp/prepare-agent-env.ts +80 -27
  142. package/src/acp/resolve-agent.test.ts +188 -28
  143. package/src/acp/resolve-agent.ts +119 -42
  144. package/src/acp/resume-hint.ts +23 -0
  145. package/src/acp/session-manager.ts +507 -73
  146. package/src/agent/compaction-circuit.ts +60 -102
  147. package/src/agent/loop.ts +403 -251
  148. package/src/api/responses/conversation-message.ts +22 -2
  149. package/src/api/responses/memory-v3-selection-log.ts +19 -10
  150. package/src/approvals/guardian-request-resolvers.ts +27 -1
  151. package/src/background-wake/next-wake.ts +1 -0
  152. package/src/cli/commands/__tests__/memory-v3.test.ts +191 -210
  153. package/src/cli/commands/channel-verification-sessions.ts +6 -6
  154. package/src/cli/commands/db/__tests__/repair.test.ts +3 -1
  155. package/src/cli/commands/memory-v3.ts +57 -199
  156. package/src/cli/commands/plugins.ts +43 -37
  157. package/src/cli/lib/__tests__/install-from-github.test.ts +790 -111
  158. package/src/cli/lib/__tests__/plugin-catalog-cache.test.ts +196 -0
  159. package/src/cli/lib/__tests__/plugin-details.test.ts +381 -0
  160. package/src/cli/lib/__tests__/plugin-marketplace.test.ts +270 -0
  161. package/src/cli/lib/__tests__/search-plugins.test.ts +233 -32
  162. package/src/cli/lib/install-from-github.ts +797 -60
  163. package/src/cli/lib/plugin-catalog-cache.ts +84 -0
  164. package/src/cli/lib/plugin-details.ts +416 -0
  165. package/src/cli/lib/plugin-marketplace.ts +215 -0
  166. package/src/cli/lib/search-plugins.ts +201 -29
  167. package/src/config/__tests__/feature-flag-registry-guard.test.ts +2 -2
  168. package/src/config/acp-defaults.test.ts +10 -0
  169. package/src/config/acp-defaults.ts +9 -3
  170. package/src/config/acp-schema.ts +1 -7
  171. package/src/config/bundled-skills/acp/SKILL.md +80 -41
  172. package/src/config/bundled-skills/acp/TOOLS.json +4 -4
  173. package/src/config/bundled-skills/app-builder/SKILL.md +224 -381
  174. package/src/config/bundled-skills/app-builder/TOOLS.json +72 -2
  175. package/src/config/bundled-skills/app-builder/references/DESIGN_SYSTEM.md +48 -0
  176. package/src/config/bundled-skills/app-builder/references/RESPONSIVE.md +57 -0
  177. package/src/config/bundled-skills/app-builder/references/SLIDES.md +38 -0
  178. package/src/config/bundled-skills/app-builder/tools/app-list.ts +62 -0
  179. package/src/config/bundled-skills/app-builder/tools/app-update.ts +18 -0
  180. package/src/config/bundled-skills/document-editor/SKILL.md +28 -23
  181. package/src/config/bundled-skills/document-editor/TOOLS.json +1 -1
  182. package/src/config/bundled-tool-registry.ts +4 -0
  183. package/src/config/call-site-defaults.ts +0 -3
  184. package/src/config/feature-flag-registry.json +10 -16
  185. package/src/config/llm-resolver.ts +39 -7
  186. package/src/config/schemas/__tests__/memory-v3.test.ts +25 -9
  187. package/src/config/schemas/call-site-catalog.ts +0 -21
  188. package/src/config/schemas/heartbeat.ts +9 -0
  189. package/src/config/schemas/llm.ts +17 -3
  190. package/src/config/schemas/memory-v3.ts +58 -8
  191. package/src/config/seed-inference-profiles.ts +18 -0
  192. package/src/context/compactor.ts +22 -4
  193. package/src/context/post-turn-tool-result-truncation.ts +39 -1
  194. package/src/context/strip-injections.ts +8 -2
  195. package/src/daemon/conversation-agent-loop-handlers.ts +18 -36
  196. package/src/daemon/conversation-agent-loop.ts +308 -1297
  197. package/src/daemon/conversation-error.ts +31 -4
  198. package/src/daemon/conversation-history.ts +1 -1
  199. package/src/daemon/conversation-lifecycle.ts +11 -255
  200. package/src/daemon/conversation-media-retry.ts +19 -6
  201. package/src/daemon/conversation-messaging.ts +17 -0
  202. package/src/daemon/conversation-process.ts +22 -141
  203. package/src/daemon/conversation-queue-manager.ts +8 -0
  204. package/src/daemon/conversation-registry.ts +159 -0
  205. package/src/daemon/conversation-runtime-assembly.ts +361 -393
  206. package/src/daemon/conversation-store.ts +9 -90
  207. package/src/daemon/conversation-surfaces.ts +165 -11
  208. package/src/daemon/conversation-workspace.ts +17 -0
  209. package/src/daemon/conversation.ts +444 -62
  210. package/src/daemon/disk-pressure-policy.ts +0 -1
  211. package/src/daemon/external-plugins-bootstrap.ts +36 -46
  212. package/src/daemon/handlers/config-channels.ts +11 -2
  213. package/src/daemon/handlers/conversations.ts +3 -1
  214. package/src/daemon/handlers/skills.ts +4 -1
  215. package/src/daemon/host-app-control-proxy.ts +72 -57
  216. package/src/daemon/host-proxy-preactivation.ts +1 -3
  217. package/src/daemon/lifecycle.ts +21 -7
  218. package/src/daemon/persist-unsendable-image.ts +62 -25
  219. package/src/daemon/process-message.ts +1 -1
  220. package/src/daemon/server.ts +2 -0
  221. package/src/daemon/tool-side-effects.ts +15 -0
  222. package/src/daemon/wake-conversation-ops.ts +269 -0
  223. package/src/embedded/plugin-api.ts +2 -2
  224. package/src/export/__tests__/transcript-formatter.test.ts +5 -0
  225. package/src/heartbeat/__tests__/heartbeat-service.test.ts +3 -0
  226. package/src/heartbeat/heartbeat-run-store.ts +23 -1
  227. package/src/heartbeat/heartbeat-service.ts +26 -0
  228. package/src/ipc/__tests__/browser-ipc.test.ts +1 -1
  229. package/src/ipc/__tests__/ui-request-route.test.ts +3 -3
  230. package/src/ipc/skill-routes/__tests__/memory.test.ts +15 -0
  231. package/src/ipc/skill-routes/memory.ts +4 -2
  232. package/src/memory/__tests__/activation-session-store.test.ts +41 -0
  233. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +87 -0
  234. package/src/memory/__tests__/onboarding-events-store.test.ts +80 -0
  235. package/src/memory/activation-session-store.ts +43 -0
  236. package/src/memory/conversation-crud.ts +29 -19
  237. package/src/memory/conversation-starter-checkpoints.ts +1 -0
  238. package/src/memory/db-init.ts +6 -0
  239. package/src/memory/job-handlers/conversation-starters.ts +13 -2
  240. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +5 -4
  241. package/src/memory/jobs-worker.ts +25 -1
  242. package/src/memory/migrations/272-acp-session-history-cwd.ts +36 -0
  243. package/src/memory/migrations/273-onboarding-events-funnel-columns.ts +46 -0
  244. package/src/memory/migrations/274-create-activation-sessions.ts +15 -0
  245. package/src/memory/migrations/index.ts +3 -0
  246. package/src/memory/onboarding-events-store.ts +66 -18
  247. package/src/memory/schema/acp.ts +4 -0
  248. package/src/memory/schema/infrastructure.ts +13 -0
  249. package/src/memory/v2/__tests__/consolidation-job.test.ts +4 -97
  250. package/src/memory/v2/__tests__/page-store.test.ts +22 -0
  251. package/src/memory/v2/consolidation-job.ts +2 -63
  252. package/src/memory/v2/types.ts +5 -0
  253. package/src/messaging/providers/telegram-bot/api.ts +14 -5
  254. package/src/notifications/__tests__/copy-composer.test.ts +244 -0
  255. package/src/notifications/access-request-copy.ts +298 -0
  256. package/src/notifications/adapters/slack.ts +3 -3
  257. package/src/notifications/adapters/telegram.ts +9 -2
  258. package/src/notifications/copy-composer.ts +49 -267
  259. package/src/notifications/decision-engine.ts +16 -35
  260. package/src/notifications/home-feed-side-effect.ts +1 -6
  261. package/src/plugin-api/constants.ts +4 -0
  262. package/src/plugin-api/index.ts +40 -11
  263. package/src/plugin-api/types.ts +108 -0
  264. package/src/plugins/defaults/compaction/compact.ts +106 -0
  265. package/src/{daemon → plugins/defaults/compaction}/context-overflow-reducer.ts +250 -42
  266. package/src/plugins/defaults/compaction/corrected-target.ts +53 -0
  267. package/src/plugins/defaults/compaction/manager-store.ts +57 -0
  268. package/src/plugins/defaults/compaction/package.json +1 -2
  269. package/src/{context → plugins/defaults/compaction}/window-manager.ts +95 -25
  270. package/src/plugins/defaults/empty-response/package.json +0 -1
  271. package/src/plugins/defaults/history-repair/package.json +0 -1
  272. package/src/plugins/defaults/index.ts +156 -26
  273. package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +100 -52
  274. package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit.ts +285 -0
  275. package/src/plugins/defaults/memory-retrieval/injector-chain.ts +2 -2
  276. package/src/plugins/defaults/{injectors/register.ts → memory-retrieval/injectors.ts} +148 -73
  277. package/src/plugins/defaults/memory-retrieval/package.json +14 -0
  278. package/src/plugins/defaults/memory-retrieval/unified-turn-context.ts +223 -0
  279. package/src/plugins/defaults/memory-v3-shadow/__tests__/capabilities.test.ts +71 -0
  280. package/src/plugins/defaults/memory-v3-shadow/__tests__/dense.test.ts +181 -0
  281. package/src/plugins/defaults/memory-v3-shadow/__tests__/edge.test.ts +247 -0
  282. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/live-integration.test.ts +147 -134
  283. package/src/plugins/defaults/memory-v3-shadow/__tests__/maintain-job.test.ts +456 -0
  284. package/src/plugins/defaults/memory-v3-shadow/__tests__/orchestrate.test.ts +662 -0
  285. package/src/plugins/defaults/memory-v3-shadow/__tests__/pool-select.test.ts +306 -0
  286. package/src/plugins/defaults/memory-v3-shadow/__tests__/render-injection.test.ts +91 -0
  287. package/src/plugins/defaults/memory-v3-shadow/__tests__/section-dense-store.test.ts +402 -0
  288. package/src/plugins/defaults/memory-v3-shadow/__tests__/section-needle.test.ts +135 -0
  289. package/src/plugins/defaults/memory-v3-shadow/__tests__/sections.test.ts +125 -0
  290. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/selection-log-store.test.ts +74 -19
  291. package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-integration.test.ts +446 -0
  292. package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +592 -0
  293. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/types.test.ts +2 -24
  294. package/src/plugins/defaults/memory-v3-shadow/capabilities.ts +91 -0
  295. package/src/plugins/defaults/memory-v3-shadow/dense.ts +97 -0
  296. package/src/plugins/defaults/memory-v3-shadow/edge.ts +252 -0
  297. package/src/plugins/defaults/memory-v3-shadow/hooks/post-compact.ts +14 -0
  298. package/src/plugins/defaults/memory-v3-shadow/hooks/user-prompt-submit.ts +19 -0
  299. package/src/plugins/defaults/memory-v3-shadow/injector.ts +76 -0
  300. package/src/plugins/defaults/memory-v3-shadow/maintain-job.ts +555 -0
  301. package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +266 -0
  302. package/src/plugins/defaults/memory-v3-shadow/package.json +14 -0
  303. package/src/plugins/defaults/memory-v3-shadow/page-content.ts +71 -0
  304. package/src/plugins/defaults/memory-v3-shadow/pool-select.ts +204 -0
  305. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/render-injection.ts +16 -8
  306. package/src/plugins/defaults/memory-v3-shadow/section-dense-store.ts +236 -0
  307. package/src/plugins/defaults/memory-v3-shadow/section-needle.ts +200 -0
  308. package/src/plugins/defaults/memory-v3-shadow/sections.ts +115 -0
  309. package/src/plugins/defaults/memory-v3-shadow/selection-log-store.ts +156 -0
  310. package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +382 -0
  311. package/src/plugins/defaults/memory-v3-shadow/types.ts +92 -0
  312. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/working-set.ts +4 -1
  313. package/src/plugins/defaults/title-generate/package.json +0 -1
  314. package/src/plugins/defaults/tool-error/package.json +0 -1
  315. package/src/plugins/defaults/tool-result-truncate/package.json +0 -1
  316. package/src/plugins/external-api.ts +12 -2
  317. package/src/plugins/pipeline.ts +6 -293
  318. package/src/plugins/registry.ts +9 -37
  319. package/src/plugins/types.ts +76 -381
  320. package/src/plugins/user-loader.ts +30 -127
  321. package/src/prompts/__tests__/system-prompt.test.ts +6 -0
  322. package/src/prompts/system-prompt.ts +61 -10
  323. package/src/prompts/templates/BOOTSTRAP-ACTIVATION-RAIL.md +71 -4
  324. package/src/providers/anthropic/client.ts +9 -10
  325. package/src/providers/inference/kimi-cjk-token-ids.ts +493 -0
  326. package/src/providers/inference/logit-bias.ts +55 -0
  327. package/src/providers/model-catalog.ts +34 -0
  328. package/src/providers/openai/__tests__/vision-not-supported.test.ts +75 -0
  329. package/src/providers/openai/chat-completions-provider.ts +44 -1
  330. package/src/providers/retry.ts +22 -0
  331. package/src/providers/types.ts +6 -0
  332. package/src/runtime/__tests__/agent-wake.test.ts +555 -691
  333. package/src/runtime/__tests__/interactive-ui.test.ts +1 -1
  334. package/src/runtime/agent-wake.ts +108 -209
  335. package/src/runtime/assistant-event-hub.ts +1 -1
  336. package/src/runtime/channel-approvals.ts +1 -1
  337. package/src/runtime/interactive-ui.ts +1 -1
  338. package/src/runtime/routes/__tests__/acp-routes.test.ts +466 -55
  339. package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +1 -1
  340. package/src/runtime/routes/__tests__/plugins-routes.test.ts +423 -73
  341. package/src/runtime/routes/__tests__/stt-routes.test.ts +112 -0
  342. package/src/runtime/routes/__tests__/surface-action-routes.test.ts +5 -4
  343. package/src/runtime/routes/__tests__/surface-content-routes.test.ts +4 -1
  344. package/src/runtime/routes/acp-routes.test.ts +185 -32
  345. package/src/runtime/routes/acp-routes.ts +328 -30
  346. package/src/runtime/routes/app-management-routes.ts +3 -0
  347. package/src/runtime/routes/approval-routes.ts +1 -1
  348. package/src/runtime/routes/browser-routes.ts +1 -1
  349. package/src/runtime/routes/browser-tabs-routes.ts +6 -10
  350. package/src/runtime/routes/channel-verification-routes.ts +14 -5
  351. package/src/runtime/routes/conversation-cli-routes.ts +1 -1
  352. package/src/runtime/routes/conversation-list-routes.ts +1 -1
  353. package/src/runtime/routes/conversation-query-routes.ts +1 -1
  354. package/src/runtime/routes/conversation-routes.ts +30 -2
  355. package/src/runtime/routes/conversation-starter-routes.ts +13 -7
  356. package/src/runtime/routes/conversations-import-routes.ts +24 -7
  357. package/src/runtime/routes/host-app-control-routes.ts +1 -1
  358. package/src/runtime/routes/host-cu-routes.ts +1 -1
  359. package/src/runtime/routes/identity-routes.ts +18 -3
  360. package/src/runtime/routes/inbound-message-handler.ts +1 -1
  361. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +33 -34
  362. package/src/runtime/routes/inference-profile-session-handler.ts +11 -0
  363. package/src/runtime/routes/inference-profile-session-reaper.ts +6 -0
  364. package/src/runtime/routes/memory-v3-routes.ts +65 -305
  365. package/src/runtime/routes/playground/__tests__/force-compact.test.ts +1 -1
  366. package/src/runtime/routes/playground/helpers.ts +1 -1
  367. package/src/runtime/routes/plugins-routes.ts +337 -35
  368. package/src/runtime/routes/stt-routes.ts +45 -12
  369. package/src/runtime/routes/surface-conversation-resolver.ts +4 -3
  370. package/src/runtime/routes/work-items-routes.ts +2 -4
  371. package/src/runtime/routes/workspace-routes.ts +50 -15
  372. package/src/runtime/services/conversation-serializer.ts +1 -1
  373. package/src/runtime/verification-outbound-actions.ts +147 -2
  374. package/src/runtime/verification-templates.ts +29 -3
  375. package/src/services/published-app-updater.ts +30 -8
  376. package/src/signals/cancel.ts +2 -4
  377. package/src/subagent/manager.ts +21 -5
  378. package/src/telemetry/__tests__/activation-funnel.test.ts +95 -0
  379. package/src/telemetry/activation-funnel.ts +167 -0
  380. package/src/telemetry/types.ts +13 -0
  381. package/src/telemetry/usage-telemetry-reporter.test.ts +154 -0
  382. package/src/telemetry/usage-telemetry-reporter.ts +26 -1
  383. package/src/tools/acp/context.ts +20 -0
  384. package/src/tools/acp/list-agents.test.ts +9 -19
  385. package/src/tools/acp/list-agents.ts +3 -15
  386. package/src/tools/acp/spawn.test.ts +173 -202
  387. package/src/tools/acp/spawn.ts +37 -172
  388. package/src/tools/acp/steer.test.ts +105 -8
  389. package/src/tools/acp/steer.ts +48 -17
  390. package/src/tools/apps/executors.ts +166 -50
  391. package/src/tools/browser/browser-execution.ts +12 -2
  392. package/src/tools/filesystem/write.ts +34 -0
  393. package/src/tools/network/web-fetch.ts +65 -24
  394. package/src/tools/skills/load.ts +1 -1
  395. package/src/tools/subagent/spawn.ts +2 -4
  396. package/src/tools/ui-surface/definitions.ts +32 -5
  397. package/src/workspace/migrations/051-seed-conversation-summarization-callsite.ts +4 -5
  398. package/src/workspace/migrations/097-enable-adaptive-thinking-managed-profiles.ts +69 -45
  399. package/docs/plugins.md +0 -832
  400. package/examples/plugins/echo/register.ts +0 -143
  401. package/src/__tests__/circuit-breaker-pipeline.test.ts +0 -405
  402. package/src/__tests__/compaction-pipeline.test.ts +0 -210
  403. package/src/__tests__/compaction-timeout-recovery.test.ts +0 -251
  404. package/src/__tests__/overflow-reduce-pipeline.test.ts +0 -667
  405. package/src/__tests__/pipeline-runner.test.ts +0 -554
  406. package/src/daemon/wake-target-adapter.ts +0 -253
  407. package/src/memory/v3/__tests__/assign.test.ts +0 -242
  408. package/src/memory/v3/__tests__/capabilities.test.ts +0 -118
  409. package/src/memory/v3/__tests__/core.test.ts +0 -39
  410. package/src/memory/v3/__tests__/health.test.ts +0 -219
  411. package/src/memory/v3/__tests__/maintain-job.test.ts +0 -288
  412. package/src/memory/v3/__tests__/needle.test.ts +0 -107
  413. package/src/memory/v3/__tests__/orchestrate.test.ts +0 -436
  414. package/src/memory/v3/__tests__/provider-blocks.test.ts +0 -13
  415. package/src/memory/v3/__tests__/reconcile.test.ts +0 -274
  416. package/src/memory/v3/__tests__/render-injection.test.ts +0 -61
  417. package/src/memory/v3/__tests__/router.test.ts +0 -332
  418. package/src/memory/v3/__tests__/selector.test.ts +0 -470
  419. package/src/memory/v3/__tests__/shadow-plugin.test.ts +0 -432
  420. package/src/memory/v3/__tests__/snapshot.test.ts +0 -168
  421. package/src/memory/v3/__tests__/tree.test.ts +0 -192
  422. package/src/memory/v3/assign.ts +0 -268
  423. package/src/memory/v3/capabilities.ts +0 -124
  424. package/src/memory/v3/core.ts +0 -26
  425. package/src/memory/v3/health.ts +0 -0
  426. package/src/memory/v3/maintain-job.ts +0 -314
  427. package/src/memory/v3/needle.ts +0 -115
  428. package/src/memory/v3/orchestrate.ts +0 -126
  429. package/src/memory/v3/page-content.ts +0 -34
  430. package/src/memory/v3/provider-blocks.ts +0 -26
  431. package/src/memory/v3/reconcile.ts +0 -523
  432. package/src/memory/v3/router.ts +0 -190
  433. package/src/memory/v3/selection-log-store.ts +0 -84
  434. package/src/memory/v3/selector.ts +0 -226
  435. package/src/memory/v3/shadow-plugin.ts +0 -411
  436. package/src/memory/v3/snapshot.ts +0 -209
  437. package/src/memory/v3/tree.ts +0 -174
  438. package/src/memory/v3/types.ts +0 -59
  439. package/src/notifications/__tests__/emit-signal-home-feed.test.ts +0 -187
  440. package/src/plugins/defaults/circuit-breaker/middlewares/circuitBreaker.ts +0 -93
  441. package/src/plugins/defaults/circuit-breaker/package.json +0 -15
  442. package/src/plugins/defaults/circuit-breaker/register.ts +0 -39
  443. package/src/plugins/defaults/compaction/middlewares/compaction.ts +0 -25
  444. package/src/plugins/defaults/compaction/register.ts +0 -35
  445. package/src/plugins/defaults/compaction/terminal.ts +0 -73
  446. package/src/plugins/defaults/empty-response/register.ts +0 -23
  447. package/src/plugins/defaults/history-repair/register.ts +0 -24
  448. package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit-temp.ts +0 -216
  449. package/src/plugins/defaults/overflow-reduce/middlewares/overflowReduce.ts +0 -126
  450. package/src/plugins/defaults/overflow-reduce/package.json +0 -15
  451. package/src/plugins/defaults/overflow-reduce/register.ts +0 -42
  452. package/src/plugins/defaults/title-generate/register.ts +0 -35
  453. package/src/plugins/defaults/tool-error/register.ts +0 -23
  454. package/src/plugins/defaults/tool-result-truncate/register.ts +0 -24
  455. package/src/proactive-artifact/aux-message-injector.ts +0 -97
  456. package/src/proactive-artifact/decision.test.ts +0 -226
  457. package/src/proactive-artifact/decision.ts +0 -165
  458. package/src/proactive-artifact/index.ts +0 -7
  459. package/src/proactive-artifact/job.test.ts +0 -962
  460. package/src/proactive-artifact/job.ts +0 -372
  461. package/src/proactive-artifact/message-copy.ts +0 -58
  462. package/src/proactive-artifact/trigger-state.test.ts +0 -286
  463. package/src/proactive-artifact/trigger-state.ts +0 -123
  464. package/src/util/map-limit.ts +0 -27
  465. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/fixtures/eval-turns.json +0 -0
  466. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/fixtures/live-turns.json +0 -0
  467. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/working-set-eviction.test.ts +0 -0
  468. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/working-set-skeleton.test.ts +0 -0
  469. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/README.md +0 -0
  470. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/assignments.json +0 -0
  471. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/core.json +0 -0
  472. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-a/topic-x.md +0 -0
  473. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-a/topic-y.md +0 -0
  474. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-b/topic-z.md +0 -0
  475. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/llm-retry.ts +0 -0
@@ -23,17 +23,22 @@ import {
23
23
  import type { Provider } from "../providers/types.js";
24
24
  import { getLogger } from "../util/logger.js";
25
25
  import { truncate } from "../util/truncate.js";
26
+ import {
27
+ buildAccessRequestContractText,
28
+ buildAccessRequestInviteDirective,
29
+ hasAccessRequestInstructions,
30
+ hasInviteFlowDirective,
31
+ } from "./access-request-copy.js";
26
32
  import {
27
33
  buildConversationCandidates,
28
34
  type ConversationCandidateSet,
29
35
  serializeCandidatesForPrompt,
30
36
  } from "./conversation-candidates.js";
31
37
  import {
32
- buildAccessRequestContractText,
33
- buildAccessRequestInviteDirective,
34
38
  composeFallbackCopy,
35
- hasAccessRequestInstructions,
36
- hasInviteFlowDirective,
39
+ deriveTitle,
40
+ nonEmpty,
41
+ readPayloadString,
37
42
  } from "./copy-composer.js";
38
43
  import { createDecision } from "./decisions-store.js";
39
44
  import {
@@ -56,21 +61,6 @@ const log = getLogger("notification-decision-engine");
56
61
  const DECISION_TIMEOUT_MS = 15_000;
57
62
  const PROMPT_VERSION = "v4";
58
63
 
59
- /**
60
- * Derive a short notification title from a message body. Used when an
61
- * assistant_tool-sourced signal supplies `requestedMessage` without an
62
- * explicit `requestedTitle`: trims to the first sentence terminator when
63
- * present, then caps the result at 60 characters with an ellipsis.
64
- */
65
- function deriveTitle(body: string): string {
66
- const firstSentenceEnd = body.search(/[.!?](\s|$)/);
67
- const candidate =
68
- firstSentenceEnd > 0 ? body.slice(0, firstSentenceEnd + 1) : body;
69
- return candidate.length > 60
70
- ? candidate.slice(0, 60).trim() + "…"
71
- : candidate.trim();
72
- }
73
-
74
64
  /**
75
65
  * Maximum character budget for identity context injected into the notification
76
66
  * decision prompt. We truncate to prevent oversized prompts when SOUL.md /
@@ -768,24 +758,15 @@ export async function evaluateSignal(
768
758
  // classifier entirely. The producer has already done the routing and
769
759
  // copy decisions — we just enforce the standard post-decision guards
770
760
  // and persist the result.
771
- if (
772
- signal.sourceChannel === "assistant_tool" &&
773
- typeof signal.contextPayload === "object" &&
774
- signal.contextPayload != null &&
775
- typeof (signal.contextPayload as Record<string, unknown>)
776
- .requestedMessage === "string" &&
777
- (
778
- (signal.contextPayload as Record<string, unknown>)
779
- .requestedMessage as string
780
- ).trim().length > 0
781
- ) {
761
+ const requestedBody = nonEmpty(
762
+ readPayloadString(signal.contextPayload, "requestedMessage"),
763
+ );
764
+ if (signal.sourceChannel === "assistant_tool" && requestedBody) {
782
765
  const payload = signal.contextPayload as Record<string, unknown>;
783
- const body = (payload.requestedMessage as string).trim();
766
+ const body = requestedBody;
784
767
  const title =
785
- typeof payload.requestedTitle === "string" &&
786
- payload.requestedTitle.trim().length > 0
787
- ? (payload.requestedTitle as string).trim()
788
- : deriveTitle(body);
768
+ nonEmpty(readPayloadString(signal.contextPayload, "requestedTitle")) ??
769
+ deriveTitle(body);
789
770
  const isUrgent =
790
771
  signal.attentionHints.urgency === "critical" ||
791
772
  signal.attentionHints.urgency === "high";
@@ -22,6 +22,7 @@ import { getConversation } from "../memory/conversation-crud.js";
22
22
  import { isBackgroundConversationType } from "../memory/conversation-types.js";
23
23
  import { getLogger } from "../util/logger.js";
24
24
  import { isConversationSeedSane } from "./conversation-seed-composer.js";
25
+ import { readPayloadString } from "./copy-composer.js";
25
26
  import type { NotificationSignal } from "./signal.js";
26
27
  import type { NotificationDecision, RenderedChannelCopy } from "./types.js";
27
28
 
@@ -231,12 +232,6 @@ function resolveHomeFeedMirror(
231
232
  return { mirror: false };
232
233
  }
233
234
 
234
- function readPayloadString(payload: unknown, key: string): string | undefined {
235
- if (!payload || typeof payload !== "object") return undefined;
236
- const value = (payload as Record<string, unknown>)[key];
237
- return typeof value === "string" ? value : undefined;
238
- }
239
-
240
235
  /**
241
236
  * Routing-intent enforcement can prune `selectedChannels` without also
242
237
  * pruning `renderedCopy`, so iterating `renderedCopy` directly risks
@@ -20,10 +20,14 @@ export const HOOKS = {
20
20
  SHUTDOWN: "shutdown",
21
21
  /** Fires once per user turn, immediately before the agent loop receives `runMessages`. */
22
22
  USER_PROMPT_SUBMIT: "user-prompt-submit",
23
+ /** Fires immediately before each provider call. A hook may edit the outbound request (e.g. the system prompt) and opt the turn into deferred output streaming. */
24
+ PRE_MODEL_CALL: "pre-model-call",
23
25
  /** Fires once per tool result, after the tool returns and before the result is sent to the provider. */
24
26
  POST_TOOL_USE: "post-tool-use",
25
27
  /** Fires when the model yields a response with no tool calls — the run's stop boundary. Decides whether to stop or continue with a follow-up turn. */
26
28
  STOP: "stop",
29
+ /** Fires for each finalized assistant message, once per model call, before it is persisted/streamed-final. A hook may transform the message content. */
30
+ POST_MODEL_CALL: "post-model-call",
27
31
  } as const;
28
32
 
29
33
  /** Union of every hook name declared in {@link HOOKS}. */
@@ -11,34 +11,46 @@
11
11
  *
12
12
  * ## Surface today
13
13
  *
14
- * The public package is intentionally **declarative**: a plugin is a
15
- * directory whose `package.json` is the manifest and whose `hooks/` /
16
- * `tools/` / `skills/` / `routes/` subdirectories are the contributions.
17
- * The host introspects the directory at load time and wires it into the
18
- * runtime — plugin authors never call a runtime registration function.
14
+ * The primary authoring model is **declarative**: a plugin is a directory
15
+ * whose `package.json` is the manifest and whose `hooks/` / `tools/` /
16
+ * `skills/` / `routes/` subdirectories are the contributions. The host
17
+ * introspects the directory at load time and wires it into the runtime.
19
18
  *
20
- * What this module exposes is therefore types-only: the context shapes
19
+ * Most of what this module exposes is therefore types: the context shapes
21
20
  * the host hands to plugin hooks, and the logger shape they include.
22
21
  *
22
+ * Alongside those types, the module exposes a small set of **runtime
23
+ * handles** for plugins that need to reach the assistant's live singletons
24
+ * (subscribe to runtime events, read secrets). These resolve to the
25
+ * assistant's own instances: the host parks the loaded plugin-api namespace
26
+ * on `globalThis` at boot, and the workspace-level shim re-binds each
27
+ * runtime export from there — so a plugin's
28
+ * `import { assistantEventHub } from "@vellumai/plugin-api"` lands on the
29
+ * same singleton the assistant uses, even when the daemon is a
30
+ * `bun --compile` binary where an absolute-path import would load a
31
+ * disjoint module copy.
32
+ *
33
+ * - {@link assistantEventHub} — the assistant's pub/sub hub for runtime events
34
+ * - {@link getSecureKeyAsync} — read a secret from secure storage
35
+ *
23
36
  * - {@link PluginInitContext} — passed to `init` hook at bootstrap
24
37
  * - {@link PluginShutdownContext} — passed to `shutdown` hook at teardown
25
38
  * - {@link UserPromptSubmitContext} — passed to `user-prompt-submit` hook,
26
39
  * fired immediately before the agent loop receives a user's prompt
40
+ * - {@link PreModelCallContext} — passed to `pre-model-call` hook, fired
41
+ * before each provider call to edit the request / defer output streaming
27
42
  * - {@link PostToolUseContext} — passed to `post-tool-use` hook, fired once
28
43
  * per tool result before it joins the provider-bound history
29
44
  * - {@link StopContext} — passed to `stop` hook, fired when the model yields
30
45
  * a response with no tool calls
46
+ * - {@link PostModelCallContext} — passed to `post-model-call` hook,
47
+ * fired for each finalized assistant message to transform its content
31
48
  * - {@link PluginHookFn} — signature every lifecycle hook implements
32
49
  * - {@link PluginLogger} — pino-compatible logger shape on the contexts
33
50
  * - {@link ToolDefinition} — author-facing tool spec (default-export shape
34
51
  * for both plugin tool files and workspace tool files)
35
52
  * - {@link ToolContext} — passed to a plugin tool's `execute` method
36
53
  * - {@link ToolExecutionResult} — return shape of a plugin tool's `execute`
37
- *
38
- * Pipeline-argument types (`MemoryArgs`, `CompactionArgs`, etc.) currently
39
- * live in `assistant/src/plugins/types.ts` and have not yet migrated into
40
- * this package. A follow-up PR will move them into this surface as the
41
- * per-pipeline schemas stabilize.
42
54
  */
43
55
 
44
56
  export type { HookName } from "./constants.js";
@@ -48,7 +60,9 @@ export type {
48
60
  PluginInitContext,
49
61
  PluginLogger,
50
62
  PluginShutdownContext,
63
+ PostModelCallContext,
51
64
  PostToolUseContext,
65
+ PreModelCallContext,
52
66
  StopContext,
53
67
  StopDecision,
54
68
  ToolContext,
@@ -57,3 +71,18 @@ export type {
57
71
  UserPromptSubmitContext,
58
72
  } from "./types.js";
59
73
  export { RiskLevel } from "./types.js";
74
+
75
+ // ─── Runtime handles ─────────────────────────────────────────────────────────
76
+ // Values (not just types) that plugins consume at module-load / init time.
77
+ // Workspace-local plugins resolve these via the boot-time shim, which
78
+ // re-binds each from the assistant's globalThis-parked namespace so they
79
+ // share module identity with the assistant's own singletons.
80
+ export type { AssistantEvent } from "../runtime/assistant-event.js";
81
+ export type {
82
+ AssistantEventCallback,
83
+ AssistantEventFilter,
84
+ AssistantEventHub,
85
+ AssistantEventSubscription,
86
+ } from "../runtime/assistant-event-hub.js";
87
+ export { assistantEventHub } from "../runtime/assistant-event-hub.js";
88
+ export { getSecureKeyAsync } from "../security/secure-keys.js";
@@ -4,6 +4,7 @@
4
4
  * removing is breaking and gated on a major bump.
5
5
  */
6
6
 
7
+ import type { LLMCallSite } from "../config/schemas/llm.js";
7
8
  import type {
8
9
  ContentBlock,
9
10
  Message,
@@ -51,8 +52,10 @@ export interface PluginLogger {
51
52
  * - `init` — {@link PluginInitContext}
52
53
  * - `shutdown` — {@link PluginShutdownContext}
53
54
  * - `user-prompt-submit` — {@link UserPromptSubmitContext}
55
+ * - `pre-model-call` — {@link PreModelCallContext}
54
56
  * - `post-tool-use` — {@link PostToolUseContext}
55
57
  * - `stop` — {@link StopContext}
58
+ * - `post-model-call` — {@link PostModelCallContext}
56
59
  */
57
60
  export type PluginHookFn<TCtx = unknown> = (ctx: TCtx) => Promise<TCtx | void>;
58
61
 
@@ -127,6 +130,39 @@ export interface PluginShutdownContext {
127
130
  export interface UserPromptSubmitContext {
128
131
  /** Conversation ID the user prompt was submitted on. */
129
132
  readonly conversationId: string;
133
+ /**
134
+ * Persisted ID of the user message that triggered this turn. Hooks that
135
+ * attach turn-scoped metadata to the originating message (e.g. recording an
136
+ * injected memory block so it survives a conversation reload) key off this
137
+ * row id rather than the in-memory message arrays, whose entries carry no id.
138
+ */
139
+ readonly userMessageId: string;
140
+ /**
141
+ * Stable ID for the request that drives this turn. Hooks that perform
142
+ * runtime injection forward it onto the injector turn context so the
143
+ * assembled blocks are attributed to the originating request; it is fixed
144
+ * for the turn and cannot be recovered from the message arrays.
145
+ */
146
+ readonly requestId: string;
147
+ /**
148
+ * Active inference profile key to surface in this turn's context, or `null`
149
+ * when the profile is unchanged since the one last announced to the model.
150
+ * Hooks that emit the `model_profile` grounding line resolve the
151
+ * human-readable label (and model id) from this key via the workspace LLM
152
+ * config rather than receiving the rendered string — the key is the minimal
153
+ * turn input the message arrays cannot carry.
154
+ */
155
+ readonly modelProfileKey: string | null;
156
+ /**
157
+ * Whether the turn has no human present to answer clarification questions
158
+ * (e.g. a scheduled, background, or headless run). Resolved once at turn
159
+ * start from the run's interactivity option, falling back to live client
160
+ * presence — a single value the hook reads rather than re-deriving from
161
+ * mutable conversation state that can flip mid-turn. Hooks that assemble the
162
+ * turn's runtime injections forward it so the assembled context reflects the
163
+ * turn's interactivity.
164
+ */
165
+ readonly isNonInteractive: boolean;
130
166
  /**
131
167
  * The text of the user prompt that triggered this turn — the resolved
132
168
  * user message (after slash-command expansion), independent of any
@@ -288,3 +324,75 @@ export interface StopContext {
288
324
  */
289
325
  readonly logger: PluginLogger;
290
326
  }
327
+
328
+ // ─── Pre-model-call hook context ─────────────────────────────────────────────
329
+
330
+ /**
331
+ * Context passed to the `pre-model-call` hook. Fires immediately before each
332
+ * provider call — once per model call within a turn, including tool-result
333
+ * follow-up calls. Because it runs for every provider call (background, subagent,
334
+ * and compaction work can share a conversation), hooks MUST self-gate on
335
+ * {@link callSite} / {@link conversationId} before acting.
336
+ *
337
+ * A hook may edit the outbound request by replacing {@link systemPrompt}, and may
338
+ * opt this turn into deferred output streaming via {@link deferAssistantOutput}.
339
+ * Mutate the context in place or return a new one; throwing is contained by the
340
+ * loop (the call proceeds with the original request).
341
+ */
342
+ export interface PreModelCallContext {
343
+ /** Conversation ID the call belongs to. */
344
+ readonly conversationId: string;
345
+ /**
346
+ * The call site this provider call serves — `"mainAgent"` for the user-facing
347
+ * reply, or a background/utility site. Omitted by call sites that don't tag one.
348
+ */
349
+ readonly callSite?: LLMCallSite;
350
+ /**
351
+ * The system prompt about to be sent. A hook may replace it (e.g. strip or
352
+ * append a section); the loop sends the resulting value.
353
+ */
354
+ systemPrompt: string | undefined;
355
+ /**
356
+ * Seeded `false`. When a hook sets it `true`, the loop suppresses this turn's
357
+ * live assistant `text_delta` stream; a `post-model-call` hook is then
358
+ * expected to produce the text the client sees (emitted once, after the reply
359
+ * is finalized). Lets a plugin replace streamed output wholesale — e.g.
360
+ * redaction that needs the full message — instead of leaking the raw stream.
361
+ */
362
+ deferAssistantOutput: boolean;
363
+ /** Logger scoped to the current turn (tag structured fields with `{ plugin }`). */
364
+ readonly logger: PluginLogger;
365
+ }
366
+
367
+ // ─── Post-model-call hook context ────────────────────────────────────────────
368
+
369
+ /**
370
+ * Context passed to the `post-model-call` hook. Fires for each finalized
371
+ * assistant message — once per model call, at the message-complete boundary —
372
+ * before the message is persisted and (if deferred) streamed-final. Unlike
373
+ * {@link StopContext}'s read-only `responseContent` (which exists for the stop
374
+ * decision), {@link content} is mutable: the loop adopts the hook's result as the
375
+ * persisted and streamed message.
376
+ *
377
+ * Fires on tool-bearing turns too (a reply can carry both text and `tool_use`),
378
+ * so a hook should transform only the blocks it owns and leave others — notably
379
+ * `tool_use` — intact. Runs for every finalized message regardless of call site;
380
+ * hooks MUST self-gate on {@link callSite} / {@link conversationId}. Mutate in
381
+ * place or return a new context; throwing is contained by the loop (the original
382
+ * content is kept).
383
+ */
384
+ export interface PostModelCallContext {
385
+ /** Conversation ID the message belongs to. */
386
+ readonly conversationId: string;
387
+ /** The call site this message serves — `"mainAgent"` for the user-facing reply. */
388
+ readonly callSite?: LLMCallSite;
389
+ /**
390
+ * The finalized message content. Mutable — transform the text blocks and leave
391
+ * `tool_use` (and other non-text blocks) intact.
392
+ */
393
+ content: ContentBlock[];
394
+ /** Provider-reported stop reason for the turn, when reported. */
395
+ readonly stopReason: string | null | undefined;
396
+ /** Logger scoped to the current turn (tag structured fields with `{ plugin }`). */
397
+ readonly logger: PluginLogger;
398
+ }
@@ -0,0 +1,106 @@
1
+ /**
2
+ * Default compaction implementation.
3
+ *
4
+ * Summarizes conversation history when the context window fills up by
5
+ * delegating to the conversation's {@link ContextWindowManager}. The agent loop
6
+ * calls {@link defaultCompact} directly with a {@link CompactionContext}; the
7
+ * request carries the conversational inputs while the compaction module resolves
8
+ * (and, if needed, builds) the manager from its per-conversation store.
9
+ *
10
+ * This module is side-effect free: importing it does not register any plugin.
11
+ */
12
+
13
+ import type { Message } from "../../../providers/types.js";
14
+ import type { TrustClass } from "../../../runtime/actor-trust-resolver.js";
15
+ import { PluginExecutionError } from "../../types.js";
16
+ import { getContextWindowManager } from "./manager-store.js";
17
+ import type {
18
+ ContextWindowResult,
19
+ EmergencyCompactOptions,
20
+ } from "./window-manager.js";
21
+
22
+ /**
23
+ * Name under which the default compaction plugin registers. Exposed so call
24
+ * sites can attribute compaction failures to the default plugin.
25
+ */
26
+ export const DEFAULT_COMPACTION_PLUGIN_NAME = "default-compaction";
27
+
28
+ /**
29
+ * Self-describing compaction request handed to {@link defaultCompact}. Carries
30
+ * the conversational inputs plus the `conversationId` the compaction module
31
+ * resolves its manager from, so callers never hold or pass a manager handle and
32
+ * the request can grow toward a model-facing compaction-method shape without
33
+ * coupling callers to the manager's option bag.
34
+ */
35
+ export interface CompactionContext {
36
+ /** Conversation whose manager performs the compaction. */
37
+ conversationId: string;
38
+ /** Message history to consider for compaction. */
39
+ messages: Message[];
40
+ /** Abort signal forwarded to the compaction summary call. */
41
+ signal?: AbortSignal;
42
+ /** Skip the auto-threshold check (forced/overflow/emergency compaction). */
43
+ force?: boolean;
44
+ /** Per-conversation inference-profile override for the summary call. */
45
+ overrideProfile?: string | null;
46
+ /** Pre-computed token estimate from a prior `shouldCompact()` call. */
47
+ precomputedEstimate?: number;
48
+ /** Legacy keep-boundary hint forwarded to the compactor. */
49
+ minKeepRecentUserTurns?: number;
50
+ /** Trust class of the actor whose turn triggered compaction. */
51
+ actorTrustClass?: TrustClass;
52
+ }
53
+
54
+ /**
55
+ * Run compaction for the turn: resolves the conversation's context window
56
+ * manager from the compaction store (building it on first access) and returns
57
+ * the (possibly summarized) message history.
58
+ */
59
+ export async function defaultCompact(
60
+ context: CompactionContext,
61
+ ): Promise<ContextWindowResult> {
62
+ const { conversationId, messages, signal, ...options } = context;
63
+ const manager = getContextWindowManager(conversationId);
64
+ if (manager == null) {
65
+ throw new PluginExecutionError(
66
+ `default-compaction: no ContextWindowManager registered for conversation ${conversationId} — the conversation must register one before compaction runs`,
67
+ DEFAULT_COMPACTION_PLUGIN_NAME,
68
+ );
69
+ }
70
+ return manager.maybeCompact(messages, signal, options);
71
+ }
72
+
73
+ /**
74
+ * Self-describing emergency-compaction request handed to
75
+ * {@link defaultEmergencyCompact}. Mirrors {@link CompactionContext} but
76
+ * carries the provider-reported token estimate at the overflow that triggered
77
+ * recovery, which sizes the summarize-around-last-tool-pair cut.
78
+ */
79
+ export interface EmergencyCompactionContext extends EmergencyCompactOptions {
80
+ /** Conversation whose manager performs the emergency compaction. */
81
+ conversationId: string;
82
+ /** Message history to summarize around the last tool_use/tool_result pair. */
83
+ messages: Message[];
84
+ /** Abort signal forwarded to the compaction summary call. */
85
+ signal?: AbortSignal;
86
+ }
87
+
88
+ /**
89
+ * Run emergency mid-turn compaction for the turn: resolves the conversation's
90
+ * context window manager from the compaction store and summarizes everything
91
+ * before the last tool_use/tool_result pair, preserving the agent's most recent
92
+ * action context while aggressively compressing earlier history.
93
+ */
94
+ export async function defaultEmergencyCompact(
95
+ context: EmergencyCompactionContext,
96
+ ): Promise<ContextWindowResult> {
97
+ const { conversationId, messages, signal, ...options } = context;
98
+ const manager = getContextWindowManager(conversationId);
99
+ if (manager == null) {
100
+ throw new PluginExecutionError(
101
+ `default-compaction: no ContextWindowManager registered for conversation ${conversationId} — the conversation must register one before emergency compaction runs`,
102
+ DEFAULT_COMPACTION_PLUGIN_NAME,
103
+ );
104
+ }
105
+ return manager.emergencyCompact(messages, options, signal);
106
+ }