@vellumai/assistant 0.8.2 → 0.8.4

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 (503) hide show
  1. package/ARCHITECTURE.md +11 -12
  2. package/docker-entrypoint.sh +13 -2
  3. package/docker-init-apt-root.sh +79 -6
  4. package/node_modules/@vellumai/gateway-client/src/types.ts +2 -0
  5. package/openapi.yaml +945 -36
  6. package/package.json +1 -1
  7. package/src/__tests__/agent-loop-exit-reason.test.ts +271 -0
  8. package/src/__tests__/agent-loop-override-profile.test.ts +1 -1
  9. package/src/__tests__/agent-loop-provider-error-recording.test.ts +195 -0
  10. package/src/__tests__/agent-loop.test.ts +88 -3
  11. package/src/__tests__/anthropic-provider.test.ts +272 -0
  12. package/src/__tests__/approval-cascade.test.ts +1 -1
  13. package/src/__tests__/background-workers-disk-pressure.test.ts +2 -1
  14. package/src/__tests__/channel-delivery-store.test.ts +193 -0
  15. package/src/__tests__/channel-reply-delivery.test.ts +284 -5
  16. package/src/__tests__/channel-retry-sweep.test.ts +274 -1
  17. package/src/__tests__/compaction-events.test.ts +1 -1
  18. package/src/__tests__/compactor-preserved-tail-count.test.ts +110 -0
  19. package/src/__tests__/compactor-tail-resolution.test.ts +107 -1
  20. package/src/__tests__/config-get-vision-flag.test.ts +136 -0
  21. package/src/__tests__/config-loader-backfill.test.ts +115 -18
  22. package/src/__tests__/config-watcher.test.ts +1 -1
  23. package/src/__tests__/context-token-estimator.test.ts +112 -57
  24. package/src/__tests__/conversation-abort-tool-results.test.ts +1 -1
  25. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +54 -3
  26. package/src/__tests__/conversation-agent-loop-overflow.test.ts +31 -6
  27. package/src/__tests__/conversation-agent-loop.test.ts +77 -3
  28. package/src/__tests__/conversation-app-control-lifecycle.test.ts +1 -1
  29. package/src/__tests__/conversation-clean-command.test.ts +137 -0
  30. package/src/__tests__/conversation-confirmation-signals.test.ts +1 -1
  31. package/src/__tests__/conversation-fork-crud.test.ts +161 -0
  32. package/src/__tests__/conversation-lifecycle.test.ts +1 -1
  33. package/src/__tests__/conversation-load-cleaned-at.test.ts +279 -0
  34. package/src/__tests__/conversation-load-history-repair.test.ts +1 -1
  35. package/src/__tests__/conversation-media-retry.test.ts +19 -8
  36. package/src/__tests__/conversation-pairing.test.ts +2 -2
  37. package/src/__tests__/conversation-process-callsite.test.ts +1 -1
  38. package/src/__tests__/conversation-provider-retry-repair.test.ts +1 -1
  39. package/src/__tests__/conversation-queue.test.ts +1 -1
  40. package/src/__tests__/conversation-runtime-assembly.test.ts +290 -85
  41. package/src/__tests__/conversation-seed-composer.test.ts +66 -4
  42. package/src/__tests__/conversation-slash-commands.test.ts +36 -8
  43. package/src/__tests__/conversation-slash-queue.test.ts +1 -1
  44. package/src/__tests__/conversation-slash-unknown.test.ts +1 -1
  45. package/src/__tests__/conversation-speed-override.test.ts +1 -1
  46. package/src/__tests__/conversation-surfaces-task-progress.test.ts +220 -0
  47. package/src/__tests__/conversation-workspace-cache-state.test.ts +1 -1
  48. package/src/__tests__/conversation-workspace-injection.test.ts +5 -1
  49. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +5 -1
  50. package/src/__tests__/credential-security-invariants.test.ts +6 -0
  51. package/src/__tests__/cu-unified-flow.test.ts +10 -1
  52. package/src/__tests__/date-context.test.ts +45 -0
  53. package/src/__tests__/dm-backfill.test.ts +64 -0
  54. package/src/__tests__/dm-persistence.test.ts +33 -0
  55. package/src/__tests__/document-find-replace.test.ts +501 -0
  56. package/src/__tests__/external-plugin-loader.test.ts +91 -19
  57. package/src/__tests__/first-greeting.test.ts +23 -2
  58. package/src/__tests__/guardian-action-no-hardcoded-copy.test.ts +0 -1
  59. package/src/__tests__/guardian-dispatch.test.ts +1 -0
  60. package/src/__tests__/headless-browser-navigate.test.ts +172 -0
  61. package/src/__tests__/heartbeat-service.test.ts +24 -164
  62. package/src/__tests__/helpers/channel-test-adapter.ts +0 -2
  63. package/src/__tests__/host-app-control-proxy.test.ts +241 -0
  64. package/src/__tests__/host-bash-proxy.test.ts +6 -0
  65. package/src/__tests__/host-browser-proxy.test.ts +10 -0
  66. package/src/__tests__/host-cu-proxy.test.ts +8 -1
  67. package/src/__tests__/host-file-proxy.test.ts +8 -1
  68. package/src/__tests__/host-proxy-preactivation.test.ts +200 -13
  69. package/src/__tests__/host-transfer-proxy.test.ts +8 -1
  70. package/src/__tests__/identity-routes.test.ts +57 -0
  71. package/src/__tests__/inbound-slack-persistence.test.ts +3 -0
  72. package/src/__tests__/injector-background-turn.test.ts +153 -0
  73. package/src/__tests__/injector-chain.test.ts +7 -0
  74. package/src/__tests__/injector-document-comments.test.ts +378 -0
  75. package/src/__tests__/injector-pkb-v2-silenced.test.ts +4 -25
  76. package/src/__tests__/lifecycle-memory-v2-seed.test.ts +9 -2
  77. package/src/__tests__/list-messages-attachments.test.ts +21 -17
  78. package/src/__tests__/list-messages-hidden-metadata.test.ts +217 -0
  79. package/src/__tests__/list-messages-page-latest.test.ts +130 -14
  80. package/src/__tests__/list-messages-tool-merge.test.ts +17 -16
  81. package/src/__tests__/llm-callsite-catalog.test.ts +25 -0
  82. package/src/__tests__/llm-catalog-parity.test.ts +3 -0
  83. package/src/__tests__/llm-context-normalization.test.ts +0 -2
  84. package/src/__tests__/llm-request-log-agent-loop-exit-reason.test.ts +116 -0
  85. package/src/__tests__/llm-request-log-error-payload.test.ts +138 -0
  86. package/src/__tests__/llm-request-log-source-clickhouse.test.ts +2 -0
  87. package/src/__tests__/llm-resolver.test.ts +340 -3
  88. package/src/__tests__/log-export-routes.test.ts +99 -2
  89. package/src/__tests__/managed-profile-guard.test.ts +10 -0
  90. package/src/__tests__/message-queue-steer.test.ts +114 -0
  91. package/src/__tests__/notification-decision-fallback.test.ts +0 -91
  92. package/src/__tests__/notification-decision-strategy.test.ts +14 -31
  93. package/src/__tests__/notification-deep-link.test.ts +15 -0
  94. package/src/__tests__/notification-guardian-path.test.ts +1 -2
  95. package/src/__tests__/notification-platform-adapter.test.ts +5 -4
  96. package/src/__tests__/notification-telegram-adapter.test.ts +1 -0
  97. package/src/__tests__/notification-vellum-adapter.test.ts +113 -0
  98. package/src/__tests__/openai-provider.test.ts +323 -3
  99. package/src/__tests__/openai-responses-cutover-guard.test.ts +3 -3
  100. package/src/__tests__/openai-responses-provider.test.ts +4 -4
  101. package/src/__tests__/openrouter-provider-only.test.ts +51 -3
  102. package/src/__tests__/openrouter-token-estimation.test.ts +34 -25
  103. package/src/__tests__/outbound-slack-persistence.test.ts +187 -20
  104. package/src/__tests__/pending-interactions-resolved-event.test.ts +190 -0
  105. package/src/__tests__/platform-proxy-context.test.ts +6 -1
  106. package/src/__tests__/platform.test.ts +0 -3
  107. package/src/__tests__/plugin-source-watcher.test.ts +302 -0
  108. package/src/__tests__/plugin-tool-contribution.test.ts +3 -3
  109. package/src/__tests__/plugin-types.test.ts +2 -2
  110. package/src/__tests__/process-message-background-slack.test.ts +1 -51
  111. package/src/__tests__/process-message-display-content.test.ts +21 -16
  112. package/src/__tests__/provider-catalog-visibility.test.ts +16 -0
  113. package/src/__tests__/provider-platform-proxy-integration.test.ts +27 -25
  114. package/src/__tests__/secret-routes-platform-proxy.test.ts +1 -1
  115. package/src/__tests__/server-history-render.test.ts +83 -4
  116. package/src/__tests__/steer-tool-repair.test.ts +249 -0
  117. package/src/__tests__/system-prompt.test.ts +57 -101
  118. package/src/__tests__/terminal-tools.test.ts +11 -1
  119. package/src/__tests__/thinking-block-replay.test.ts +113 -0
  120. package/src/__tests__/thread-backfill.test.ts +370 -22
  121. package/src/__tests__/tool-executor.test.ts +90 -1
  122. package/src/__tests__/tool-result-metadata-plumbing.test.ts +167 -0
  123. package/src/__tests__/twilio-routes.test.ts +1 -1
  124. package/src/__tests__/web-fetch.test.ts +2 -2
  125. package/src/__tests__/workspace-git-service.test.ts +88 -5
  126. package/src/__tests__/workspace-migration-087-memory-router-balanced-profile.test.ts +228 -0
  127. package/src/__tests__/workspace-migration-088-deprecate-background-conversation-override.test.ts +158 -0
  128. package/src/a2a/__tests__/agent-card.test.ts +98 -0
  129. package/src/a2a/__tests__/e2e-a2a-channel.test.ts +597 -0
  130. package/src/a2a/__tests__/protocol-helpers.test.ts +113 -0
  131. package/src/a2a/__tests__/task-store.test.ts +246 -0
  132. package/src/a2a/agent-card.ts +58 -0
  133. package/src/a2a/feature-gate.ts +8 -0
  134. package/src/a2a/protocol-constants.ts +21 -0
  135. package/src/a2a/protocol-errors.ts +50 -0
  136. package/src/a2a/protocol-types.ts +162 -0
  137. package/src/a2a/task-store.ts +168 -0
  138. package/src/agent/attachments.ts +1 -0
  139. package/src/agent/loop.ts +208 -22
  140. package/src/background-wake/next-wake.test.ts +289 -0
  141. package/src/background-wake/next-wake.ts +172 -0
  142. package/src/browser/operations.ts +15 -0
  143. package/src/channels/config.ts +9 -0
  144. package/src/channels/types.ts +14 -0
  145. package/src/cli/commands/__tests__/conversations-slack.test.ts +572 -0
  146. package/src/cli/commands/__tests__/memory-v2.test.ts +9 -12
  147. package/src/cli/{__tests__ → commands/__tests__}/notifications.test.ts +201 -28
  148. package/src/cli/commands/__tests__/schedules.test.ts +469 -0
  149. package/src/cli/commands/conversations.ts +128 -1
  150. package/src/cli/commands/inference-providers.ts +147 -1
  151. package/src/cli/commands/memory-v2.ts +308 -0
  152. package/src/cli/commands/notifications.ts +89 -37
  153. package/src/cli/commands/plugins.ts +67 -0
  154. package/src/cli/commands/schedules.ts +297 -5
  155. package/src/cli/lib/__tests__/search-plugins.test.ts +261 -0
  156. package/src/cli/lib/install-from-github.ts +8 -9
  157. package/src/cli/lib/search-plugins.ts +163 -0
  158. package/src/cli/program.ts +14 -0
  159. package/src/cli/utils/conversation-id.ts +17 -5
  160. package/src/config/assistant-feature-flags.ts +24 -54
  161. package/src/config/bundled-skills/app-builder/SKILL.md +117 -1
  162. package/src/config/bundled-skills/document-editor/SKILL.md +115 -0
  163. package/src/config/bundled-skills/document-editor/TOOLS.json +240 -0
  164. package/src/config/bundled-skills/document-editor/tools/comment-list.ts +12 -0
  165. package/src/config/bundled-skills/document-editor/tools/comment-reply.ts +12 -0
  166. package/src/config/bundled-skills/document-editor/tools/comment-resolve.ts +12 -0
  167. package/src/config/bundled-skills/document-editor/tools/document-find.ts +12 -0
  168. package/src/config/bundled-skills/document-editor/tools/document-replace-text.ts +12 -0
  169. package/src/config/bundled-skills/media-processing/SKILL.md +8 -0
  170. package/src/config/bundled-skills/phone-calls/SKILL.md +1 -1
  171. package/src/config/bundled-skills/schedule/SKILL.md +8 -0
  172. package/src/config/bundled-tool-registry.ts +22 -12
  173. package/src/config/call-site-defaults.ts +124 -0
  174. package/src/config/feature-flag-registry.json +111 -23
  175. package/src/config/llm-resolver.ts +66 -1
  176. package/src/config/schema.ts +2 -0
  177. package/src/config/schemas/__tests__/memory-v2.test.ts +7 -3
  178. package/src/config/schemas/call-site-catalog.ts +21 -0
  179. package/src/config/schemas/channels.ts +9 -0
  180. package/src/config/schemas/conversations.ts +10 -0
  181. package/src/config/schemas/heartbeat.ts +14 -0
  182. package/src/config/schemas/llm.ts +4 -3
  183. package/src/config/schemas/memory-retrospective.ts +1 -1
  184. package/src/config/schemas/memory-v2.ts +51 -4
  185. package/src/config/schemas/memory.ts +3 -1
  186. package/src/config/seed-inference-profiles.ts +99 -29
  187. package/src/context/compactor.ts +80 -13
  188. package/src/context/token-estimator.ts +72 -31
  189. package/src/context/window-manager.ts +25 -0
  190. package/src/credential-health/credential-health-service.ts +34 -19
  191. package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +3 -22
  192. package/src/daemon/__tests__/conversation-tool-setup.test.ts +66 -6
  193. package/src/daemon/__tests__/native-web-search-metadata.test.ts +357 -0
  194. package/src/daemon/__tests__/web-search-status-text.test.ts +287 -0
  195. package/src/daemon/conversation-agent-loop-handlers.ts +231 -23
  196. package/src/daemon/conversation-agent-loop.ts +252 -56
  197. package/src/daemon/conversation-lifecycle.ts +142 -116
  198. package/src/daemon/conversation-messaging.ts +3 -0
  199. package/src/daemon/conversation-process.ts +273 -0
  200. package/src/daemon/conversation-queue-manager.ts +14 -0
  201. package/src/daemon/conversation-runtime-assembly.ts +144 -75
  202. package/src/daemon/conversation-slash.ts +37 -5
  203. package/src/daemon/conversation-surfaces.ts +45 -2
  204. package/src/daemon/conversation-tool-setup.ts +7 -0
  205. package/src/daemon/conversation.ts +42 -12
  206. package/src/daemon/date-context.ts +40 -0
  207. package/src/daemon/first-greeting.ts +10 -0
  208. package/src/daemon/guardian-action-generators.ts +1 -125
  209. package/src/daemon/handlers/__tests__/config-a2a-accept.test.ts +498 -0
  210. package/src/daemon/handlers/__tests__/config-a2a-complete.test.ts +248 -0
  211. package/src/daemon/handlers/__tests__/config-a2a-invite.test.ts +154 -0
  212. package/src/daemon/handlers/__tests__/config-a2a-redeem.test.ts +133 -0
  213. package/src/daemon/handlers/__tests__/config-a2a.test.ts +95 -0
  214. package/src/daemon/handlers/config-a2a.ts +449 -0
  215. package/src/daemon/handlers/config-model.test.ts +1 -0
  216. package/src/daemon/handlers/conversations.ts +80 -0
  217. package/src/daemon/handlers/shared.ts +92 -29
  218. package/src/daemon/host-app-control-proxy.ts +69 -18
  219. package/src/daemon/host-bash-proxy.ts +1 -1
  220. package/src/daemon/host-cu-proxy.ts +1 -1
  221. package/src/daemon/host-file-proxy.ts +1 -1
  222. package/src/daemon/host-proxy-preactivation.ts +85 -18
  223. package/src/daemon/host-transfer-proxy.ts +1 -1
  224. package/src/daemon/lifecycle.ts +67 -65
  225. package/src/daemon/memory-v2-startup.ts +49 -13
  226. package/src/daemon/message-protocol.ts +4 -0
  227. package/src/daemon/message-types/conversations.ts +8 -0
  228. package/src/daemon/message-types/document-comments.ts +50 -0
  229. package/src/daemon/message-types/messages.ts +68 -1
  230. package/src/daemon/message-types/notifications.ts +21 -0
  231. package/src/daemon/message-types/surfaces.ts +3 -1
  232. package/src/daemon/message-types/web-activity.ts +57 -0
  233. package/src/daemon/pkb-reminder-builder.test.ts +10 -53
  234. package/src/daemon/pkb-reminder-builder.ts +4 -19
  235. package/src/daemon/plugin-source-watcher.ts +135 -3
  236. package/src/daemon/process-message.ts +72 -12
  237. package/src/daemon/query-complexity-router.ts +75 -0
  238. package/src/daemon/skill-memory-refresh.ts +5 -1
  239. package/src/daemon/trust-context.ts +6 -0
  240. package/src/daemon/wake-target-adapter.ts +2 -0
  241. package/src/documents/document-comments-store.test.ts +338 -0
  242. package/src/documents/document-comments-store.ts +237 -0
  243. package/src/documents/document-store.ts +202 -0
  244. package/src/export/__tests__/transcript-formatter.test.ts +121 -0
  245. package/src/export/transcript-formatter.ts +54 -20
  246. package/src/heartbeat/__tests__/heartbeat-service.test.ts +44 -1
  247. package/src/heartbeat/heartbeat-service.ts +35 -191
  248. package/src/home/__tests__/feed-types.test.ts +40 -0
  249. package/src/home/__tests__/suggested-prompts.test.ts +33 -2
  250. package/src/home/feed-types.ts +20 -3
  251. package/src/home/home-content-refresh.ts +52 -0
  252. package/src/home/home-greeting-cache.ts +69 -0
  253. package/src/home/home-greeting.ts +94 -0
  254. package/src/home/suggested-prompts.ts +177 -9
  255. package/src/ipc/cli-client.ts +147 -45
  256. package/src/memory/__tests__/conversation-queries.test.ts +220 -0
  257. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +135 -2
  258. package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +2 -50
  259. package/src/memory/__tests__/memory-retrospective-job.test.ts +407 -10
  260. package/src/memory/conversation-crud.ts +133 -43
  261. package/src/memory/conversation-queries.ts +87 -1
  262. package/src/memory/conversation-title-service.ts +26 -4
  263. package/src/memory/db-init.ts +22 -0
  264. package/src/memory/delivery-crud.ts +41 -0
  265. package/src/memory/delivery-status.ts +141 -15
  266. package/src/memory/external-conversation-store.ts +32 -1
  267. package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +84 -3
  268. package/src/memory/graph/conversation-graph-memory.ts +18 -6
  269. package/src/memory/graph/tools.ts +6 -37
  270. package/src/memory/invite-store.ts +53 -0
  271. package/src/memory/jobs-worker.ts +21 -1
  272. package/src/memory/llm-request-log-source-clickhouse.ts +7 -2
  273. package/src/memory/llm-request-log-store.ts +92 -1
  274. package/src/memory/memory-retrospective-constants.ts +28 -0
  275. package/src/memory/memory-retrospective-enqueue.ts +4 -22
  276. package/src/memory/memory-retrospective-job.ts +438 -21
  277. package/src/memory/memory-retrospective-startup-cleanup.ts +3 -3
  278. package/src/memory/memory-v2-activation-log-store.ts +26 -8
  279. package/src/memory/migrations/100-core-tables.ts +1 -0
  280. package/src/memory/migrations/109-external-conversation-bindings.ts +1 -0
  281. package/src/memory/migrations/250-provider-connection-base-url-and-models.ts +28 -0
  282. package/src/memory/migrations/251-a2a-tasks.ts +49 -0
  283. package/src/memory/migrations/252-llm-request-log-agent-loop-exit-reason.ts +32 -0
  284. package/src/memory/migrations/253-conversation-last-notified-profile.ts +15 -0
  285. package/src/memory/migrations/253-document-comments.ts +47 -0
  286. package/src/memory/migrations/254-external-conversation-binding-chat-name.ts +43 -0
  287. package/src/memory/migrations/255-channel-inbound-delivery-attempts.ts +24 -0
  288. package/src/memory/migrations/256-memory-v2-injection-events.ts +113 -0
  289. package/src/memory/migrations/257-strip-base-url-non-openai-compatible.ts +22 -0
  290. package/src/memory/migrations/258-onboarding-events-prior-assistants.ts +13 -0
  291. package/src/memory/migrations/259-conversation-cleaned-at.ts +33 -0
  292. package/src/memory/migrations/index.ts +20 -0
  293. package/src/memory/migrations/registry.ts +33 -0
  294. package/src/memory/onboarding-events-store.ts +7 -0
  295. package/src/memory/schema/a2a.ts +15 -0
  296. package/src/memory/schema/calls.ts +1 -0
  297. package/src/memory/schema/conversations.ts +3 -0
  298. package/src/memory/schema/index.ts +1 -0
  299. package/src/memory/schema/inference.ts +2 -0
  300. package/src/memory/schema/infrastructure.ts +2 -0
  301. package/src/memory/v2/__tests__/activation-store.test.ts +25 -23
  302. package/src/memory/v2/__tests__/cli-command-store.test.ts +404 -0
  303. package/src/memory/v2/__tests__/frontmatter-sweep.test.ts +25 -4
  304. package/src/memory/v2/__tests__/injection-events.test.ts +318 -0
  305. package/src/memory/v2/__tests__/injection.test.ts +221 -17
  306. package/src/memory/v2/__tests__/page-index.test.ts +365 -1
  307. package/src/memory/v2/__tests__/router.test.ts +489 -1
  308. package/src/memory/v2/__tests__/static-context.test.ts +12 -1
  309. package/src/memory/v2/activation-store.ts +14 -16
  310. package/src/memory/v2/cli-command-content.ts +19 -0
  311. package/src/memory/v2/cli-command-store.ts +304 -0
  312. package/src/memory/v2/consolidation-job.ts +14 -0
  313. package/src/memory/v2/frontmatter-sweep.ts +7 -1
  314. package/src/memory/v2/injection-events.ts +101 -0
  315. package/src/memory/v2/injection.ts +69 -29
  316. package/src/memory/v2/page-index.ts +246 -19
  317. package/src/memory/v2/page-store.ts +18 -0
  318. package/src/memory/v2/router.ts +209 -55
  319. package/src/memory/v2/static-context.ts +4 -4
  320. package/src/memory/v2/types.ts +23 -0
  321. package/src/messaging/providers/a2a/__tests__/deliver.test.ts +274 -0
  322. package/src/messaging/providers/a2a/deliver.ts +156 -0
  323. package/src/messaging/providers/gmail/client.ts +9 -2
  324. package/src/messaging/providers/index.ts +18 -3
  325. package/src/messaging/providers/slack/__tests__/adapter-mention-rendering.test.ts +329 -3
  326. package/src/messaging/providers/slack/__tests__/adapter-token-routing.test.ts +34 -1
  327. package/src/messaging/providers/slack/adapter.ts +178 -25
  328. package/src/messaging/providers/slack/api.test.ts +54 -0
  329. package/src/messaging/providers/slack/api.ts +119 -3
  330. package/src/messaging/providers/slack/client.ts +12 -0
  331. package/src/messaging/providers/slack/deep-link.ts +20 -1
  332. package/src/messaging/providers/slack/message-metadata.test.ts +48 -0
  333. package/src/messaging/providers/slack/message-metadata.ts +156 -0
  334. package/src/messaging/providers/slack/render-transcript.test.ts +107 -75
  335. package/src/messaging/providers/slack/render-transcript.ts +176 -49
  336. package/src/messaging/providers/slack/send.test.ts +77 -0
  337. package/src/messaging/providers/slack/send.ts +8 -2
  338. package/src/messaging/providers/slack/types.ts +14 -0
  339. package/src/notifications/__tests__/broadcaster.test.ts +203 -0
  340. package/src/notifications/__tests__/decision-engine.test.ts +283 -0
  341. package/src/notifications/__tests__/deterministic-checks.test.ts +286 -0
  342. package/src/notifications/__tests__/emit-signal-home-feed.test.ts +5 -1
  343. package/src/notifications/__tests__/home-feed-side-effect.test.ts +521 -36
  344. package/src/notifications/adapters/macos.ts +12 -2
  345. package/src/notifications/broadcaster.ts +29 -4
  346. package/src/notifications/conversation-seed-composer.ts +14 -2
  347. package/src/notifications/copy-composer.ts +17 -64
  348. package/src/notifications/decision-engine.ts +111 -44
  349. package/src/notifications/deferred-emit.ts +135 -0
  350. package/src/notifications/deterministic-checks.ts +96 -0
  351. package/src/notifications/emit-signal.ts +10 -1
  352. package/src/notifications/home-feed-side-effect.ts +136 -27
  353. package/src/notifications/signal.ts +0 -4
  354. package/src/notifications/types.ts +8 -0
  355. package/src/oauth/connect-orchestrator.ts +3 -0
  356. package/src/oauth/credential-token-resolver.ts +2 -0
  357. package/src/oauth/manual-token-connection.ts +19 -0
  358. package/src/oauth/oauth-store.ts +12 -0
  359. package/src/oauth/platform-connection.test.ts +43 -3
  360. package/src/oauth/platform-connection.ts +13 -4
  361. package/src/oauth/seed-providers.ts +22 -0
  362. package/src/permissions/prompter.ts +5 -2
  363. package/src/permissions/secret-prompter.ts +4 -1
  364. package/src/plugins/defaults/injectors.ts +118 -26
  365. package/src/plugins/external-plugin-loader.ts +82 -10
  366. package/src/plugins/types.ts +16 -7
  367. package/src/prompts/__tests__/system-prompt.test.ts +44 -45
  368. package/src/prompts/__tests__/task-progress-hint-section.test.ts +4 -8
  369. package/src/prompts/normalize-onboarding.ts +40 -0
  370. package/src/prompts/sections.ts +32 -14
  371. package/src/prompts/system-prompt.ts +105 -76
  372. package/src/prompts/template-detection.ts +37 -0
  373. package/src/prompts/templates/BOOTSTRAP-CONTENT-AUTOMATION.md +141 -0
  374. package/src/prompts/templates/BOOTSTRAP.md +13 -5
  375. package/src/prompts/templates/VOICE.md +3 -0
  376. package/src/prompts/templates/system-sections.ts +51 -10
  377. package/src/providers/__tests__/inference.test.ts +2 -0
  378. package/src/providers/anthropic/client.ts +132 -5
  379. package/src/providers/call-site-routing.ts +24 -6
  380. package/src/providers/connection-resolution.ts +63 -13
  381. package/src/providers/fireworks/client.ts +20 -2
  382. package/src/providers/inference/__tests__/adapter-factory-openai-compatible.test.ts +74 -0
  383. package/src/providers/inference/__tests__/base-url-route-validation.test.ts +342 -0
  384. package/src/providers/inference/__tests__/base-url-security.test.ts +189 -0
  385. package/src/providers/inference/__tests__/codex-token-refresh.test.ts +254 -0
  386. package/src/providers/inference/__tests__/connections-openai-compatible.test.ts +175 -0
  387. package/src/providers/inference/__tests__/connections-status-label.test.ts +15 -0
  388. package/src/providers/inference/adapter-factory.ts +24 -21
  389. package/src/providers/inference/auth.ts +15 -3
  390. package/src/providers/inference/backfill.ts +14 -1
  391. package/src/providers/inference/codex-token-refresh.ts +128 -0
  392. package/src/providers/inference/connections.ts +85 -5
  393. package/src/providers/inference/resolve-auth.ts +50 -5
  394. package/src/providers/model-catalog.ts +244 -242
  395. package/src/providers/model-intents.ts +3 -3
  396. package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +235 -0
  397. package/src/providers/openai/chat-completions-provider.ts +215 -25
  398. package/src/providers/openai/responses-provider.ts +9 -3
  399. package/src/providers/openrouter/client.ts +46 -4
  400. package/src/providers/platform-proxy/constants.ts +3 -4
  401. package/src/providers/provider-catalog-visibility.ts +3 -1
  402. package/src/providers/provider-send-message.ts +27 -12
  403. package/src/providers/registry.ts +30 -1
  404. package/src/providers/types.ts +25 -0
  405. package/src/runtime/__tests__/agent-wake.test.ts +214 -0
  406. package/src/runtime/__tests__/background-job-runner.test.ts +128 -0
  407. package/src/runtime/agent-wake.ts +212 -57
  408. package/src/runtime/auth/route-policy.ts +20 -3
  409. package/src/runtime/background-job-runner.ts +26 -0
  410. package/src/runtime/channel-reply-delivery.ts +182 -47
  411. package/src/runtime/channel-retry-sweep.ts +141 -16
  412. package/src/runtime/http-server.ts +7 -16
  413. package/src/runtime/http-types.ts +7 -51
  414. package/src/runtime/pending-interactions.ts +51 -8
  415. package/src/runtime/routes/__tests__/consolidation-routes.test.ts +258 -0
  416. package/src/runtime/routes/__tests__/content-source-routes.test.ts +162 -0
  417. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +121 -5
  418. package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +275 -44
  419. package/src/runtime/routes/__tests__/llm-call-sites-routes.test.ts +12 -0
  420. package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +14 -0
  421. package/src/runtime/routes/__tests__/memory-v2-simulate-route.test.ts +271 -0
  422. package/src/runtime/routes/__tests__/sanity-routes.test.ts +280 -0
  423. package/src/runtime/routes/__tests__/slack-channel-routes.test.ts +266 -0
  424. package/src/runtime/routes/approval-routes.ts +4 -1
  425. package/src/runtime/routes/channel-availability-routes.ts +5 -0
  426. package/src/runtime/routes/chatgpt-subscription-auth-routes.ts +246 -0
  427. package/src/runtime/routes/consolidation-routes.ts +100 -0
  428. package/src/runtime/routes/content-source-routes.ts +78 -0
  429. package/src/runtime/routes/conversation-cli-routes.ts +146 -1
  430. package/src/runtime/routes/conversation-query-routes.ts +130 -12
  431. package/src/runtime/routes/conversation-routes.ts +288 -76
  432. package/src/runtime/routes/document-comments-routes.ts +287 -0
  433. package/src/runtime/routes/documents-routes.ts +33 -0
  434. package/src/runtime/routes/home-feed-routes.ts +6 -3
  435. package/src/runtime/routes/host-app-control-routes.ts +1 -1
  436. package/src/runtime/routes/host-browser-routes.ts +8 -1
  437. package/src/runtime/routes/identity-routes.ts +21 -0
  438. package/src/runtime/routes/inbound-message-handler.ts +288 -58
  439. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +365 -6
  440. package/src/runtime/routes/inbound-stages/background-dispatch.ts +283 -82
  441. package/src/runtime/routes/index.ts +14 -4
  442. package/src/runtime/routes/inference-provider-connection-routes.ts +192 -3
  443. package/src/runtime/routes/integrations/a2a.ts +294 -0
  444. package/src/runtime/routes/llm-call-sites-routes.ts +11 -1
  445. package/src/runtime/routes/log-export-routes.ts +39 -0
  446. package/src/runtime/routes/memory-v2-routes.ts +217 -0
  447. package/src/runtime/routes/notification-routes.ts +19 -2
  448. package/src/runtime/routes/question-routes.ts +4 -1
  449. package/src/runtime/routes/sanity-routes.ts +159 -0
  450. package/src/runtime/routes/slack-channel-routes.ts +187 -0
  451. package/src/runtime/routes/subagents-routes.ts +41 -0
  452. package/src/runtime/services/conversation-serializer.ts +30 -4
  453. package/src/schedule/integration-status.ts +3 -1
  454. package/src/security/__tests__/oauth2-device-code.test.ts +479 -0
  455. package/src/security/oauth2-device-code.ts +307 -0
  456. package/src/security/oauth2.ts +26 -9
  457. package/src/security/secure-keys.ts +5 -0
  458. package/src/skills/catalog-install.ts +6 -2
  459. package/src/subagent/manager.ts +2 -0
  460. package/src/tools/browser/__tests__/pinned-tabs.test.ts +80 -0
  461. package/src/tools/browser/browser-execution.ts +93 -0
  462. package/src/tools/browser/cdp-client/__tests__/factory.test.ts +28 -0
  463. package/src/tools/browser/cdp-client/__tests__/types.test.ts +1 -0
  464. package/src/tools/browser/cdp-client/cdp-inspect-client.ts +10 -0
  465. package/src/tools/browser/cdp-client/extension-cdp-client.ts +15 -1
  466. package/src/tools/browser/cdp-client/factory.ts +87 -3
  467. package/src/tools/browser/cdp-client/local-cdp-client.ts +9 -0
  468. package/src/tools/browser/cdp-client/types.ts +36 -0
  469. package/src/tools/browser/pinned-tabs.ts +90 -0
  470. package/src/tools/document/document-comment-tool.test.ts +379 -0
  471. package/src/tools/document/document-comment-tool.ts +156 -0
  472. package/src/tools/document/document-tool.ts +128 -2
  473. package/src/tools/memory/register.ts +1 -9
  474. package/src/tools/network/__tests__/web-fetch-metadata.test.ts +229 -0
  475. package/src/tools/network/__tests__/web-search-metadata.test.ts +346 -0
  476. package/src/tools/network/domain-normalize.ts +17 -0
  477. package/src/tools/network/web-fetch.ts +213 -64
  478. package/src/tools/network/web-search.ts +191 -66
  479. package/src/tools/registry.ts +2 -2
  480. package/src/tools/terminal/safe-env.ts +3 -2
  481. package/src/tools/tool-approval-handler.ts +19 -12
  482. package/src/tools/types.ts +41 -2
  483. package/src/tools/ui-surface/definitions.ts +3 -1
  484. package/src/types/onboarding-context.ts +4 -0
  485. package/src/util/__tests__/favicon.test.ts +84 -0
  486. package/src/util/favicon.ts +40 -0
  487. package/src/util/platform.ts +0 -5
  488. package/src/workspace/git-service.ts +75 -4
  489. package/src/workspace/migrations/087-memory-router-balanced-profile.ts +91 -0
  490. package/src/workspace/migrations/088-deprecate-background-conversation-override.ts +103 -0
  491. package/src/workspace/migrations/registry.ts +4 -0
  492. package/src/__tests__/guardian-action-conversation-turn.test.ts +0 -441
  493. package/src/config/bundled-skills/document/SKILL.md +0 -54
  494. package/src/config/bundled-skills/document/TOOLS.json +0 -106
  495. package/src/daemon/seed-files.ts +0 -18
  496. package/src/memory/graph/__tests__/remember-description.test.ts +0 -55
  497. package/src/runtime/guardian-action-conversation-turn.ts +0 -99
  498. package/src/runtime/routes/interface-routes.ts +0 -43
  499. /package/src/config/bundled-skills/{document → document-editor}/tools/document-create.ts +0 -0
  500. /package/src/config/bundled-skills/{document → document-editor}/tools/document-delete.ts +0 -0
  501. /package/src/config/bundled-skills/{document → document-editor}/tools/document-list.ts +0 -0
  502. /package/src/config/bundled-skills/{document → document-editor}/tools/document-read.ts +0 -0
  503. /package/src/config/bundled-skills/{document → document-editor}/tools/document-update.ts +0 -0
@@ -32,6 +32,7 @@ import {
32
32
  } from "../credential-execution/startup-timeout.js";
33
33
  import { FilingService } from "../filing/filing-service.js";
34
34
  import { HeartbeatService } from "../heartbeat/heartbeat-service.js";
35
+ import { startHomeContentRefresh } from "../home/home-content-refresh.js";
35
36
  import { backfillRelationshipStateIfMissing } from "../home/relationship-state-writer.js";
36
37
  import { closeSentry, initSentry, setSentryDeviceId } from "../instrument.js";
37
38
  import { getMcpServerManager } from "../mcp/manager.js";
@@ -49,6 +50,7 @@ import { startMemoryJobsWorker } from "../memory/jobs-worker.js";
49
50
  import { initQdrantClient, resolveQdrantUrl } from "../memory/qdrant-client.js";
50
51
  import { QdrantManager } from "../memory/qdrant-manager.js";
51
52
  import { rotateToolInvocations } from "../memory/tool-usage-store.js";
53
+ import { sweepConceptPageFrontmatter } from "../memory/v2/frontmatter-sweep.js";
52
54
  import {
53
55
  emitNotificationSignal,
54
56
  registerBroadcastFn,
@@ -96,10 +98,6 @@ import {
96
98
  import { WorkspaceHeartbeatService } from "../workspace/heartbeat-service.js";
97
99
  import { WORKSPACE_MIGRATIONS } from "../workspace/migrations/registry.js";
98
100
  import { runWorkspaceMigrations } from "../workspace/migrations/runner.js";
99
- import {
100
- createApprovalConversationGenerator,
101
- createApprovalCopyGenerator,
102
- } from "./approval-generators.js";
103
101
  import {
104
102
  cleanupPidFile,
105
103
  cleanupPidFileIfOwner,
@@ -111,10 +109,6 @@ import {
111
109
  stopDiskPressureGuard,
112
110
  } from "./disk-pressure-guard.js";
113
111
  import { bootstrapPlugins } from "./external-plugins-bootstrap.js";
114
- import {
115
- createGuardianActionCopyGenerator,
116
- createGuardianFollowUpConversationGenerator,
117
- } from "./guardian-action-generators.js";
118
112
  import { backfillSlackInjectionTemplates } from "./handlers/config-slack-channel.js";
119
113
  import { installAssistantSymlink } from "./install-symlink.js";
120
114
  import {
@@ -128,7 +122,6 @@ import {
128
122
  registerMessagingProviders,
129
123
  registerWatcherProviders,
130
124
  } from "./providers-setup.js";
131
- import { seedInterfaceFiles } from "./seed-files.js";
132
125
  import { DaemonServer } from "./server.js";
133
126
  import { installShutdownHandlers } from "./shutdown-handlers.js";
134
127
  import { refreshSkillCapabilityMemories } from "./skill-memory-refresh.js";
@@ -276,8 +269,13 @@ async function startCesProcess(
276
269
 
277
270
  // Entry point for the daemon process itself
278
271
  export async function runDaemon(): Promise<void> {
272
+ const startupStartedAt = Date.now();
273
+ // dotenv loads before the first log call so the lazy root logger
274
+ // initializes against the final VELLUM_WORKSPACE_DIR / log path, not
275
+ // whatever was in the live environment at process spawn.
279
276
  loadDotEnv();
280
277
  validateEnv();
278
+ log.info({ version: APP_VERSION }, "Daemon starting");
281
279
 
282
280
  try {
283
281
  // Initialize crash reporting eagerly so early startup failures are
@@ -322,6 +320,35 @@ export async function runDaemon(): Promise<void> {
322
320
  const signingKey = resolveSigningKey();
323
321
  initAuthSigningKey(signingKey);
324
322
 
323
+ // Start the runtime HTTP server early so /healthz answers ASAP.
324
+ let runtimeHttp: RuntimeHttpServer | null = null;
325
+ const httpPort = getRuntimeHttpPort();
326
+ const httpHostname = getRuntimeHttpHost();
327
+ log.info({ httpPort }, "Daemon startup: starting runtime HTTP server");
328
+
329
+ runtimeHttp = new RuntimeHttpServer({
330
+ port: httpPort,
331
+ hostname: httpHostname,
332
+ });
333
+
334
+ // Isolated try/catch around start() — a bind failure (port in use,
335
+ // permission denied, fd exhaustion) must not tear down the rest of
336
+ // daemon startup. The daemon falls back to IPC-only operation when
337
+ // runtimeHttp is null.
338
+ try {
339
+ await runtimeHttp.start();
340
+ log.info(
341
+ { port: httpPort, hostname: httpHostname },
342
+ "Daemon startup: runtime HTTP server listening",
343
+ );
344
+ } catch (err) {
345
+ log.warn(
346
+ { err, port: httpPort },
347
+ "Failed to start runtime HTTP server, continuing without it",
348
+ );
349
+ runtimeHttp = null;
350
+ }
351
+
325
352
  // Pre-populate feature flag overrides so subsequent sync
326
353
  // isAssistantFeatureFlagEnabled() calls have data. Fired non-blocking
327
354
  // so a slow or unreachable gateway doesn't delay daemon startup (the
@@ -331,8 +358,6 @@ export async function runDaemon(): Promise<void> {
331
358
  log.warn({ err }, "Background feature flag init failed"),
332
359
  );
333
360
 
334
- seedInterfaceFiles();
335
-
336
361
  log.info("Daemon startup: initializing DB");
337
362
  ensurePromptFiles();
338
363
 
@@ -448,6 +473,10 @@ export async function runDaemon(): Promise<void> {
448
473
  );
449
474
  });
450
475
 
476
+ // Pre-warm LLM-generated home page content (greeting + suggestion
477
+ // prompts) so the GET handler never triggers LLM calls.
478
+ startHomeContentRefresh();
479
+
451
480
  // Backfill injection templates on Slack bot token credentials so the
452
481
  // credential proxy can inject Authorization headers. Safe on every startup.
453
482
  try {
@@ -861,34 +890,16 @@ export async function runDaemon(): Promise<void> {
861
890
  })();
862
891
  }
863
892
 
864
- // Build the BM25 corpus stats (per-token document frequencies and
865
- // average document length) used by the v2 sparse channel, then
866
- // re-seed v2 skill entries so any skill vectors written during the
867
- // cold-start window with the legacy TF encoder get rewritten with
868
- // stemmed BM25 vectors. Fire-and-forget for the same reason as PKB
869
- // reconcile — the stats and skill reseed are optional optimizations,
870
- // never boot-blocking dependencies.
871
893
  void rebuildBm25CorpusStatsAndReseedSkills(config);
872
894
 
873
- // Validate every concept page's frontmatter against the strict
874
- // schema and emit a `warn` per offender. Surfaces schema drift
875
- // (unknown keys, type mismatches) at boot time instead of waiting
876
- // for the failure to manifest as a silent V2 retrieval no-op when
877
- // a bad page first lands in a conversation's top-K. Fire-and-forget
878
- // and the sweep itself never throws defense in depth via the
879
- // outer try/catch.
880
- void (async () => {
881
- try {
882
- const { sweepConceptPageFrontmatter } =
883
- await import("../memory/v2/frontmatter-sweep.js");
884
- await sweepConceptPageFrontmatter(getWorkspaceDir());
885
- } catch (err) {
886
- log.warn(
887
- { err },
888
- "Concept page frontmatter sweep threw — continuing startup",
889
- );
890
- }
891
- })();
895
+ try {
896
+ await sweepConceptPageFrontmatter(config, getWorkspaceDir());
897
+ } catch (err) {
898
+ log.warn(
899
+ { err },
900
+ "Concept page frontmatter sweep threwcontinuing startup",
901
+ );
902
+ }
892
903
  }
893
904
 
894
905
  log.info("Daemon startup: starting memory worker");
@@ -1009,24 +1020,12 @@ export async function runDaemon(): Promise<void> {
1009
1020
  },
1010
1021
  );
1011
1022
 
1012
- // Start the runtime HTTP server for optional REST API access.
1013
- // Defaults to port 7821.
1014
- let runtimeHttp: RuntimeHttpServer | null = null;
1015
- const httpPort = getRuntimeHttpPort();
1016
- log.info({ httpPort }, "Daemon startup: starting runtime HTTP server");
1017
-
1018
- const hostname = getRuntimeHttpHost();
1019
-
1020
- runtimeHttp = new RuntimeHttpServer({
1021
- port: httpPort,
1022
- hostname,
1023
- approvalCopyGenerator: createApprovalCopyGenerator(),
1024
- approvalConversationGenerator: createApprovalConversationGenerator(),
1025
- guardianActionCopyGenerator: createGuardianActionCopyGenerator(),
1026
- guardianFollowUpConversationGenerator:
1027
- createGuardianFollowUpConversationGenerator(),
1028
- });
1029
-
1023
+ // Wire up the runtime HTTP server's deferred dependencies. The server
1024
+ // itself was bound early in runDaemon (right after the auth signing key
1025
+ // was loaded) so /healthz and /readyz already answer 200 OK; these
1026
+ // registrations attach the live DaemonServer / CES / relay handlers to
1027
+ // the running routes. They're module-level state, so they're effective
1028
+ // even when the HTTP server failed to bind (IPC clients still work).
1030
1029
  registerSecretsDeps({
1031
1030
  getCesClient: () => server.getCesClient(),
1032
1031
  onProviderCredentialsChanged: () =>
@@ -1043,8 +1042,9 @@ export async function runDaemon(): Promise<void> {
1043
1042
  log.warn({ err }, "Background Qdrant init failed"),
1044
1043
  );
1045
1044
 
1046
- // Inject voice bridge deps BEFORE attempting to start the HTTP server.
1047
- // The bridge must be available even when the HTTP server fails to bind.
1045
+ // Inject voice bridge deps so route handlers + the relay pipeline can
1046
+ // resolve a conversation by ID once a call lands. Module-level state,
1047
+ // so available even when the HTTP server failed to bind.
1048
1048
  setVoiceBridgeDeps({
1049
1049
  getOrCreateConversation: (conversationId, _transport) =>
1050
1050
  server.getConversationForMessages(conversationId),
@@ -1063,7 +1063,6 @@ export async function runDaemon(): Promise<void> {
1063
1063
  },
1064
1064
  });
1065
1065
  try {
1066
- await runtimeHttp.start();
1067
1066
  setRelayBroadcast((msg) => broadcastMessage(msg));
1068
1067
  setPointerMessageProcessor(
1069
1068
  async (conversationId, instruction, requiredFacts) => {
@@ -1201,14 +1200,10 @@ export async function runDaemon(): Promise<void> {
1201
1200
  },
1202
1201
  );
1203
1202
  server.broadcastStatus();
1204
- log.info(
1205
- { port: httpPort, hostname },
1206
- "Daemon startup: runtime HTTP server listening",
1207
- );
1208
1203
  } catch (err) {
1209
1204
  log.warn(
1210
- { err, port: httpPort },
1211
- "Failed to start runtime HTTP server, continuing without it",
1205
+ { err },
1206
+ "Failed to wire runtime HTTP server deps, continuing without them",
1212
1207
  );
1213
1208
  runtimeHttp = null;
1214
1209
  }
@@ -1240,7 +1235,6 @@ export async function runDaemon(): Promise<void> {
1240
1235
  }
1241
1236
 
1242
1237
  writePid(process.pid);
1243
- log.info({ pid: process.pid }, "Daemon started");
1244
1238
 
1245
1239
  // Install the `assistant` CLI symlink idempotently on every daemon start.
1246
1240
  // Non-blocking — failures are logged but don't affect startup.
@@ -1357,6 +1351,14 @@ export async function runDaemon(): Promise<void> {
1357
1351
  cleanupPidFile();
1358
1352
  },
1359
1353
  });
1354
+
1355
+ log.info(
1356
+ {
1357
+ durationMs: Date.now() - startupStartedAt,
1358
+ pid: process.pid,
1359
+ },
1360
+ "Daemon started",
1361
+ );
1360
1362
  } catch (err) {
1361
1363
  log.error({ err }, "Daemon startup failed — cleaning up");
1362
1364
  stopDiskPressureGuardForLifecycle();
@@ -35,6 +35,19 @@ export function maybeSeedMemoryV2Skills(config: AssistantConfig): void {
35
35
  );
36
36
  }
37
37
 
38
+ /**
39
+ * Fire-and-forget seed of the v2 CLI-subcommand entries (indexed alongside
40
+ * concept pages and skills in `memory_v2_concept_pages` under the
41
+ * `cli-commands/<name>` slug prefix). Dynamic import keeps v2 code out of the
42
+ * startup graph when the gate is off. Never awaits — startup must not block.
43
+ */
44
+ export function maybeSeedMemoryV2CliCommands(config: AssistantConfig): void {
45
+ if (!config.memory.v2.enabled) return;
46
+ void import("../memory/v2/cli-command-store.js")
47
+ .then(({ seedV2CliCommandEntries }) => seedV2CliCommandEntries())
48
+ .catch((err) => log.warn({ err }, "Failed to seed v2 CLI-command entries"));
49
+ }
50
+
38
51
  /**
39
52
  * Build the v2 BM25 corpus stats (per-token document frequencies + avg doc
40
53
  * length), then re-seed the v2 skill entries so any skills written during
@@ -56,6 +69,8 @@ export function maybeSeedMemoryV2Skills(config: AssistantConfig): void {
56
69
  export async function rebuildBm25CorpusStatsAndReseedSkills(
57
70
  config: AssistantConfig,
58
71
  ): Promise<void> {
72
+ if (!config.memory.v2.enabled) return;
73
+
59
74
  try {
60
75
  const { rebuildConceptPageCorpusStats } =
61
76
  await import("../memory/v2/sparse-bm25.js");
@@ -69,19 +84,40 @@ export async function rebuildBm25CorpusStatsAndReseedSkills(
69
84
  return;
70
85
  }
71
86
 
72
- if (!config.memory.v2.enabled) return;
73
- try {
74
- const { seedV2SkillEntries } = await import("../memory/v2/skill-store.js");
75
- await seedV2SkillEntries({ throwOnError: true });
76
- log.info(
77
- "Memory v2 skill embeddings re-seeded with BM25 vectors after corpus-stats build",
78
- );
79
- } catch (err) {
80
- log.warn(
81
- { err },
82
- "Failed to re-seed v2 skill entries after BM25 corpus-stats build — skills seeded during cold start may keep TF-only sparse vectors until next reseed",
83
- );
84
- }
87
+ // Skills and CLI commands share the unified collection but are independent
88
+ // catalogs — reseed in parallel so the second one isn't gated on the first.
89
+ await Promise.all([
90
+ (async () => {
91
+ try {
92
+ const { seedV2SkillEntries } =
93
+ await import("../memory/v2/skill-store.js");
94
+ await seedV2SkillEntries({ throwOnError: true });
95
+ log.info(
96
+ "Memory v2 skill embeddings re-seeded with BM25 vectors after corpus-stats build",
97
+ );
98
+ } catch (err) {
99
+ log.warn(
100
+ { err },
101
+ "Failed to re-seed v2 skill entries after BM25 corpus-stats build — skills seeded during cold start may keep TF-only sparse vectors until next reseed",
102
+ );
103
+ }
104
+ })(),
105
+ (async () => {
106
+ try {
107
+ const { seedV2CliCommandEntries } =
108
+ await import("../memory/v2/cli-command-store.js");
109
+ await seedV2CliCommandEntries({ throwOnError: true });
110
+ log.info(
111
+ "Memory v2 CLI-command embeddings re-seeded with BM25 vectors after corpus-stats build",
112
+ );
113
+ } catch (err) {
114
+ log.warn(
115
+ { err },
116
+ "Failed to re-seed v2 CLI-command entries after BM25 corpus-stats build — entries seeded during cold start may keep TF-only sparse vectors until next reseed",
117
+ );
118
+ }
119
+ })(),
120
+ ]);
85
121
  }
86
122
 
87
123
  /**
@@ -22,6 +22,7 @@ export * from "./message-types/contacts.js";
22
22
  export * from "./message-types/conversations.js";
23
23
  export * from "./message-types/diagnostics.js";
24
24
  export * from "./message-types/disk-pressure.js";
25
+ export * from "./message-types/document-comments.js";
25
26
  export * from "./message-types/documents.js";
26
27
  export * from "./message-types/guardian-actions.js";
27
28
  export * from "./message-types/home.js";
@@ -45,6 +46,7 @@ export * from "./message-types/subagents.js";
45
46
  export * from "./message-types/surfaces.js";
46
47
  export * from "./message-types/sync.js";
47
48
  export * from "./message-types/upgrades.js";
49
+ export * from "./message-types/web-activity.js";
48
50
  export * from "./message-types/work-items.js";
49
51
  export * from "./message-types/workspace.js";
50
52
 
@@ -76,6 +78,7 @@ import type {
76
78
  _DiagnosticsServerMessages,
77
79
  } from "./message-types/diagnostics.js";
78
80
  import type { _DiskPressureServerMessages } from "./message-types/disk-pressure.js";
81
+ import type { _DocumentCommentsServerMessages } from "./message-types/document-comments.js";
79
82
  import type {
80
83
  _DocumentsClientMessages,
81
84
  _DocumentsServerMessages,
@@ -192,6 +195,7 @@ export type ServerMessage =
192
195
  | _BrowserServerMessages
193
196
  | _SubagentsServerMessages
194
197
  | _DocumentsServerMessages
198
+ | _DocumentCommentsServerMessages
195
199
  | _GuardianActionsServerMessages
196
200
  | _SyncInvalidationServerMessages
197
201
  | _HomeServerMessages
@@ -224,6 +224,7 @@ export interface ConversationTitleUpdated {
224
224
  interface ChannelBinding {
225
225
  sourceChannel: ChannelId;
226
226
  externalChatId: string;
227
+ externalChatName?: string | null;
227
228
  externalThreadId?: string | null;
228
229
  externalUserId?: string | null;
229
230
  displayName?: string | null;
@@ -236,6 +237,13 @@ interface ChannelBinding {
236
237
  webUrl?: string;
237
238
  };
238
239
  };
240
+ slackChannel?: {
241
+ channelId: string;
242
+ name?: string;
243
+ link?: {
244
+ webUrl?: string;
245
+ };
246
+ };
239
247
  }
240
248
 
241
249
  /** Attention state metadata for a conversation's latest assistant message. */
@@ -0,0 +1,50 @@
1
+ // Document comment event types (Server → Client).
2
+
3
+ export interface DocumentCommentCreated {
4
+ type: "document_comment_created";
5
+ conversationId: string;
6
+ surfaceId: string;
7
+ comment: {
8
+ id: string;
9
+ surfaceId: string;
10
+ author: string;
11
+ content: string;
12
+ anchorStart?: number;
13
+ anchorEnd?: number;
14
+ anchorText?: string;
15
+ parentCommentId?: string;
16
+ status: string;
17
+ createdAt: number;
18
+ updatedAt: number;
19
+ };
20
+ }
21
+
22
+ export interface DocumentCommentResolved {
23
+ type: "document_comment_resolved";
24
+ conversationId: string;
25
+ surfaceId: string;
26
+ commentId: string;
27
+ resolvedBy: string;
28
+ }
29
+
30
+ export interface DocumentCommentReopened {
31
+ type: "document_comment_reopened";
32
+ conversationId: string;
33
+ surfaceId: string;
34
+ commentId: string;
35
+ }
36
+
37
+ export interface DocumentCommentDeleted {
38
+ type: "document_comment_deleted";
39
+ conversationId: string;
40
+ surfaceId: string;
41
+ commentId: string;
42
+ }
43
+
44
+ // --- Domain-level union alias (consumed by the barrel file) ---
45
+
46
+ export type _DocumentCommentsServerMessages =
47
+ | DocumentCommentCreated
48
+ | DocumentCommentResolved
49
+ | DocumentCommentReopened
50
+ | DocumentCommentDeleted;
@@ -2,6 +2,7 @@
2
2
 
3
3
  import type { ChannelId, InterfaceId } from "../../channels/types.js";
4
4
  import type { CommandIntent, UserMessageAttachment } from "./shared.js";
5
+ import type { ToolActivityMetadata } from "./web-activity.js";
5
6
 
6
7
  // === Client → Server ===
7
8
 
@@ -175,6 +176,9 @@ export interface ToolResult {
175
176
  approvalReason?: string;
176
177
  /** Snapshot of the auto-approve threshold at execution time. */
177
178
  riskThreshold?: string;
179
+ /** Structured activity metadata for rich client rendering. Optional; old
180
+ * clients that key off `result` continue to work unchanged. */
181
+ activityMetadata?: ToolActivityMetadata;
178
182
  }
179
183
 
180
184
  export interface ConfirmationRequest {
@@ -363,6 +367,12 @@ export interface MessageQueuedDeleted {
363
367
  requestId: string;
364
368
  }
365
369
 
370
+ export interface MessageSteered {
371
+ type: "message_steered";
372
+ conversationId: string;
373
+ requestId: string;
374
+ }
375
+
366
376
  export interface SuggestionResponse {
367
377
  type: "suggestion_response";
368
378
  requestId: string;
@@ -390,6 +400,45 @@ export interface ConfirmationStateChanged {
390
400
  toolUseId?: string;
391
401
  }
392
402
 
403
+ /**
404
+ * Lifecycle states reported by `interaction_resolved`.
405
+ *
406
+ * - `"approved"` / `"rejected"` — user-supplied verdict on a confirmation.
407
+ * - `"answered"` — user/client provided a response (secret value, question
408
+ * answer, host-proxy result).
409
+ * - `"cancelled"` — the interaction was torn down without a user response
410
+ * (timeout, abort, dispose, prompter shutdown).
411
+ * - `"superseded"` — invalidated by a newer event (auto-deny on enqueue, a
412
+ * fresh user message arriving while a confirmation was outstanding).
413
+ */
414
+ export type InteractionResolutionState =
415
+ | "approved"
416
+ | "rejected"
417
+ | "answered"
418
+ | "cancelled"
419
+ | "superseded";
420
+
421
+ /**
422
+ * Broadcast when a pending interaction (confirmation, secret, question,
423
+ * host-proxy request) transitions to a resolved state. Clients use this to
424
+ * drop attention/processing indicators without polling.
425
+ */
426
+ export interface InteractionResolved {
427
+ type: "interaction_resolved";
428
+ requestId: string;
429
+ /**
430
+ * Conversation key for the interaction. The daemon's internal conversation
431
+ * id and the web client's conversation key coincide today (see
432
+ * `conversation-key-store.ts`); the field is named after the client-facing
433
+ * concept.
434
+ */
435
+ conversationKey: string;
436
+ state: InteractionResolutionState;
437
+ /** Kind of the resolved interaction (e.g. "confirmation", "secret", "host_bash"). */
438
+ kind: string;
439
+ conversationId?: string;
440
+ }
441
+
393
442
  /**
394
443
  * Server-side assistant activity lifecycle for thinking indicator placement.
395
444
  *
@@ -426,6 +475,21 @@ export interface AssistantActivityState {
426
475
  statusText?: string;
427
476
  }
428
477
 
478
+ /**
479
+ * Emitted when the query complexity auto-router selects a non-default
480
+ * profile for the current turn. Clients use this to show an inline
481
+ * notification (e.g. "Using Quality for this response"). Only fires when
482
+ * the router picks a profile — not when the user explicitly pinned one.
483
+ */
484
+ export interface TurnProfileAutoRouted {
485
+ type: "turn_profile_auto_routed";
486
+ conversationId: string;
487
+ /** Profile key (e.g. "quality-optimized"). */
488
+ profile: string;
489
+ /** Human-readable label (e.g. "Quality"). */
490
+ profileLabel: string;
491
+ }
492
+
429
493
  /**
430
494
  * Broadcast to clients when a conversation's inference-profile override
431
495
  * changes. `profile` is the profile name (a key in `llm.profiles`) or
@@ -497,8 +561,11 @@ export type _MessagesServerMessages =
497
561
  | MessageDequeued
498
562
  | MessageRequestComplete
499
563
  | MessageQueuedDeleted
564
+ | MessageSteered
500
565
  | SuggestionResponse
501
566
  | TraceEvent
502
567
  | ConfirmationStateChanged
503
568
  | AssistantActivityState
504
- | ConversationInferenceProfileUpdated;
569
+ | TurnProfileAutoRouted
570
+ | ConversationInferenceProfileUpdated
571
+ | InteractionResolved;
@@ -14,6 +14,20 @@ export interface NotificationIntent {
14
14
  * Clients not bound to this guardian should ignore the notification.
15
15
  */
16
16
  targetGuardianPrincipalId?: string;
17
+ /**
18
+ * When true, the client must NOT post this intent to the OS notification
19
+ * surface (`UNUserNotificationCenter` on macOS). Non-banner side effects
20
+ * (guardian filtering, fallback dedup, mark-unseen + history catch-up on
21
+ * the paired conversation) still run. The home-feed inbox entry is
22
+ * written independently by `home-feed-side-effect.ts` and is unaffected
23
+ * by this flag.
24
+ *
25
+ * Set by the server based on `attentionHints.urgency`: true for
26
+ * `low`/`medium`, false for `high`/`critical`. The notification center
27
+ * is the always-on canonical inbox; the OS banner is reserved for
28
+ * signals the user opted into push for (urgency >= high).
29
+ */
30
+ silent?: boolean;
17
31
  }
18
32
 
19
33
  /** Server push — broadcast when a notification creates a new vellum conversation. */
@@ -39,6 +53,13 @@ export interface NotificationConversationCreated {
39
53
  * conversation is attributed correctly.
40
54
  */
41
55
  source?: string;
56
+ /**
57
+ * Mirrors `NotificationIntent.silent`. When true the client must not
58
+ * post a fallback OS banner for this conversation — the sidebar entry
59
+ * still appears, but the always-on inbox is the only surfaced channel.
60
+ * Derived from the originating signal's `attentionHints.urgency`.
61
+ */
62
+ silent?: boolean;
42
63
  }
43
64
 
44
65
  /** Client ack sent after UNUserNotificationCenter.add() completes (or fails). */
@@ -10,13 +10,15 @@ export type SurfaceType =
10
10
  | "confirmation"
11
11
  | "dynamic_page"
12
12
  | "file_upload"
13
- | "document_preview";
13
+ | "document_preview"
14
+ | "task_preferences";
14
15
 
15
16
  export const INTERACTIVE_SURFACE_TYPES: SurfaceType[] = [
16
17
  "form",
17
18
  "confirmation",
18
19
  "dynamic_page",
19
20
  "file_upload",
21
+ "task_preferences",
20
22
  ];
21
23
 
22
24
  export interface SurfaceAction {
@@ -0,0 +1,57 @@
1
+ // Shared structured result types for web-search and web-fetch tool activity.
2
+ //
3
+ // These types describe live (SSE-time) metadata that producers (search/fetch
4
+ // tool executors) emit and consumers (clients) render alongside the existing
5
+ // `result: string` payload. Persistence to conversation history is out of
6
+ // scope for this plan; the metadata is live-only.
7
+
8
+ export type WebSearchProviderId =
9
+ | "anthropic-native"
10
+ | "brave"
11
+ | "perplexity"
12
+ | "tavily";
13
+
14
+ export interface WebSearchResultItem {
15
+ rank: number; // 1-indexed
16
+ title: string;
17
+ url: string;
18
+ domain: string; // lowercased host
19
+ faviconUrl?: string;
20
+ snippet?: string; // not populated for anthropic-native (content encrypted)
21
+ age?: string; // Brave-only freshness hint
22
+ score?: number; // Tavily-only
23
+ }
24
+
25
+ export interface WebSearchMetadata {
26
+ query: string;
27
+ provider: WebSearchProviderId;
28
+ resultCount: number;
29
+ durationMs: number;
30
+ results: WebSearchResultItem[];
31
+ /** Present when search itself failed; results[] will be empty. */
32
+ errorMessage?: string;
33
+ }
34
+
35
+ export interface WebFetchMetadata {
36
+ url: string;
37
+ finalUrl: string;
38
+ status: number;
39
+ contentType?: string;
40
+ byteCount: number;
41
+ charCount: number;
42
+ truncated: boolean;
43
+ title?: string;
44
+ domain: string;
45
+ faviconUrl?: string;
46
+ redirectCount: number;
47
+ durationMs: number;
48
+ errorMessage?: string;
49
+ /** Set when extracted text is dramatically smaller than raw HTML — likely a JS-rendered SPA whose meaningful content the static fetcher missed. */
50
+ mayRequireJavaScript?: boolean;
51
+ }
52
+
53
+ /** Discriminated container so future tools can add their own metadata. */
54
+ export interface ToolActivityMetadata {
55
+ webSearch?: WebSearchMetadata;
56
+ webFetch?: WebFetchMetadata;
57
+ }