@vellumai/assistant 0.8.7 → 0.8.8-dev.202606052332.17fc8ea

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 (570) hide show
  1. package/Dockerfile +20 -4
  2. package/bun.lock +2 -2
  3. package/docker-entrypoint.sh +4 -2
  4. package/docker-init-apt-root.sh +3 -1
  5. package/docker-kata-apt-env.sh +3 -1
  6. package/docker-kata-runtime-family.sh +12 -0
  7. package/docs/architecture/memory.md +1 -1
  8. package/examples/plugins/echo/README.md +61 -66
  9. package/examples/plugins/echo/hooks/post-tool-use.ts +18 -0
  10. package/examples/plugins/echo/hooks/stop.ts +16 -0
  11. package/examples/plugins/echo/hooks/user-prompt-submit.ts +18 -0
  12. package/examples/plugins/echo/package.json +1 -2
  13. package/examples/plugins/echo/src/emit.ts +19 -0
  14. package/node_modules/@vellumai/skill-host-contracts/src/server-message.ts +3 -3
  15. package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +7 -6
  16. package/openapi.yaml +3378 -335
  17. package/package.json +2 -2
  18. package/scripts/generate-openapi.ts +68 -41
  19. package/src/__tests__/agent-loop-exit-reason.test.ts +35 -93
  20. package/src/__tests__/agent-loop-provider-error-recording.test.ts +1 -1
  21. package/src/__tests__/agent-loop.test.ts +37 -87
  22. package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +2 -0
  23. package/src/__tests__/annotate-activity-metadata.test.ts +262 -0
  24. package/src/__tests__/annotate-risk-options.test.ts +2 -3
  25. package/src/__tests__/anthropic-provider.test.ts +95 -2
  26. package/src/__tests__/app-control-flow.test.ts +1 -1
  27. package/src/__tests__/app-dir-path-guard.test.ts +1 -0
  28. package/src/__tests__/approval-routes-http.test.ts +4 -1
  29. package/src/__tests__/assistant-event-hub.test.ts +25 -0
  30. package/src/__tests__/assistant-events-sse-shed.test.ts +8 -0
  31. package/src/__tests__/{conversation-stream-state.test.ts → assistant-stream-state.test.ts} +252 -91
  32. package/src/__tests__/auth-fallback-events-store.test.ts +116 -0
  33. package/src/__tests__/background-workers-disk-pressure.test.ts +6 -0
  34. package/src/__tests__/btw-routes.test.ts +62 -3
  35. package/src/__tests__/build-persisted-content.test.ts +184 -0
  36. package/src/__tests__/catalog-files.test.ts +1 -1
  37. package/src/__tests__/channel-approval-routes.test.ts +1 -1
  38. package/src/__tests__/channel-approvals.test.ts +1 -1
  39. package/src/__tests__/clawhub-files.test.ts +1 -1
  40. package/src/__tests__/compaction-circuit.test.ts +258 -0
  41. package/src/__tests__/compaction-direct.test.ts +132 -0
  42. package/src/__tests__/compaction.benchmark.test.ts +0 -30
  43. package/src/__tests__/config-watcher.test.ts +1 -1
  44. package/src/__tests__/conversation-abort-tool-results.test.ts +57 -19
  45. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +6 -5
  46. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +10 -7
  47. package/src/__tests__/conversation-agent-loop-overflow.test.ts +316 -1143
  48. package/src/__tests__/conversation-agent-loop.test.ts +638 -1655
  49. package/src/__tests__/conversation-analysis-routes.test.ts +6 -0
  50. package/src/__tests__/conversation-clean-command.test.ts +5 -2
  51. package/src/__tests__/conversation-history-web-search.test.ts +11 -1
  52. package/src/__tests__/conversation-pairing.test.ts +4 -31
  53. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +6 -0
  54. package/src/__tests__/conversation-provider-retry-repair.test.ts +30 -10
  55. package/src/__tests__/conversation-queue.test.ts +2 -0
  56. package/src/__tests__/conversation-routes-disk-view.test.ts +3 -0
  57. package/src/__tests__/conversation-routes-slash-commands.test.ts +6 -5
  58. package/src/__tests__/conversation-runtime-assembly.test.ts +310 -300
  59. package/src/__tests__/conversation-runtime-workspace.test.ts +105 -45
  60. package/src/__tests__/conversation-slash-commands.test.ts +8 -42
  61. package/src/__tests__/conversation-slash-queue.test.ts +6 -1
  62. package/src/__tests__/conversation-starter-routes.test.ts +14 -6
  63. package/src/__tests__/conversation-surfaces-action-delivery.test.ts +84 -0
  64. package/src/__tests__/conversation-sync-tags.test.ts +27 -15
  65. package/src/__tests__/conversation-title-service.test.ts +135 -2
  66. package/src/__tests__/conversation-workspace-cache-state.test.ts +17 -16
  67. package/src/__tests__/conversation-workspace-injection.test.ts +67 -2
  68. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +7 -6
  69. package/src/__tests__/conversations-import-system-filter.test.ts +101 -0
  70. package/src/__tests__/cross-provider-web-search.test.ts +214 -1
  71. package/src/__tests__/db-acp-history.test.ts +101 -0
  72. package/src/__tests__/db-schedule-syntax-migration.test.ts +5 -0
  73. package/src/__tests__/dm-persistence.test.ts +5 -1
  74. package/src/__tests__/dynamic-page-surface.test.ts +31 -0
  75. package/src/__tests__/empty-response-hook.test.ts +304 -0
  76. package/src/__tests__/feature-flag-test-helpers.ts +2 -2
  77. package/src/__tests__/file-write-tool.test.ts +63 -0
  78. package/src/__tests__/gateway-only-guard.test.ts +12 -2
  79. package/src/__tests__/gemini-image-service.test.ts +13 -0
  80. package/src/__tests__/guardian-grant-minting.test.ts +1 -1
  81. package/src/__tests__/guardian-routing-invariants.test.ts +2 -4
  82. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +1 -1
  83. package/src/__tests__/heartbeat-disk-pressure.test.ts +1 -0
  84. package/src/__tests__/heartbeat-service.test.ts +1 -0
  85. package/src/__tests__/helpers/mock-provider.ts +110 -0
  86. package/src/__tests__/helpers/native-web-search-harness.ts +129 -0
  87. package/src/__tests__/history-repair-hook.test.ts +1 -0
  88. package/src/__tests__/host-app-control-routes.test.ts +1 -1
  89. package/src/__tests__/host-cu-routes-targeted.test.ts +3 -3
  90. package/src/__tests__/identity-intro-cache.test.ts +12 -100
  91. package/src/__tests__/identity-routes.test.ts +248 -7
  92. package/src/__tests__/inbound-slack-persistence.test.ts +5 -1
  93. package/src/__tests__/injector-background-turn.test.ts +3 -9
  94. package/src/__tests__/injector-chain.test.ts +139 -275
  95. package/src/__tests__/injector-disk-pressure.test.ts +75 -41
  96. package/src/__tests__/injector-document-comments.test.ts +3 -3
  97. package/src/__tests__/injector-pkb-v2-silenced.test.ts +30 -22
  98. package/src/__tests__/injector-v3-suppression.test.ts +31 -37
  99. package/src/__tests__/internal-telemetry-routes.test.ts +109 -0
  100. package/src/__tests__/list-messages-hidden-metadata.test.ts +38 -0
  101. package/src/__tests__/list-messages-page-latest.test.ts +60 -0
  102. package/src/__tests__/list-messages-tool-merge.test.ts +20 -0
  103. package/src/__tests__/llm-usage-store.test.ts +223 -1
  104. package/src/__tests__/memory-retrieval-hook.test.ts +297 -0
  105. package/src/__tests__/memory-v2-static-injector.test.ts +103 -35
  106. package/src/__tests__/native-web-search.test.ts +191 -0
  107. package/src/__tests__/onboarding-template-contract.test.ts +2 -0
  108. package/src/__tests__/openai-image-service.test.ts +17 -0
  109. package/src/__tests__/openai-provider.test.ts +31 -1
  110. package/src/__tests__/{overflow-reduce-pipeline.test.ts → overflow-reduction-loop.test.ts} +64 -284
  111. package/src/__tests__/persist-unsendable-image.test.ts +215 -0
  112. package/src/__tests__/persistence-secret-redaction.test.ts +1 -0
  113. package/src/__tests__/pkb-autoinject.test.ts +2 -5
  114. package/src/__tests__/plugin-api-shim.test.ts +3 -6
  115. package/src/__tests__/plugin-bootstrap.test.ts +14 -40
  116. package/src/__tests__/plugin-registry.test.ts +3 -76
  117. package/src/__tests__/plugin-types.test.ts +0 -193
  118. package/src/__tests__/process-message-display-content.test.ts +6 -2
  119. package/src/__tests__/reaction-persistence.test.ts +1 -1
  120. package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +5 -1
  121. package/src/__tests__/resolve-trust-class.test.ts +4 -4
  122. package/src/__tests__/runtime-events-sse-reconnect.test.ts +60 -23
  123. package/src/__tests__/schedule-routes.test.ts +603 -2
  124. package/src/__tests__/schedule-store.test.ts +41 -0
  125. package/src/__tests__/schedule-tools.test.ts +35 -0
  126. package/src/__tests__/send-endpoint-busy.test.ts +4 -1
  127. package/src/__tests__/server-history-render.test.ts +314 -1
  128. package/src/__tests__/skill-feature-flags-integration.test.ts +33 -0
  129. package/src/__tests__/skillssh-files.test.ts +1 -1
  130. package/src/__tests__/subagent-call-site-routing.test.ts +1 -1
  131. package/src/__tests__/subagent-fork-notifications.test.ts +1 -3
  132. package/src/__tests__/subagent-fork-spawn.test.ts +1 -1
  133. package/src/__tests__/subagent-manager-notify.test.ts +1 -3
  134. package/src/__tests__/subagent-notify-parent.test.ts +1 -3
  135. package/src/__tests__/subagent-spawn-tool-fork.test.ts +1 -1
  136. package/src/__tests__/system-prompt.test.ts +20 -0
  137. package/src/__tests__/task-scheduler.test.ts +162 -1
  138. package/src/__tests__/terminal-tools.test.ts +6 -1
  139. package/src/__tests__/title-generate-hook.test.ts +319 -0
  140. package/src/__tests__/tool-error-hook.test.ts +278 -0
  141. package/src/__tests__/tool-preview-lifecycle.test.ts +468 -5
  142. package/src/__tests__/tool-result-metadata-plumbing.test.ts +1 -0
  143. package/src/__tests__/tool-result-truncate-hook.test.ts +127 -0
  144. package/src/__tests__/tool-result-truncation.test.ts +0 -2
  145. package/src/__tests__/ui-choice-copy-surfaces.test.ts +254 -0
  146. package/src/__tests__/ui-work-result-surface.test.ts +159 -0
  147. package/src/__tests__/usage-routes.test.ts +285 -1
  148. package/src/__tests__/user-plugin-loader.test.ts +54 -286
  149. package/src/__tests__/voice-session-bridge.test.ts +6 -3
  150. package/src/__tests__/web-search-backend-failure.test.ts +166 -0
  151. package/src/acp/__tests__/agent-process.test.ts +161 -0
  152. package/src/acp/__tests__/client-handler.test.ts +40 -0
  153. package/src/acp/__tests__/helpers/acp-history-db.ts +82 -0
  154. package/src/acp/__tests__/helpers/exec-file-stub.ts +101 -0
  155. package/src/acp/__tests__/prepare-agent-env.test.ts +137 -0
  156. package/src/acp/__tests__/session-manager-persistence.test.ts +95 -28
  157. package/src/acp/__tests__/session-manager-resume.test.ts +736 -0
  158. package/src/acp/agent-process.ts +61 -1
  159. package/src/acp/auto-install.test.ts +196 -0
  160. package/src/acp/auto-install.ts +177 -0
  161. package/src/acp/client-handler.ts +31 -0
  162. package/src/acp/feature-gate.test.ts +48 -0
  163. package/src/acp/feature-gate.ts +34 -0
  164. package/src/acp/prepare-agent-env.ts +83 -29
  165. package/src/acp/resolve-agent.test.ts +320 -7
  166. package/src/acp/resolve-agent.ts +182 -18
  167. package/src/acp/resume-hint.ts +25 -0
  168. package/src/acp/session-manager.ts +495 -73
  169. package/src/acp/types.ts +8 -0
  170. package/src/agent/compaction-circuit.ts +60 -102
  171. package/src/agent/loop.ts +362 -485
  172. package/src/api/events/assistant-thinking-delta.ts +33 -0
  173. package/src/api/events/tool-output-chunk.ts +45 -0
  174. package/src/api/events/tool-use-preview-start.ts +32 -0
  175. package/src/api/events/trace-event.ts +69 -0
  176. package/src/api/index.ts +48 -13
  177. package/src/api/responses/conversation-message.ts +374 -0
  178. package/src/approvals/guardian-request-resolvers.ts +1 -1
  179. package/src/avatar/__tests__/avatar-store.test.ts +34 -29
  180. package/src/background-wake/next-wake.ts +1 -0
  181. package/src/cli/commands/__tests__/notifications.test.ts +58 -14
  182. package/src/cli/commands/notifications.ts +112 -60
  183. package/src/config/__tests__/feature-flag-registry-guard.test.ts +2 -2
  184. package/src/config/acp-defaults.test.ts +10 -0
  185. package/src/config/acp-defaults.ts +6 -0
  186. package/src/config/assistant-feature-flags.ts +22 -11
  187. package/src/config/bundled-skills/acp/SKILL.md +83 -31
  188. package/src/config/bundled-skills/acp/TOOLS.json +4 -4
  189. package/src/config/bundled-skills/app-builder/SKILL.md +224 -398
  190. package/src/config/bundled-skills/app-builder/TOOLS.json +29 -0
  191. package/src/config/bundled-skills/app-builder/references/DESIGN_SYSTEM.md +48 -0
  192. package/src/config/bundled-skills/app-builder/references/RESPONSIVE.md +57 -0
  193. package/src/config/bundled-skills/app-builder/references/SLIDES.md +38 -0
  194. package/src/config/bundled-skills/app-builder/references/examples/README.md +17 -0
  195. package/src/config/bundled-skills/app-builder/references/examples/expense-tracker.md +515 -0
  196. package/src/config/bundled-skills/app-builder/references/examples/focus-timer.md +342 -0
  197. package/src/config/bundled-skills/app-builder/references/examples/habit-tracker.md +490 -0
  198. package/src/config/bundled-skills/app-builder/tools/app-list.ts +62 -0
  199. package/src/config/bundled-skills/document-editor/SKILL.md +28 -23
  200. package/src/config/bundled-skills/document-editor/TOOLS.json +1 -1
  201. package/src/config/bundled-skills/messaging/SKILL.md +0 -7
  202. package/src/config/bundled-tool-registry.ts +2 -0
  203. package/src/config/feature-flag-cache.ts +3 -3
  204. package/src/config/feature-flag-registry.json +48 -7
  205. package/src/config/schemas/__tests__/memory-v2.test.ts +1 -0
  206. package/src/config/schemas/__tests__/memory-v3.test.ts +25 -0
  207. package/src/config/schemas/heartbeat.ts +9 -0
  208. package/src/config/schemas/llm.ts +1 -0
  209. package/src/config/schemas/memory-v2.ts +8 -0
  210. package/src/config/schemas/memory-v3.ts +8 -0
  211. package/src/config/schemas/platform.ts +8 -0
  212. package/src/config/seed-inference-profiles.ts +2 -2
  213. package/src/config/skills.ts +13 -0
  214. package/src/context/compactor.ts +1 -1
  215. package/src/context/strip-injections.ts +128 -0
  216. package/src/context/token-estimator.ts +23 -0
  217. package/src/context/tool-result-truncation.ts +0 -23
  218. package/src/context/window-manager.ts +5 -7
  219. package/src/credential-execution/executable-discovery.ts +16 -0
  220. package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +6 -0
  221. package/src/daemon/__tests__/inference-profile-notification.test.ts +153 -0
  222. package/src/daemon/__tests__/native-web-search-metadata.test.ts +10 -8
  223. package/src/daemon/assistant-attachments.ts +1 -1
  224. package/src/daemon/config-watcher.ts +2 -2
  225. package/src/daemon/context-overflow-reducer.ts +0 -1
  226. package/src/daemon/conversation-agent-loop-handlers.ts +594 -153
  227. package/src/daemon/conversation-agent-loop.ts +301 -997
  228. package/src/daemon/conversation-history.ts +5 -4
  229. package/src/daemon/conversation-lifecycle.ts +3 -4
  230. package/src/daemon/conversation-messaging.ts +7 -6
  231. package/src/daemon/conversation-process.ts +11 -16
  232. package/src/daemon/conversation-registry.ts +159 -0
  233. package/src/daemon/conversation-runtime-assembly.ts +218 -398
  234. package/src/daemon/conversation-slash.ts +6 -25
  235. package/src/daemon/conversation-store.ts +9 -90
  236. package/src/daemon/conversation-surfaces.ts +222 -4
  237. package/src/daemon/conversation-tool-setup.ts +2 -29
  238. package/src/daemon/conversation-workspace.ts +17 -0
  239. package/src/daemon/conversation.ts +32 -20
  240. package/src/daemon/external-plugins-bootstrap.ts +17 -18
  241. package/src/daemon/handlers/config-a2a.ts +51 -36
  242. package/src/daemon/handlers/config-slack-channel.ts +20 -14
  243. package/src/daemon/handlers/config-telegram.ts +16 -2
  244. package/src/daemon/handlers/conversations.ts +3 -1
  245. package/src/daemon/handlers/shared.ts +156 -84
  246. package/src/daemon/handlers/skills.ts +42 -10
  247. package/src/daemon/lifecycle.ts +25 -0
  248. package/src/daemon/message-types/apps.ts +1 -29
  249. package/src/daemon/message-types/messages.ts +9 -57
  250. package/src/daemon/message-types/skills.ts +2 -0
  251. package/src/daemon/message-types/surfaces.ts +136 -3
  252. package/src/daemon/now-scratchpad.ts +21 -0
  253. package/src/daemon/orphan-reaper.test.ts +210 -0
  254. package/src/daemon/orphan-reaper.ts +240 -0
  255. package/src/daemon/overflow-reduction-loop.ts +230 -0
  256. package/src/daemon/persist-unsendable-image.ts +117 -0
  257. package/src/daemon/process-message.ts +1 -3
  258. package/src/daemon/server.ts +2 -0
  259. package/src/daemon/trace-emitter.ts +6 -4
  260. package/src/daemon/trust-context.ts +19 -0
  261. package/src/daemon/wake-target-adapter.ts +3 -1
  262. package/src/heartbeat/__tests__/heartbeat-service.test.ts +3 -0
  263. package/src/heartbeat/heartbeat-run-store.ts +23 -1
  264. package/src/heartbeat/heartbeat-service.ts +26 -0
  265. package/src/home/home-greeting-cache.ts +24 -1
  266. package/src/ipc/__tests__/browser-ipc.test.ts +1 -1
  267. package/src/ipc/__tests__/ui-request-route.test.ts +3 -3
  268. package/src/ipc/gateway-client.test.ts +2 -2
  269. package/src/ipc/gateway-client.ts +3 -3
  270. package/src/ipc/skill-routes/__tests__/memory.test.ts +15 -0
  271. package/src/ipc/skill-routes/memory.ts +4 -2
  272. package/src/media/gemini-image-service.ts +15 -0
  273. package/src/media/openai-image-service.ts +14 -0
  274. package/src/media/types.ts +34 -0
  275. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +56 -0
  276. package/src/memory/auth-fallback-events-store.ts +94 -0
  277. package/src/memory/conversation-starter-checkpoints.ts +1 -0
  278. package/src/memory/conversation-title-service.ts +65 -41
  279. package/src/memory/db-init.ts +6 -0
  280. package/src/memory/graph/__tests__/conversation-graph-memory-registry.test.ts +119 -0
  281. package/src/memory/graph/conversation-graph-memory.ts +65 -0
  282. package/src/memory/job-handlers/conversation-starters.ts +13 -2
  283. package/src/memory/jobs-store.ts +33 -0
  284. package/src/memory/jobs-worker.ts +32 -5
  285. package/src/memory/llm-usage-store.ts +224 -50
  286. package/src/memory/migrations/222-strip-placeholder-sentinels-from-messages.ts +6 -5
  287. package/src/memory/migrations/270-schedule-source-conversation.ts +13 -0
  288. package/src/memory/migrations/271-create-auth-fallback-events.ts +21 -0
  289. package/src/memory/migrations/272-acp-session-history-cwd.ts +36 -0
  290. package/src/memory/migrations/index.ts +3 -0
  291. package/src/memory/pkb/autoinject.ts +61 -0
  292. package/src/memory/pkb/context.ts +50 -0
  293. package/src/memory/pkb/types.ts +14 -0
  294. package/src/memory/schedule-attribution-sql.ts +104 -0
  295. package/src/memory/schema/acp.ts +4 -0
  296. package/src/memory/schema/infrastructure.ts +16 -0
  297. package/src/memory/usage-grouped-buckets.ts +6 -1
  298. package/src/memory/v2/__tests__/consolidation-job.test.ts +4 -4
  299. package/src/memory/v2/consolidation-job.ts +14 -5
  300. package/src/notifications/conversation-pairing.ts +8 -15
  301. package/src/notifications/decision-engine.ts +6 -3
  302. package/src/notifications/home-feed-side-effect.ts +12 -1
  303. package/src/permissions/prompter.ts +4 -0
  304. package/src/plugin-api/constants.ts +4 -0
  305. package/src/plugin-api/index.ts +7 -5
  306. package/src/plugin-api/types.ts +151 -1
  307. package/src/plugins/defaults/compaction/compact.ts +59 -0
  308. package/src/plugins/defaults/compaction/package.json +1 -1
  309. package/src/plugins/defaults/compaction/register.ts +8 -19
  310. package/src/plugins/defaults/empty-response/hooks/stop.ts +126 -0
  311. package/src/plugins/defaults/empty-response/register.ts +8 -13
  312. package/src/plugins/defaults/index.ts +2 -18
  313. package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +95 -0
  314. package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit-temp.ts +216 -0
  315. package/src/plugins/defaults/memory-retrieval/injector-chain.ts +35 -0
  316. package/src/plugins/defaults/{injectors/register.ts → memory-retrieval/injectors.ts} +288 -81
  317. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/assign.test.ts +4 -4
  318. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/health.test.ts +16 -0
  319. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/live-integration.test.ts +4 -4
  320. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/maintain-job.test.ts +5 -5
  321. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/orchestrate.test.ts +48 -12
  322. package/src/plugins/defaults/memory-v3-shadow/__tests__/provider-blocks.test.ts +13 -0
  323. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/reconcile.test.ts +2 -2
  324. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/render-injection.test.ts +1 -1
  325. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/router.test.ts +104 -32
  326. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/selection-log-store.test.ts +8 -8
  327. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/selector.test.ts +96 -30
  328. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/shadow-plugin.test.ts +34 -16
  329. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/assign.ts +5 -5
  330. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/capabilities.ts +2 -2
  331. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/health.ts +0 -0
  332. package/src/plugins/defaults/memory-v3-shadow/hooks/post-compact.ts +14 -0
  333. package/src/plugins/defaults/memory-v3-shadow/hooks/user-prompt-submit.ts +19 -0
  334. package/src/plugins/defaults/memory-v3-shadow/injector.ts +75 -0
  335. package/src/plugins/defaults/memory-v3-shadow/llm-retry.ts +32 -0
  336. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/maintain-job.ts +8 -8
  337. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/orchestrate.ts +26 -14
  338. package/src/plugins/defaults/{llm-call → memory-v3-shadow}/package.json +2 -2
  339. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/page-content.ts +2 -2
  340. package/src/plugins/defaults/memory-v3-shadow/provider-blocks.ts +26 -0
  341. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/reconcile.ts +3 -3
  342. package/src/plugins/defaults/memory-v3-shadow/register.ts +26 -0
  343. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/render-injection.ts +1 -1
  344. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/router.ts +51 -45
  345. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/selection-log-store.ts +4 -4
  346. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/selector.ts +61 -46
  347. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/shadow-plugin.ts +69 -99
  348. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/tree.ts +1 -1
  349. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/types.ts +8 -0
  350. package/src/plugins/defaults/title-generate/hooks/stop.ts +75 -0
  351. package/src/plugins/defaults/title-generate/hooks/user-prompt-submit.ts +35 -0
  352. package/src/plugins/defaults/title-generate/package.json +1 -1
  353. package/src/plugins/defaults/title-generate/register.ts +18 -18
  354. package/src/plugins/defaults/tool-error/hooks/post-tool-use.ts +118 -0
  355. package/src/plugins/defaults/tool-error/package.json +1 -1
  356. package/src/plugins/defaults/tool-error/register.ts +9 -21
  357. package/src/plugins/defaults/tool-result-truncate/hooks/post-tool-use.ts +32 -0
  358. package/src/plugins/defaults/tool-result-truncate/register.ts +10 -21
  359. package/src/plugins/defaults/tool-result-truncate/terminal.ts +37 -18
  360. package/src/plugins/external-api.ts +2 -2
  361. package/src/plugins/pipeline.ts +6 -305
  362. package/src/plugins/registry.ts +10 -55
  363. package/src/plugins/types.ts +62 -797
  364. package/src/plugins/user-loader.ts +30 -127
  365. package/src/proactive-artifact/aux-message-injector.ts +4 -4
  366. package/src/proactive-artifact/job.test.ts +8 -13
  367. package/src/prompts/__tests__/system-prompt.test.ts +42 -0
  368. package/src/prompts/templates/BOOTSTRAP-ACTIVATION-RAIL.md +64 -0
  369. package/src/prompts/templates/BOOTSTRAP.md +2 -2
  370. package/src/prompts/templates/system-sections.ts +15 -0
  371. package/src/providers/anthropic/client.ts +37 -29
  372. package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +112 -0
  373. package/src/providers/openai/chat-completions-provider.ts +44 -0
  374. package/src/providers/openrouter/client.ts +1 -0
  375. package/src/providers/placeholder-sentinels.ts +35 -0
  376. package/src/runtime/__tests__/agent-wake.test.ts +10 -6
  377. package/src/runtime/__tests__/interactive-ui.test.ts +1 -1
  378. package/src/runtime/agent-wake.ts +2 -5
  379. package/src/runtime/assistant-event-hub.ts +37 -7
  380. package/src/runtime/{conversation-stream-state.ts → assistant-stream-state.ts} +132 -58
  381. package/src/runtime/channel-approvals.ts +1 -1
  382. package/src/runtime/http-router.ts +16 -21
  383. package/src/runtime/http-types.ts +16 -70
  384. package/src/runtime/interactive-ui.ts +1 -1
  385. package/src/runtime/pending-interactions.ts +1 -0
  386. package/src/runtime/routes/__tests__/acp-routes.test.ts +283 -55
  387. package/src/runtime/routes/__tests__/consolidation-routes.test.ts +265 -2
  388. package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +1 -1
  389. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +31 -1
  390. package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +6 -2
  391. package/src/runtime/routes/__tests__/surface-action-routes.test.ts +5 -4
  392. package/src/runtime/routes/__tests__/surface-content-routes.test.ts +4 -1
  393. package/src/runtime/routes/__tests__/tts-routes.test.ts +6 -2
  394. package/src/runtime/routes/acp-routes.test.ts +89 -25
  395. package/src/runtime/routes/acp-routes.ts +81 -29
  396. package/src/runtime/routes/app-management-routes.ts +6 -117
  397. package/src/runtime/routes/app-routes.ts +13 -15
  398. package/src/runtime/routes/approval-routes.ts +1 -1
  399. package/src/runtime/routes/attachment-routes.ts +26 -15
  400. package/src/runtime/routes/avatar-routes.ts +26 -0
  401. package/src/runtime/routes/browser-routes.ts +1 -1
  402. package/src/runtime/routes/browser-tabs-routes.ts +6 -10
  403. package/src/runtime/routes/btw-routes.ts +29 -23
  404. package/src/runtime/routes/consolidation-routes.ts +120 -20
  405. package/src/runtime/routes/conversation-cli-routes.ts +1 -1
  406. package/src/runtime/routes/conversation-list-routes.ts +1 -1
  407. package/src/runtime/routes/conversation-query-routes.ts +3 -1
  408. package/src/runtime/routes/conversation-routes.ts +372 -185
  409. package/src/runtime/routes/conversation-starter-routes.ts +13 -7
  410. package/src/runtime/routes/conversations-import-routes.ts +24 -7
  411. package/src/runtime/routes/documents-routes.ts +4 -0
  412. package/src/runtime/routes/domain-routes.ts +51 -37
  413. package/src/runtime/routes/epoch-millis-range.ts +34 -0
  414. package/src/runtime/routes/events-routes.ts +28 -34
  415. package/src/runtime/routes/gateway-log-routes.ts +26 -4
  416. package/src/runtime/routes/heartbeat-routes.ts +32 -12
  417. package/src/runtime/routes/host-app-control-routes.ts +1 -1
  418. package/src/runtime/routes/host-cu-routes.ts +1 -1
  419. package/src/runtime/routes/identity-intro-cache.ts +11 -34
  420. package/src/runtime/routes/identity-routes.ts +224 -18
  421. package/src/runtime/routes/image-generation-routes.ts +40 -2
  422. package/src/runtime/routes/inbound-message-handler.ts +1 -1
  423. package/src/runtime/routes/index.ts +2 -0
  424. package/src/runtime/routes/integrations/a2a.ts +12 -10
  425. package/src/runtime/routes/integrations/slack/__tests__/channel.test.ts +16 -0
  426. package/src/runtime/routes/integrations/slack/channel.ts +4 -0
  427. package/src/runtime/routes/integrations/slack/share.ts +27 -6
  428. package/src/runtime/routes/integrations/telegram.ts +6 -0
  429. package/src/runtime/routes/integrations/twilio.ts +42 -0
  430. package/src/runtime/routes/internal-telemetry-routes.ts +88 -0
  431. package/src/runtime/routes/log-export-routes.ts +8 -0
  432. package/src/runtime/routes/memory-v2-routes.ts +15 -8
  433. package/src/runtime/routes/memory-v3-routes.ts +66 -34
  434. package/src/runtime/routes/oauth-apps.ts +66 -12
  435. package/src/runtime/routes/oauth-providers.ts +44 -5
  436. package/src/runtime/routes/platform-routes.ts +81 -5
  437. package/src/runtime/routes/playground/__tests__/force-compact.test.ts +6 -4
  438. package/src/runtime/routes/playground/force-compact.ts +1 -1
  439. package/src/runtime/routes/playground/helpers.ts +1 -1
  440. package/src/runtime/routes/rename-conversation-routes.ts +5 -0
  441. package/src/runtime/routes/schedule-routes.ts +152 -42
  442. package/src/runtime/routes/secret-routes.ts +14 -2
  443. package/src/runtime/routes/skills-routes.ts +43 -14
  444. package/src/runtime/routes/surface-conversation-resolver.ts +4 -3
  445. package/src/runtime/routes/tool-call-confirmation-enrichment.test.ts +161 -0
  446. package/src/runtime/routes/tool-call-confirmation-enrichment.ts +107 -0
  447. package/src/runtime/routes/trust-rules-routes.ts +26 -2
  448. package/src/runtime/routes/tts-routes.ts +35 -0
  449. package/src/runtime/routes/types.ts +66 -8
  450. package/src/runtime/routes/usage-routes.ts +47 -39
  451. package/src/runtime/routes/webhook-routes.ts +41 -2
  452. package/src/runtime/routes/work-items-routes.ts +2 -4
  453. package/src/runtime/routes/workspace-routes.ts +4 -0
  454. package/src/runtime/services/__tests__/analyze-conversation.test.ts +6 -0
  455. package/src/runtime/services/analyze-conversation.ts +2 -2
  456. package/src/runtime/services/conversation-serializer.ts +1 -1
  457. package/src/schedule/schedule-store.ts +20 -1
  458. package/src/schedule/schedule-usage-store.ts +83 -0
  459. package/src/schedule/scheduler.ts +12 -5
  460. package/src/signals/cancel.ts +2 -4
  461. package/src/skills/catalog-files.ts +2 -2
  462. package/src/skills/catalog-install.ts +3 -0
  463. package/src/skills/categories-cache.ts +118 -0
  464. package/src/skills/clawhub-files.ts +1 -2
  465. package/src/skills/skillssh-files.ts +1 -2
  466. package/src/subagent/manager.ts +17 -5
  467. package/src/telemetry/types.ts +29 -1
  468. package/src/telemetry/usage-telemetry-reporter.test.ts +112 -3
  469. package/src/telemetry/usage-telemetry-reporter.ts +57 -2
  470. package/src/tools/acp/context.ts +20 -0
  471. package/src/tools/acp/list-agents.test.ts +7 -1
  472. package/src/tools/acp/spawn.test.ts +158 -55
  473. package/src/tools/acp/spawn.ts +47 -72
  474. package/src/tools/acp/steer.test.ts +105 -8
  475. package/src/tools/acp/steer.ts +48 -17
  476. package/src/tools/apps/executors.ts +13 -8
  477. package/src/tools/executor.ts +1 -53
  478. package/src/tools/filesystem/write.ts +34 -0
  479. package/src/tools/network/__tests__/web-search-metadata.test.ts +7 -1
  480. package/src/tools/network/__tests__/web-search.test.ts +11 -3
  481. package/src/tools/network/web-search-error.test.ts +248 -0
  482. package/src/tools/network/web-search-error.ts +267 -0
  483. package/src/tools/network/web-search.ts +207 -48
  484. package/src/tools/schedule/create.ts +2 -0
  485. package/src/tools/subagent/spawn.ts +2 -4
  486. package/src/tools/terminal/safe-env.ts +10 -1
  487. package/src/tools/ui-surface/definitions.ts +34 -5
  488. package/src/tts/__tests__/provider-catalog-consistency.test.ts +85 -1
  489. package/src/tts/provider-catalog.ts +76 -1
  490. package/src/util/mutex.ts +47 -0
  491. package/src/workspace/git-service.ts +1 -42
  492. package/src/workspace/migrations/051-seed-conversation-summarization-callsite.ts +4 -5
  493. package/src/workspace/migrations/095-bump-heartbeat-interval-30m-to-60m.ts +51 -0
  494. package/src/workspace/migrations/096-reduce-quality-profile-effort.ts +72 -0
  495. package/src/workspace/migrations/097-enable-adaptive-thinking-managed-profiles.ts +117 -0
  496. package/src/workspace/migrations/registry.ts +6 -0
  497. package/docs/plugins.md +0 -836
  498. package/examples/plugins/echo/register.ts +0 -184
  499. package/src/__tests__/bootstrap-turn-cleanup.test.ts +0 -44
  500. package/src/__tests__/circuit-breaker-pipeline.test.ts +0 -405
  501. package/src/__tests__/compaction-pipeline.test.ts +0 -210
  502. package/src/__tests__/compaction-timeout-recovery.test.ts +0 -251
  503. package/src/__tests__/empty-response-pipeline.test.ts +0 -423
  504. package/src/__tests__/llm-call-pipeline.test.ts +0 -287
  505. package/src/__tests__/memory-retrieval-pipeline.test.ts +0 -418
  506. package/src/__tests__/persistence-pipeline.test.ts +0 -503
  507. package/src/__tests__/pipeline-runner.test.ts +0 -564
  508. package/src/__tests__/title-generate-pipeline.test.ts +0 -211
  509. package/src/__tests__/token-estimate-pipeline.test.ts +0 -479
  510. package/src/__tests__/tool-error-pipeline.test.ts +0 -241
  511. package/src/__tests__/tool-execute-pipeline.test.ts +0 -417
  512. package/src/__tests__/tool-result-truncate-pipeline.test.ts +0 -341
  513. package/src/daemon/bootstrap-turn-cleanup.ts +0 -45
  514. package/src/gallery/default-gallery.ts +0 -1359
  515. package/src/gallery/gallery-manifest.ts +0 -28
  516. package/src/home/feature-gate.ts +0 -22
  517. package/src/memory/v3/provider-blocks.ts +0 -16
  518. package/src/plugins/defaults/circuit-breaker/middlewares/circuitBreaker.ts +0 -93
  519. package/src/plugins/defaults/circuit-breaker/package.json +0 -15
  520. package/src/plugins/defaults/circuit-breaker/register.ts +0 -39
  521. package/src/plugins/defaults/compaction/middlewares/compaction.ts +0 -25
  522. package/src/plugins/defaults/compaction/terminal.ts +0 -73
  523. package/src/plugins/defaults/empty-response/middlewares/emptyResponse.ts +0 -22
  524. package/src/plugins/defaults/empty-response/terminal.ts +0 -106
  525. package/src/plugins/defaults/injectors/package.json +0 -15
  526. package/src/plugins/defaults/llm-call/middlewares/llmCall.ts +0 -17
  527. package/src/plugins/defaults/llm-call/register.ts +0 -45
  528. package/src/plugins/defaults/memory-retrieval/middlewares/memoryRetrieval.ts +0 -17
  529. package/src/plugins/defaults/memory-retrieval/package.json +0 -15
  530. package/src/plugins/defaults/memory-retrieval/register.ts +0 -181
  531. package/src/plugins/defaults/overflow-reduce/middlewares/overflowReduce.ts +0 -126
  532. package/src/plugins/defaults/overflow-reduce/package.json +0 -15
  533. package/src/plugins/defaults/overflow-reduce/register.ts +0 -42
  534. package/src/plugins/defaults/persistence/middlewares/persistence.ts +0 -19
  535. package/src/plugins/defaults/persistence/package.json +0 -15
  536. package/src/plugins/defaults/persistence/register.ts +0 -38
  537. package/src/plugins/defaults/persistence/terminal.ts +0 -83
  538. package/src/plugins/defaults/title-generate/terminal.ts +0 -31
  539. package/src/plugins/defaults/token-estimate/middlewares/tokenEstimate.ts +0 -23
  540. package/src/plugins/defaults/token-estimate/package.json +0 -15
  541. package/src/plugins/defaults/token-estimate/register.ts +0 -34
  542. package/src/plugins/defaults/token-estimate/terminal.ts +0 -40
  543. package/src/plugins/defaults/tool-error/middlewares/toolError.ts +0 -21
  544. package/src/plugins/defaults/tool-error/terminal.ts +0 -47
  545. package/src/plugins/defaults/tool-execute/middlewares/toolExecute.ts +0 -23
  546. package/src/plugins/defaults/tool-execute/package.json +0 -15
  547. package/src/plugins/defaults/tool-execute/register.ts +0 -49
  548. package/src/plugins/defaults/tool-result-truncate/middlewares/toolResultTruncate.ts +0 -23
  549. package/src/plugins/defaults/tool-result-truncate/types.ts +0 -22
  550. package/src/skills/category-inference.ts +0 -111
  551. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/capabilities.test.ts +0 -0
  552. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/core.test.ts +0 -0
  553. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/fixtures/eval-turns.json +0 -0
  554. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/fixtures/live-turns.json +0 -0
  555. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/needle.test.ts +0 -0
  556. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/snapshot.test.ts +0 -0
  557. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/tree.test.ts +0 -0
  558. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/types.test.ts +0 -0
  559. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/working-set-eviction.test.ts +0 -0
  560. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/working-set-skeleton.test.ts +0 -0
  561. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/core.ts +0 -0
  562. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/README.md +0 -0
  563. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/assignments.json +0 -0
  564. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/core.json +0 -0
  565. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-a/topic-x.md +0 -0
  566. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-a/topic-y.md +0 -0
  567. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-b/topic-z.md +0 -0
  568. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/needle.ts +0 -0
  569. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/snapshot.ts +0 -0
  570. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/working-set.ts +0 -0
@@ -73,14 +73,15 @@ function buildCsp(scriptSrc: string): string {
73
73
  ].join("; ");
74
74
  }
75
75
 
76
- function servePageHeaders({ pathParams }: ResponseHeaderArgs): Record<string, string> {
76
+ function servePageHeaders({
77
+ pathParams,
78
+ }: ResponseHeaderArgs): Record<string, string> {
77
79
  const appId = pathParams?.appId as string;
78
80
  const app = getApp(appId);
79
81
  // Multifile apps use external scripts — no 'unsafe-inline' for script-src.
80
82
  // Legacy apps contain inline event handlers that require 'unsafe-inline'.
81
- const scriptSrc = app && isMultifileApp(app)
82
- ? "'self'"
83
- : "'self' 'unsafe-inline'";
83
+ const scriptSrc =
84
+ app && isMultifileApp(app) ? "'self'" : "'self' 'unsafe-inline'";
84
85
  return {
85
86
  "Content-Type": "text/html; charset=utf-8",
86
87
  "Content-Security-Policy": buildCsp(scriptSrc),
@@ -186,9 +187,7 @@ const DIST_CONTENT_TYPES: Record<string, string> = {
186
187
  * Serve a static file from an app's dist/ directory.
187
188
  * Validates the filename to prevent path traversal.
188
189
  */
189
- function handleServeDistFile({
190
- pathParams,
191
- }: RouteHandlerArgs): Uint8Array {
190
+ function handleServeDistFile({ pathParams }: RouteHandlerArgs): Uint8Array {
192
191
  const appId = pathParams?.appId as string;
193
192
  const filename = pathParams?.filename as string;
194
193
 
@@ -225,9 +224,7 @@ function handleServeDistFile({
225
224
  /** 50 MB — generous cap for zip app bundles. */
226
225
  const MAX_SHARE_BODY_BYTES = 50 * 1024 * 1024;
227
226
 
228
- async function handleShareApp({
229
- rawBody,
230
- }: RouteHandlerArgs): Promise<{
227
+ async function handleShareApp({ rawBody }: RouteHandlerArgs): Promise<{
231
228
  shareToken: string;
232
229
  shareUrl: string;
233
230
  bundleSizeBytes: number;
@@ -275,9 +272,7 @@ async function handleShareApp({
275
272
  };
276
273
  }
277
274
 
278
- function handleDownloadSharedApp({
279
- pathParams,
280
- }: RouteHandlerArgs): Uint8Array {
275
+ function handleDownloadSharedApp({ pathParams }: RouteHandlerArgs): Uint8Array {
281
276
  const shareToken = pathParams?.token as string;
282
277
  const record = getSharedAppLink(shareToken);
283
278
  if (!record) {
@@ -348,8 +343,7 @@ export const ROUTES: RouteDefinition[] = [
348
343
  allowedPrincipalTypes: ACTOR_PRINCIPALS,
349
344
  },
350
345
  summary: "Serve app dist file",
351
- description:
352
- "Serve a static asset from an app's compiled dist/ directory.",
346
+ description: "Serve a static asset from an app's compiled dist/ directory.",
353
347
  tags: ["apps"],
354
348
  responseHeaders: ({ pathParams }) => ({
355
349
  "Content-Type":
@@ -411,6 +405,10 @@ export const ROUTES: RouteDefinition[] = [
411
405
  "Content-Type": "application/zip",
412
406
  "Content-Disposition": 'attachment; filename="app.vellum"',
413
407
  },
408
+ responseBody: {
409
+ contentType: "application/zip",
410
+ schema: { type: "string", format: "binary" },
411
+ },
414
412
  handler: handleDownloadSharedApp,
415
413
  },
416
414
  {
@@ -9,7 +9,7 @@
9
9
  */
10
10
  import { z } from "zod";
11
11
 
12
- import { findConversation } from "../../daemon/conversation-store.js";
12
+ import { findConversation } from "../../daemon/conversation-registry.js";
13
13
  import { getConversationByKey } from "../../memory/conversation-key-store.js";
14
14
  import type { UserDecision } from "../../permissions/types.js";
15
15
  import { getLogger } from "../../util/logger.js";
@@ -663,6 +663,10 @@ export const ROUTES: RouteDefinition[] = [
663
663
  "Serve raw file bytes for an attachment. Supports Range headers.",
664
664
  tags: ["attachments"],
665
665
  responseStatus: ({ headers }) => (headers?.["range"] ? "206" : "200"),
666
+ responseBody: {
667
+ contentType: "application/octet-stream",
668
+ schema: { type: "string", format: "binary" },
669
+ },
666
670
  additionalResponses: {
667
671
  "416": { description: "Range Not Satisfiable" },
668
672
  },
@@ -719,21 +723,28 @@ export const ROUTES: RouteDefinition[] = [
719
723
  description:
720
724
  "Upload an attachment. Supports application/json (base64 data or file path reference), multipart/form-data (file + filename + mimeType fields), and application/octet-stream (raw bytes with filename and mimeType query params).",
721
725
  tags: ["attachments"],
722
- requestBody: z.object({
723
- filename: z.string(),
724
- mimeType: z.string(),
725
- data: z.string().describe("Base64-encoded file data").optional(),
726
- filePath: z
727
- .string()
728
- .describe("On-disk file path (file-backed upload)")
729
- .optional(),
730
- trustedSource: z
731
- .boolean()
732
- .describe(
733
- "Set by the gateway when the file came from a guardian-bound channel actor. Honored only when the request is authenticated as a gateway service token; ignored otherwise.",
734
- )
735
- .optional(),
736
- }),
726
+ // Advertised as multipart/form-data — the form web clients actually send,
727
+ // so the generated SDK types a real `{ file, filename, mimeType }` body
728
+ // instead of erasing it. The handler additionally accepts application/json
729
+ // (base64/file-path) and application/octet-stream by sniffing the request
730
+ // Content-Type header (see handleUploadAttachmentRoute); those forms are
731
+ // used over raw HTTP by the gateway and are not consumed via the SDK.
732
+ requestBody: {
733
+ contentType: "multipart/form-data",
734
+ schema: {
735
+ type: "object",
736
+ properties: {
737
+ file: {
738
+ type: "string",
739
+ format: "binary",
740
+ description: "The file to upload",
741
+ },
742
+ filename: { type: "string" },
743
+ mimeType: { type: "string" },
744
+ },
745
+ required: ["file", "filename", "mimeType"],
746
+ },
747
+ },
737
748
  responseBody: z.object({
738
749
  id: z.string(),
739
750
  original_filename: z.string(),
@@ -363,6 +363,32 @@ export const ROUTES: RouteDefinition[] = [
363
363
  summary: "Get character components",
364
364
  description: "Return available avatar character components.",
365
365
  tags: ["avatar"],
366
+ responseBody: z.object({
367
+ bodyShapes: z.array(
368
+ z.object({
369
+ id: z.string(),
370
+ viewBox: z.object({ width: z.number(), height: z.number() }),
371
+ faceCenter: z.object({ x: z.number(), y: z.number() }),
372
+ svgPath: z.string(),
373
+ }),
374
+ ),
375
+ eyeStyles: z.array(
376
+ z.object({
377
+ id: z.string(),
378
+ sourceViewBox: z.object({ width: z.number(), height: z.number() }),
379
+ eyeCenter: z.object({ x: z.number(), y: z.number() }),
380
+ paths: z.array(z.object({ svgPath: z.string(), color: z.string() })),
381
+ }),
382
+ ),
383
+ colors: z.array(z.object({ id: z.string(), hex: z.string() })),
384
+ faceCenterOverrides: z.array(
385
+ z.object({
386
+ bodyShape: z.string(),
387
+ eyeStyle: z.string(),
388
+ faceCenter: z.object({ x: z.number(), y: z.number() }),
389
+ }),
390
+ ),
391
+ }),
366
392
  },
367
393
  {
368
394
  operationId: "avatar_get_state",
@@ -16,7 +16,7 @@ import {
16
16
  BROWSER_OPERATIONS,
17
17
  type BrowserOperation,
18
18
  } from "../../browser/types.js";
19
- import { findConversation } from "../../daemon/conversation-store.js";
19
+ import { findConversation } from "../../daemon/conversation-registry.js";
20
20
  import type { ContentBlock } from "../../providers/types.js";
21
21
  import { LOCAL_PRINCIPALS } from "../auth/route-policy.js";
22
22
  import type { RouteDefinition, RouteHandlerArgs } from "./types.js";
@@ -7,7 +7,7 @@
7
7
 
8
8
  import { z } from "zod";
9
9
 
10
- import { findConversation } from "../../daemon/conversation-store.js";
10
+ import { findConversation } from "../../daemon/conversation-registry.js";
11
11
  import { getCdpClient } from "../../tools/browser/cdp-client/factory.js";
12
12
  import {
13
13
  clearPinnedTab,
@@ -73,11 +73,7 @@ async function handleBrowserTabs({ body = {} }: RouteHandlerArgs) {
73
73
  ? result.clientId
74
74
  : undefined;
75
75
  if (result?.tabId !== undefined) {
76
- setPinnedTab(
77
- resolvedConversationId,
78
- String(result.tabId),
79
- clientId,
80
- );
76
+ setPinnedTab(resolvedConversationId, String(result.tabId), clientId);
81
77
  }
82
78
  return { ok: true, tab: result };
83
79
  } finally {
@@ -88,10 +84,10 @@ async function handleBrowserTabs({ body = {} }: RouteHandlerArgs) {
88
84
  if (command === "new") {
89
85
  const cdp = getCdpClient(context, cdpOptions);
90
86
  try {
91
- const result = await cdp.send<{ tabId?: number | string; clientId?: string }>(
92
- "Vellum.createTab",
93
- {},
94
- );
87
+ const result = await cdp.send<{
88
+ tabId?: number | string;
89
+ clientId?: string;
90
+ }>("Vellum.createTab", {});
95
91
  // Normalise to string for internal use (setCdpSessionId / setPinnedTab)
96
92
  // and keep the numeric form for the API response.
97
93
  const newTabIdStr: string | undefined =
@@ -9,21 +9,18 @@
9
9
  * intro generation. The response is streamed as SSE events (`btw_text_delta`,
10
10
  * `btw_complete`, `btw_error`).
11
11
  *
12
- * No messages are persisted. `conversation.processing` is never set or checked.
12
+ * No messages are persisted. The conversation's processing flag is never set or checked.
13
13
  */
14
14
 
15
- import { existsSync, readFileSync } from "node:fs";
16
-
17
15
  import { z } from "zod";
18
16
 
17
+ import { isAssistantFeatureFlagEnabled } from "../../config/assistant-feature-flags.js";
19
18
  import { getConfig } from "../../config/loader.js";
20
- import { readNowScratchpad } from "../../daemon/conversation-runtime-assembly.js";
21
19
  import { getOrCreateConversation } from "../../daemon/conversation-store.js";
22
- import { parseIdentityFields } from "../../daemon/handlers/identity.js";
20
+ import { readNowScratchpad } from "../../daemon/now-scratchpad.js";
23
21
  import { getConversationByKey } from "../../memory/conversation-key-store.js";
24
22
  import { getAllToolDefinitions } from "../../tools/registry.js";
25
23
  import { getLogger } from "../../util/logger.js";
26
- import { getWorkspacePromptPath } from "../../util/platform.js";
27
24
  import { ACTOR_PRINCIPALS } from "../auth/route-policy.js";
28
25
  import { runBtwSidechain } from "../btw-sidechain.js";
29
26
  import { BadRequestError, ServiceUnavailableError } from "./errors.js";
@@ -37,6 +34,9 @@ const IDENTITY_INTRO_KEY = "identity-intro";
37
34
 
38
35
  /** Conversation key used by the client for empty-state greeting generation. */
39
36
  const GREETING_KEY = "greeting";
37
+ const EMPTY_STATE_DYNAMIC_GREETINGS_FLAG =
38
+ "empty-state-dynamic-greetings" as const;
39
+ const STATIC_EMPTY_STATE_GREETING = "What are we working on?";
40
40
 
41
41
  // ---------------------------------------------------------------------------
42
42
  // SSE helpers
@@ -68,26 +68,22 @@ async function handleBtw({
68
68
 
69
69
  const trimmedContent = content.trim();
70
70
 
71
- // ----- Identity intro fast-path -----
71
+ if (
72
+ conversationKey === GREETING_KEY &&
73
+ !isAssistantFeatureFlagEnabled(
74
+ EMPTY_STATE_DYNAMIC_GREETINGS_FLAG,
75
+ getConfig(),
76
+ )
77
+ ) {
78
+ return streamText(STATIC_EMPTY_STATE_GREETING);
79
+ }
80
+
81
+ // ----- Cached identity intro fast-path -----
72
82
  if (conversationKey === IDENTITY_INTRO_KEY) {
73
- let fastText: string | undefined;
74
- const identityPath = getWorkspacePromptPath("IDENTITY.md");
75
- if (existsSync(identityPath)) {
76
- const fields = parseIdentityFields(readFileSync(identityPath, "utf-8"));
77
- if (fields.name) {
78
- fastText = `Hi, I'm ${fields.name}!`;
79
- }
80
- }
81
- fastText ??= getCachedIntro()?.greetings[0];
83
+ const fastText = getCachedIntro()?.greetings[0];
82
84
  if (fastText) {
83
85
  log.debug("Returning identity intro fast-path");
84
- return new ReadableStream({
85
- start(controller) {
86
- controller.enqueue(sseEvent("btw_text_delta", { text: fastText }));
87
- controller.enqueue(sseEvent("btw_complete", {}));
88
- controller.close();
89
- },
90
- });
86
+ return streamText(fastText);
91
87
  }
92
88
  }
93
89
 
@@ -171,6 +167,16 @@ async function handleBtw({
171
167
  });
172
168
  }
173
169
 
170
+ function streamText(text: string): ReadableStream<Uint8Array> {
171
+ return new ReadableStream({
172
+ start(controller) {
173
+ controller.enqueue(sseEvent("btw_text_delta", { text }));
174
+ controller.enqueue(sseEvent("btw_complete", {}));
175
+ controller.close();
176
+ },
177
+ });
178
+ }
179
+
174
180
  // ---------------------------------------------------------------------------
175
181
  // Route definitions
176
182
  // ---------------------------------------------------------------------------
@@ -15,26 +15,39 @@
15
15
 
16
16
  import { z } from "zod";
17
17
 
18
- import { getConfig } from "../../config/loader.js";
18
+ import {
19
+ getConfig,
20
+ invalidateConfigCache,
21
+ loadRawConfig,
22
+ saveRawConfig,
23
+ } from "../../config/loader.js";
24
+ import type { AssistantConfig } from "../../config/schema.js";
19
25
  import { getMemoryCheckpoint } from "../../memory/checkpoints.js";
20
26
  import {
21
27
  getMessageRoleStatsByConversation,
22
28
  listConversationsBySource,
23
29
  } from "../../memory/conversation-queries.js";
24
30
  import {
31
+ cancelPendingAutomaticConsolidationJobs,
25
32
  enqueueMemoryJob,
26
33
  hasActiveJobOfType,
34
+ MEMORY_V2_CONSOLIDATION_JOB_TRIGGERS,
27
35
  } from "../../memory/jobs-store.js";
28
36
  import { GRAPH_MAINTENANCE_CHECKPOINTS } from "../../memory/jobs-worker.js";
37
+ import { getUsageCostForConversationWindow } from "../../memory/llm-usage-store.js";
29
38
  import { MEMORY_V2_CONSOLIDATION_SOURCE } from "../../memory/v2/constants.js";
30
39
  import { ACTOR_PRINCIPALS } from "../auth/route-policy.js";
31
- import { BadRequestError } from "./errors.js";
40
+ import { BadRequestError, InternalError } from "./errors.js";
32
41
  import type { RouteDefinition, RouteHandlerArgs } from "./types.js";
33
42
 
34
43
  function isConsolidationAvailable(): boolean {
35
44
  return getConfig().memory.v2.enabled;
36
45
  }
37
46
 
47
+ function isAutomaticConsolidationEnabled(config: AssistantConfig): boolean {
48
+ return config.memory.v2.enabled && config.memory.v2.consolidation_enabled;
49
+ }
50
+
38
51
  function consolidationIntervalMs(): number {
39
52
  return getConfig().memory.v2.consolidation_interval_hours * 60 * 60 * 1000;
40
53
  }
@@ -48,6 +61,61 @@ function readLastRunAt(): number | null {
48
61
  return Number.isFinite(parsed) ? parsed : null;
49
62
  }
50
63
 
64
+ function readConsolidationConfigResponse() {
65
+ const config = getConfig();
66
+ const available = config.memory.v2.enabled;
67
+ const enabled = isAutomaticConsolidationEnabled(config);
68
+ const intervalMs = consolidationIntervalMs();
69
+ const lastRunAt = readLastRunAt();
70
+ const nextRunAt =
71
+ enabled && lastRunAt != null ? lastRunAt + intervalMs : null;
72
+ return {
73
+ available,
74
+ enabled,
75
+ intervalMs,
76
+ nextRunAt,
77
+ lastRunAt,
78
+ success: true,
79
+ };
80
+ }
81
+
82
+ function handleUpdateConfig(body: Record<string, unknown>) {
83
+ const consolidationPatch: Record<string, unknown> = {};
84
+ const disablingAutomaticConsolidation = body.enabled === false;
85
+ if ("enabled" in body && typeof body.enabled === "boolean") {
86
+ consolidationPatch.consolidation_enabled = body.enabled;
87
+ }
88
+
89
+ try {
90
+ const raw = loadRawConfig() as Record<string, unknown>;
91
+ const memory =
92
+ raw.memory != null && typeof raw.memory === "object"
93
+ ? (raw.memory as Record<string, unknown>)
94
+ : {};
95
+ const v2 =
96
+ memory.v2 != null && typeof memory.v2 === "object"
97
+ ? (memory.v2 as Record<string, unknown>)
98
+ : {};
99
+
100
+ raw.memory = {
101
+ ...memory,
102
+ v2: {
103
+ ...v2,
104
+ ...consolidationPatch,
105
+ },
106
+ };
107
+ saveRawConfig(raw);
108
+ invalidateConfigCache();
109
+ if (disablingAutomaticConsolidation) {
110
+ cancelPendingAutomaticConsolidationJobs();
111
+ }
112
+ } catch {
113
+ throw new InternalError("Failed to save consolidation config");
114
+ }
115
+
116
+ return readConsolidationConfigResponse();
117
+ }
118
+
51
119
  // ---------------------------------------------------------------------------
52
120
  // Shared ROUTES
53
121
  // ---------------------------------------------------------------------------
@@ -74,18 +142,36 @@ export const ROUTES: RouteDefinition[] = [
74
142
  success: z.boolean(),
75
143
  }),
76
144
  handler: async (_args: RouteHandlerArgs) => {
77
- const enabled = getConfig().memory.v2.enabled;
78
- const intervalMs = consolidationIntervalMs();
79
- const lastRunAt = readLastRunAt();
80
- const nextRunAt = lastRunAt != null ? lastRunAt + intervalMs : null;
81
- return {
82
- available: enabled,
83
- enabled,
84
- intervalMs,
85
- nextRunAt,
86
- lastRunAt,
87
- success: true,
88
- };
145
+ return readConsolidationConfigResponse();
146
+ },
147
+ },
148
+ {
149
+ operationId: "updateConsolidationConfig",
150
+ endpoint: "consolidation/config",
151
+ method: "PUT",
152
+ policy: {
153
+ requiredScopes: ["settings.write"],
154
+ allowedPrincipalTypes: ACTOR_PRINCIPALS,
155
+ },
156
+ summary: "Update consolidation config",
157
+ description: "Update the memory v2 consolidation schedule configuration.",
158
+ tags: ["consolidation"],
159
+ requestBody: z.object({
160
+ enabled: z
161
+ .boolean()
162
+ .optional()
163
+ .describe("Enable or disable automatic consolidation"),
164
+ }),
165
+ responseBody: z.object({
166
+ available: z.boolean(),
167
+ enabled: z.boolean(),
168
+ intervalMs: z.number(),
169
+ nextRunAt: z.number().nullable(),
170
+ lastRunAt: z.number().nullable(),
171
+ success: z.boolean(),
172
+ }),
173
+ handler: async ({ body = {} }: RouteHandlerArgs) => {
174
+ return handleUpdateConfig(body);
89
175
  },
90
176
  },
91
177
  {
@@ -117,7 +203,9 @@ export const ROUTES: RouteDefinition[] = [
117
203
  if (hasActiveJobOfType("memory_v2_consolidate")) {
118
204
  return { success: true, ran: false, jobId: null };
119
205
  }
120
- const jobId = enqueueMemoryJob("memory_v2_consolidate", {});
206
+ const jobId = enqueueMemoryJob("memory_v2_consolidate", {
207
+ trigger: MEMORY_V2_CONSOLIDATION_JOB_TRIGGERS.manual,
208
+ });
121
209
  return { success: true, ran: true, jobId };
122
210
  },
123
211
  },
@@ -170,6 +258,9 @@ export const ROUTES: RouteDefinition[] = [
170
258
  skipReason: z.string().nullable(),
171
259
  error: z.string().nullable(),
172
260
  conversationId: z.string().nullable(),
261
+ conversationExists: z.boolean(),
262
+ conversationArchivedAt: z.number().nullable(),
263
+ estimatedCostUsd: z.number(),
173
264
  createdAt: z.number(),
174
265
  }),
175
266
  )
@@ -195,24 +286,33 @@ export const ROUTES: RouteDefinition[] = [
195
286
  rows.map((r) => r.id),
196
287
  "assistant",
197
288
  );
289
+ const now = Date.now();
198
290
  return {
199
291
  runs: rows.map((c) => {
200
292
  const stat = assistantStats.get(c.id);
201
293
  const hasAssistantOutput = (stat?.count ?? 0) > 0;
202
294
  const finishedAt = hasAssistantOutput ? stat!.lastAt : null;
295
+ const estimatedCostUsd =
296
+ c.totalEstimatedCost > 0
297
+ ? c.totalEstimatedCost
298
+ : getUsageCostForConversationWindow({
299
+ conversationId: c.id,
300
+ from: c.createdAt,
301
+ to: finishedAt ?? now,
302
+ });
203
303
  return {
204
304
  id: c.id,
205
305
  scheduledFor: c.createdAt,
206
306
  startedAt: c.createdAt,
207
307
  finishedAt,
208
- durationMs:
209
- finishedAt != null ? finishedAt - c.createdAt : null,
210
- status: (hasAssistantOutput ? "ok" : "running") as
211
- | "ok"
212
- | "running",
308
+ durationMs: finishedAt != null ? finishedAt - c.createdAt : null,
309
+ status: (hasAssistantOutput ? "ok" : "running") as "ok" | "running",
213
310
  skipReason: null,
214
311
  error: null,
215
312
  conversationId: c.id,
313
+ conversationExists: true,
314
+ conversationArchivedAt: c.archivedAt,
315
+ estimatedCostUsd,
216
316
  createdAt: c.createdAt,
217
317
  };
218
318
  }),
@@ -9,7 +9,7 @@
9
9
  import { v4 as uuid } from "uuid";
10
10
  import { z } from "zod";
11
11
 
12
- import { findConversation } from "../../daemon/conversation-store.js";
12
+ import { findConversation } from "../../daemon/conversation-registry.js";
13
13
  import { clearAllConversations as clearAllActive } from "../../daemon/handlers/conversations.js";
14
14
  import { formatJson, formatMarkdown } from "../../export/formatter.js";
15
15
  import { ipcCall as ipcCallGateway } from "../../ipc/gateway-client.js";
@@ -9,7 +9,7 @@
9
9
 
10
10
  import { z } from "zod";
11
11
 
12
- import { findConversation } from "../../daemon/conversation-store.js";
12
+ import { findConversation } from "../../daemon/conversation-registry.js";
13
13
  import {
14
14
  type Confidence,
15
15
  getAttentionStateByConversationIds,
@@ -72,7 +72,7 @@ import { type LogRow } from "../../memory/llm-request-log-store.js";
72
72
  import { getMemoryRecallLogByMessageIds } from "../../memory/memory-recall-log-store.js";
73
73
  import { getMemoryV2ActivationLogByMessageIds } from "../../memory/memory-v2-activation-log-store.js";
74
74
  import { MEMORY_V2_CONSOLIDATION_SOURCE } from "../../memory/v2/constants.js";
75
- import { getMemoryV3SelectionForInspector } from "../../memory/v3/selection-log-store.js";
75
+ import { getMemoryV3SelectionForInspector } from "../../plugins/defaults/memory-v3-shadow/selection-log-store.js";
76
76
  import {
77
77
  createConnection,
78
78
  listConnections,
@@ -1171,6 +1171,8 @@ export const ROUTES: RouteDefinition[] = [
1171
1171
  description:
1172
1172
  "Deep-merge a partial JSON object into the settings.json configuration.",
1173
1173
  tags: ["config"],
1174
+ requestBody: z.record(z.string(), z.unknown()),
1175
+ responseBody: z.object({ ok: z.boolean() }),
1174
1176
  handler: handlePatchConfig,
1175
1177
  },
1176
1178
  {