@vellumai/assistant 0.8.7 → 0.8.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (387) hide show
  1. package/Dockerfile +20 -4
  2. package/docker-entrypoint.sh +4 -2
  3. package/docker-init-apt-root.sh +3 -1
  4. package/docker-kata-apt-env.sh +3 -1
  5. package/docker-kata-runtime-family.sh +12 -0
  6. package/docs/architecture/memory.md +1 -1
  7. package/docs/plugins.md +75 -79
  8. package/examples/plugins/echo/README.md +6 -12
  9. package/examples/plugins/echo/register.ts +0 -41
  10. package/node_modules/@vellumai/skill-host-contracts/src/server-message.ts +3 -3
  11. package/openapi.yaml +3381 -348
  12. package/package.json +1 -1
  13. package/scripts/generate-openapi.ts +68 -41
  14. package/src/__tests__/agent-loop-exit-reason.test.ts +34 -39
  15. package/src/__tests__/agent-loop-provider-error-recording.test.ts +1 -1
  16. package/src/__tests__/agent-loop.test.ts +37 -87
  17. package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +2 -0
  18. package/src/__tests__/annotate-activity-metadata.test.ts +262 -0
  19. package/src/__tests__/annotate-risk-options.test.ts +2 -3
  20. package/src/__tests__/anthropic-provider.test.ts +95 -2
  21. package/src/__tests__/assistant-event-hub.test.ts +25 -0
  22. package/src/__tests__/assistant-events-sse-shed.test.ts +8 -0
  23. package/src/__tests__/{conversation-stream-state.test.ts → assistant-stream-state.test.ts} +252 -91
  24. package/src/__tests__/auth-fallback-events-store.test.ts +116 -0
  25. package/src/__tests__/background-workers-disk-pressure.test.ts +6 -0
  26. package/src/__tests__/btw-routes.test.ts +62 -3
  27. package/src/__tests__/build-persisted-content.test.ts +184 -0
  28. package/src/__tests__/catalog-files.test.ts +1 -1
  29. package/src/__tests__/clawhub-files.test.ts +1 -1
  30. package/src/__tests__/compaction-pipeline.test.ts +1 -1
  31. package/src/__tests__/compaction.benchmark.test.ts +0 -30
  32. package/src/__tests__/config-watcher.test.ts +1 -1
  33. package/src/__tests__/conversation-abort-tool-results.test.ts +57 -19
  34. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +6 -2
  35. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +10 -4
  36. package/src/__tests__/conversation-agent-loop-overflow.test.ts +313 -1136
  37. package/src/__tests__/conversation-agent-loop.test.ts +596 -1616
  38. package/src/__tests__/conversation-analysis-routes.test.ts +6 -0
  39. package/src/__tests__/conversation-history-web-search.test.ts +11 -1
  40. package/src/__tests__/conversation-pairing.test.ts +4 -31
  41. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +6 -0
  42. package/src/__tests__/conversation-provider-retry-repair.test.ts +26 -5
  43. package/src/__tests__/conversation-queue.test.ts +2 -0
  44. package/src/__tests__/conversation-routes-disk-view.test.ts +3 -0
  45. package/src/__tests__/conversation-routes-slash-commands.test.ts +6 -5
  46. package/src/__tests__/conversation-runtime-assembly.test.ts +170 -229
  47. package/src/__tests__/conversation-runtime-workspace.test.ts +3 -24
  48. package/src/__tests__/conversation-slash-commands.test.ts +8 -42
  49. package/src/__tests__/conversation-slash-queue.test.ts +6 -1
  50. package/src/__tests__/conversation-surfaces-action-delivery.test.ts +84 -0
  51. package/src/__tests__/conversation-sync-tags.test.ts +27 -15
  52. package/src/__tests__/conversation-title-service.test.ts +135 -2
  53. package/src/__tests__/conversation-workspace-injection.test.ts +6 -1
  54. package/src/__tests__/cross-provider-web-search.test.ts +214 -1
  55. package/src/__tests__/db-schedule-syntax-migration.test.ts +5 -0
  56. package/src/__tests__/dm-persistence.test.ts +5 -1
  57. package/src/__tests__/empty-response-hook.test.ts +304 -0
  58. package/src/__tests__/feature-flag-test-helpers.ts +2 -2
  59. package/src/__tests__/gemini-image-service.test.ts +13 -0
  60. package/src/__tests__/helpers/mock-provider.ts +110 -0
  61. package/src/__tests__/helpers/native-web-search-harness.ts +129 -0
  62. package/src/__tests__/history-repair-hook.test.ts +1 -0
  63. package/src/__tests__/identity-intro-cache.test.ts +12 -100
  64. package/src/__tests__/identity-routes.test.ts +248 -7
  65. package/src/__tests__/inbound-slack-persistence.test.ts +5 -1
  66. package/src/__tests__/injector-background-turn.test.ts +2 -8
  67. package/src/__tests__/injector-chain.test.ts +106 -270
  68. package/src/__tests__/injector-disk-pressure.test.ts +3 -12
  69. package/src/__tests__/injector-document-comments.test.ts +2 -2
  70. package/src/__tests__/injector-pkb-v2-silenced.test.ts +30 -22
  71. package/src/__tests__/injector-v3-suppression.test.ts +31 -37
  72. package/src/__tests__/internal-telemetry-routes.test.ts +109 -0
  73. package/src/__tests__/list-messages-page-latest.test.ts +60 -0
  74. package/src/__tests__/list-messages-tool-merge.test.ts +20 -0
  75. package/src/__tests__/llm-usage-store.test.ts +223 -1
  76. package/src/__tests__/memory-retrieval-hook.test.ts +297 -0
  77. package/src/__tests__/memory-v2-static-injector.test.ts +103 -35
  78. package/src/__tests__/native-web-search.test.ts +191 -0
  79. package/src/__tests__/onboarding-template-contract.test.ts +2 -0
  80. package/src/__tests__/openai-image-service.test.ts +17 -0
  81. package/src/__tests__/openai-provider.test.ts +31 -1
  82. package/src/__tests__/persist-unsendable-image.test.ts +215 -0
  83. package/src/__tests__/persistence-secret-redaction.test.ts +1 -0
  84. package/src/__tests__/pipeline-runner.test.ts +29 -39
  85. package/src/__tests__/pkb-autoinject.test.ts +2 -5
  86. package/src/__tests__/plugin-bootstrap.test.ts +13 -28
  87. package/src/__tests__/plugin-registry.test.ts +0 -27
  88. package/src/__tests__/plugin-types.test.ts +2 -125
  89. package/src/__tests__/process-message-display-content.test.ts +6 -2
  90. package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +5 -1
  91. package/src/__tests__/resolve-trust-class.test.ts +4 -4
  92. package/src/__tests__/runtime-events-sse-reconnect.test.ts +60 -23
  93. package/src/__tests__/schedule-routes.test.ts +603 -2
  94. package/src/__tests__/schedule-store.test.ts +41 -0
  95. package/src/__tests__/schedule-tools.test.ts +35 -0
  96. package/src/__tests__/server-history-render.test.ts +314 -1
  97. package/src/__tests__/skillssh-files.test.ts +1 -1
  98. package/src/__tests__/system-prompt.test.ts +20 -0
  99. package/src/__tests__/task-scheduler.test.ts +162 -1
  100. package/src/__tests__/terminal-tools.test.ts +6 -1
  101. package/src/__tests__/title-generate-hook.test.ts +319 -0
  102. package/src/__tests__/tool-error-hook.test.ts +278 -0
  103. package/src/__tests__/tool-preview-lifecycle.test.ts +468 -5
  104. package/src/__tests__/tool-result-metadata-plumbing.test.ts +1 -0
  105. package/src/__tests__/tool-result-truncate-hook.test.ts +127 -0
  106. package/src/__tests__/tool-result-truncation.test.ts +0 -2
  107. package/src/__tests__/ui-choice-copy-surfaces.test.ts +254 -0
  108. package/src/__tests__/ui-work-result-surface.test.ts +159 -0
  109. package/src/__tests__/usage-routes.test.ts +285 -1
  110. package/src/__tests__/user-plugin-loader.test.ts +2 -2
  111. package/src/__tests__/voice-session-bridge.test.ts +6 -3
  112. package/src/__tests__/web-search-backend-failure.test.ts +166 -0
  113. package/src/agent/loop.ts +346 -442
  114. package/src/api/events/assistant-thinking-delta.ts +33 -0
  115. package/src/api/events/tool-output-chunk.ts +45 -0
  116. package/src/api/events/tool-use-preview-start.ts +32 -0
  117. package/src/api/events/trace-event.ts +69 -0
  118. package/src/api/index.ts +48 -13
  119. package/src/api/responses/conversation-message.ts +368 -0
  120. package/src/avatar/__tests__/avatar-store.test.ts +34 -29
  121. package/src/cli/commands/__tests__/notifications.test.ts +58 -14
  122. package/src/cli/commands/notifications.ts +112 -60
  123. package/src/config/assistant-feature-flags.ts +22 -11
  124. package/src/config/bundled-skills/app-builder/SKILL.md +3 -20
  125. package/src/config/bundled-skills/app-builder/references/examples/README.md +17 -0
  126. package/src/config/bundled-skills/app-builder/references/examples/expense-tracker.md +515 -0
  127. package/src/config/bundled-skills/app-builder/references/examples/focus-timer.md +342 -0
  128. package/src/config/bundled-skills/app-builder/references/examples/habit-tracker.md +490 -0
  129. package/src/config/bundled-skills/document-editor/SKILL.md +1 -1
  130. package/src/config/bundled-skills/messaging/SKILL.md +0 -7
  131. package/src/config/feature-flag-cache.ts +3 -3
  132. package/src/config/feature-flag-registry.json +35 -3
  133. package/src/config/schemas/__tests__/memory-v2.test.ts +1 -0
  134. package/src/config/schemas/__tests__/memory-v3.test.ts +25 -0
  135. package/src/config/schemas/llm.ts +1 -0
  136. package/src/config/schemas/memory-v2.ts +8 -0
  137. package/src/config/schemas/memory-v3.ts +8 -0
  138. package/src/config/schemas/platform.ts +8 -0
  139. package/src/config/seed-inference-profiles.ts +2 -2
  140. package/src/config/skills.ts +13 -0
  141. package/src/context/compactor.ts +1 -1
  142. package/src/context/strip-injections.ts +122 -0
  143. package/src/context/token-estimator.ts +23 -0
  144. package/src/context/tool-result-truncation.ts +0 -23
  145. package/src/context/window-manager.ts +3 -6
  146. package/src/credential-execution/executable-discovery.ts +16 -0
  147. package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +6 -0
  148. package/src/daemon/__tests__/inference-profile-notification.test.ts +153 -0
  149. package/src/daemon/__tests__/native-web-search-metadata.test.ts +10 -8
  150. package/src/daemon/assistant-attachments.ts +1 -1
  151. package/src/daemon/config-watcher.ts +2 -2
  152. package/src/daemon/context-overflow-reducer.ts +0 -1
  153. package/src/daemon/conversation-agent-loop-handlers.ts +605 -153
  154. package/src/daemon/conversation-agent-loop.ts +281 -760
  155. package/src/daemon/conversation-history.ts +5 -4
  156. package/src/daemon/conversation-lifecycle.ts +3 -4
  157. package/src/daemon/conversation-messaging.ts +7 -6
  158. package/src/daemon/conversation-process.ts +11 -16
  159. package/src/daemon/conversation-runtime-assembly.ts +130 -347
  160. package/src/daemon/conversation-slash.ts +6 -25
  161. package/src/daemon/conversation-surfaces.ts +222 -4
  162. package/src/daemon/conversation-tool-setup.ts +2 -29
  163. package/src/daemon/conversation.ts +32 -14
  164. package/src/daemon/external-plugins-bootstrap.ts +9 -10
  165. package/src/daemon/handlers/config-a2a.ts +51 -36
  166. package/src/daemon/handlers/config-slack-channel.ts +20 -14
  167. package/src/daemon/handlers/config-telegram.ts +16 -2
  168. package/src/daemon/handlers/shared.ts +156 -84
  169. package/src/daemon/handlers/skills.ts +39 -10
  170. package/src/daemon/lifecycle.ts +4 -0
  171. package/src/daemon/message-types/apps.ts +1 -29
  172. package/src/daemon/message-types/messages.ts +9 -57
  173. package/src/daemon/message-types/skills.ts +2 -0
  174. package/src/daemon/message-types/surfaces.ts +136 -3
  175. package/src/daemon/now-scratchpad.ts +21 -0
  176. package/src/daemon/orphan-reaper.test.ts +210 -0
  177. package/src/daemon/orphan-reaper.ts +240 -0
  178. package/src/daemon/persist-unsendable-image.ts +117 -0
  179. package/src/daemon/process-message.ts +1 -3
  180. package/src/daemon/trace-emitter.ts +6 -4
  181. package/src/daemon/trust-context.ts +19 -0
  182. package/src/daemon/wake-target-adapter.ts +3 -1
  183. package/src/home/home-greeting-cache.ts +24 -1
  184. package/src/ipc/gateway-client.test.ts +2 -2
  185. package/src/ipc/gateway-client.ts +3 -3
  186. package/src/media/gemini-image-service.ts +15 -0
  187. package/src/media/openai-image-service.ts +14 -0
  188. package/src/media/types.ts +34 -0
  189. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +56 -0
  190. package/src/memory/auth-fallback-events-store.ts +94 -0
  191. package/src/memory/conversation-title-service.ts +65 -41
  192. package/src/memory/db-init.ts +4 -0
  193. package/src/memory/graph/__tests__/conversation-graph-memory-registry.test.ts +119 -0
  194. package/src/memory/graph/conversation-graph-memory.ts +65 -0
  195. package/src/memory/jobs-store.ts +33 -0
  196. package/src/memory/jobs-worker.ts +31 -4
  197. package/src/memory/llm-usage-store.ts +224 -50
  198. package/src/memory/migrations/222-strip-placeholder-sentinels-from-messages.ts +6 -5
  199. package/src/memory/migrations/270-schedule-source-conversation.ts +13 -0
  200. package/src/memory/migrations/271-create-auth-fallback-events.ts +21 -0
  201. package/src/memory/migrations/index.ts +2 -0
  202. package/src/memory/pkb/autoinject.ts +61 -0
  203. package/src/memory/pkb/context.ts +50 -0
  204. package/src/memory/pkb/types.ts +14 -0
  205. package/src/memory/schedule-attribution-sql.ts +104 -0
  206. package/src/memory/schema/infrastructure.ts +16 -0
  207. package/src/memory/usage-grouped-buckets.ts +6 -1
  208. package/src/memory/v2/__tests__/consolidation-job.test.ts +1 -1
  209. package/src/memory/v2/consolidation-job.ts +1 -1
  210. package/src/memory/v3/__tests__/health.test.ts +16 -0
  211. package/src/memory/v3/__tests__/orchestrate.test.ts +45 -9
  212. package/src/memory/v3/__tests__/provider-blocks.test.ts +13 -0
  213. package/src/memory/v3/__tests__/router.test.ts +101 -29
  214. package/src/memory/v3/__tests__/selector.test.ts +93 -27
  215. package/src/memory/v3/__tests__/shadow-plugin.test.ts +23 -5
  216. package/src/memory/v3/health.ts +0 -0
  217. package/src/memory/v3/llm-retry.ts +32 -0
  218. package/src/memory/v3/orchestrate.ts +26 -14
  219. package/src/memory/v3/provider-blocks.ts +15 -5
  220. package/src/memory/v3/router.ts +48 -42
  221. package/src/memory/v3/selector.ts +57 -42
  222. package/src/memory/v3/shadow-plugin.ts +47 -15
  223. package/src/memory/v3/types.ts +8 -0
  224. package/src/notifications/conversation-pairing.ts +8 -15
  225. package/src/notifications/decision-engine.ts +6 -3
  226. package/src/notifications/home-feed-side-effect.ts +12 -1
  227. package/src/permissions/prompter.ts +4 -0
  228. package/src/plugin-api/constants.ts +4 -0
  229. package/src/plugin-api/index.ts +8 -1
  230. package/src/plugin-api/types.ts +151 -1
  231. package/src/plugins/defaults/empty-response/hooks/stop.ts +126 -0
  232. package/src/plugins/defaults/empty-response/register.ts +8 -13
  233. package/src/plugins/defaults/index.ts +1 -15
  234. package/src/plugins/defaults/injectors/register.ts +243 -74
  235. package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +91 -0
  236. package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit-temp.ts +216 -0
  237. package/src/plugins/defaults/memory-retrieval/injector-chain.ts +35 -0
  238. package/src/plugins/defaults/title-generate/hooks/stop.ts +75 -0
  239. package/src/plugins/defaults/title-generate/hooks/user-prompt-submit.ts +35 -0
  240. package/src/plugins/defaults/title-generate/package.json +1 -1
  241. package/src/plugins/defaults/title-generate/register.ts +18 -18
  242. package/src/plugins/defaults/tool-error/hooks/post-tool-use.ts +118 -0
  243. package/src/plugins/defaults/tool-error/package.json +1 -1
  244. package/src/plugins/defaults/tool-error/register.ts +9 -21
  245. package/src/plugins/defaults/tool-result-truncate/hooks/post-tool-use.ts +32 -0
  246. package/src/plugins/defaults/tool-result-truncate/register.ts +10 -21
  247. package/src/plugins/defaults/tool-result-truncate/terminal.ts +37 -18
  248. package/src/plugins/pipeline.ts +6 -18
  249. package/src/plugins/registry.ts +8 -25
  250. package/src/plugins/types.ts +43 -474
  251. package/src/proactive-artifact/aux-message-injector.ts +3 -3
  252. package/src/proactive-artifact/job.test.ts +7 -12
  253. package/src/prompts/__tests__/system-prompt.test.ts +36 -0
  254. package/src/prompts/templates/BOOTSTRAP-ACTIVATION-RAIL.md +62 -0
  255. package/src/prompts/templates/BOOTSTRAP.md +2 -2
  256. package/src/prompts/templates/system-sections.ts +15 -0
  257. package/src/providers/anthropic/client.ts +37 -29
  258. package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +112 -0
  259. package/src/providers/openai/chat-completions-provider.ts +44 -0
  260. package/src/providers/openrouter/client.ts +1 -0
  261. package/src/providers/placeholder-sentinels.ts +35 -0
  262. package/src/runtime/__tests__/agent-wake.test.ts +5 -1
  263. package/src/runtime/agent-wake.ts +2 -2
  264. package/src/runtime/assistant-event-hub.ts +36 -6
  265. package/src/runtime/{conversation-stream-state.ts → assistant-stream-state.ts} +132 -58
  266. package/src/runtime/http-router.ts +16 -21
  267. package/src/runtime/http-types.ts +16 -70
  268. package/src/runtime/pending-interactions.ts +1 -0
  269. package/src/runtime/routes/__tests__/consolidation-routes.test.ts +265 -2
  270. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +31 -1
  271. package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +6 -2
  272. package/src/runtime/routes/__tests__/tts-routes.test.ts +6 -2
  273. package/src/runtime/routes/app-management-routes.ts +6 -117
  274. package/src/runtime/routes/app-routes.ts +13 -15
  275. package/src/runtime/routes/attachment-routes.ts +26 -15
  276. package/src/runtime/routes/avatar-routes.ts +26 -0
  277. package/src/runtime/routes/btw-routes.ts +29 -23
  278. package/src/runtime/routes/consolidation-routes.ts +120 -20
  279. package/src/runtime/routes/conversation-query-routes.ts +2 -0
  280. package/src/runtime/routes/conversation-routes.ts +358 -184
  281. package/src/runtime/routes/documents-routes.ts +4 -0
  282. package/src/runtime/routes/domain-routes.ts +51 -37
  283. package/src/runtime/routes/epoch-millis-range.ts +34 -0
  284. package/src/runtime/routes/events-routes.ts +28 -34
  285. package/src/runtime/routes/gateway-log-routes.ts +26 -4
  286. package/src/runtime/routes/heartbeat-routes.ts +32 -12
  287. package/src/runtime/routes/identity-intro-cache.ts +11 -34
  288. package/src/runtime/routes/identity-routes.ts +208 -17
  289. package/src/runtime/routes/image-generation-routes.ts +40 -2
  290. package/src/runtime/routes/index.ts +2 -0
  291. package/src/runtime/routes/integrations/a2a.ts +12 -10
  292. package/src/runtime/routes/integrations/slack/__tests__/channel.test.ts +16 -0
  293. package/src/runtime/routes/integrations/slack/channel.ts +4 -0
  294. package/src/runtime/routes/integrations/slack/share.ts +27 -6
  295. package/src/runtime/routes/integrations/telegram.ts +6 -0
  296. package/src/runtime/routes/integrations/twilio.ts +42 -0
  297. package/src/runtime/routes/internal-telemetry-routes.ts +88 -0
  298. package/src/runtime/routes/log-export-routes.ts +8 -0
  299. package/src/runtime/routes/memory-v2-routes.ts +15 -8
  300. package/src/runtime/routes/memory-v3-routes.ts +50 -28
  301. package/src/runtime/routes/oauth-apps.ts +66 -12
  302. package/src/runtime/routes/oauth-providers.ts +44 -5
  303. package/src/runtime/routes/platform-routes.ts +81 -5
  304. package/src/runtime/routes/playground/__tests__/force-compact.test.ts +6 -4
  305. package/src/runtime/routes/playground/force-compact.ts +1 -1
  306. package/src/runtime/routes/rename-conversation-routes.ts +5 -0
  307. package/src/runtime/routes/schedule-routes.ts +152 -42
  308. package/src/runtime/routes/secret-routes.ts +14 -2
  309. package/src/runtime/routes/skills-routes.ts +43 -14
  310. package/src/runtime/routes/tool-call-confirmation-enrichment.test.ts +161 -0
  311. package/src/runtime/routes/tool-call-confirmation-enrichment.ts +107 -0
  312. package/src/runtime/routes/trust-rules-routes.ts +26 -2
  313. package/src/runtime/routes/tts-routes.ts +35 -0
  314. package/src/runtime/routes/types.ts +66 -8
  315. package/src/runtime/routes/usage-routes.ts +47 -39
  316. package/src/runtime/routes/webhook-routes.ts +41 -2
  317. package/src/runtime/routes/workspace-routes.ts +4 -0
  318. package/src/runtime/services/__tests__/analyze-conversation.test.ts +6 -0
  319. package/src/runtime/services/analyze-conversation.ts +2 -2
  320. package/src/schedule/schedule-store.ts +20 -1
  321. package/src/schedule/schedule-usage-store.ts +83 -0
  322. package/src/schedule/scheduler.ts +12 -5
  323. package/src/skills/catalog-files.ts +2 -2
  324. package/src/skills/catalog-install.ts +3 -0
  325. package/src/skills/categories-cache.ts +118 -0
  326. package/src/skills/clawhub-files.ts +1 -2
  327. package/src/skills/skillssh-files.ts +1 -2
  328. package/src/telemetry/types.ts +29 -1
  329. package/src/telemetry/usage-telemetry-reporter.test.ts +112 -3
  330. package/src/telemetry/usage-telemetry-reporter.ts +57 -2
  331. package/src/tools/executor.ts +1 -53
  332. package/src/tools/network/__tests__/web-search-metadata.test.ts +7 -1
  333. package/src/tools/network/__tests__/web-search.test.ts +11 -3
  334. package/src/tools/network/web-search-error.test.ts +248 -0
  335. package/src/tools/network/web-search-error.ts +267 -0
  336. package/src/tools/network/web-search.ts +207 -48
  337. package/src/tools/schedule/create.ts +2 -0
  338. package/src/tools/terminal/safe-env.ts +10 -1
  339. package/src/tools/ui-surface/definitions.ts +9 -1
  340. package/src/tts/__tests__/provider-catalog-consistency.test.ts +85 -1
  341. package/src/tts/provider-catalog.ts +76 -1
  342. package/src/util/mutex.ts +47 -0
  343. package/src/workspace/git-service.ts +1 -42
  344. package/src/workspace/migrations/095-bump-heartbeat-interval-30m-to-60m.ts +51 -0
  345. package/src/workspace/migrations/096-reduce-quality-profile-effort.ts +72 -0
  346. package/src/workspace/migrations/097-enable-adaptive-thinking-managed-profiles.ts +93 -0
  347. package/src/workspace/migrations/registry.ts +6 -0
  348. package/src/__tests__/bootstrap-turn-cleanup.test.ts +0 -44
  349. package/src/__tests__/empty-response-pipeline.test.ts +0 -423
  350. package/src/__tests__/llm-call-pipeline.test.ts +0 -287
  351. package/src/__tests__/memory-retrieval-pipeline.test.ts +0 -418
  352. package/src/__tests__/persistence-pipeline.test.ts +0 -503
  353. package/src/__tests__/title-generate-pipeline.test.ts +0 -211
  354. package/src/__tests__/token-estimate-pipeline.test.ts +0 -479
  355. package/src/__tests__/tool-error-pipeline.test.ts +0 -241
  356. package/src/__tests__/tool-execute-pipeline.test.ts +0 -417
  357. package/src/__tests__/tool-result-truncate-pipeline.test.ts +0 -341
  358. package/src/daemon/bootstrap-turn-cleanup.ts +0 -45
  359. package/src/gallery/default-gallery.ts +0 -1359
  360. package/src/gallery/gallery-manifest.ts +0 -28
  361. package/src/home/feature-gate.ts +0 -22
  362. package/src/plugins/defaults/empty-response/middlewares/emptyResponse.ts +0 -22
  363. package/src/plugins/defaults/empty-response/terminal.ts +0 -106
  364. package/src/plugins/defaults/injectors/package.json +0 -15
  365. package/src/plugins/defaults/llm-call/middlewares/llmCall.ts +0 -17
  366. package/src/plugins/defaults/llm-call/package.json +0 -15
  367. package/src/plugins/defaults/llm-call/register.ts +0 -45
  368. package/src/plugins/defaults/memory-retrieval/middlewares/memoryRetrieval.ts +0 -17
  369. package/src/plugins/defaults/memory-retrieval/package.json +0 -15
  370. package/src/plugins/defaults/memory-retrieval/register.ts +0 -181
  371. package/src/plugins/defaults/persistence/middlewares/persistence.ts +0 -19
  372. package/src/plugins/defaults/persistence/package.json +0 -15
  373. package/src/plugins/defaults/persistence/register.ts +0 -38
  374. package/src/plugins/defaults/persistence/terminal.ts +0 -83
  375. package/src/plugins/defaults/title-generate/terminal.ts +0 -31
  376. package/src/plugins/defaults/token-estimate/middlewares/tokenEstimate.ts +0 -23
  377. package/src/plugins/defaults/token-estimate/package.json +0 -15
  378. package/src/plugins/defaults/token-estimate/register.ts +0 -34
  379. package/src/plugins/defaults/token-estimate/terminal.ts +0 -40
  380. package/src/plugins/defaults/tool-error/middlewares/toolError.ts +0 -21
  381. package/src/plugins/defaults/tool-error/terminal.ts +0 -47
  382. package/src/plugins/defaults/tool-execute/middlewares/toolExecute.ts +0 -23
  383. package/src/plugins/defaults/tool-execute/package.json +0 -15
  384. package/src/plugins/defaults/tool-execute/register.ts +0 -49
  385. package/src/plugins/defaults/tool-result-truncate/middlewares/toolResultTruncate.ts +0 -23
  386. package/src/plugins/defaults/tool-result-truncate/types.ts +0 -22
  387. package/src/skills/category-inference.ts +0 -111
@@ -1,28 +0,0 @@
1
- export interface GalleryManifest {
2
- version: number;
3
- updatedAt: string;
4
- categories: GalleryCategory[];
5
- apps: GalleryApp[];
6
- }
7
-
8
- export interface GalleryCategory {
9
- id: string; // e.g. "productivity", "health", "fun"
10
- name: string; // Display name
11
- icon: string; // Emoji
12
- }
13
-
14
- export interface GalleryApp {
15
- id: string; // Unique identifier
16
- name: string;
17
- description: string;
18
- icon: string; // Emoji
19
- category: string; // Category ID
20
- version: string; // e.g. "1.0.0"
21
- featured?: boolean;
22
- schemaJson: string; // JSON schema for app records
23
- htmlDefinition: string; // Complete HTML app (also serves as compiled fallback)
24
- /** 2 = multi-file TSX format with sourceFiles */
25
- formatVersion?: number;
26
- /** Maps relative path to file content, e.g. { "src/main.tsx": "...", "src/index.html": "..." } */
27
- sourceFiles?: Record<string, string>;
28
- }
@@ -1,22 +0,0 @@
1
- import { isAssistantFeatureFlagEnabled } from "../config/assistant-feature-flags.js";
2
- import type { AssistantConfig } from "../config/schema.js";
3
-
4
- const HOME_PAGE_FLAG_KEY = "home-page" as const;
5
-
6
- /**
7
- * Whether the home page / home feed surface is enabled for this install.
8
- *
9
- * `home-page` is a `"both"`-scope flag: the client renders the home feed as the
10
- * landing view, and the notification pipeline uses it to decide whether passive
11
- * notifications have a home-feed surface to land on (when off, they fall back to
12
- * materializing a conversation instead of being suppressed).
13
- *
14
- * `config` is accepted for parity with the other gate modules but is unused —
15
- * the value resolves from the gateway override cache / registry default.
16
- */
17
- export function isHomePageEnabled(config?: AssistantConfig): boolean {
18
- return isAssistantFeatureFlagEnabled(
19
- HOME_PAGE_FLAG_KEY,
20
- (config ?? {}) as AssistantConfig,
21
- );
22
- }
@@ -1,22 +0,0 @@
1
- import type {
2
- EmptyResponseArgs,
3
- EmptyResponseResult,
4
- Middleware,
5
- } from "../../../types.js";
6
-
7
- /**
8
- * Passthrough middleware for the `emptyResponse` pipeline. Forwards to
9
- * `next(args)` unchanged; the actual empty-response decision lives in the
10
- * terminal handler (`../terminal.ts`), wired in at the `runPipeline` call site
11
- * in `agent/loop.ts`.
12
- *
13
- * Defaults register at the OUTERMOST onion position, so deciding here without
14
- * calling `next` would shadow every later-registered plugin. Routing through
15
- * `next(args)` lets user middleware participate normally.
16
- */
17
- const passthrough: Middleware<EmptyResponseArgs, EmptyResponseResult> = async (
18
- args,
19
- next,
20
- ) => next(args);
21
-
22
- export default passthrough;
@@ -1,106 +0,0 @@
1
- /**
2
- * Default `emptyResponse` behavior: decides whether an empty assistant turn
3
- * should be nudged (re-queried) or accepted.
4
- *
5
- * This module is side-effect free: importing it does not register any plugin.
6
- *
7
- * The handler inspects the turn snapshot and returns one of:
8
- *
9
- * 1. `"nudge"` — fired in two distinct shapes:
10
- * (a) **Post-tool empty.** The turn produced no visible text,
11
- * no tool calls, follows at least one prior tool-use turn,
12
- * no earlier turn in this run() has already delivered
13
- * visible text, AND the retry counter is below
14
- * `maxEmptyResponseRetries`. Uses `NUDGE_TEXT`.
15
- * (b) **Refusal stop.** The provider returned
16
- * `stopReason === "refusal"` with no visible text and no
17
- * tool calls (Anthropic's safety classifier). Nudges even
18
- * on turn 0 / before any tool use, because a refusal on
19
- * the first model call of the run is a hard guarantee
20
- * that no organic text exists yet — without intervening
21
- * we'd persist an empty assistant bubble to the user.
22
- * Uses the refusal-specific `REFUSAL_NUDGE_TEXT`. The
23
- * retry cap still applies; after `maxEmptyResponseRetries`
24
- * refusals in a row the terminal falls through to accept.
25
- * The loop appends the chosen `nudgeText` as a `user` turn
26
- * and re-queries the model.
27
- * 2. `"accept"` — every other case. The turn either legitimately ended
28
- * (model said its piece earlier), is still in progress
29
- * (tool calls pending), or exhausted its retry budget. The
30
- * loop pushes the assistant message and continues normally.
31
- *
32
- * The default never returns `"error"` — that action is an escape hatch for
33
- * downstream plugins (e.g. a circuit breaker) that want to surface an
34
- * explicit error instead of silently absorbing an empty turn.
35
- *
36
- * `MAX_EMPTY_RESPONSE_RETRIES` lives in `agent/loop.ts` and is passed in via
37
- * `EmptyResponseArgs.maxEmptyResponseRetries` so the cap is declared in one
38
- * place only.
39
- */
40
-
41
- import type { EmptyResponseArgs, EmptyResponseResult } from "../../types.js";
42
-
43
- /**
44
- * Canonical nudge text. Must stay verbatim so a plugin that wraps the
45
- * default cannot accidentally see a different string.
46
- *
47
- * Wire-compat note: this is shown to the LLM, not the user. Edits here
48
- * affect model behavior but not end-user UX directly.
49
- */
50
- const NUDGE_TEXT =
51
- "<system_notice>Your previous response was empty. You must respond to the user with a summary of what you found or did. Do not use any tools — just respond with text.</system_notice>";
52
-
53
- /**
54
- * Refusal-specific nudge. Used when the provider stops with `"refusal"`
55
- * before any tool use — i.e. the safety classifier zeroed the response.
56
- * Kept distinct from `NUDGE_TEXT` so the model gets context-appropriate
57
- * guidance (no "summary of what you found or did" — there is no tool
58
- * trail to summarize on a turn-0 refusal).
59
- *
60
- * Wire-compat note: this is shown to the LLM, not the user. Edits here
61
- * affect retry behavior but not end-user UX directly.
62
- */
63
- export const REFUSAL_NUDGE_TEXT =
64
- '<system_notice>Your previous response was empty because the upstream provider returned stop_reason="refusal". Please answer the user\'s last message directly with a plain-text response. Do not use any tools — just respond with text.</system_notice>';
65
-
66
- /**
67
- * Decide whether an empty turn should be nudged or accepted. Exported so the
68
- * agent loop can call it directly and tests can verify the decision logic.
69
- */
70
- export function defaultEmptyResponseTerminal(
71
- args: EmptyResponseArgs,
72
- ): EmptyResponseResult {
73
- const hasVisibleText = args.responseContent.some(
74
- (block) =>
75
- block.type === "text" &&
76
- typeof (block as { text?: unknown }).text === "string" &&
77
- (block as { text: string }).text.trim().length > 0,
78
- );
79
-
80
- // Refusal stop with zero usable content — the provider's safety
81
- // classifier zeroed the response. Nudge regardless of toolUseTurns or
82
- // priorAssistantHadVisibleText: a `"refusal"` stop with no visible
83
- // text and no tool calls IS the failure mode this branch exists to
84
- // catch (otherwise we persist an empty assistant bubble to the user).
85
- // Still respect the retry cap so a persistent classifier doesn't
86
- // burn turns indefinitely.
87
- const isRefusal =
88
- args.stopReason === "refusal" &&
89
- !hasVisibleText &&
90
- args.toolUseBlocksLength === 0;
91
-
92
- if (isRefusal && args.emptyResponseRetries < args.maxEmptyResponseRetries) {
93
- return { action: "nudge", nudgeText: REFUSAL_NUDGE_TEXT };
94
- }
95
-
96
- const isEmptyTurn =
97
- !hasVisibleText &&
98
- args.toolUseBlocksLength === 0 &&
99
- args.toolUseTurns > 0 &&
100
- !args.priorAssistantHadVisibleText;
101
-
102
- if (isEmptyTurn && args.emptyResponseRetries < args.maxEmptyResponseRetries) {
103
- return { action: "nudge", nudgeText: NUDGE_TEXT };
104
- }
105
- return { action: "accept" };
106
- }
@@ -1,15 +0,0 @@
1
- {
2
- "name": "default-injectors",
3
- "version": "1.0.0",
4
- "description": "First-party default plugin wrapping the assistant's built-in injectors pipeline with a passthrough implementation.",
5
- "private": true,
6
- "license": "MIT",
7
- "type": "module",
8
- "main": "./register.ts",
9
- "engines": {
10
- "node": ">=20.12.0"
11
- },
12
- "peerDependencies": {
13
- "@vellumai/plugin-api": "^0.8.0"
14
- }
15
- }
@@ -1,17 +0,0 @@
1
- import type { LLMCallArgs, LLMCallResult, Middleware } from "../../../types.js";
2
-
3
- /**
4
- * Passthrough middleware for the `llmCall` pipeline. Forwards to `next(args)`
5
- * unchanged so any user-registered middleware (registered later, inner in the
6
- * onion) still runs and the terminal at the call site (`agent/loop.ts`)
7
- * performs the actual `provider.sendMessage(...)` call.
8
- *
9
- * Defaults register at the OUTERMOST onion position; forwarding
10
- * unconditionally keeps user-registered middleware reachable.
11
- */
12
- const defaultLlmCall: Middleware<LLMCallArgs, LLMCallResult> =
13
- async function defaultLlmCall(args, next, _ctx) {
14
- return next(args);
15
- };
16
-
17
- export default defaultLlmCall;
@@ -1,15 +0,0 @@
1
- {
2
- "name": "default-llm-call",
3
- "version": "1.0.0",
4
- "description": "First-party default plugin wrapping the assistant's built-in llm-call pipeline with a passthrough implementation.",
5
- "private": true,
6
- "license": "MIT",
7
- "type": "module",
8
- "main": "./register.ts",
9
- "engines": {
10
- "node": ">=20.12.0"
11
- },
12
- "peerDependencies": {
13
- "@vellumai/plugin-api": "^0.8.0"
14
- }
15
- }
@@ -1,45 +0,0 @@
1
- /**
2
- * Default `llmCall` plugin — a passthrough that declares the pipeline
3
- * surface and yields to downstream middleware.
4
- *
5
- * The plugin system wraps every LLM request in the `llmCall` pipeline. The
6
- * actual call to {@link Provider.sendMessage} lives in the `runPipeline`
7
- * terminal at the call site (`agent/loop.ts`); this default's only job is to
8
- * contribute the manifest (`provides.llmCall: "v1"`) so other plugins can
9
- * negotiate against the pipeline surface.
10
- *
11
- * This plugin registers at module load — before user plugins are loaded by
12
- * `bootstrapPlugins()` — so it sits at the outermost layer in
13
- * `composeMiddleware`'s onion ordering. To keep user-registered middleware
14
- * reachable, the middleware forwards unconditionally via `next(args)`.
15
- *
16
- * Registered from `daemon/external-plugins-bootstrap.ts` via a side-effect
17
- * import so the plugin is present in the registry before
18
- * {@link bootstrapPlugins} walks it.
19
- *
20
- * Design doc: `.private/plans/agent-plugin-system.md` (PR 15).
21
- */
22
-
23
- import { type Plugin } from "../../types.js";
24
- import llmCall from "./middlewares/llmCall.js";
25
- import pkg from "./package.json" with { type: "json" };
26
-
27
- /**
28
- * The default LLM-call plugin. Its `llmCall` middleware is a passthrough that
29
- * forwards to `next(args)` unchanged so any user-registered middleware
30
- * (registered later, inner in the onion) still runs and the terminal at the
31
- * call site performs the actual `provider.sendMessage(...)` call.
32
- *
33
- * Manifest declares `provides.llmCall: "v1"` so other plugins can negotiate
34
- * against the pipeline surface and `requires.pluginRuntime: "v1"` to satisfy
35
- * the registry's mandatory capability check.
36
- */
37
- export const defaultLlmCallPlugin: Plugin = {
38
- manifest: {
39
- name: pkg.name,
40
- version: pkg.version,
41
- },
42
- middleware: {
43
- llmCall,
44
- },
45
- };
@@ -1,17 +0,0 @@
1
- import type { MemoryArgs, MemoryResult, Middleware } from "../../../types.js";
2
-
3
- /**
4
- * Passthrough middleware for the `memoryRetrieval` pipeline.
5
- *
6
- * Keeping a real middleware registered (rather than an empty list) makes the
7
- * pipeline observable in `plugin.pipeline` logs with a non-empty `chain` field
8
- * and lets third-party plugins rely on the default slot being present even
9
- * when nothing is overriding it. The work happens in the terminal supplied by
10
- * the agent loop, which calls `runDefaultMemoryRetrieval`.
11
- */
12
- const defaultMemoryRetrievalMiddleware: Middleware<MemoryArgs, MemoryResult> =
13
- async function defaultMemoryRetrieval(args, next) {
14
- return next(args);
15
- };
16
-
17
- export default defaultMemoryRetrievalMiddleware;
@@ -1,15 +0,0 @@
1
- {
2
- "name": "default-memory-retrieval",
3
- "version": "0.0.1",
4
- "description": "First-party default plugin wrapping the assistant's built-in memory-retrieval pipeline with a passthrough implementation.",
5
- "private": true,
6
- "license": "MIT",
7
- "type": "module",
8
- "main": "./register.ts",
9
- "engines": {
10
- "node": ">=20.12.0"
11
- },
12
- "peerDependencies": {
13
- "@vellumai/plugin-api": "^0.8.0"
14
- }
15
- }
@@ -1,181 +0,0 @@
1
- /**
2
- * Default `memoryRetrieval` plugin.
3
- *
4
- * Encapsulates the three retrievals the agent loop performs before building
5
- * the runtime-injection block for a turn:
6
- *
7
- * 1. **PKB context** via {@link readPkbContext} — always-loaded workspace
8
- * notes (INDEX.md, essentials.md, …) that precede the user's message.
9
- * 2. **NOW.md scratchpad** via {@link readNowScratchpad} — the short
10
- * user-maintained note the assistant keeps up to date.
11
- * 3. **Memory graph** via {@link ConversationGraphMemory.prepareMemory} —
12
- * dispatches to context-load or per-turn retrieval depending on
13
- * initialization state; gated on the actor being trusted (guardian).
14
- *
15
- * The default plugin registers a pass-through middleware so the pipeline
16
- * runner always has at least one entry and downstream telemetry observes a
17
- * deterministic chain. The actual retrieval runs in the terminal supplied
18
- * by the agent loop; centralizing the helper here (as
19
- * {@link runDefaultMemoryRetrieval}) makes it trivial for a plugin to
20
- * fall back to the default behavior by calling this helper from its own
21
- * middleware.
22
- *
23
- * See `.private/plans/agent-plugin-system.md` PR 20 for the containing
24
- * milestone.
25
- */
26
-
27
- import type { AssistantConfig } from "../../../config/schema.js";
28
- import {
29
- readNowScratchpad,
30
- readPkbContext,
31
- } from "../../../daemon/conversation-runtime-assembly.js";
32
- import type { ServerMessage } from "../../../daemon/message-protocol.js";
33
- import type { ConversationGraphMemory } from "../../../memory/graph/conversation-graph-memory.js";
34
- import type { Message } from "../../../providers/types.js";
35
- import {
36
- type MemoryArgs,
37
- type MemoryResult,
38
- type Plugin,
39
- } from "../../types.js";
40
- import defaultMemoryRetrievalMiddleware from "./middlewares/memoryRetrieval.js";
41
- import pkg from "./package.json" with { type: "json" };
42
-
43
- /**
44
- * Discriminator the agent loop uses to narrow `MemoryResult.memoryGraphBlocks`
45
- * back into the full {@link GraphMemoryPayload} shape. Plugins that substitute
46
- * their own memory blocks without setting this marker will fall through the
47
- * agent loop's graph-result consumption path — which is the intended escape
48
- * hatch for custom retrievers.
49
- */
50
- export const DEFAULT_MEMORY_GRAPH_KIND = "default.graph" as const;
51
-
52
- /**
53
- * Shape of the single block the default memory-graph retriever emits.
54
- *
55
- * Mirrors the object returned by
56
- * {@link ConversationGraphMemory.prepareMemory} — the agent loop consumes
57
- * every field downstream (PKB query vectors, metrics persistence, memory
58
- * event emission). Kept as a concrete type here so both the terminal and the
59
- * agent loop can share one import.
60
- */
61
- export interface GraphMemoryPayload {
62
- readonly kind: typeof DEFAULT_MEMORY_GRAPH_KIND;
63
- readonly result: Awaited<
64
- ReturnType<ConversationGraphMemory["prepareMemory"]>
65
- >;
66
- }
67
-
68
- /**
69
- * External state the default retriever needs but the pipeline args cannot
70
- * carry (conversation-scoped graph handle, event sink, live message list).
71
- * Passed as a second argument to {@link runDefaultMemoryRetrieval} rather
72
- * than threaded through {@link MemoryArgs} to keep the plugin-facing
73
- * pipeline surface minimal.
74
- */
75
- export interface DefaultMemoryRetrievalDeps {
76
- /** Live message list for this turn (pre-injection). */
77
- readonly messages: Message[];
78
- /** Per-conversation memory graph handle. */
79
- readonly graphMemory: ConversationGraphMemory;
80
- /** Assistant config snapshot. */
81
- readonly config: AssistantConfig;
82
- /** Event sink used by the graph retriever (memory_status events). */
83
- readonly onEvent: (msg: ServerMessage) => void;
84
- /** True when the actor for this turn is trusted (guardian-class). */
85
- readonly isTrustedActor: boolean;
86
- }
87
-
88
- /**
89
- * Run the default retrieval. Always returns a {@link MemoryResult}; skips
90
- * the memory-graph call entirely when the actor is not trusted (matches the
91
- * prior agent-loop gate).
92
- *
93
- * The returned `memoryGraphBlocks` is either empty (when the actor is not
94
- * trusted) or a single {@link GraphMemoryPayload} wrapping the graph
95
- * retriever's full output. The agent loop narrows via
96
- * {@link DEFAULT_MEMORY_GRAPH_KIND} to consume it.
97
- *
98
- * Memory retrieval blocks the turn — there is no soft timeout here. Memory
99
- * is critical context, and silently dropping it produces a worse outcome
100
- * than a slower turn. Cancellation still works via `args.signal`, which is
101
- * threaded into `prepareMemory`.
102
- */
103
- export async function runDefaultMemoryRetrieval(
104
- args: MemoryArgs,
105
- deps: DefaultMemoryRetrievalDeps,
106
- ): Promise<MemoryResult> {
107
- // NOW.md and PKB are read unconditionally — the agent loop decides
108
- // whether to inject them based on first-turn / post-compaction gating.
109
- const pkbContent = readPkbContext();
110
- const nowContent = readNowScratchpad();
111
-
112
- if (!deps.isTrustedActor) {
113
- // Untrusted actors skip memory-graph retrieval entirely — preserves the
114
- // pre-plugin gate that lived inline in `conversation-agent-loop.ts`.
115
- return {
116
- pkbContent,
117
- nowContent,
118
- memoryGraphBlocks: [],
119
- };
120
- }
121
-
122
- const graphResult = await deps.graphMemory.prepareMemory(
123
- deps.messages,
124
- deps.config,
125
- args.signal,
126
- deps.onEvent,
127
- );
128
-
129
- const payload: GraphMemoryPayload = {
130
- kind: DEFAULT_MEMORY_GRAPH_KIND,
131
- result: graphResult,
132
- };
133
-
134
- return {
135
- pkbContent,
136
- nowContent,
137
- memoryGraphBlocks: [payload],
138
- };
139
- }
140
-
141
- /**
142
- * Narrow a {@link MemoryResult} memory-graph block back into the full
143
- * {@link GraphMemoryPayload} the default retriever emits. Returns `null` when
144
- * the pipeline output came from a custom retriever (no blocks, or a block
145
- * without the {@link DEFAULT_MEMORY_GRAPH_KIND} discriminator).
146
- *
147
- * The agent loop uses this helper to decide whether to run its downstream
148
- * graph-result consumption path (query-vector propagation, metric
149
- * persistence, memory-event emission). Custom retrievers that skip that
150
- * path are expected to handle their own side effects inside their
151
- * middleware.
152
- */
153
- export function asDefaultGraphPayload(
154
- blocks: ReadonlyArray<unknown>,
155
- ): GraphMemoryPayload | null {
156
- const first = blocks[0];
157
- if (
158
- first != null &&
159
- typeof first === "object" &&
160
- "kind" in first &&
161
- (first as { kind?: unknown }).kind === DEFAULT_MEMORY_GRAPH_KIND
162
- ) {
163
- return first as GraphMemoryPayload;
164
- }
165
- return null;
166
- }
167
-
168
- /**
169
- * Default plugin exposing the `memoryRetrieval` pipeline slot. Registered
170
- * by {@link registerDefaultMemoryRetrievalPlugin} from the plugin
171
- * bootstrap wiring so ordering is deterministic across boots.
172
- */
173
- export const defaultMemoryRetrievalPlugin: Plugin = {
174
- manifest: {
175
- name: pkg.name,
176
- version: pkg.version,
177
- },
178
- middleware: {
179
- memoryRetrieval: defaultMemoryRetrievalMiddleware,
180
- },
181
- };
@@ -1,19 +0,0 @@
1
- import type { Middleware, PersistArgs, PersistResult } from "../../../types.js";
2
-
3
- /**
4
- * Passthrough middleware for the `persistence` pipeline. Forwards to
5
- * `next(args)` unchanged; the actual dispatch lives in the terminal handler
6
- * (`../terminal.ts`), wired in at the `runPipeline` call sites in
7
- * `daemon/conversation-agent-loop.ts` and
8
- * `daemon/conversation-agent-loop-handlers.ts`.
9
- *
10
- * Defaults register at the OUTERMOST onion position, so deciding here without
11
- * calling `next` would shadow every later-registered plugin. Routing through
12
- * `next(args)` lets user middleware participate normally.
13
- */
14
- const passthrough: Middleware<PersistArgs, PersistResult> = async (
15
- args,
16
- next,
17
- ) => next(args);
18
-
19
- export default passthrough;
@@ -1,15 +0,0 @@
1
- {
2
- "name": "default-persistence",
3
- "version": "1.0.0",
4
- "description": "First-party default plugin wrapping the assistant's built-in persistence pipeline with a passthrough implementation.",
5
- "private": true,
6
- "license": "MIT",
7
- "type": "module",
8
- "main": "./register.ts",
9
- "engines": {
10
- "node": ">=20.12.0"
11
- },
12
- "peerDependencies": {
13
- "@vellumai/plugin-api": "^0.8.0"
14
- }
15
- }
@@ -1,38 +0,0 @@
1
- /**
2
- * Default `persistence` plugin.
3
- *
4
- * The plugin's middleware is a passthrough — it calls `next(args)` and returns
5
- * the result unchanged. The actual dispatch lives in the terminal handler in
6
- * `./terminal.ts`, which is wired in as the pipeline's `terminal` argument by
7
- * `runPipeline` call sites in `daemon/conversation-agent-loop.ts` and
8
- * `daemon/conversation-agent-loop-handlers.ts`. This separation matters: the
9
- * default plugin is registered before any user plugin (defaults load first in
10
- * `bootstrapPlugins()`), which puts it at the OUTERMOST position of the onion
11
- * chain. If the default middleware were to invoke the terminal directly
12
- * without calling `next`, it would shadow every later-registered plugin.
13
- * Routing through `next(args)` lets user middleware participate normally.
14
- *
15
- * Manifest declares `provides.persistence: "v1"` so other plugins can
16
- * negotiate against the pipeline surface and `requires.pluginRuntime: "v1"`
17
- * to satisfy the registry's mandatory capability check.
18
- *
19
- * Registered from `daemon/external-plugins-bootstrap.ts` via a side-effect
20
- * import so the plugin is present in the registry before
21
- * {@link bootstrapPlugins} walks it.
22
- *
23
- * Design doc: `.private/plans/agent-plugin-system.md` (PR 27).
24
- */
25
-
26
- import { type Plugin } from "../../types.js";
27
- import persistence from "./middlewares/persistence.js";
28
- import pkg from "./package.json" with { type: "json" };
29
-
30
- export const defaultPersistencePlugin: Plugin = {
31
- manifest: {
32
- name: pkg.name,
33
- version: pkg.version,
34
- },
35
- middleware: {
36
- persistence,
37
- },
38
- };
@@ -1,83 +0,0 @@
1
- /**
2
- * Default `persistence` behavior: writes conversation messages to the database
3
- * (and optionally the JSONL disk view).
4
- *
5
- * This module is side-effect free: importing it does not register any plugin.
6
- *
7
- * The handler dispatches on the discriminated {@link PersistArgs.op} field:
8
- *
9
- * - `add` → {@link addMessage}, optionally followed by
10
- * {@link syncMessageToDisk} when `args.syncToDisk` is true.
11
- * - `reserve` → {@link reserveMessage} — pre-allocates an empty row
12
- * for assistant anchor stamping.
13
- * - `updateContent` → {@link updateMessageContent} — overwrites an existing
14
- * row's content (returns `void`, wrapped as
15
- * `{ op: "updateContent" }`).
16
- * - `update` → {@link updateMessageMetadata} (returns `void`, wrapped
17
- * as `{ op: "update" }`).
18
- * - `delete` → {@link deleteMessageById} (returns the segment/summary
19
- * IDs the caller must clean up out-of-band).
20
- */
21
-
22
- import {
23
- addMessage,
24
- deleteMessageById,
25
- reserveMessage,
26
- updateMessageContent,
27
- updateMessageMetadata,
28
- } from "../../../memory/conversation-crud.js";
29
- import { syncMessageToDisk } from "../../../memory/conversation-disk-view.js";
30
- import type { PersistArgs, PersistResult } from "../../types.js";
31
-
32
- /**
33
- * Persist a message according to `args.op`. Exported so the agent-loop call
34
- * sites can invoke it directly and tests can verify each op in isolation.
35
- */
36
- export async function defaultPersistenceTerminal(
37
- args: PersistArgs,
38
- ): Promise<PersistResult> {
39
- switch (args.op) {
40
- case "add": {
41
- const message = await addMessage(
42
- args.conversationId,
43
- args.role,
44
- args.content,
45
- {
46
- metadata: args.metadata,
47
- ...args.addOptions,
48
- },
49
- );
50
- // Sync the just-persisted row to the JSONL disk view when the caller
51
- // opted in. The handler that emits tool-result rows sets
52
- // `syncToDisk: true` so the disk view stays in lockstep with the DB.
53
- if (args.syncToDisk && args.createdAtMs !== undefined) {
54
- syncMessageToDisk(args.conversationId, message.id, args.createdAtMs);
55
- }
56
- return { op: "add", message };
57
- }
58
- case "reserve": {
59
- const message = await reserveMessage(
60
- args.conversationId,
61
- args.role,
62
- args.metadata,
63
- );
64
- return { op: "reserve", message };
65
- }
66
- case "updateContent": {
67
- updateMessageContent(args.messageId, args.content);
68
- return { op: "updateContent" };
69
- }
70
- case "update": {
71
- updateMessageMetadata(args.messageId, args.updates);
72
- return { op: "update" };
73
- }
74
- case "delete": {
75
- const deleted = deleteMessageById(args.messageId);
76
- return {
77
- op: "delete",
78
- segmentIds: deleted.segmentIds,
79
- deletedSummaryIds: deleted.deletedSummaryIds,
80
- };
81
- }
82
- }
83
- }