@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,35 +1,23 @@
1
1
  /**
2
- * Default `toolError` plugin.
2
+ * Default `tool-error` plugin.
3
3
  *
4
- * The plugin's middleware is a passthrough it calls `next(args)` and returns
5
- * the result unchanged. The actual nudge-decision logic lives in the terminal
6
- * handler in `./terminal.ts`, which is wired in as the pipeline's `terminal`
7
- * argument by the `runPipeline` call site in `agent/loop.ts`. This separation
8
- * matters: the default plugin is registered before any user plugin (defaults
9
- * load first via module-side-effect imports / `registerDefaultPlugins`), which
10
- * puts it at the OUTERMOST position of the onion chain. If the default
11
- * middleware invoked the decision logic directly without calling `next`, it
12
- * would shadow every later-registered plugin. Routing through `next(args)`
13
- * lets user middleware participate normally.
14
- *
15
- * Design doc: `.private/plans/agent-plugin-system.md` (PR 19).
4
+ * Contributes a `post-tool-use` hook that coaches the model to retry or report
5
+ * a failed tool call, bounded per tool so an unrecoverable error doesn't churn.
6
+ * The coaching is surfaced via `additionalContext` (a separate provider-only
7
+ * block), leaving the tool result's own content untouched. The decision logic
8
+ * lives in `./hooks/post-tool-use.ts`.
16
9
  */
17
10
 
18
11
  import { type Plugin } from "../../types.js";
19
- import defaultToolErrorMiddleware from "./middlewares/toolError.js";
12
+ import postToolUse from "./hooks/post-tool-use.js";
20
13
  import pkg from "./package.json" with { type: "json" };
21
14
 
22
- /**
23
- * Plugin registration for the default `toolError` behavior. Registered by
24
- * `daemon/external-plugins-bootstrap.ts` via a side-effect import so the
25
- * middleware is available to the pipeline runner from daemon startup.
26
- */
27
15
  export const defaultToolErrorPlugin: Plugin = {
28
16
  manifest: {
29
17
  name: pkg.name,
30
18
  version: pkg.version,
31
19
  },
32
- middleware: {
33
- toolError: defaultToolErrorMiddleware,
20
+ hooks: {
21
+ "post-tool-use": postToolUse,
34
22
  },
35
23
  };
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Default `post-tool-use` hook: tail-drops an oversized tool result down to a
3
+ * character budget derived from the model's context window, keeping a single
4
+ * result from blowing the provider's context.
5
+ *
6
+ * Defaults register before any user plugin, so this hook runs at the front of
7
+ * the `post-tool-use` chain — every later hook sees an already-bounded result.
8
+ * The hook mutates `toolResponse.content` in place.
9
+ */
10
+
11
+ import type { PluginHookFn, PostToolUseContext } from "@vellumai/plugin-api";
12
+
13
+ import { truncateToolResult } from "../terminal.js";
14
+
15
+ const postToolUse: PluginHookFn<PostToolUseContext> = async (ctx) => {
16
+ const { content, truncated } = truncateToolResult(
17
+ ctx.toolResponse.content,
18
+ ctx.maxInputTokens,
19
+ );
20
+ if (truncated) {
21
+ ctx.toolResponse.content = content;
22
+ ctx.logger.warn(
23
+ {
24
+ plugin: "tool-result-truncate",
25
+ toolUseId: ctx.toolResponse.tool_use_id,
26
+ },
27
+ "Truncated oversized tool result to prevent context overflow",
28
+ );
29
+ }
30
+ };
31
+
32
+ export default postToolUse;
@@ -1,35 +1,24 @@
1
1
  /**
2
- * Default `toolResultTruncate` plugin.
2
+ * Default `tool-result-truncate` plugin.
3
3
  *
4
- * The plugin's middleware is a passthrough it calls `next(args)` and returns
5
- * the result unchanged. The actual truncation lives in the terminal handler in
6
- * `./terminal.ts`, which is wired in as the pipeline's `terminal` argument by
7
- * the `runPipeline` call site in `agent/loop.ts`. This separation matters: the
8
- * default plugin is registered before any user plugin (defaults load first in
9
- * `bootstrapPlugins()`), which puts it at the OUTERMOST position of the onion
10
- * chain. If the default
11
- * middleware were to invoke the terminal directly without calling `next`, it
12
- * would shadow every later-registered plugin (including hot-reloaded ones).
13
- * Routing through `next(args)` lets user middleware participate normally.
14
- *
15
- * Design doc: `.private/plans/agent-plugin-system.md` (PR 17).
4
+ * Contributes a `post-tool-use` hook that tail-drops an oversized tool result
5
+ * down to a character budget derived from the model's context window before
6
+ * the result is sent to the provider. The truncation implementation lives in
7
+ * `./terminal.ts`; the hook in `./hooks/post-tool-use.ts` wires it into the
8
+ * lifecycle. Defaults register before user plugins, so this runs at the front
9
+ * of the hook chain.
16
10
  */
17
11
 
18
12
  import { type Plugin } from "../../types.js";
19
- import toolResultTruncate from "./middlewares/toolResultTruncate.js";
13
+ import postToolUse from "./hooks/post-tool-use.js";
20
14
  import pkg from "./package.json" with { type: "json" };
21
15
 
22
- /**
23
- * Plugin descriptor for the default tool-result truncation middleware.
24
- * Registered by `plugins/defaults/index.ts` so the registry always has at
25
- * least one middleware for the `toolResultTruncate` pipeline.
26
- */
27
16
  export const defaultToolResultTruncatePlugin: Plugin = {
28
17
  manifest: {
29
18
  name: pkg.name,
30
19
  version: pkg.version,
31
20
  },
32
- middleware: {
33
- toolResultTruncate,
21
+ hooks: {
22
+ "post-tool-use": postToolUse,
34
23
  },
35
24
  };
@@ -1,15 +1,11 @@
1
1
  /**
2
- * Default `toolResultTruncate` behavior: tail-drops oversized tool-result text
3
- * down to a character budget, plus the truncation primitive it wraps.
2
+ * Tool-result truncation: tail-drops oversized tool-result text down to a
3
+ * character budget derived from the model's context window, plus the
4
+ * primitives it wraps.
4
5
  *
5
6
  * This module is side-effect free: importing it does not register any plugin.
6
7
  */
7
8
 
8
- import type {
9
- ToolResultTruncateArgs,
10
- ToolResultTruncateResult,
11
- } from "./types.js";
12
-
13
9
  const HIGH_SURROGATE_START = 0xd800;
14
10
  const HIGH_SURROGATE_END = 0xdbff;
15
11
  const LOW_SURROGATE_START = 0xdc00;
@@ -98,16 +94,39 @@ export function truncateToolResultText(text: string, maxChars: number): string {
98
94
  }
99
95
 
100
96
  /**
101
- * Truncate a single tool-result block's content to `args.maxChars`. Exported
102
- * so the agent loop can call it directly and tests can verify the default
103
- * behavior.
97
+ * Maximum share of the context window that a single tool result may occupy.
98
+ */
99
+ const MAX_TOOL_RESULT_CONTEXT_SHARE = 0.3;
100
+
101
+ /**
102
+ * Absolute cap on tool-result characters (~100K tokens).
103
+ */
104
+ export const HARD_MAX_TOOL_RESULT_CHARS = 400_000;
105
+
106
+ /**
107
+ * Calculate the maximum allowed characters for a tool result based on the
108
+ * context window size. Uses ~4 chars per token as a rough heuristic.
109
+ */
110
+ export function calculateMaxToolResultChars(
111
+ contextWindowTokens: number,
112
+ ): number {
113
+ return Math.min(
114
+ HARD_MAX_TOOL_RESULT_CHARS,
115
+ Math.floor(contextWindowTokens * MAX_TOOL_RESULT_CONTEXT_SHARE * 4),
116
+ );
117
+ }
118
+
119
+ /**
120
+ * Truncate a tool result's content to fit the model's context window. Derives
121
+ * the character budget from `maxInputTokens` and tail-drops anything beyond it.
122
+ * Returns the (possibly truncated) content alongside a `truncated` flag the
123
+ * caller can use for telemetry.
104
124
  */
105
- export function defaultToolResultTruncateTerminal(
106
- args: ToolResultTruncateArgs,
107
- ): ToolResultTruncateResult {
108
- const truncated = truncateToolResultText(args.content, args.maxChars);
109
- return {
110
- content: truncated,
111
- truncated: truncated !== args.content,
112
- };
125
+ export function truncateToolResult(
126
+ content: string,
127
+ maxInputTokens: number,
128
+ ): { content: string; truncated: boolean } {
129
+ const maxChars = calculateMaxToolResultChars(maxInputTokens);
130
+ const next = truncateToolResultText(content, maxChars);
131
+ return { content: next, truncated: next !== content };
113
132
  }
@@ -20,8 +20,7 @@
20
20
  * timer. A timeout rejection is a `PluginTimeoutError` carrying the
21
21
  * pipeline name, the best-known offending plugin (from `ctx.pluginName`),
22
22
  * and elapsed ms. When `timeoutMs` is `null`/`undefined`, no timer is
23
- * armed — pipelines like `llmCall` and `toolExecute` rely on downstream
24
- * timeouts instead.
23
+ * armed — pipelines like `compaction` rely on downstream timeouts instead.
25
24
  */
26
25
 
27
26
  import type { Logger } from "pino";
@@ -43,27 +42,16 @@ const moduleLogger = getLogger("plugin-pipeline");
43
42
  /**
44
43
  * Default per-pipeline timeout budgets in milliseconds. A value of `null`
45
44
  * means the runner does NOT arm a timer — the pipeline relies on its
46
- * downstream for budgeting (e.g. `llmCall` defers to provider-level HTTP
47
- * timeouts; `toolExecute` defers to the per-tool timeout already enforced
48
- * by `ToolExecutor`).
45
+ * downstream for budgeting (e.g. `compaction` defers to the provider-level
46
+ * HTTP timeouts of the summary call it wraps).
49
47
  *
50
48
  * Callers pass the appropriate entry as `runPipeline`'s `timeoutMs` argument.
51
49
  * The design doc locks these numbers in; do not tweak without coordinating
52
50
  * a design update.
53
51
  */
54
52
  export const DEFAULT_TIMEOUTS: Record<PipelineName, number | null> = {
55
- turn: null,
56
- llmCall: null,
57
- toolExecute: null,
58
- memoryRetrieval: null,
59
- tokenEstimate: null,
60
53
  compaction: null,
61
54
  overflowReduce: null,
62
- persistence: null,
63
- titleGenerate: null,
64
- toolResultTruncate: null,
65
- emptyResponse: null,
66
- toolError: null,
67
55
  circuitBreaker: null,
68
56
  };
69
57
 
@@ -114,7 +102,7 @@ export function composeMiddleware<A, R>(
114
102
  *
115
103
  * When `args` carries no `AbortSignal` property, the original object is
116
104
  * returned unchanged — pipelines whose terminals don't consume a signal
117
- * (e.g. `persistence`, `tokenEstimate`) see identical behavior to before.
105
+ * (e.g. `circuitBreaker`) see identical behavior to before.
118
106
  * The return value's `cleanup()` tears down any `addEventListener("abort",
119
107
  * ...)` handlers attached to the caller's signal so a pipeline that
120
108
  * completes successfully doesn't leak listeners on the caller's controller.
@@ -316,9 +304,9 @@ export async function runPipeline<A, R>(
316
304
  *
317
305
  * `runHook` is the hook-side counterpart to {@link runPipeline}:
318
306
  * `runPipeline` composes middleware around a terminal handler for stateful
319
- * request/response pipelines (memory retrieval, history repair, etc.);
307
+ * request/response pipelines (compaction, overflow reduction, etc.);
320
308
  * `runHook` walks ordered hook functions for declarative chain-style
321
- * context transformations (`user-prompt-submit` today).
309
+ * context transformations (`user-prompt-submit`, `post-tool-use`).
322
310
  *
323
311
  * @param name The hook identifier — pick one from {@link HOOKS}.
324
312
  * @param initialCtx Context the first hook receives.
@@ -9,10 +9,10 @@
9
9
  * closed-registration latch that protects `bootstrapPlugins()` from
10
10
  * late-arriving registrations.
11
11
  *
12
- * Registration is order-preserving: {@link getRegisteredPlugins},
13
- * {@link getMiddlewaresFor}, and (secondarily) {@link getInjectors} all reflect
14
- * the order in which {@link registerPlugin} was called, which in turn
15
- * determines onion order for middleware composition in the pipeline runner.
12
+ * Registration is order-preserving: {@link getRegisteredPlugins} and
13
+ * {@link getMiddlewaresFor} reflect the order in which {@link registerPlugin}
14
+ * was called, which in turn determines onion order for middleware composition
15
+ * in the pipeline runner.
16
16
  *
17
17
  * This module does not call `Plugin.init()` — that is the job of the
18
18
  * bootstrap (see PR 14). It also does not wire the registry into the daemon;
@@ -22,7 +22,6 @@
22
22
  */
23
23
 
24
24
  import {
25
- type Injector,
26
25
  type PipelineMiddlewareMap,
27
26
  type PipelineName,
28
27
  type Plugin,
@@ -47,7 +46,7 @@ const registeredPlugins = new Map<string, Plugin>();
47
46
  * top-level `await` later resolves and still tries to call
48
47
  * {@link registerPlugin}. Without the latch such a late arrival would land in
49
48
  * the registry after `bootstrapPlugins()` has already walked it, leaving the
50
- * plugin visible to `getMiddlewaresFor()` / `getInjectors()` with its
49
+ * plugin visible to `getMiddlewaresFor()` with its
51
50
  * `init()` hook never invoked.
52
51
  */
53
52
  let registrationClosed = false;
@@ -190,22 +189,6 @@ export function getHooksFor<TCtx = unknown>(
190
189
  return out;
191
190
  }
192
191
 
193
- /**
194
- * Flatten every registered plugin's `injectors` array and sort the result by
195
- * `order` ascending. Two injectors with the same `order` retain their relative
196
- * registration order (stable sort via `Array.prototype.sort`).
197
- */
198
- export function getInjectors(): Injector[] {
199
- const out: Injector[] = [];
200
- for (const plugin of registeredPlugins.values()) {
201
- if (plugin.injectors && plugin.injectors.length > 0) {
202
- out.push(...plugin.injectors);
203
- }
204
- }
205
- out.sort((a, b) => a.order - b.order);
206
- return out;
207
- }
208
-
209
192
  /**
210
193
  * Close the per-boot registration window. After this call, any attempt to
211
194
  * register a genuinely new plugin throws a {@link PluginExecutionError}.
@@ -226,9 +209,9 @@ export function closeRegistration(): void {
226
209
  /**
227
210
  * Remove a plugin from the registry. Invoked from the bootstrap's failure path
228
211
  * after {@link Plugin.onShutdown} and contribution teardown have run, so
229
- * {@link getMiddlewaresFor} and {@link getInjectors} no longer expose a
230
- * plugin whose `init()` aborted mid-bootstrap. Without this, every subsequent
231
- * pipeline invocation would re-enter the uninitialized plugin's middleware.
212
+ * {@link getMiddlewaresFor} no longer exposes a plugin whose `init()` aborted
213
+ * mid-bootstrap. Without this, every subsequent pipeline invocation would
214
+ * re-enter the uninitialized plugin's middleware.
232
215
  * Safe to call on an already-absent name (no-op).
233
216
  */
234
217
  export function unregisterPlugin(name: string): void {