@vellumai/assistant 0.8.1 → 0.8.3

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 (630) hide show
  1. package/ARCHITECTURE.md +13 -19
  2. package/Dockerfile +75 -1
  3. package/bun.lock +11 -1
  4. package/docker-entrypoint.sh +17 -0
  5. package/docker-init-apt-root.sh +167 -0
  6. package/docker-kata-apt-env.sh +39 -0
  7. package/docs/plugins.md +88 -47
  8. package/docs/skills.md +9 -7
  9. package/examples/plugins/echo/README.md +27 -27
  10. package/examples/plugins/echo/package.json +3 -0
  11. package/examples/plugins/echo/register.ts +31 -31
  12. package/node_modules/@vellumai/slack-text/src/index.test.ts +114 -14
  13. package/node_modules/@vellumai/slack-text/src/index.ts +82 -18
  14. package/openapi.yaml +642 -5
  15. package/package.json +3 -1
  16. package/scripts/generate-openapi.ts +83 -10
  17. package/scripts/sync-llm-catalog.ts +2 -2
  18. package/scripts/sync-web-search-catalog.ts +47 -25
  19. package/src/__tests__/agent-image-optimize.test.ts +11 -3
  20. package/src/__tests__/agent-loop-exit-reason.test.ts +272 -0
  21. package/src/__tests__/agent-loop-provider-error-recording.test.ts +195 -0
  22. package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +131 -0
  23. package/src/__tests__/anthropic-provider.test.ts +45 -0
  24. package/src/__tests__/app-builder-tool-scripts.test.ts +9 -3
  25. package/src/__tests__/app-executors.test.ts +220 -4
  26. package/src/__tests__/auto-analysis-end-to-end.test.ts +35 -0
  27. package/src/__tests__/bundled-asset.test.ts +6 -6
  28. package/src/__tests__/channel-availability-routes.test.ts +206 -0
  29. package/src/__tests__/channel-delivery-store.test.ts +289 -1
  30. package/src/__tests__/circuit-breaker-pipeline.test.ts +0 -1
  31. package/src/__tests__/clawhub.test.ts +75 -16
  32. package/src/__tests__/compactor-tail-resolution.test.ts +147 -0
  33. package/src/__tests__/config-get-vision-flag.test.ts +136 -0
  34. package/src/__tests__/config-loader-backfill.test.ts +115 -18
  35. package/src/__tests__/config-schema.test.ts +21 -0
  36. package/src/__tests__/config-set-route.test.ts +80 -0
  37. package/src/__tests__/config-sounds-sync.test.ts +97 -0
  38. package/src/__tests__/config-watcher-skill-reseed.test.ts +453 -0
  39. package/src/__tests__/context-search-conversations-source.test.ts +117 -2
  40. package/src/__tests__/context-search-memory-v2-source.test.ts +0 -1
  41. package/src/__tests__/context-search-workspace-source.test.ts +7 -0
  42. package/src/__tests__/context-token-estimator.test.ts +31 -65
  43. package/src/__tests__/conversation-abort-tool-results.test.ts +4 -1
  44. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +1 -0
  45. package/src/__tests__/conversation-agent-loop-overflow.test.ts +92 -92
  46. package/src/__tests__/conversation-agent-loop.test.ts +59 -1
  47. package/src/__tests__/conversation-error.test.ts +42 -3
  48. package/src/__tests__/conversation-fork-crud.test.ts +82 -0
  49. package/src/__tests__/conversation-inference-profile-route.test.ts +40 -4
  50. package/src/__tests__/conversation-lifecycle.test.ts +173 -0
  51. package/src/__tests__/conversation-media-retry.test.ts +19 -8
  52. package/src/__tests__/conversation-message-sync-tags.test.ts +97 -0
  53. package/src/__tests__/conversation-pairing.test.ts +54 -0
  54. package/src/__tests__/conversation-process-callsite.test.ts +4 -1
  55. package/src/__tests__/conversation-provider-retry-repair.test.ts +5 -1
  56. package/src/__tests__/conversation-queue.test.ts +4 -1
  57. package/src/__tests__/conversation-runtime-assembly.test.ts +102 -13
  58. package/src/__tests__/conversation-slash-queue.test.ts +59 -1
  59. package/src/__tests__/conversation-slash-unknown.test.ts +4 -1
  60. package/src/__tests__/conversation-surfaces-table-action.test.ts +360 -0
  61. package/src/__tests__/conversation-sync-tags.test.ts +235 -0
  62. package/src/__tests__/conversation-workspace-injection.test.ts +5 -1
  63. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +5 -1
  64. package/src/__tests__/credential-security-invariants.test.ts +3 -2
  65. package/src/__tests__/date-context.test.ts +45 -0
  66. package/src/__tests__/db-slack-external-content-normalization.test.ts +301 -0
  67. package/src/__tests__/delete-managed-skill-tool.test.ts +55 -13
  68. package/src/__tests__/disk-pressure-tools.test.ts +1 -0
  69. package/src/__tests__/dm-backfill.test.ts +121 -10
  70. package/src/__tests__/document-tool-security.test.ts +258 -0
  71. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +0 -1
  72. package/src/__tests__/edit-propagation.test.ts +33 -0
  73. package/src/__tests__/empty-response-pipeline.test.ts +0 -4
  74. package/src/__tests__/external-plugin-loader.test.ts +151 -55
  75. package/src/__tests__/filing-service.test.ts +140 -0
  76. package/src/__tests__/get-skill-detail-audit.test.ts +0 -4
  77. package/src/__tests__/guardian-action-no-hardcoded-copy.test.ts +0 -1
  78. package/src/__tests__/guardian-dispatch.test.ts +1 -0
  79. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +43 -62
  80. package/src/__tests__/heartbeat-service.test.ts +24 -164
  81. package/src/__tests__/helpers/channel-test-adapter.ts +0 -2
  82. package/src/__tests__/helpers/tar-fixtures.ts +39 -0
  83. package/src/__tests__/helpers/wait-for.ts +21 -0
  84. package/src/__tests__/history-repair-pipeline.test.ts +0 -3
  85. package/src/__tests__/history-repair.test.ts +73 -0
  86. package/src/__tests__/host-app-control-proxy.test.ts +507 -10
  87. package/src/__tests__/host-proxy-preactivation.test.ts +200 -13
  88. package/src/__tests__/image-credentials.test.ts +1 -1
  89. package/src/__tests__/inbound-slack-persistence.test.ts +2 -0
  90. package/src/__tests__/inference-no-mode-boot-e2e.test.ts +1 -1
  91. package/src/__tests__/inference-profile-reaper.test.ts +4 -2
  92. package/src/__tests__/inference-profile-session-handler.test.ts +18 -6
  93. package/src/__tests__/inference-profile-session-ipc.test.ts +17 -5
  94. package/src/__tests__/injector-background-turn.test.ts +153 -0
  95. package/src/__tests__/injector-chain.test.ts +15 -8
  96. package/src/__tests__/install-skill-routing.test.ts +155 -37
  97. package/src/__tests__/lifecycle-memory-v2-seed.test.ts +99 -3
  98. package/src/__tests__/list-messages-page-latest.test.ts +55 -0
  99. package/src/__tests__/llm-call-pipeline.test.ts +0 -3
  100. package/src/__tests__/llm-callsite-catalog.test.ts +25 -0
  101. package/src/__tests__/llm-catalog-parity.test.ts +58 -13
  102. package/src/__tests__/llm-request-log-agent-loop-exit-reason.test.ts +116 -0
  103. package/src/__tests__/llm-request-log-error-payload.test.ts +138 -0
  104. package/src/__tests__/llm-request-log-source-clickhouse.test.ts +36 -0
  105. package/src/__tests__/llm-request-log-source-factory.test.ts +29 -53
  106. package/src/__tests__/llm-resolver.test.ts +255 -2
  107. package/src/__tests__/llm-usage-store.test.ts +114 -0
  108. package/src/__tests__/managed-profile-guard.test.ts +41 -29
  109. package/src/__tests__/managed-skill-lifecycle.test.ts +109 -18
  110. package/src/__tests__/managed-store.test.ts +84 -192
  111. package/src/__tests__/media-generate-image.test.ts +1 -1
  112. package/src/__tests__/memory-retrieval-pipeline.test.ts +0 -2
  113. package/src/__tests__/messages-after-tiebreaker.test.ts +122 -0
  114. package/src/__tests__/notification-decision-fallback.test.ts +0 -91
  115. package/src/__tests__/notification-decision-strategy.test.ts +14 -31
  116. package/src/__tests__/notification-deep-link.test.ts +15 -0
  117. package/src/__tests__/notification-guardian-path.test.ts +1 -2
  118. package/src/__tests__/notification-platform-adapter.test.ts +5 -4
  119. package/src/__tests__/notification-telegram-adapter.test.ts +1 -0
  120. package/src/__tests__/notification-vellum-adapter.test.ts +113 -0
  121. package/src/__tests__/oauth-commands-routes.test.ts +168 -16
  122. package/src/__tests__/oauth-provider-profiles.test.ts +9 -0
  123. package/src/__tests__/openai-provider.test.ts +242 -3
  124. package/src/__tests__/openai-responses-cutover-guard.test.ts +17 -9
  125. package/src/__tests__/openrouter-provider-only.test.ts +51 -3
  126. package/src/__tests__/openrouter-token-estimation.test.ts +34 -25
  127. package/src/__tests__/overflow-reduce-pipeline.test.ts +0 -2
  128. package/src/__tests__/persistence-pipeline.test.ts +0 -2
  129. package/src/__tests__/{managed-proxy-context.test.ts → platform-proxy-context.test.ts} +7 -2
  130. package/src/__tests__/platform.test.ts +2 -0
  131. package/src/__tests__/plugin-api-shim.test.ts +125 -0
  132. package/src/__tests__/plugin-bootstrap.test.ts +10 -36
  133. package/src/__tests__/plugin-external-api.test.ts +68 -0
  134. package/src/__tests__/plugin-registry.test.ts +0 -77
  135. package/src/__tests__/plugin-route-contribution.test.ts +0 -1
  136. package/src/__tests__/plugin-skill-contribution.test.ts +0 -2
  137. package/src/__tests__/plugin-tool-contribution.test.ts +16 -15
  138. package/src/__tests__/plugin-types.test.ts +3 -13
  139. package/src/__tests__/process-message-background-slack.test.ts +8 -1
  140. package/src/__tests__/process-message-display-content.test.ts +421 -0
  141. package/src/__tests__/provider-catalog-visibility.test.ts +158 -0
  142. package/src/__tests__/provider-error-scenarios.test.ts +111 -0
  143. package/src/__tests__/{provider-managed-proxy-integration.test.ts → provider-platform-proxy-integration.test.ts} +33 -31
  144. package/src/__tests__/scaffold-managed-skill-tool.test.ts +65 -13
  145. package/src/__tests__/schedule-routes.test.ts +50 -3
  146. package/src/__tests__/schedule-store.test.ts +94 -0
  147. package/src/__tests__/scheduler-reuse-conversation.test.ts +54 -7
  148. package/src/__tests__/schema-transforms.test.ts +20 -0
  149. package/src/__tests__/search-skills-unified.test.ts +0 -5
  150. package/src/__tests__/{secret-routes-managed-proxy.test.ts → secret-routes-platform-proxy.test.ts} +1 -1
  151. package/src/__tests__/server-history-render.test.ts +43 -0
  152. package/src/__tests__/skill-load-feature-flag.test.ts +0 -12
  153. package/src/__tests__/skill-load-tool.test.ts +27 -89
  154. package/src/__tests__/skill-memory.test.ts +23 -3
  155. package/src/__tests__/skills-file-content-endpoint.test.ts +9 -38
  156. package/src/__tests__/skills-files-catalog-fallback.test.ts +0 -3
  157. package/src/__tests__/skills-install-extract.test.ts +49 -38
  158. package/src/__tests__/skills-install-staging.test.ts +159 -0
  159. package/src/__tests__/skills-uninstall.test.ts +9 -41
  160. package/src/__tests__/skills.test.ts +51 -58
  161. package/src/__tests__/slack-channel-config.test.ts +9 -0
  162. package/src/__tests__/subagent-tool-filtering.test.ts +50 -0
  163. package/src/__tests__/system-prompt.test.ts +670 -63
  164. package/src/__tests__/terminal-tools.test.ts +28 -1
  165. package/src/__tests__/thread-backfill.test.ts +557 -27
  166. package/src/__tests__/title-generate-pipeline.test.ts +0 -13
  167. package/src/__tests__/token-estimate-pipeline.test.ts +0 -3
  168. package/src/__tests__/tool-error-pipeline.test.ts +0 -3
  169. package/src/__tests__/tool-execute-pipeline.test.ts +0 -5
  170. package/src/__tests__/tool-executor-lifecycle-events.test.ts +1 -1
  171. package/src/__tests__/tool-executor.test.ts +16 -4
  172. package/src/__tests__/tool-result-truncate-pipeline.test.ts +0 -12
  173. package/src/__tests__/turn-events-store.test.ts +256 -0
  174. package/src/__tests__/twilio-routes.test.ts +4 -0
  175. package/src/__tests__/user-plugin-loader.test.ts +0 -7
  176. package/src/__tests__/voice-session-bridge.test.ts +198 -0
  177. package/src/__tests__/web-search-catalog-parity.test.ts +32 -10
  178. package/src/__tests__/workspace-migration-057-repair-stale-gemini-model-ids.test.ts +115 -3
  179. package/src/__tests__/workspace-migration-072-seed-reply-suggestion-callsite.test.ts +50 -0
  180. package/src/__tests__/workspace-migration-073-repair-recall-callsite-empty-profile.test.ts +153 -0
  181. package/src/__tests__/workspace-migration-085-memory-v2-bm25-b-reembed-disabled-v2-pages.test.ts +220 -0
  182. package/src/__tests__/workspace-migration-086-revert-stale-gemini-mis-rewrites.test.ts +269 -0
  183. package/src/__tests__/workspace-migration-087-memory-router-balanced-profile.test.ts +228 -0
  184. package/src/__tests__/workspace-migration-remove-legacy-skills-index.test.ts +309 -0
  185. package/src/__tests__/workspace-migrations-runner.test.ts +111 -3
  186. package/src/a2a/__tests__/agent-card.test.ts +98 -0
  187. package/src/a2a/__tests__/e2e-a2a-channel.test.ts +597 -0
  188. package/src/a2a/__tests__/protocol-helpers.test.ts +113 -0
  189. package/src/a2a/__tests__/task-store.test.ts +246 -0
  190. package/src/a2a/agent-card.ts +58 -0
  191. package/src/a2a/feature-gate.ts +8 -0
  192. package/src/a2a/protocol-constants.ts +21 -0
  193. package/src/a2a/protocol-errors.ts +50 -0
  194. package/src/a2a/protocol-types.ts +162 -0
  195. package/src/a2a/task-store.ts +168 -0
  196. package/src/acp/resolve-agent.ts +1 -1
  197. package/src/agent/image-optimize.ts +13 -5
  198. package/src/agent/loop.ts +167 -18
  199. package/src/calls/voice-session-bridge.ts +61 -42
  200. package/src/channels/config.ts +9 -0
  201. package/src/channels/types.ts +122 -0
  202. package/src/cli/__tests__/unknown-command.test.ts +24 -0
  203. package/src/cli/commands/__tests__/changelog.test.ts +304 -319
  204. package/src/cli/{__tests__ → commands/__tests__}/notifications.test.ts +201 -28
  205. package/src/cli/commands/__tests__/schedules.test.ts +960 -0
  206. package/src/cli/commands/changelog.ts +106 -42
  207. package/src/cli/commands/conversations.ts +102 -17
  208. package/src/cli/commands/default-action.ts +10 -53
  209. package/src/cli/commands/notifications.ts +388 -346
  210. package/src/cli/commands/plugins.ts +252 -0
  211. package/src/cli/commands/schedules.ts +683 -0
  212. package/src/cli/commands/telemetry.ts +40 -0
  213. package/src/cli/lib/__tests__/cli-colors.test.ts +48 -0
  214. package/src/cli/lib/__tests__/confirm-prompt.test.ts +159 -0
  215. package/src/cli/lib/__tests__/install-from-github.test.ts +355 -0
  216. package/src/cli/lib/__tests__/list-installed-plugins.test.ts +154 -0
  217. package/src/cli/lib/__tests__/search-plugins.test.ts +261 -0
  218. package/src/cli/lib/__tests__/uninstall-plugin.test.ts +124 -0
  219. package/src/cli/lib/__tests__/unknown-command.test.ts +106 -0
  220. package/src/cli/lib/cli-colors.ts +12 -0
  221. package/src/cli/lib/confirm-prompt.ts +79 -0
  222. package/src/cli/lib/install-from-github.ts +303 -0
  223. package/src/cli/lib/list-installed-plugins.ts +137 -0
  224. package/src/cli/lib/search-plugins.ts +163 -0
  225. package/src/cli/lib/uninstall-plugin.ts +82 -0
  226. package/src/cli/lib/unknown-command.ts +111 -0
  227. package/src/cli/program.ts +52 -2
  228. package/src/config/assistant-feature-flags.ts +24 -54
  229. package/src/config/bundled-skills/app-builder/SKILL.md +140 -22
  230. package/src/config/bundled-skills/app-builder/TOOLS.json +7 -0
  231. package/src/config/bundled-skills/computer-use/TOOLS.json +15 -52
  232. package/src/config/bundled-skills/document/SKILL.md +23 -3
  233. package/src/config/bundled-skills/document/TOOLS.json +53 -0
  234. package/src/config/bundled-skills/document/tools/document-delete.ts +12 -0
  235. package/src/config/bundled-skills/document/tools/document-list.ts +12 -0
  236. package/src/config/bundled-skills/document/tools/document-read.ts +12 -0
  237. package/src/config/bundled-skills/phone-calls/SKILL.md +1 -1
  238. package/src/config/bundled-skills/skill-management/SKILL.md +2 -2
  239. package/src/config/bundled-skills/skill-management/TOOLS.json +7 -7
  240. package/src/config/bundled-tool-registry.ts +6 -0
  241. package/src/config/call-site-defaults.ts +105 -0
  242. package/src/config/feature-flag-registry.json +41 -9
  243. package/src/config/llm-resolver.ts +52 -1
  244. package/src/config/loader.ts +64 -38
  245. package/src/config/schema.ts +9 -10
  246. package/src/config/schemas/__tests__/llm-request-logs.test.ts +36 -0
  247. package/src/config/schemas/__tests__/memory-v2.test.ts +3 -3
  248. package/src/config/schemas/channels.ts +17 -0
  249. package/src/config/schemas/compaction.ts +28 -0
  250. package/src/config/schemas/conversations.ts +10 -0
  251. package/src/config/schemas/heartbeat.ts +23 -0
  252. package/src/config/schemas/llm-request-logs.ts +31 -7
  253. package/src/config/schemas/llm.ts +1 -0
  254. package/src/config/schemas/memory-retrieval.ts +18 -0
  255. package/src/config/schemas/memory-retrospective.ts +1 -1
  256. package/src/config/schemas/memory-v2.ts +4 -4
  257. package/src/config/schemas/memory.ts +3 -1
  258. package/src/config/schemas/tools.ts +14 -0
  259. package/src/config/seed-inference-profiles.ts +99 -29
  260. package/src/config/skills.ts +3 -96
  261. package/src/context/compactor.ts +1107 -0
  262. package/src/context/token-estimator.ts +34 -36
  263. package/src/context/window-manager.ts +197 -1520
  264. package/src/credential-execution/managed-catalog.ts +37 -0
  265. package/src/credential-health/credential-health-service.ts +280 -19
  266. package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +33 -18
  267. package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +138 -0
  268. package/src/daemon/__tests__/conversation-tool-setup.test.ts +74 -0
  269. package/src/daemon/approval-generators.ts +8 -6
  270. package/src/daemon/config-watcher.ts +94 -31
  271. package/src/daemon/conversation-agent-loop-handlers.ts +78 -0
  272. package/src/daemon/conversation-agent-loop.ts +198 -11
  273. package/src/daemon/conversation-error.ts +171 -37
  274. package/src/daemon/conversation-lifecycle.ts +53 -40
  275. package/src/daemon/conversation-messaging.ts +25 -6
  276. package/src/daemon/conversation-process.ts +49 -12
  277. package/src/daemon/conversation-runtime-assembly.ts +25 -1
  278. package/src/daemon/conversation-slash.ts +12 -5
  279. package/src/daemon/conversation-store.ts +11 -4
  280. package/src/daemon/conversation-tool-setup.ts +39 -7
  281. package/src/daemon/conversation.ts +33 -8
  282. package/src/daemon/date-context.ts +40 -0
  283. package/src/daemon/external-plugins-bootstrap.ts +217 -181
  284. package/src/daemon/first-greeting.ts +22 -2
  285. package/src/daemon/guardian-action-generators.ts +1 -125
  286. package/src/daemon/handlers/__tests__/config-a2a-complete.test.ts +248 -0
  287. package/src/daemon/handlers/__tests__/config-a2a-invite.test.ts +154 -0
  288. package/src/daemon/handlers/__tests__/config-a2a-redeem.test.ts +133 -0
  289. package/src/daemon/handlers/__tests__/config-a2a.test.ts +95 -0
  290. package/src/daemon/handlers/config-a2a.ts +289 -0
  291. package/src/daemon/handlers/config-model.ts +6 -5
  292. package/src/daemon/handlers/config-slack-channel.ts +15 -3
  293. package/src/daemon/handlers/conversations.ts +1 -0
  294. package/src/daemon/handlers/shared.ts +14 -5
  295. package/src/daemon/handlers/skills.ts +111 -108
  296. package/src/daemon/history-repair.ts +28 -1
  297. package/src/daemon/host-app-control-proxy.ts +153 -27
  298. package/src/daemon/host-proxy-preactivation.ts +85 -18
  299. package/src/daemon/lifecycle.ts +89 -91
  300. package/src/daemon/meet-host-supervisor.ts +5 -4
  301. package/src/daemon/memory-v2-startup.ts +85 -0
  302. package/src/daemon/message-protocol.ts +1 -0
  303. package/src/daemon/message-types/conversations.ts +25 -0
  304. package/src/daemon/message-types/messages.ts +61 -0
  305. package/src/daemon/message-types/notifications.ts +21 -0
  306. package/src/daemon/message-types/subagents.ts +1 -0
  307. package/src/daemon/message-types/sync.ts +1 -0
  308. package/src/daemon/pkb-reminder-builder.test.ts +11 -54
  309. package/src/daemon/pkb-reminder-builder.ts +5 -20
  310. package/src/daemon/plugin-source-watcher.ts +146 -0
  311. package/src/daemon/process-message.ts +24 -3
  312. package/src/daemon/server.ts +11 -2
  313. package/src/daemon/skill-memory-refresh.ts +33 -0
  314. package/src/daemon/wake-target-adapter.ts +2 -0
  315. package/src/documents/document-store.ts +221 -3
  316. package/src/embedded/plugin-api.ts +40 -0
  317. package/src/export/__tests__/transcript-formatter.test.ts +121 -0
  318. package/src/export/transcript-formatter.ts +54 -20
  319. package/src/filing/filing-service.ts +39 -0
  320. package/src/heartbeat/__tests__/heartbeat-service.test.ts +135 -6
  321. package/src/heartbeat/heartbeat-run-store.ts +2 -1
  322. package/src/heartbeat/heartbeat-service.ts +73 -189
  323. package/src/home/__tests__/feed-types.test.ts +80 -0
  324. package/src/home/feed-types.ts +36 -2
  325. package/src/home/post-connect-feed.ts +1 -0
  326. package/src/index.ts +18 -1
  327. package/src/ipc/cli-client.ts +147 -45
  328. package/src/live-voice/__tests__/live-voice-stt.test.ts +57 -0
  329. package/src/mcp/client.ts +20 -4
  330. package/src/media/image-credentials.ts +3 -3
  331. package/src/memory/__tests__/bookmark-crud.test.ts +33 -27
  332. package/src/memory/__tests__/conversation-queries.test.ts +483 -0
  333. package/src/memory/__tests__/jobs-worker-v2-graph-trigger-embed.test.ts +113 -0
  334. package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +2 -50
  335. package/src/memory/__tests__/memory-retrospective-job.test.ts +87 -4
  336. package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +119 -14
  337. package/src/memory/__tests__/message-content.test.ts +35 -0
  338. package/src/memory/bookmark-crud.ts +42 -10
  339. package/src/memory/context-search/sources/conversations.ts +62 -2
  340. package/src/memory/context-search/sources/workspace.ts +4 -0
  341. package/src/memory/conversation-crud.ts +63 -19
  342. package/src/memory/conversation-queries.ts +197 -11
  343. package/src/memory/conversation-title-service.ts +26 -4
  344. package/src/memory/db-init.ts +12 -0
  345. package/src/memory/delivery-crud.ts +152 -5
  346. package/src/memory/embedding-backend.ts +4 -4
  347. package/src/memory/external-conversation-store.ts +66 -5
  348. package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +150 -12
  349. package/src/memory/graph/conversation-graph-memory.ts +49 -21
  350. package/src/memory/graph/tools.ts +9 -40
  351. package/src/memory/indexer.ts +34 -29
  352. package/src/memory/invite-store.ts +53 -0
  353. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +73 -0
  354. package/src/memory/jobs/embed-concept-page.ts +20 -11
  355. package/src/memory/jobs-worker.ts +6 -1
  356. package/src/memory/llm-request-log-source-clickhouse.ts +24 -12
  357. package/src/memory/llm-request-log-source.ts +19 -52
  358. package/src/memory/llm-request-log-store.ts +92 -1
  359. package/src/memory/llm-usage-store.ts +125 -5
  360. package/src/memory/memory-retrospective-enqueue.ts +1 -20
  361. package/src/memory/memory-retrospective-job.ts +33 -6
  362. package/src/memory/memory-retrospective-startup-cleanup.ts +72 -5
  363. package/src/memory/message-content.ts +1 -1
  364. package/src/memory/migrations/109-external-conversation-bindings.ts +15 -4
  365. package/src/memory/migrations/229-delete-private-conversations.test.ts +38 -1
  366. package/src/memory/migrations/229-delete-private-conversations.ts +7 -0
  367. package/src/memory/migrations/247-external-conversation-binding-thread-id.ts +78 -0
  368. package/src/memory/migrations/248-create-onboarding-events.ts +21 -0
  369. package/src/memory/migrations/249-normalize-slack-external-content.ts +240 -0
  370. package/src/memory/migrations/250-provider-connection-base-url-and-models.ts +28 -0
  371. package/src/memory/migrations/251-a2a-tasks.ts +49 -0
  372. package/src/memory/migrations/252-llm-request-log-agent-loop-exit-reason.ts +32 -0
  373. package/src/memory/migrations/index.ts +9 -0
  374. package/src/memory/migrations/registry.ts +16 -0
  375. package/src/memory/onboarding-events-store.ts +106 -0
  376. package/src/memory/schema/a2a.ts +15 -0
  377. package/src/memory/schema/bookmarks.ts +0 -2
  378. package/src/memory/schema/calls.ts +1 -0
  379. package/src/memory/schema/index.ts +1 -0
  380. package/src/memory/schema/inference.ts +3 -3
  381. package/src/memory/schema/infrastructure.ts +13 -0
  382. package/src/memory/turn-events-store.ts +127 -2
  383. package/src/memory/v2/__tests__/activation-store.test.ts +25 -23
  384. package/src/memory/v2/__tests__/activation.test.ts +0 -8
  385. package/src/memory/v2/__tests__/cli-command-store.test.ts +404 -0
  386. package/src/memory/v2/__tests__/frontmatter-sweep.test.ts +25 -4
  387. package/src/memory/v2/__tests__/injection.test.ts +288 -11
  388. package/src/memory/v2/__tests__/migration.test.ts +87 -0
  389. package/src/memory/v2/__tests__/page-index.test.ts +83 -0
  390. package/src/memory/v2/__tests__/prompts-router.test.ts +58 -6
  391. package/src/memory/v2/__tests__/qdrant.test.ts +66 -3
  392. package/src/memory/v2/__tests__/router.test.ts +15 -0
  393. package/src/memory/v2/__tests__/skill-store.test.ts +387 -8
  394. package/src/memory/v2/__tests__/static-context.test.ts +12 -1
  395. package/src/memory/v2/activation-store.ts +14 -16
  396. package/src/memory/v2/cli-command-content.ts +19 -0
  397. package/src/memory/v2/cli-command-store.ts +304 -0
  398. package/src/memory/v2/frontmatter-sweep.ts +7 -1
  399. package/src/memory/v2/injection.ts +81 -26
  400. package/src/memory/v2/migration.ts +49 -19
  401. package/src/memory/v2/page-index.ts +63 -8
  402. package/src/memory/v2/prompts/router.ts +11 -8
  403. package/src/memory/v2/prompts/sweep.ts +2 -2
  404. package/src/memory/v2/qdrant.ts +135 -7
  405. package/src/memory/v2/router.ts +9 -8
  406. package/src/memory/v2/skill-store.ts +120 -35
  407. package/src/memory/v2/static-context.ts +4 -4
  408. package/src/memory/v2/types.ts +23 -0
  409. package/src/messaging/providers/a2a/__tests__/deliver.test.ts +274 -0
  410. package/src/messaging/providers/a2a/deliver.ts +156 -0
  411. package/src/messaging/providers/gmail/client.ts +9 -2
  412. package/src/messaging/providers/index.ts +11 -2
  413. package/src/messaging/providers/slack/__tests__/adapter-token-routing.test.ts +45 -5
  414. package/src/messaging/providers/slack/__tests__/download.test.ts +231 -0
  415. package/src/messaging/providers/slack/adapter.ts +43 -5
  416. package/src/messaging/providers/slack/client.ts +27 -0
  417. package/src/messaging/providers/slack/deep-link.ts +65 -0
  418. package/src/messaging/providers/slack/download.ts +104 -0
  419. package/src/messaging/providers/slack/message-metadata.test.ts +32 -0
  420. package/src/messaging/providers/slack/message-metadata.ts +27 -0
  421. package/src/messaging/providers/slack/render-transcript.test.ts +134 -0
  422. package/src/messaging/providers/slack/render-transcript.ts +69 -5
  423. package/src/messaging/providers/slack/types.ts +20 -1
  424. package/src/notifications/__tests__/broadcaster.test.ts +203 -0
  425. package/src/notifications/__tests__/decision-engine.test.ts +283 -0
  426. package/src/notifications/__tests__/deterministic-checks.test.ts +286 -0
  427. package/src/notifications/__tests__/emit-signal-home-feed.test.ts +1 -0
  428. package/src/notifications/__tests__/home-feed-side-effect.test.ts +430 -7
  429. package/src/notifications/adapters/macos.ts +12 -2
  430. package/src/notifications/broadcaster.ts +29 -4
  431. package/src/notifications/conversation-pairing.ts +2 -1
  432. package/src/notifications/copy-composer.ts +17 -64
  433. package/src/notifications/decision-engine.ts +113 -45
  434. package/src/notifications/deterministic-checks.ts +96 -0
  435. package/src/notifications/emit-signal.ts +21 -1
  436. package/src/notifications/home-feed-side-effect.ts +138 -5
  437. package/src/notifications/signal.ts +3 -5
  438. package/src/notifications/types.ts +8 -0
  439. package/src/oauth/connection-resolver.ts +8 -4
  440. package/src/oauth/platform-connection.test.ts +43 -3
  441. package/src/oauth/platform-connection.ts +19 -6
  442. package/src/oauth/seed-providers.ts +10 -1
  443. package/src/permissions/checker.ts +2 -0
  444. package/src/permissions/ipc-risk-types.ts +1 -0
  445. package/src/permissions/question-prompter.test.ts +416 -0
  446. package/src/permissions/question-prompter.ts +294 -0
  447. package/src/platform/client.test.ts +1 -1
  448. package/src/platform/client.ts +1 -1
  449. package/src/plugin-api/constants.ts +26 -0
  450. package/src/plugin-api/index.ts +34 -1
  451. package/src/plugin-api/types.ts +104 -22
  452. package/src/plugins/defaults/circuit-breaker.ts +0 -5
  453. package/src/plugins/defaults/compaction.ts +0 -4
  454. package/src/plugins/defaults/empty-response.ts +0 -2
  455. package/src/plugins/defaults/history-repair.ts +0 -2
  456. package/src/plugins/defaults/injectors.ts +74 -22
  457. package/src/plugins/defaults/llm-call.ts +0 -2
  458. package/src/plugins/defaults/memory-retrieval.ts +0 -1
  459. package/src/plugins/defaults/overflow-reduce.ts +0 -1
  460. package/src/plugins/defaults/persistence.ts +0 -2
  461. package/src/plugins/defaults/title-generate.ts +0 -5
  462. package/src/plugins/defaults/token-estimate.ts +0 -2
  463. package/src/plugins/defaults/tool-error.ts +0 -7
  464. package/src/plugins/defaults/tool-execute.ts +0 -2
  465. package/src/plugins/defaults/tool-result-truncate.ts +0 -4
  466. package/src/plugins/ensure-plugin-api-shim.ts +96 -0
  467. package/src/plugins/external-api.ts +104 -0
  468. package/src/plugins/external-plugin-loader.ts +187 -42
  469. package/src/plugins/feature-gate.ts +22 -0
  470. package/src/plugins/pipeline.ts +37 -0
  471. package/src/plugins/registry.ts +48 -80
  472. package/src/plugins/types.ts +40 -26
  473. package/src/plugins/user-loader.ts +21 -2
  474. package/src/proactive-artifact/aux-message-injector.ts +11 -0
  475. package/src/proactive-artifact/job.test.ts +37 -5
  476. package/src/prompts/__tests__/system-prompt.test.ts +10 -43
  477. package/src/prompts/__tests__/task-progress-hint-section.test.ts +95 -0
  478. package/src/prompts/normalize-onboarding.ts +27 -0
  479. package/src/prompts/sections.ts +302 -0
  480. package/src/prompts/system-prompt.ts +63 -174
  481. package/src/prompts/templates/BOOTSTRAP.md +17 -1
  482. package/src/prompts/templates/system-sections.ts +164 -0
  483. package/src/providers/__tests__/inference.test.ts +24 -7
  484. package/src/providers/anthropic/client.ts +28 -28
  485. package/src/providers/call-site-routing.ts +24 -6
  486. package/src/providers/connection-resolution.ts +68 -11
  487. package/src/providers/inference/__tests__/adapter-factory-openai-compatible.test.ts +74 -0
  488. package/src/providers/inference/__tests__/connections-openai-compatible.test.ts +175 -0
  489. package/src/providers/inference/__tests__/connections-status-label.test.ts +15 -0
  490. package/src/providers/inference/adapter-factory.ts +32 -6
  491. package/src/providers/inference/auth.ts +12 -0
  492. package/src/providers/inference/backfill.ts +14 -1
  493. package/src/providers/inference/connections.ts +159 -34
  494. package/src/providers/inference/resolve-auth.ts +14 -4
  495. package/src/providers/model-catalog.ts +249 -12
  496. package/src/providers/model-intents.ts +3 -3
  497. package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +235 -0
  498. package/src/providers/openai/chat-completions-provider.ts +169 -8
  499. package/src/providers/openrouter/client.ts +49 -4
  500. package/src/providers/{managed-proxy → platform-proxy}/constants.ts +4 -2
  501. package/src/providers/{managed-proxy → platform-proxy}/context.ts +3 -3
  502. package/src/providers/provider-availability.ts +17 -2
  503. package/src/providers/provider-catalog-visibility.ts +38 -0
  504. package/src/providers/provider-send-message.ts +27 -12
  505. package/src/providers/registry.ts +52 -15
  506. package/src/providers/retry.ts +47 -1
  507. package/src/runtime/__tests__/agent-wake.test.ts +152 -0
  508. package/src/runtime/agent-wake.ts +103 -15
  509. package/src/runtime/auth/route-policy.ts +21 -1
  510. package/src/runtime/btw-sidechain.ts +2 -0
  511. package/src/runtime/http-server.ts +7 -16
  512. package/src/runtime/http-types.ts +19 -47
  513. package/src/runtime/migrations/origin-mode.ts +1 -1
  514. package/src/runtime/pending-interactions.ts +1 -0
  515. package/src/runtime/routes/__tests__/bookmark-routes.test.ts +17 -0
  516. package/src/runtime/routes/__tests__/consolidation-routes.test.ts +258 -0
  517. package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +5 -1
  518. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +172 -23
  519. package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +275 -44
  520. package/src/runtime/routes/__tests__/llm-call-sites-routes.test.ts +12 -0
  521. package/src/runtime/routes/__tests__/question-routes.test.ts +395 -0
  522. package/src/runtime/routes/__tests__/tts-routes.test.ts +64 -1
  523. package/src/runtime/routes/acp-routes-list.test.ts +143 -0
  524. package/src/runtime/routes/acp-routes.ts +5 -3
  525. package/src/runtime/routes/auth-routes.ts +1 -1
  526. package/src/runtime/routes/bookmark-routes.ts +5 -3
  527. package/src/runtime/routes/btw-routes.ts +5 -1
  528. package/src/runtime/routes/channel-availability-routes.ts +126 -0
  529. package/src/runtime/routes/consolidation-routes.ts +100 -0
  530. package/src/runtime/routes/conversation-cli-routes.ts +44 -3
  531. package/src/runtime/routes/conversation-list-routes.ts +3 -20
  532. package/src/runtime/routes/conversation-management-routes.ts +17 -42
  533. package/src/runtime/routes/conversation-query-routes.ts +99 -35
  534. package/src/runtime/routes/conversation-routes.ts +97 -11
  535. package/src/runtime/routes/documents-routes.ts +25 -86
  536. package/src/runtime/routes/group-routes.ts +5 -0
  537. package/src/runtime/routes/inbound-conversation.ts +28 -8
  538. package/src/runtime/routes/inbound-message-handler.ts +236 -41
  539. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +111 -0
  540. package/src/runtime/routes/inbound-stages/background-dispatch.ts +32 -1
  541. package/src/runtime/routes/inbound-stages/edit-intercept.ts +17 -4
  542. package/src/runtime/routes/index.ts +8 -0
  543. package/src/runtime/routes/inference-profile-session-handler.ts +17 -44
  544. package/src/runtime/routes/inference-profile-session-reaper.ts +7 -21
  545. package/src/runtime/routes/inference-provider-connection-routes.ts +199 -22
  546. package/src/runtime/routes/integrations/a2a.ts +235 -0
  547. package/src/runtime/routes/integrations/slack/share.ts +4 -52
  548. package/src/runtime/routes/integrations/slack/token.ts +43 -0
  549. package/src/runtime/routes/integrations/twilio.ts +6 -13
  550. package/src/runtime/routes/llm-call-sites-routes.ts +11 -1
  551. package/src/runtime/routes/notification-routes.ts +1 -1
  552. package/src/runtime/routes/oauth-commands-routes.ts +105 -15
  553. package/src/runtime/routes/oauth-lifecycle-routes.ts +43 -0
  554. package/src/runtime/routes/question-routes.ts +259 -0
  555. package/src/runtime/routes/rename-conversation-routes.ts +2 -33
  556. package/src/runtime/routes/schedule-routes.ts +4 -7
  557. package/src/runtime/routes/subagents-routes.ts +98 -18
  558. package/src/runtime/routes/telemetry-routes.ts +27 -0
  559. package/src/runtime/routes/tts-routes.ts +27 -2
  560. package/src/runtime/routes/workspace-routes.test.ts +43 -0
  561. package/src/runtime/routes/workspace-routes.ts +28 -0
  562. package/src/runtime/services/conversation-serializer.ts +39 -7
  563. package/src/runtime/sync/resource-sync-events.ts +93 -1
  564. package/src/schedule/schedule-store.ts +27 -2
  565. package/src/schedule/scheduler.ts +9 -1
  566. package/src/security/__tests__/untrusted-content.test.ts +86 -0
  567. package/src/security/untrusted-content.ts +93 -8
  568. package/src/skills/catalog-files.ts +1 -1
  569. package/src/skills/catalog-install.ts +233 -116
  570. package/src/skills/clawhub.ts +70 -13
  571. package/src/skills/managed-store.ts +4 -119
  572. package/src/skills/skillssh-registry.ts +27 -48
  573. package/src/subagent/manager.ts +17 -7
  574. package/src/telemetry/types.ts +113 -1
  575. package/src/telemetry/usage-telemetry-reporter.test.ts +312 -5
  576. package/src/telemetry/usage-telemetry-reporter.ts +113 -7
  577. package/src/tools/apps/executors.ts +58 -7
  578. package/src/tools/ask-question/ask-question-tool.test.ts +509 -0
  579. package/src/tools/ask-question/ask-question-tool.ts +304 -0
  580. package/src/tools/browser/browser-execution.ts +15 -11
  581. package/src/tools/computer-use/definitions.ts +3 -3
  582. package/src/tools/credentials/vault.ts +1 -1
  583. package/src/tools/document/document-tool.ts +124 -1
  584. package/src/tools/filesystem/edit.ts +1 -1
  585. package/src/tools/filesystem/list.ts +1 -1
  586. package/src/tools/filesystem/read.ts +1 -1
  587. package/src/tools/filesystem/write.ts +5 -2
  588. package/src/tools/host-filesystem/transfer.ts +1 -1
  589. package/src/tools/host-terminal/host-shell.ts +1 -1
  590. package/src/tools/memory/register.ts +1 -9
  591. package/src/tools/permission-checker.ts +1 -1
  592. package/src/tools/registry.ts +17 -7
  593. package/src/tools/schedule/create.ts +2 -2
  594. package/src/tools/schema-transforms.ts +7 -2
  595. package/src/tools/side-effects.ts +1 -0
  596. package/src/tools/skills/delete-managed.ts +4 -4
  597. package/src/tools/skills/execute.ts +1 -1
  598. package/src/tools/skills/scaffold-managed.ts +3 -2
  599. package/src/tools/subagent/notify-parent.ts +1 -1
  600. package/src/tools/system/request-permission.ts +2 -2
  601. package/src/tools/terminal/safe-env.ts +60 -1
  602. package/src/tools/tool-manifest.ts +2 -0
  603. package/src/tools/types.ts +107 -21
  604. package/src/tools/ui-surface/definitions.ts +6 -5
  605. package/src/tts/__tests__/provider-adapters.test.ts +76 -2
  606. package/src/tts/providers/elevenlabs-provider.ts +75 -1
  607. package/src/types/onboarding-context.ts +2 -0
  608. package/src/util/errors.ts +17 -0
  609. package/src/util/platform.ts +10 -0
  610. package/src/watcher/__tests__/engine.test.ts +22 -0
  611. package/src/watcher/engine.ts +6 -2
  612. package/src/workspace/migrations/057-repair-stale-gemini-model-ids.ts +80 -15
  613. package/src/workspace/migrations/072-seed-reply-suggestion-callsite.ts +35 -22
  614. package/src/workspace/migrations/073-repair-recall-callsite-empty-profile.ts +3 -1
  615. package/src/workspace/migrations/083-system-prompt-prefix-to-file.ts +191 -0
  616. package/src/workspace/migrations/084-remove-legacy-skills-index.ts +276 -0
  617. package/src/workspace/migrations/085-memory-v2-bm25-b-reembed-disabled-v2-pages.ts +137 -0
  618. package/src/workspace/migrations/086-revert-stale-gemini-mis-rewrites.ts +198 -0
  619. package/src/workspace/migrations/087-memory-router-balanced-profile.ts +91 -0
  620. package/src/workspace/migrations/registry.ts +10 -0
  621. package/src/workspace/migrations/runner.ts +39 -9
  622. package/src/workspace/migrations/types.ts +4 -0
  623. package/examples/plugins/echo/bun.lock +0 -25
  624. package/src/__tests__/context-window-manager.test.ts +0 -2481
  625. package/src/__tests__/guardian-action-conversation-turn.test.ts +0 -441
  626. package/src/context/__tests__/compact-prompt.test.ts +0 -63
  627. package/src/context/prompts/compact.md +0 -26
  628. package/src/memory/graph/__tests__/remember-description.test.ts +0 -55
  629. package/src/prompts/__tests__/build-cli-reference-section.test.ts +0 -37
  630. package/src/runtime/guardian-action-conversation-turn.ts +0 -99
@@ -15,7 +15,7 @@ let mockAssistantId = "";
15
15
  // Module mocks
16
16
  // ---------------------------------------------------------------------------
17
17
 
18
- mock.module("../providers/managed-proxy/context.js", () => ({
18
+ mock.module("../providers/platform-proxy/context.js", () => ({
19
19
  resolveManagedProxyContext: async () => mockManagedProxyCtx,
20
20
  }));
21
21
 
@@ -6,7 +6,7 @@
6
6
  */
7
7
 
8
8
  import { getPlatformAssistantId } from "../config/env.js";
9
- import { resolveManagedProxyContext } from "../providers/managed-proxy/context.js";
9
+ import { resolveManagedProxyContext } from "../providers/platform-proxy/context.js";
10
10
  import { credentialKey } from "../security/credential-key.js";
11
11
  import { getSecureKeyAsync } from "../security/secure-keys.js";
12
12
  import { getLogger } from "../util/logger.js";
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Public hook-name constants.
3
+ *
4
+ * Plugin authors reference hooks by name in two places: the keys on
5
+ * `Plugin.hooks` and the daemon's `runHook(name, ctx)` call sites.
6
+ * Centralizing the string literals here keeps the typo surface minimal
7
+ * and lets call sites import a typed constant instead of repeating a
8
+ * free-form string.
9
+ *
10
+ * New hooks land here as additional `HOOKS.*` entries. The runtime
11
+ * `runHook(name, ctx)` accepts any string (so test fixtures and
12
+ * forward-compat hooks can still chain through), but call sites in
13
+ * first-party code should always reach for a `HOOKS.*` constant.
14
+ */
15
+
16
+ export const HOOKS = {
17
+ /** Plugin bootstrap. Fires once when the daemon loads the plugin. */
18
+ INIT: "init",
19
+ /** Plugin teardown. Fires once when the daemon unloads the plugin. */
20
+ SHUTDOWN: "shutdown",
21
+ /** Fires once per user turn, immediately before the agent loop receives `runMessages`. */
22
+ USER_PROMPT_SUBMIT: "user-prompt-submit",
23
+ } as const;
24
+
25
+ /** Union of every hook name declared in {@link HOOKS}. */
26
+ export type HookName = (typeof HOOKS)[keyof typeof HOOKS];
@@ -8,6 +8,39 @@
8
8
  *
9
9
  * Keep this file's surface stable across minor/patch releases. Anything
10
10
  * exported here is part of the public contract.
11
+ *
12
+ * ## Surface today
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.
19
+ *
20
+ * What this module exposes is therefore types-only: the context shapes
21
+ * the host hands to plugin hooks, and the logger shape they include.
22
+ *
23
+ * - {@link PluginInitContext} — passed to `init` hook at bootstrap
24
+ * - {@link PluginShutdownContext} — passed to `shutdown` hook at teardown
25
+ * - {@link UserPromptSubmitContext} — passed to `user-prompt-submit` hook,
26
+ * fired immediately before the agent loop receives a user's prompt
27
+ * - {@link PluginLogger} — pino-compatible logger shape on the contexts
28
+ * - {@link ToolContext} — passed to a plugin tool's `execute` method
29
+ * - {@link ToolExecutionResult} — return shape of a plugin tool's `execute`
30
+ *
31
+ * Pipeline-argument types (`LLMCallArgs`, `MemoryArgs`, etc.) currently
32
+ * live in `assistant/src/plugins/types.ts` and have not yet migrated into
33
+ * this package. A follow-up PR will move them into this surface as the
34
+ * per-pipeline schemas stabilize.
11
35
  */
12
36
 
13
- export type { PluginInitContext, PluginShutdownContext } from "./types.js";
37
+ export type { HookName } from "./constants.js";
38
+ export { HOOKS } from "./constants.js";
39
+ export type {
40
+ PluginInitContext,
41
+ PluginLogger,
42
+ PluginShutdownContext,
43
+ ToolContext,
44
+ ToolExecutionResult,
45
+ UserPromptSubmitContext,
46
+ } from "./types.js";
@@ -1,21 +1,64 @@
1
1
  /**
2
2
  * Public plugin-API types.
3
3
  *
4
- * This module is the source-of-truth for types that plugin authors depend on.
5
- * The rest of the assistant imports from here via relative paths
6
- * (`../plugin-api/types.js`). At publish time, this file's contents are
7
- * bundled into the `@vellumai/plugin-api` npm package; at runtime in the
8
- * assistant binary, the same source is reachable to user plugins via a
9
- * boot-time shim that re-exports from the embedded bundle.
10
- *
11
- * Today this module is intentionally narrow only `PluginInitContext` and
12
- * `PluginShutdownContext`. Additional public types migrate over in
13
- * follow-up PRs as the surface stabilizes.
14
- *
15
- * Internal-only types (pipeline shapes, middleware, manifest validation,
16
- * etc.) stay in `assistant/src/plugins/types.ts` until they're ready to
17
- * become public.
4
+ * This module is the entry point plugin authors land on when they import
5
+ * from `@vellumai/plugin-api`. The shapes here are the canonical public
6
+ * contract anything exported is part of the surface that semver gates.
7
+ *
8
+ * ## Tool-execution types
9
+ *
10
+ * `ToolContext` and `ToolExecutionResult` are re-exports of the narrow,
11
+ * stable bases defined alongside their daemon-internal counterparts in
12
+ * `assistant/src/tools/types.ts`. The daemon-internal `ToolContext` /
13
+ * `ToolExecutionResult` (with CES, trust classification, lifecycle
14
+ * events, sensitive-output bindings, risk metadata, etc.) `extends`
15
+ * the public bases, so the runtime can hand plugins the full value
16
+ * without a manual cast and tsc enforces the structural relationship.
17
+ * Plugin tools see the narrow surface only — they MUST NOT set fields
18
+ * that belong to the daemon-internal extension.
19
+ *
20
+ * ## Hook contexts
21
+ *
22
+ * The init / shutdown hook contexts are owned by this module directly.
23
+ * They have no daemon-internal extension today (the daemon constructs
24
+ * and hands them straight through), so there's nothing to inherit from.
25
+ *
26
+ * ## Compatibility
27
+ *
28
+ * Adding fields to any public shape is non-breaking. Renaming or
29
+ * removing fields is breaking and gated on a major bump of
30
+ * `@vellumai/plugin-api`.
31
+ */
32
+
33
+ import type { Message } from "../providers/types.js";
34
+
35
+ // ─── Tool-execution types (re-exported from daemon source-of-truth) ──────────
36
+
37
+ export type {
38
+ PluginToolContext as ToolContext,
39
+ PluginToolExecutionResult as ToolExecutionResult,
40
+ } from "../tools/types.js";
41
+
42
+ // ─── Logger ──────────────────────────────────────────────────────────────────
43
+
44
+ /**
45
+ * Minimal pino-compatible logger surface handed to plugin hooks. The host
46
+ * supplies a pino child logger bound to `{ plugin: <name> }`; this
47
+ * interface intentionally captures only the two call shapes plugin code
48
+ * needs (structured object + optional message), so the public surface
49
+ * doesn't take a dependency on pino's full type machinery.
50
+ *
51
+ * Each method accepts a structured-fields object followed by an optional
52
+ * message string. Plugin authors that need pino's wider API (`child()`,
53
+ * `level`, etc.) can cast to their own narrower interface in plugin code
54
+ * — but the canonical contract here covers the 99% case.
18
55
  */
56
+ export interface PluginLogger {
57
+ info(obj: Record<string, unknown>, msg?: string): void;
58
+ warn(obj: Record<string, unknown>, msg?: string): void;
59
+ error(obj: Record<string, unknown>, msg?: string): void;
60
+ debug(obj: Record<string, unknown>, msg?: string): void;
61
+ }
19
62
 
20
63
  // ─── Init context ────────────────────────────────────────────────────────────
21
64
 
@@ -29,17 +72,17 @@ export interface PluginInitContext {
29
72
  config: unknown;
30
73
  /** Resolved credential values keyed by the entries of `manifest.requiresCredential`. */
31
74
  credentials: Record<string, string>;
32
- /**
33
- * Pino-compatible child logger bound to `{ plugin: <name> }`. Untyped here
34
- * to avoid pulling pino into the types module.
35
- */
36
- logger: unknown;
75
+ /** Pino-compatible child logger bound to `{ plugin: <name> }`. */
76
+ logger: PluginLogger;
37
77
  /** Absolute path to `<workspaceDir>/plugins-data/<plugin>/` (created by bootstrap). */
38
78
  pluginStorageDir: string;
39
- /** Assistant semver for compatibility checks inside the plugin. */
79
+ /**
80
+ * Assistant semver. Plugins can compare against this for defensive
81
+ * runtime checks — but the canonical compat contract is the host
82
+ * version against the plugin's `peerDependencies["@vellumai/plugin-api"]`
83
+ * semver range, enforced at load time by the external-plugin loader.
84
+ */
40
85
  assistantVersion: string;
41
- /** Capability → version-list map (`ASSISTANT_API_VERSIONS`) for defensive runtime checks. */
42
- apiVersions: Record<string, string[]>;
43
86
  }
44
87
 
45
88
  // ─── Shutdown context ────────────────────────────────────────────────────────
@@ -60,3 +103,42 @@ export interface PluginShutdownContext {
60
103
  /** Assistant semver for compatibility checks inside the plugin. */
61
104
  assistantVersion: string;
62
105
  }
106
+
107
+ // ─── User-prompt-submit hook context ─────────────────────────────────────────
108
+
109
+ /**
110
+ * Context passed to the `user-prompt-submit` hook. Fires once per user
111
+ * turn, after the agent loop has prepared the message list (PKB / NOW /
112
+ * memory-graph injections, history repair, overflow reduction all already
113
+ * applied) and immediately before the messages are handed to the agent
114
+ * loop's tool/LLM iteration.
115
+ *
116
+ * The hook may transform `latestMessages` either by mutating it in place
117
+ * (`push` / `splice` / `length = 0`) or by returning a new context with
118
+ * a fresh `latestMessages` array — see {@link PluginHookFn}'s polymorphic
119
+ * return shape. The daemon threads the final `latestMessages` value into
120
+ * `agentLoop.run()` as the run-messages argument.
121
+ *
122
+ * `originalMessages` is the user's original message list, frozen for the
123
+ * hook. Plugins should treat it as a stable reference point if they need
124
+ * to recover from earlier transformations or compare against the pristine
125
+ * state.
126
+ *
127
+ * Multiple plugins' hooks chain in registration order — each plugin's
128
+ * hook sees the previous plugin's mutations (whether by reassignment or
129
+ * in-place mutation).
130
+ */
131
+ export interface UserPromptSubmitContext {
132
+ /** Conversation ID the user prompt was submitted on. */
133
+ readonly conversationId: string;
134
+ /**
135
+ * The user's original message list, immutable for the hook. Plugins
136
+ * may snapshot or compare against this but MUST NOT mutate it.
137
+ */
138
+ readonly originalMessages: ReadonlyArray<Message>;
139
+ /**
140
+ * The working message list that flows into `agentLoop.run`. Plugins
141
+ * may mutate this in place or replace it by returning a new context.
142
+ */
143
+ latestMessages: Message[];
144
+ }
@@ -55,11 +55,6 @@ export const defaultCircuitBreakerPlugin: Plugin = {
55
55
  manifest: {
56
56
  name: "default-circuit-breaker",
57
57
  version: "1.0.0",
58
- provides: { circuitBreakerApi: "v1" },
59
- requires: {
60
- pluginRuntime: "v1",
61
- circuitBreakerApi: "v1",
62
- },
63
58
  },
64
59
 
65
60
  middleware: {
@@ -112,10 +112,6 @@ export const defaultCompactionPlugin: Plugin = {
112
112
  manifest: {
113
113
  name: DEFAULT_COMPACTION_PLUGIN_NAME,
114
114
  version: "1.0.0",
115
- requires: {
116
- pluginRuntime: "v1",
117
- compactionApi: "v1",
118
- },
119
115
  },
120
116
  middleware: {
121
117
  compaction: defaultCompactionMiddleware,
@@ -95,8 +95,6 @@ export const defaultEmptyResponsePlugin: Plugin = {
95
95
  manifest: {
96
96
  name: "default-empty-response",
97
97
  version: "1.0.0",
98
- provides: { emptyResponseApi: "v1" },
99
- requires: { pluginRuntime: "v1", emptyResponseApi: "v1" },
100
98
  },
101
99
  middleware: {
102
100
  emptyResponse: passthrough,
@@ -54,8 +54,6 @@ export const defaultHistoryRepairPlugin: Plugin = {
54
54
  manifest: {
55
55
  name: "default-history-repair",
56
56
  version: "1.0.0",
57
- provides: { historyRepair: "v1" },
58
- requires: { pluginRuntime: "v1", historyRepairApi: "v1" },
59
57
  },
60
58
  middleware: {
61
59
  historyRepair: passthrough,
@@ -19,6 +19,7 @@
19
19
  * | `pkb-reminder` | 35 | after-memory-prefix |
20
20
  * | `memory-v2-static` | 38 | after-memory-prefix |
21
21
  * | `now-md` | 40 | after-memory-prefix |
22
+ * | `active-documents` | 45 | prepend-user-tail |
22
23
  * | `subagent-status` | 50 | append-user-tail |
23
24
  * | `slack-messages` | 60 | replace-run-messages |
24
25
  * | `thread-focus` | 70 | append-user-tail |
@@ -86,11 +87,13 @@ const PKB_HINT_ARCHIVE_THRESHOLD = 0.7;
86
87
  export const DEFAULT_INJECTOR_ORDER = {
87
88
  diskPressureWarning: 5,
88
89
  workspaceContext: 10,
90
+ backgroundTurn: 15,
89
91
  unifiedTurnContext: 20,
90
92
  pkbContext: 30,
91
93
  pkbReminder: 35,
92
94
  memoryV2Static: 38,
93
95
  nowMd: 40,
96
+ activeDocuments: 45,
94
97
  subagentStatus: 50,
95
98
  slackMessages: 60,
96
99
  threadFocus: 70,
@@ -169,6 +172,39 @@ const workspaceContextInjector: Injector = {
169
172
  },
170
173
  };
171
174
 
175
+ /**
176
+ * `background-turn` injector — order 15, prepend-user-tail.
177
+ *
178
+ * Wraps the tail user message with a `<background_turn>` block that tells
179
+ * the assistant the guardian isn't watching and that anything noteworthy
180
+ * should be surfaced via the `notifications` skill. Fires only when (a) the
181
+ * conversation's type is "background" or "scheduled" (see
182
+ * `isBackgroundConversationType`) AND (b) no client is currently connected
183
+ * (`isNonInteractive`). The second gate is what prevents the reminder from
184
+ * firing on a manual follow-up the guardian sends into a background thread
185
+ * — at that point the guardian IS watching, so the framing doesn't apply.
186
+ *
187
+ * The inner text is read from `config.conversations.backgroundInjection`, so
188
+ * operators can edit the reminder without a code change. Setting it to the
189
+ * empty string disables the injection entirely.
190
+ */
191
+ const backgroundTurnInjector: Injector = {
192
+ name: "background-turn",
193
+ order: DEFAULT_INJECTOR_ORDER.backgroundTurn,
194
+ async produce(ctx: TurnContext): Promise<InjectionBlock | null> {
195
+ const inputs = readInjectionInputs(ctx);
196
+ if (!inputs.isBackgroundConversation) return null;
197
+ if (!inputs.isNonInteractive) return null;
198
+ const inner = getConfig().conversations.backgroundInjection;
199
+ if (!inner) return null;
200
+ return {
201
+ id: "background-turn",
202
+ text: `<background_turn>\n${inner}\n</background_turn>`,
203
+ placement: "prepend-user-tail",
204
+ };
205
+ },
206
+ };
207
+
172
208
  /**
173
209
  * `unified-turn-context` injector — order 20, prepend-user-tail.
174
210
  *
@@ -251,24 +287,9 @@ const pkbReminderInjector: Injector = {
251
287
  const mode = inputs.mode ?? "full";
252
288
  if (mode !== "full") return null;
253
289
  if (!inputs.pkbActive) return null;
254
- // The `memory-retrospective` feature flag enables a focused background
255
- // retrospective pass that catches what the in-conversation `remember`
256
- // calls miss. When that backstop is on, the per-turn pressure to call
257
- // `remember` softens to a judgment framing. When it's off, the original
258
- // high-pressure BODY is used so users without the retrospective still
259
- // get aggressive capture in-conversation.
260
- let relaxed = false;
261
- try {
262
- relaxed = isAssistantFeatureFlagEnabled(
263
- "memory-retrospective",
264
- getConfig(),
265
- );
266
- } catch {
267
- // Best-effort — fall back to the default (non-relaxed) BODY.
268
- }
269
290
  const reminder = isPkbInjectionSilencedByV2()
270
- ? buildPkbReminder([], relaxed)
271
- : await buildPkbReminderWithHints(inputs, relaxed);
291
+ ? buildPkbReminder([])
292
+ : await buildPkbReminderWithHints(inputs);
272
293
  return {
273
294
  id: "pkb-reminder",
274
295
  text: reminder,
@@ -298,7 +319,6 @@ function buildPkbContextBlock(content: string): string {
298
319
  */
299
320
  async function buildPkbReminderWithHints(
300
321
  inputs: TurnInjectionInputs,
301
- relaxed: boolean,
302
322
  ): Promise<string> {
303
323
  let hints: string[] = [];
304
324
  const queryVector = inputs.pkbQueryVector;
@@ -359,7 +379,7 @@ async function buildPkbReminderWithHints(
359
379
  hints = [];
360
380
  }
361
381
  }
362
- return buildPkbReminder(hints, relaxed);
382
+ return buildPkbReminder(hints);
363
383
  }
364
384
 
365
385
  /**
@@ -438,6 +458,39 @@ const nowMdInjector: Injector = {
438
458
  },
439
459
  };
440
460
 
461
+ /**
462
+ * `active-documents` injector — order 45, prepend-user-tail.
463
+ *
464
+ * Injects an `<active_documents>` block listing open documents in the
465
+ * conversation so the assistant can target them with `document_update`
466
+ * instead of creating duplicates via `document_create`.
467
+ *
468
+ * Gating:
469
+ * - `mode === "full"`.
470
+ * - `activeDocuments` has at least one entry.
471
+ */
472
+ const activeDocumentsInjector: Injector = {
473
+ name: "active-documents",
474
+ order: DEFAULT_INJECTOR_ORDER.activeDocuments,
475
+ async produce(ctx: TurnContext): Promise<InjectionBlock | null> {
476
+ const inputs = readInjectionInputs(ctx);
477
+ const mode = inputs.mode ?? "full";
478
+ if (mode !== "full") return null;
479
+ const docs = inputs.activeDocuments;
480
+ if (!docs || docs.length === 0) return null;
481
+ const lines = docs.map(
482
+ (d) =>
483
+ `- surface_id: "${d.surfaceId}", title: "${d.title}", words: ${d.wordCount}`,
484
+ );
485
+ const text = `<active_documents>\nThe following documents are open in this conversation. Use document_update with the surface_id to edit them — do NOT call document_create for documents that already exist.\n${lines.join("\n")}\n</active_documents>`;
486
+ return {
487
+ id: "active-documents",
488
+ text,
489
+ placement: "prepend-user-tail",
490
+ };
491
+ },
492
+ };
493
+
441
494
  /**
442
495
  * `subagent-status` injector — order 50, append-user-tail.
443
496
  *
@@ -562,18 +615,17 @@ export const defaultInjectorsPlugin: Plugin = {
562
615
  manifest: {
563
616
  name: "default-injectors",
564
617
  version: "1.0.0",
565
- requires: {
566
- pluginRuntime: "v1",
567
- },
568
618
  },
569
619
  injectors: [
570
620
  diskPressureWarningInjector,
571
621
  workspaceContextInjector,
622
+ backgroundTurnInjector,
572
623
  unifiedTurnContextInjector,
573
624
  pkbContextInjector,
574
625
  pkbReminderInjector,
575
626
  memoryV2StaticInjector,
576
627
  nowMdInjector,
628
+ activeDocumentsInjector,
577
629
  subagentStatusInjector,
578
630
  slackMessagesInjector,
579
631
  threadFocusInjector,
@@ -42,8 +42,6 @@ export const defaultLlmCallPlugin: Plugin = {
42
42
  manifest: {
43
43
  name: "default-llm-call",
44
44
  version: "1.0.0",
45
- provides: { llmCall: "v1" },
46
- requires: { pluginRuntime: "v1" },
47
45
  },
48
46
  middleware: {
49
47
  llmCall: async function defaultLlmCall(
@@ -190,7 +190,6 @@ export const defaultMemoryRetrievalPlugin: Plugin = {
190
190
  manifest: {
191
191
  name: "default-memory-retrieval",
192
192
  version: "0.0.1",
193
- requires: { pluginRuntime: "v1", memoryApi: "v1" },
194
193
  },
195
194
  middleware: {
196
195
  memoryRetrieval: defaultMemoryRetrievalMiddleware,
@@ -156,7 +156,6 @@ export const defaultOverflowReducePlugin: Plugin = {
156
156
  manifest: {
157
157
  name: "default-overflow-reduce",
158
158
  version: "1.0.0",
159
- requires: { pluginRuntime: "v1", overflowReduceApi: "v1" },
160
159
  },
161
160
  middleware: {
162
161
  overflowReduce: defaultOverflowReduceMiddleware,
@@ -98,8 +98,6 @@ export const defaultPersistencePlugin: Plugin = {
98
98
  manifest: {
99
99
  name: "default-persistence",
100
100
  version: "1.0.0",
101
- provides: { persistence: "v1" },
102
- requires: { pluginRuntime: "v1" },
103
101
  },
104
102
  middleware: {
105
103
  persistence: passthrough,
@@ -64,11 +64,6 @@ export const defaultTitleGeneratePlugin: Plugin = {
64
64
  manifest: {
65
65
  name: "default-title-generate",
66
66
  version: "1.0.0",
67
- provides: { titleGenerate: "v1" },
68
- requires: {
69
- pluginRuntime: "v1",
70
- titleGenerateApi: "v1",
71
- },
72
67
  },
73
68
  };
74
69
 
@@ -72,8 +72,6 @@ export const defaultTokenEstimatePlugin: Plugin = {
72
72
  manifest: {
73
73
  name: "default-token-estimate",
74
74
  version: "1.0.0",
75
- provides: { tokenEstimate: "v1" },
76
- requires: { pluginRuntime: "v1", tokenEstimateApi: "v1" },
77
75
  },
78
76
  middleware: {
79
77
  tokenEstimate: passthrough,
@@ -90,13 +90,6 @@ export const defaultToolErrorPlugin: Plugin = {
90
90
  manifest: {
91
91
  name: "default-tool-error",
92
92
  version: "1.0.0",
93
- requires: {
94
- pluginRuntime: "v1",
95
- toolErrorApi: "v1",
96
- },
97
- provides: {
98
- toolError: "v1",
99
- },
100
93
  },
101
94
  middleware: {
102
95
  toolError: defaultToolErrorMiddleware,
@@ -58,8 +58,6 @@ export const defaultToolExecutePlugin: Plugin = {
58
58
  manifest: {
59
59
  name: "default-tool-execute",
60
60
  version: "1.0.0",
61
- provides: { toolExecuteApi: "v1" },
62
- requires: { pluginRuntime: "v1", toolExecuteApi: "v1" },
63
61
  },
64
62
  middleware: {
65
63
  toolExecute: defaultToolExecute,
@@ -55,10 +55,6 @@ export const defaultToolResultTruncatePlugin: Plugin = {
55
55
  manifest: {
56
56
  name: "default-tool-result-truncate",
57
57
  version: "1.0.0",
58
- requires: {
59
- pluginRuntime: "v1",
60
- toolResultTruncateApi: "v1",
61
- },
62
58
  },
63
59
  middleware: {
64
60
  toolResultTruncate: passthrough,
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Materializes the workspace-level `@vellumai/plugin-api` shim so that
3
+ * user plugins under `<workspaceDir>/plugins/<name>/` can resolve a
4
+ * standard bare import:
5
+ *
6
+ * import { ... } from "@vellumai/plugin-api";
7
+ *
8
+ * Bun's Node-style resolution walks up from the plugin directory and
9
+ * finds `<workspaceDir>/node_modules/@vellumai/plugin-api/` — a tiny
10
+ * shim package whose `index.js` re-binds the plugin-api namespace that
11
+ * the assistant already loaded into its module graph (and parked on
12
+ * `globalThis` under {@link PLUGIN_API_REGISTRY_KEY}).
13
+ *
14
+ * This avoids duplicating the plugin-api package per plugin while still
15
+ * letting the assistant's compiled binary be the single source of truth
16
+ * for the public API. The runtime mechanism is uniform across:
17
+ * - JIT / Docker: plugin-api loads from source, shim re-binds via globalThis
18
+ * - `bun --compile` (macOS bare-metal): plugin-api ships inside the
19
+ * binary's regular code graph (Bun's bundler resolves
20
+ * `import * as pluginApi from "../plugin-api/index.js"` at compile
21
+ * time, inlining relative imports), shim re-binds via globalThis
22
+ *
23
+ * Idempotent: safe to call repeatedly. The shim's contents are
24
+ * deterministic given the runtime export list — fresh exports (added in
25
+ * later PRs) automatically expand the generated `index.js`.
26
+ *
27
+ * Called from {@link loadUserPlugins} at the top of its body so the
28
+ * ordering constraint (shim exists before any plugin's
29
+ * `import "@vellumai/plugin-api"` is parsed) is enforced by code, not
30
+ * by a docstring in `lifecycle.ts`.
31
+ */
32
+
33
+ import { mkdir, writeFile } from "node:fs/promises";
34
+ import { join } from "node:path";
35
+
36
+ import assistantPkg from "../../package.json" with { type: "json" };
37
+ import {
38
+ PLUGIN_API_EXPORTS,
39
+ PLUGIN_API_REGISTRY_KEY,
40
+ } from "../embedded/plugin-api.js";
41
+ import { getLogger } from "../util/logger.js";
42
+ import { getWorkspaceDir } from "../util/platform.js";
43
+
44
+ const log = getLogger("plugin-api-shim");
45
+
46
+ const PACKAGE_NAME = "@vellumai/plugin-api";
47
+
48
+ /**
49
+ * Build the body of the workspace shim's `index.js`. Exported so the
50
+ * smoke test can assert against the same generator the daemon uses.
51
+ */
52
+ export function buildShimSource(
53
+ exports: readonly string[] = PLUGIN_API_EXPORTS,
54
+ registryKey: symbol = PLUGIN_API_REGISTRY_KEY,
55
+ ): string {
56
+ const description = registryKey.description ?? "";
57
+ const lines = [
58
+ `const api = globalThis[Symbol.for(${JSON.stringify(description)})];`,
59
+ ...exports.map((name) => `export const ${name} = api.${name};`),
60
+ ];
61
+ return `${lines.join("\n")}\n`;
62
+ }
63
+
64
+ export async function ensurePluginApiShim(opts?: {
65
+ /** Override the workspace root. Defaults to `getWorkspaceDir()`. */
66
+ workspaceDir?: string;
67
+ }): Promise<void> {
68
+ const workspaceDir = opts?.workspaceDir ?? getWorkspaceDir();
69
+ const shimDir = join(workspaceDir, "node_modules", PACKAGE_NAME);
70
+
71
+ await mkdir(shimDir, { recursive: true });
72
+
73
+ const indexJs = buildShimSource();
74
+ const packageJson = `${JSON.stringify(
75
+ {
76
+ name: PACKAGE_NAME,
77
+ version: assistantPkg.version,
78
+ type: "module",
79
+ main: "./index.js",
80
+ },
81
+ null,
82
+ 2,
83
+ )}\n`;
84
+
85
+ await writeFile(join(shimDir, "index.js"), indexJs);
86
+ await writeFile(join(shimDir, "package.json"), packageJson);
87
+
88
+ log.info(
89
+ {
90
+ shimDir,
91
+ exports: PLUGIN_API_EXPORTS,
92
+ version: assistantPkg.version,
93
+ },
94
+ "plugin-api shim materialized",
95
+ );
96
+ }