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

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