@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
@@ -29,7 +29,7 @@
29
29
  */
30
30
 
31
31
  type FlagSlot = {
32
- overrides: Record<string, boolean> | null;
32
+ overrides: Record<string, boolean | string> | null;
33
33
  fromGateway: boolean;
34
34
  };
35
35
 
@@ -44,7 +44,7 @@ function slot(): FlagSlot {
44
44
  }
45
45
 
46
46
  /** Read the current override cache. `null` means not yet populated. */
47
- export function getCachedOverrides(): Record<string, boolean> | null {
47
+ export function getCachedOverrides(): Record<string, boolean | string> | null {
48
48
  return slot().overrides;
49
49
  }
50
50
 
@@ -66,7 +66,7 @@ export function isCachedFromGateway(): boolean {
66
66
  * `initFeatureFlagOverrides()` calls are no-ops.
67
67
  */
68
68
  export function setCachedOverrides(
69
- overrides: Record<string, boolean>,
69
+ overrides: Record<string, boolean | string>,
70
70
  options: { fromGateway: boolean },
71
71
  ): void {
72
72
  const s = slot();
@@ -26,11 +26,20 @@
26
26
  "defaultEnabled": false
27
27
  },
28
28
  {
29
- "id": "prechat-onboarding-condensed-flow",
29
+ "id": "pre-chat-onboarding-experiment-2026-06-06",
30
30
  "scope": "client",
31
- "key": "prechat-onboarding-condensed-flow",
32
- "label": "Condensed Pre-chat Onboarding",
33
- "description": "Enable the condensed pre-chat onboarding flow for a standard LaunchDarkly percentage rollout.",
31
+ "key": "pre-chat-onboarding-experiment-2026-06-06",
32
+ "label": "Pre-chat Onboarding Experiment 2026-06-06",
33
+ "description": "Pre-chat onboarding experiment with control and variant-a arms. Control shows the full funnel; variant-a shows the condensed pared-down flow.",
34
+ "defaultEnabled": "control",
35
+ "values": ["control", "variant-a"]
36
+ },
37
+ {
38
+ "id": "experiment-activation-flow-2026-06-03",
39
+ "scope": "client",
40
+ "key": "experiment-activation-flow-2026-06-03",
41
+ "label": "Activation Flow Experiment 2026-06-03",
42
+ "description": "Route allowlisted users to the activation-rail bootstrap template after pre-chat. Off by default and targeted through LaunchDarkly.",
34
43
  "defaultEnabled": false
35
44
  },
36
45
  {
@@ -57,6 +66,14 @@
57
66
  "description": "Control Developer nav visibility in macOS settings",
58
67
  "defaultEnabled": false
59
68
  },
69
+ {
70
+ "id": "system-schedule-toggles",
71
+ "scope": "assistant",
72
+ "key": "system-schedule-toggles",
73
+ "label": "System Schedule Toggles",
74
+ "description": "Show Heartbeat and Consolidation pause toggles on the schedules settings page. The toggles only pause automatic runs; manual Run now remains available.",
75
+ "defaultEnabled": false
76
+ },
60
77
  {
61
78
  "id": "developer-menu-items",
62
79
  "scope": "client",
@@ -363,7 +380,7 @@
363
380
  },
364
381
  {
365
382
  "id": "home-page",
366
- "scope": "both",
383
+ "scope": "client",
367
384
  "key": "home-page",
368
385
  "label": "Home Page",
369
386
  "description": "Enable the Home page as the default landing view.",
@@ -450,11 +467,35 @@
450
467
  "defaultEnabled": false
451
468
  },
452
469
  {
453
- "id": "self-intro-greeting",
470
+ "id": "empty-state-dynamic-greetings",
454
471
  "scope": "assistant",
472
+ "key": "empty-state-dynamic-greetings",
473
+ "label": "Dynamic Empty-State Greetings",
474
+ "description": "Enable the empty new-chat screen to refresh cached greeting options via the empty-state greeting LLM call site. When off, the assistant serves workspace-authored greetings or static fallbacks only.",
475
+ "defaultEnabled": false
476
+ },
477
+ {
478
+ "id": "self-intro-greeting",
479
+ "scope": "both",
455
480
  "key": "self-intro-greeting",
456
481
  "label": "Self-intro first message",
457
- "description": "On the first conversation, send a natural self-introduction (e.g. \"Hi Vela, I'm alex. Nice to meet you.\") on the user's behalf and route it through real LLM inference, instead of serving the canned first greeting. Names come from the onboarding context; falls back to the canned greeting when no name is known. See assistant/src/daemon/first-greeting.ts (buildSelfIntroMessage).",
482
+ "description": "On the first conversation, send a natural self-introduction (e.g. \"Hi Vela, I'm alex. Nice to meet you.\") on the user's behalf and route it through real LLM inference, instead of serving the canned first greeting. Names come from the onboarding context; falls back to the canned greeting when no name is known. Exposed to clients so pre-hatch onboarding can compute the source-of-truth initial message, and to the assistant so older clients can still be gated server-side. See assistant/src/daemon/first-greeting.ts (buildSelfIntroMessage).",
483
+ "defaultEnabled": false
484
+ },
485
+ {
486
+ "id": "provider-first-profile-creation",
487
+ "scope": "client",
488
+ "key": "provider-first-profile-creation",
489
+ "label": "Provider-First Profile Creation",
490
+ "description": "New profile creation flow: pick (or inline-create) a provider first, then a model, with pre-filled provider and profile name/key, plus a quick-add \"+\" in the chat composer's Model Profile menu. When off, profile creation uses the previous field order and there is no composer quick-add.",
491
+ "defaultEnabled": false
492
+ },
493
+ {
494
+ "id": "acp",
495
+ "scope": "assistant",
496
+ "key": "acp",
497
+ "label": "ACP Coding Agents",
498
+ "description": "Enable spawning and steering external coding agents (Claude Code, Codex, Gemini) via the Agent Client Protocol. Alternative gate to the acp.enabled workspace config field; either enables the subsystem.",
458
499
  "defaultEnabled": false
459
500
  }
460
501
  ]
@@ -23,6 +23,7 @@ describe("MemoryV2ConfigSchema", () => {
23
23
  bm25_k1: 1.2,
24
24
  bm25_b: 0.4,
25
25
  consolidation_interval_hours: 4,
26
+ consolidation_enabled: true,
26
27
  consolidation_max_buffer_lines: 100,
27
28
  max_page_chars: 5000,
28
29
  consolidation_prompt_path: null,
@@ -0,0 +1,25 @@
1
+ import { describe, expect, test } from "bun:test";
2
+
3
+ import { MemoryV3ConfigSchema } from "../memory-v3.js";
4
+
5
+ describe("MemoryV3ConfigSchema", () => {
6
+ test("parses an empty object to documented defaults", () => {
7
+ const parsed = MemoryV3ConfigSchema.parse({});
8
+ expect(parsed).toEqual({
9
+ workingSet: { maxPages: 150, evictWindow: 5 },
10
+ l2Concurrency: 16,
11
+ });
12
+ });
13
+
14
+ test("accepts an explicit l2Concurrency override", () => {
15
+ expect(MemoryV3ConfigSchema.parse({ l2Concurrency: 8 }).l2Concurrency).toBe(
16
+ 8,
17
+ );
18
+ });
19
+
20
+ test("rejects a non-positive or non-integer l2Concurrency", () => {
21
+ expect(() => MemoryV3ConfigSchema.parse({ l2Concurrency: 0 })).toThrow();
22
+ expect(() => MemoryV3ConfigSchema.parse({ l2Concurrency: -4 })).toThrow();
23
+ expect(() => MemoryV3ConfigSchema.parse({ l2Concurrency: 1.5 })).toThrow();
24
+ });
25
+ });
@@ -56,6 +56,15 @@ export const HeartbeatConfigSchema = z
56
56
  .describe(
57
57
  "Maximum heartbeats that can run consecutively without a guardian message. Counter resets when the guardian sends a message. Set to null for unlimited.",
58
58
  ),
59
+ maxDailyRuns: z
60
+ .number({ error: "heartbeat.maxDailyRuns must be a number" })
61
+ .int("heartbeat.maxDailyRuns must be an integer")
62
+ .positive("heartbeat.maxDailyRuns must be a positive integer")
63
+ .nullable()
64
+ .default(2)
65
+ .describe(
66
+ "Maximum heartbeats that can run per calendar day. Resets at midnight local time. Set to null for unlimited.",
67
+ ),
59
68
  disposition: z
60
69
  .string({ error: "heartbeat.disposition must be a string" })
61
70
  .default(
@@ -21,6 +21,7 @@ const LLMProvider = z.enum([
21
21
  "fireworks",
22
22
  "openrouter",
23
23
  "openai-compatible",
24
+ "minimax",
24
25
  ]);
25
26
  type LLMProvider = z.infer<typeof LLMProvider>;
26
27
 
@@ -194,6 +194,14 @@ export const MemoryV2ConfigSchema = z
194
194
  .describe(
195
195
  "Hours between scheduled consolidation runs that synthesize buffered memories into concept pages",
196
196
  ),
197
+ consolidation_enabled: z
198
+ .boolean({
199
+ error: "memory.v2.consolidation_enabled must be a boolean",
200
+ })
201
+ .default(true)
202
+ .describe(
203
+ "Whether automatic scheduled consolidation runs are enabled. Manual run-now requests remain available while memory.v2.enabled is true.",
204
+ ),
197
205
  consolidation_max_buffer_lines: z
198
206
  .number({
199
207
  error: "memory.v2.consolidation_max_buffer_lines must be a number",
@@ -33,6 +33,14 @@ export const MemoryV3ConfigSchema = z
33
33
  workingSet: MemoryV3WorkingSetSchema.default(
34
34
  MemoryV3WorkingSetSchema.parse({}),
35
35
  ),
36
+ l2Concurrency: z
37
+ .number({ error: "memory.v3.l2Concurrency must be a number" })
38
+ .int("memory.v3.l2Concurrency must be an integer")
39
+ .positive("memory.v3.l2Concurrency must be a positive integer")
40
+ .default(16)
41
+ .describe(
42
+ "Bounded fan-out for the per-leaf L2 selection (number of leaf selector calls in flight at once).",
43
+ ),
36
44
  })
37
45
  .describe("Memory v3 — topic-tree routing with a carry-forward working set");
38
46
 
@@ -87,6 +87,14 @@ export const DaemonConfigSchema = z
87
87
  .describe(
88
88
  "Whether the daemon records conversations even when no client is connected",
89
89
  ),
90
+ reapOrphanedSubprocesses: z
91
+ .boolean({
92
+ error: "daemon.reapOrphanedSubprocesses must be a boolean",
93
+ })
94
+ .default(false)
95
+ .describe(
96
+ "Whether the daemon, when running as PID 1 in a container, periodically reaps orphaned subprocesses that reparented to it. Off by default while the behavior is being validated.",
97
+ ),
90
98
  })
91
99
  .describe("Background daemon process configuration");
92
100
 
@@ -58,7 +58,7 @@ const MANAGED_PROFILE_TEMPLATES: Record<string, ManagedProfileTemplate> = {
58
58
  label: "Quality",
59
59
  description: "Best results with the most capable model",
60
60
  maxTokens: 32000,
61
- effort: "max",
61
+ effort: "high",
62
62
  thinking: { enabled: true, streamThinking: true },
63
63
  contextWindow: { maxInputTokens: DEFAULT_CONTEXT_WINDOW_MAX_INPUT_TOKENS },
64
64
  },
@@ -104,7 +104,7 @@ const USER_PROFILE_TEMPLATES: Record<string, ManagedProfileTemplate> = {
104
104
  label: "Quality",
105
105
  description: "Best results with the most capable model",
106
106
  maxTokens: 32000,
107
- effort: "max",
107
+ effort: "high",
108
108
  thinking: { enabled: true, streamThinking: true },
109
109
  contextWindow: { maxInputTokens: DEFAULT_CONTEXT_WINDOW_MAX_INPUT_TOKENS },
110
110
  },
@@ -52,6 +52,7 @@ const VellumMetadataSchema = z
52
52
 
53
53
  const SkillMetadataSchema = z
54
54
  .object({
55
+ icon: z.string().optional(),
55
56
  emoji: z.string().optional(),
56
57
  vellum: VellumMetadataSchema.optional(),
57
58
  })
@@ -210,6 +211,7 @@ interface ParsedFrontmatter {
210
211
  displayName: string;
211
212
  description: string;
212
213
  body: string;
214
+ icon?: string;
213
215
  emoji?: string;
214
216
  includes?: string[];
215
217
  featureFlag?: string;
@@ -253,6 +255,7 @@ function parseFrontmatter(
253
255
  }
254
256
 
255
257
  // metadata is already a parsed object from YAML — validate with Zod schema
258
+ let icon: string | undefined;
256
259
  let emoji: string | undefined;
257
260
  let parsedMeta: z.infer<typeof SkillMetadataSchema> | undefined;
258
261
  let vellum: z.infer<typeof VellumMetadataSchema> | undefined;
@@ -271,6 +274,7 @@ function parseFrontmatter(
271
274
  if (zodResult.success) {
272
275
  parsedMeta = zodResult.data;
273
276
  vellum = parsedMeta.vellum;
277
+ icon = parsedMeta.icon;
274
278
  emoji = vellum?.emoji ?? parsedMeta.emoji;
275
279
  } else {
276
280
  // Zod validation failed — fall back to raw parsed object so we don't
@@ -284,6 +288,9 @@ function parseFrontmatter(
284
288
  const raw = metadataRaw as Record<string, unknown>;
285
289
  parsedMeta = raw as z.infer<typeof SkillMetadataSchema>;
286
290
  vellum = raw?.vellum as z.infer<typeof VellumMetadataSchema>;
291
+ if (typeof parsedMeta?.icon === "string") {
292
+ icon = parsedMeta.icon;
293
+ }
287
294
  if (vellum && typeof vellum === "object") {
288
295
  emoji = typeof vellum.emoji === "string" ? vellum.emoji : undefined;
289
296
  }
@@ -337,6 +344,7 @@ function parseFrontmatter(
337
344
  displayName,
338
345
  description,
339
346
  body: strippedBody,
347
+ icon,
340
348
  emoji,
341
349
  includes,
342
350
  featureFlag,
@@ -489,6 +497,7 @@ function readSkillFromDirectory(
489
497
  directoryPath,
490
498
  skillFilePath,
491
499
  body: parsed.body,
500
+ icon: parsed.icon,
492
501
  emoji: parsed.emoji,
493
502
 
494
503
  source,
@@ -540,6 +549,7 @@ function readBundledSkillFromDirectory(
540
549
  skillFilePath,
541
550
  body: parsed.body,
542
551
  bundled: true,
552
+ icon: parsed.icon,
543
553
  emoji: parsed.emoji,
544
554
 
545
555
  source: "bundled",
@@ -599,6 +609,7 @@ function loadBundledSkills(): SkillSummary[] {
599
609
  directoryPath: skill.directoryPath,
600
610
  skillFilePath: skill.skillFilePath,
601
611
  bundled: true,
612
+ icon: skill.icon,
602
613
  emoji: skill.emoji,
603
614
 
604
615
  source: "bundled",
@@ -649,6 +660,7 @@ function skillSummaryFromDefinition(
649
660
  directoryPath: skill.directoryPath,
650
661
  skillFilePath: skill.skillFilePath,
651
662
  bundled: skill.bundled,
663
+ icon: skill.icon,
652
664
  emoji: skill.emoji,
653
665
  source,
654
666
  toolManifest: skill.toolManifest,
@@ -836,6 +848,7 @@ export function loadSkillCatalog(
836
848
  description: parsed.description,
837
849
  directoryPath: directory,
838
850
  skillFilePath,
851
+ icon: parsed.icon,
839
852
  emoji: parsed.emoji,
840
853
 
841
854
  source: "workspace",
@@ -21,7 +21,6 @@
21
21
  import { optimizeImageForTransport } from "../agent/image-optimize.js";
22
22
  import type { CompactionConfig } from "../config/schemas/compaction.js";
23
23
  import type { LLMCallSite } from "../config/schemas/llm.js";
24
- import { stripInjectionsForCompaction } from "../daemon/conversation-runtime-assembly.js";
25
24
  import { filterMessagesForUntrustedActor } from "../daemon/message-provenance.js";
26
25
  import {
27
26
  getAttachmentContent,
@@ -42,6 +41,7 @@ import {
42
41
  type TrustClass,
43
42
  } from "../runtime/actor-trust-resolver.js";
44
43
  import { getLogger } from "../util/logger.js";
44
+ import { stripInjectionsForCompaction } from "./strip-injections.js";
45
45
  import { estimatePromptTokens } from "./token-estimator.js";
46
46
 
47
47
  const log = getLogger("compactor");
@@ -0,0 +1,128 @@
1
+ /**
2
+ * Runtime-injection stripping for compaction and overflow recovery.
3
+ *
4
+ * Runtime injections (turn context, memory, NOW.md, workspace, Slack
5
+ * chronological, etc.) persist in message history to keep the conversation
6
+ * prefix stable for Anthropic's prefix caching. They only need to be removed
7
+ * when compaction rewrites the message array, so the compactor summarizes the
8
+ * raw persistent messages rather than the ephemeral injected blocks.
9
+ *
10
+ * This module is the compaction-layer home for that strip so both the agent
11
+ * loop (which drives the compaction pipeline) and the compactor can call it
12
+ * without reaching up into the daemon orchestrator.
13
+ */
14
+ import type { Message } from "../providers/types.js";
15
+
16
+ /**
17
+ * A matcher for an injected text block. A plain string matches by prefix
18
+ * (`startsWith`). A `{ prefix, suffix }` wrapper requires BOTH the opening
19
+ * prefix and the closing suffix, so user-authored content that merely begins
20
+ * with an injection-like opening tag (e.g. a message discussing `<info>`
21
+ * markup) is not mistaken for an injected block and dropped. This mirrors
22
+ * `countMemoryPrefixBlocks`, which only treats `<memory>…</memory>` /
23
+ * `<info>…</info>` blocks as injected when the full wrapper is present.
24
+ */
25
+ export type InjectionMatcher = string | { prefix: string; suffix: string };
26
+
27
+ /**
28
+ * Remove text blocks from user messages that match any of the given matchers.
29
+ * If stripping removes all content blocks from a message, the message itself
30
+ * is dropped.
31
+ *
32
+ * This is the shared primitive behind the individual strip* functions and
33
+ * the `stripInjectionsForCompaction` pipeline.
34
+ */
35
+ export function stripUserTextBlocksByPrefix(
36
+ messages: Message[],
37
+ matchers: InjectionMatcher[],
38
+ ): Message[] {
39
+ return messages
40
+ .map((message) => {
41
+ if (message.role !== "user") return message;
42
+ const nextContent = message.content.filter((block) => {
43
+ if (block.type !== "text") return true;
44
+ return !matchers.some((m) =>
45
+ typeof m === "string"
46
+ ? block.text.startsWith(m)
47
+ : block.text.startsWith(m.prefix) && block.text.endsWith(m.suffix),
48
+ );
49
+ });
50
+ if (nextContent.length === message.content.length) return message;
51
+ if (nextContent.length === 0) return null;
52
+ return { ...message, content: nextContent };
53
+ })
54
+ .filter(
55
+ (message): message is NonNullable<typeof message> => message != null,
56
+ );
57
+ }
58
+
59
+ /** Matchers stripped by the pipeline (order doesn't matter — single pass). */
60
+ const RUNTIME_INJECTION_PREFIXES: InjectionMatcher[] = [
61
+ "<channel_capabilities>",
62
+ "<channel_command_context>",
63
+ "<disk_pressure_warning>",
64
+ "<channel_turn_context>", // backward-compat: strip legacy separate channel blocks
65
+ "<guardian_context>",
66
+ "<inbound_actor_context>", // backward-compat: strip legacy separate actor blocks
67
+ "<interface_turn_context>", // backward-compat: strip legacy separate interface blocks
68
+ // NOTE: <turn_context> is intentionally NOT stripped — unified turn context
69
+ // blocks persist in history so the assistant retains temporal/actor grounding.
70
+ "<background_turn>",
71
+ "<memory_context __injected>",
72
+ "<memory_context>", // backward-compat: strip legacy blocks from pre-__injected history
73
+ // The static `memory-v2-static` block (`<info>\n…</info>`) and the
74
+ // dynamic activation block (`<memory>\n…</memory>`, plus legacy
75
+ // `<memory __injected>…`) are both stripped so each compaction
76
+ // re-injects the freshest essentials/threads/recent/buffer view and
77
+ // re-runs the activation pipeline, matching the `<knowledge_base>`
78
+ // cadence. The activation pipeline dedupes via `everInjected`, and
79
+ // compaction handles aggregate growth, so accumulation does not cause
80
+ // unbounded context growth. Both wrappers may appear in persisted rows.
81
+ //
82
+ // These two use the full `{ prefix, suffix }` wrapper shape (not a bare
83
+ // prefix) so that user-authored text merely starting with `<memory>\n` or
84
+ // `<info>\n` is never silently dropped during compaction/`/clean`. This
85
+ // matches the full-wrapper requirement in `countMemoryPrefixBlocks`.
86
+ { prefix: "<memory>\n", suffix: "\n</memory>" },
87
+ { prefix: "<info>\n", suffix: "\n</info>" },
88
+ "<voice_call_control>",
89
+ "<workspace_top_level>", // backward-compat: strip legacy workspace blocks
90
+ // The `<workspace>` top-level block is stripped so each compaction re-injects
91
+ // a fresh directory snapshot rather than carrying a stale listing into the
92
+ // summary — matching the `<knowledge_base>`/`<NOW.md>` cadence and keeping the
93
+ // `workspace-context` injector's presence detection in lockstep (the block is
94
+ // present exactly when compaction would strip it). The full `{ prefix, suffix }`
95
+ // wrapper shape ensures user-authored text merely starting with `<workspace>\n`
96
+ // is never mistaken for an injected block.
97
+ { prefix: "<workspace>\n", suffix: "\n</workspace>" },
98
+ "<temporal_context>\nToday:", // backward-compat: strip legacy temporal blocks
99
+ "<active_subagents>",
100
+ "<active_workspace>",
101
+ "<active_dynamic_page>",
102
+ "<non_interactive_context>",
103
+ // Shared prefix catches both the current NOW.md tag and any pre-line-limit
104
+ // variant that may linger in in-flight histories during a rolling deploy.
105
+ "<NOW.md Always keep this up to date",
106
+ "<now_scratchpad>", // backward-compat: strip legacy blocks from pre-rename history
107
+ "<knowledge_base>",
108
+ "<pkb>", // backward-compat: strip legacy tag from pre-rename history
109
+ "<system_reminder>",
110
+ "<transport_hints>",
111
+ // The Slack active-thread focus block is non-persisted and injected on
112
+ // the FINAL user turn only. Strip it here so re-assembly during compaction
113
+ // and overflow recovery does not duplicate it across turns.
114
+ "<active_thread>",
115
+ "<system_notice>One or more tool calls returned an error.",
116
+ ];
117
+
118
+ /**
119
+ * Strip all runtime-injected context from message history in a single pass.
120
+ *
121
+ * Used only during compaction and overflow recovery — not on normal turns.
122
+ * Runtime injections persist in history to keep the conversation prefix
123
+ * stable for Anthropic's prefix caching. Stripping is only needed when
124
+ * compaction rewrites the message array (cache miss is expected anyway).
125
+ */
126
+ export function stripInjectionsForCompaction(messages: Message[]): Message[] {
127
+ return stripUserTextBlocksByPrefix(messages, RUNTIME_INJECTION_PREFIXES);
128
+ }
@@ -359,6 +359,29 @@ export function estimatePromptTokens(
359
359
  return correction === 1.0 ? raw : Math.ceil(raw * correction);
360
360
  }
361
361
 
362
+ /**
363
+ * Calibrated prompt-token estimate including the tool-definition budget.
364
+ *
365
+ * Combines the per-tool budget ({@link estimateToolsTokens}) with the
366
+ * message/system estimate ({@link estimatePromptTokens}) under the EWMA
367
+ * calibration correction. This is the estimate the overflow gate consumes;
368
+ * the pre-send calibration capture in `agent/loop.ts` deliberately stays on
369
+ * `estimatePromptTokensRaw` so the calibrator trains against the uncorrected
370
+ * value rather than chasing its own output.
371
+ */
372
+ export function estimatePromptTokensWithTools(
373
+ history: Message[],
374
+ systemPrompt: string | undefined,
375
+ tools: ToolDefinition[],
376
+ providerName: string,
377
+ ): number {
378
+ const toolTokenBudget = tools.length > 0 ? estimateToolsTokens(tools) : 0;
379
+ return estimatePromptTokens(history, systemPrompt, {
380
+ providerName,
381
+ toolTokenBudget,
382
+ });
383
+ }
384
+
362
385
  function stableJson(value: unknown): string {
363
386
  try {
364
387
  return JSON.stringify(value);
@@ -5,29 +5,6 @@ import type {
5
5
  ToolResultContent,
6
6
  } from "../providers/types.js";
7
7
 
8
- /**
9
- * Maximum share of the context window that a single tool result may occupy.
10
- */
11
- const MAX_TOOL_RESULT_CONTEXT_SHARE = 0.3;
12
-
13
- /**
14
- * Absolute cap on tool-result characters (~100K tokens).
15
- */
16
- export const HARD_MAX_TOOL_RESULT_CHARS = 400_000;
17
-
18
- /**
19
- * Calculate the maximum allowed characters for a tool result based on the
20
- * context window size. Uses ~4 chars per token as a rough heuristic.
21
- */
22
- export function calculateMaxToolResultChars(
23
- contextWindowTokens: number,
24
- ): number {
25
- return Math.min(
26
- HARD_MAX_TOOL_RESULT_CHARS,
27
- Math.floor(contextWindowTokens * MAX_TOOL_RESULT_CONTEXT_SHARE * 4),
28
- );
29
- }
30
-
31
8
  /**
32
9
  * Aggressively truncate all tool-result text across an entire message history.
33
10
  *
@@ -40,7 +40,8 @@ const INTERNAL_CONTEXT_SUMMARY_MESSAGES = new WeakSet<Message>();
40
40
 
41
41
  // ---------------------------------------------------------------------------
42
42
  // Public types — preserved for downstream consumers (agent loop, conversation,
43
- // plugin pipeline, applyCompactionResult, routes/playground/force-compact).
43
+ // default compaction plugin, applyCompactionResult,
44
+ // routes/playground/force-compact).
44
45
  // ---------------------------------------------------------------------------
45
46
 
46
47
  export interface ContextWindowResult {
@@ -90,7 +91,6 @@ export interface ShouldCompactResult {
90
91
  }
91
92
 
92
93
  export interface ContextWindowCompactOptions {
93
- lastCompactedAt?: number;
94
94
  /** Skip the auto-threshold check (used for /compact and recovery). */
95
95
  force?: boolean;
96
96
  /**
@@ -104,14 +104,12 @@ export interface ContextWindowCompactOptions {
104
104
  */
105
105
  precomputedEstimate?: number;
106
106
  /**
107
- * Legacy fields retained for backwards compatibility with existing
108
- * callers. The new assistant-driven compactor does not consume them
109
- * the model decides where to cut and what to keep — but accepting them
107
+ * Legacy field retained for backwards compatibility with existing
108
+ * callers. The new assistant-driven compactor does not consume it
109
+ * the model decides where to cut and what to keep — but accepting it
110
110
  * here lets callers keep their existing call sites unchanged.
111
111
  */
112
112
  minKeepRecentUserTurns?: number;
113
- conversationOriginChannel?: string;
114
- targetInputTokensOverride?: number;
115
113
  /**
116
114
  * Trust class of the actor whose turn triggered compaction. Forwarded to
117
115
  * the compactor so the image manifest excludes guardian-only attachments
@@ -17,6 +17,7 @@
17
17
  */
18
18
 
19
19
  import { existsSync } from "node:fs";
20
+ import { createRequire } from "node:module";
20
21
  import { dirname, join } from "node:path";
21
22
 
22
23
  import { getIsContainerized } from "../config/env-registry.js";
@@ -160,6 +161,21 @@ export function discoverLocalCes():
160
161
  return { mode: "local-source", sourcePath: sourceEntry };
161
162
  }
162
163
 
164
+ // npm-layout fallback: resolve via node_modules when installed as a package
165
+ try {
166
+ const _require = createRequire(import.meta.url);
167
+ const pkgPath = _require.resolve(
168
+ "@vellumai/credential-executor/package.json",
169
+ );
170
+ const npmSourceEntry = join(dirname(pkgPath), "src", "main.ts");
171
+ if (existsSync(npmSourceEntry)) {
172
+ log.info({ path: npmSourceEntry }, "Found CES source via npm package");
173
+ return { mode: "local-source", sourcePath: npmSourceEntry };
174
+ }
175
+ } catch {
176
+ // Package not installed — fall through to unavailable
177
+ }
178
+
163
179
  const reason = `CES executable not found. Searched: ${searchPaths.join(", ")}; also checked source at ${sourceEntry}`;
164
180
  log.warn(reason);
165
181
  return { mode: "unavailable", reason };
@@ -165,6 +165,12 @@ function makeDisposeContext(
165
165
  const ctx = {
166
166
  conversationId: overrides.conversationId ?? "conv-1",
167
167
  processing: false,
168
+ isProcessing(this: { processing: boolean }) {
169
+ return this.processing;
170
+ },
171
+ setProcessing(this: { processing: boolean }, value: boolean) {
172
+ this.processing = value;
173
+ },
168
174
  abortController,
169
175
  prompter,
170
176
  secretPrompter,