@vellumai/assistant 0.7.3 → 0.8.1

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 (778) hide show
  1. package/AGENTS.md +11 -0
  2. package/ARCHITECTURE.md +29 -28
  3. package/Dockerfile +6 -4
  4. package/README.md +2 -2
  5. package/__tests__/permissions/gateway-threshold-reader.test.ts +236 -9
  6. package/bun.lock +3 -0
  7. package/docker-entrypoint.sh +16 -0
  8. package/eslint-rules/__tests__/cli-no-daemon-internals.test.ts +420 -0
  9. package/eslint-rules/cli-no-daemon-internals.js +283 -0
  10. package/eslint.config.mjs +12 -0
  11. package/knip.json +3 -1
  12. package/node_modules/@vellumai/ipc-server-utils/bun.lock +24 -0
  13. package/node_modules/@vellumai/ipc-server-utils/package.json +18 -0
  14. package/node_modules/@vellumai/ipc-server-utils/src/index.ts +6 -0
  15. package/node_modules/@vellumai/ipc-server-utils/src/socket-watchdog.test.ts +430 -0
  16. package/node_modules/@vellumai/ipc-server-utils/src/socket-watchdog.ts +221 -0
  17. package/node_modules/@vellumai/ipc-server-utils/tsconfig.json +20 -0
  18. package/node_modules/@vellumai/skill-host-contracts/src/client.ts +10 -1
  19. package/openapi.yaml +4126 -959
  20. package/package.json +5 -1
  21. package/scripts/generate-openapi.ts +52 -4
  22. package/scripts/sync-llm-catalog.ts +165 -0
  23. package/scripts/sync-web-search-catalog.ts +107 -0
  24. package/src/__tests__/actor-trust-resolver-address-fallback.test.ts +169 -0
  25. package/src/__tests__/agent-loop-override-profile.test.ts +26 -1
  26. package/src/__tests__/annotate-risk-options.test.ts +291 -0
  27. package/src/__tests__/anthropic-provider.test.ts +92 -2
  28. package/src/__tests__/app-control-flow.test.ts +7 -0
  29. package/src/__tests__/approval-cascade.test.ts +8 -16
  30. package/src/__tests__/approval-routes-http.test.ts +6 -0
  31. package/src/__tests__/assistant-events-sse-shed.test.ts +232 -0
  32. package/src/__tests__/auto-analysis-end-to-end.test.ts +12 -25
  33. package/src/__tests__/avatar-identity-sync.test.ts +87 -0
  34. package/src/__tests__/background-workers-disk-pressure.test.ts +11 -22
  35. package/src/__tests__/btw-routes.test.ts +1 -0
  36. package/src/__tests__/call-constants.test.ts +10 -1
  37. package/src/__tests__/call-controller.test.ts +127 -0
  38. package/src/__tests__/call-site-routing-provider.test.ts +172 -45
  39. package/src/__tests__/cancel-resolves-conversation-key.test.ts +44 -3
  40. package/src/__tests__/channel-policy.test.ts +12 -0
  41. package/src/__tests__/checker.test.ts +89 -0
  42. package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +88 -30
  43. package/src/__tests__/compact-event-conversation-id-guard.test.ts +33 -5
  44. package/src/__tests__/compaction-strip-metadata-clear.test.ts +26 -1
  45. package/src/__tests__/config-loader-backfill.test.ts +526 -102
  46. package/src/__tests__/config-loader-corrupt.test.ts +68 -0
  47. package/src/__tests__/config-loader-platform-defaults.test.ts +345 -8
  48. package/src/__tests__/config-schema-cmd.test.ts +63 -29
  49. package/src/__tests__/config-schema.test.ts +14 -3
  50. package/src/__tests__/config-set-platform-guard.test.ts +75 -152
  51. package/src/__tests__/config-set-route.test.ts +198 -0
  52. package/src/__tests__/config-watcher.test.ts +6 -0
  53. package/src/__tests__/contacts-tools.test.ts +51 -199
  54. package/src/__tests__/context-search-agent-protocol.test.ts +21 -2
  55. package/src/__tests__/context-search-agent-runner.test.ts +22 -138
  56. package/src/__tests__/context-search-conversations-source.test.ts +42 -16
  57. package/src/__tests__/context-search-fanout.test.ts +20 -157
  58. package/src/__tests__/context-search-memory-source.test.ts +3 -26
  59. package/src/__tests__/context-search-memory-v2-source.test.ts +3 -3
  60. package/src/__tests__/context-search-types.test.ts +7 -2
  61. package/src/__tests__/context-window-manager.test.ts +389 -1
  62. package/src/__tests__/conversation-abort-tool-results.test.ts +1 -6
  63. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +1 -1
  64. package/src/__tests__/conversation-agent-loop-overflow.test.ts +2 -1
  65. package/src/__tests__/conversation-agent-loop.test.ts +3 -3
  66. package/src/__tests__/conversation-confirmation-signals.test.ts +5 -13
  67. package/src/__tests__/conversation-crud-inference-profile.test.ts +100 -0
  68. package/src/__tests__/conversation-error.test.ts +38 -0
  69. package/src/__tests__/conversation-fork-crud.test.ts +241 -1
  70. package/src/__tests__/conversation-inference-profile-route.test.ts +14 -14
  71. package/src/__tests__/conversation-init.benchmark.test.ts +2 -1
  72. package/src/__tests__/conversation-lifecycle.test.ts +124 -0
  73. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +100 -1
  74. package/src/__tests__/conversation-process-callsite.test.ts +22 -7
  75. package/src/__tests__/conversation-provider-retry-repair.test.ts +1 -6
  76. package/src/__tests__/conversation-runtime-assembly.test.ts +19 -10
  77. package/src/__tests__/conversation-slash-commands.test.ts +194 -2
  78. package/src/__tests__/conversation-slash-unknown.test.ts +1 -6
  79. package/src/__tests__/conversation-surfaces-action-delivery.test.ts +170 -9
  80. package/src/__tests__/conversation-surfaces-app-control.test.ts +323 -3
  81. package/src/__tests__/conversation-surfaces-data-persist.test.ts +73 -1
  82. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +59 -0
  83. package/src/__tests__/conversation-workspace-injection.test.ts +1 -7
  84. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +1 -7
  85. package/src/__tests__/credential-security-invariants.test.ts +5 -6
  86. package/src/__tests__/daemon-credential-client.test.ts +56 -1
  87. package/src/__tests__/db-activation-state-fk-cascade.test.ts +132 -0
  88. package/src/__tests__/db-conversation-inference-profile-migration.test.ts +37 -0
  89. package/src/__tests__/db-memory-graph-event-date-repair.test.ts +43 -20
  90. package/src/__tests__/db-proxy-transaction.test.ts +206 -0
  91. package/src/__tests__/external-plugin-loader.test.ts +458 -0
  92. package/src/__tests__/filing-service.test.ts +25 -22
  93. package/src/__tests__/fixtures/mock-chrome-extension.ts +5 -0
  94. package/src/__tests__/gateway-only-guard.test.ts +0 -1
  95. package/src/__tests__/graph-extraction-event-date.test.ts +34 -0
  96. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +10 -34
  97. package/src/__tests__/heartbeat-disk-pressure.test.ts +21 -8
  98. package/src/__tests__/heartbeat-service.test.ts +50 -233
  99. package/src/__tests__/history-repair.test.ts +89 -0
  100. package/src/__tests__/host-app-control-proxy.test.ts +109 -1
  101. package/src/__tests__/host-app-control-routes.test.ts +247 -1
  102. package/src/__tests__/host-browser-proxy.test.ts +416 -20
  103. package/src/__tests__/host-browser-routes.test.ts +325 -33
  104. package/src/__tests__/host-proxy-preactivation.test.ts +211 -0
  105. package/src/__tests__/inference-no-mode-boot-e2e.test.ts +246 -0
  106. package/src/__tests__/inference-profile-reaper.test.ts +154 -0
  107. package/src/__tests__/inference-profile-session-handler.test.ts +398 -0
  108. package/src/__tests__/inference-profile-session-ipc.test.ts +236 -0
  109. package/src/__tests__/injector-chain.test.ts +24 -16
  110. package/src/__tests__/injector-pkb-v2-silenced.test.ts +10 -7
  111. package/src/__tests__/inline-skill-load-permissions.test.ts +6 -1
  112. package/src/__tests__/install-skill-routing.test.ts +2 -2
  113. package/src/__tests__/lifecycle-memory-v2-seed.test.ts +169 -67
  114. package/src/__tests__/llm-callsite-catalog.test.ts +20 -1
  115. package/src/__tests__/llm-catalog-parity.test.ts +146 -0
  116. package/src/__tests__/llm-request-log-source-clickhouse.test.ts +188 -0
  117. package/src/__tests__/llm-request-log-source-factory.test.ts +124 -0
  118. package/src/__tests__/llm-resolver.test.ts +46 -0
  119. package/src/__tests__/managed-profile-guard.test.ts +131 -2
  120. package/src/__tests__/mcp-auth-routes.test.ts +1 -0
  121. package/src/__tests__/mcp-cli.test.ts +182 -220
  122. package/src/__tests__/mcp-health-check.test.ts +56 -27
  123. package/src/__tests__/memory-jobs-worker-lanes.test.ts +18 -11
  124. package/src/__tests__/message-complete-display-id.test.ts +175 -0
  125. package/src/__tests__/notification-decision-fallback.test.ts +91 -0
  126. package/src/__tests__/notification-decision-strategy.test.ts +22 -0
  127. package/src/__tests__/notification-platform-adapter.test.ts +229 -0
  128. package/src/__tests__/oauth-cli.test.ts +38 -1888
  129. package/src/__tests__/oauth-commands-routes.test.ts +711 -0
  130. package/src/__tests__/oauth-connect-routes.test.ts +174 -11
  131. package/src/__tests__/oauth-providers-routes.test.ts +14 -10
  132. package/src/__tests__/openai-responses-cutover-guard.test.ts +33 -12
  133. package/src/__tests__/openai-responses-provider.test.ts +17 -0
  134. package/src/__tests__/plugin-bootstrap.test.ts +31 -2
  135. package/src/__tests__/plugin-route-contribution.test.ts +31 -3
  136. package/src/__tests__/plugin-tool-contribution.test.ts +31 -3
  137. package/src/__tests__/plugin-types.test.ts +13 -11
  138. package/src/__tests__/process-message-background-slack.test.ts +46 -0
  139. package/src/__tests__/profile-entry-status.test.ts +43 -0
  140. package/src/__tests__/provider-managed-proxy-integration.test.ts +12 -4
  141. package/src/__tests__/provider-registry-ollama.test.ts +12 -4
  142. package/src/__tests__/provider-send-message-override-profile.test.ts +10 -4
  143. package/src/__tests__/relay-server.test.ts +164 -2
  144. package/src/__tests__/retry-thinking-tool-choice.test.ts +15 -0
  145. package/src/__tests__/schedule-retry.test.ts +56 -4
  146. package/src/__tests__/schedule-routes.test.ts +104 -0
  147. package/src/__tests__/scheduler-disk-pressure.test.ts +0 -4
  148. package/src/__tests__/scheduler-recurrence.test.ts +87 -34
  149. package/src/__tests__/scheduler-reuse-conversation.test.ts +161 -5
  150. package/src/__tests__/scheduler-wake.test.ts +0 -63
  151. package/src/__tests__/secret-allowlist.test.ts +1 -0
  152. package/src/__tests__/secret-prompt-log-hygiene.test.ts +7 -5
  153. package/src/__tests__/secret-prompter-channel-fallback.test.ts +7 -5
  154. package/src/__tests__/secret-response-routing.test.ts +7 -5
  155. package/src/__tests__/secret-routes-managed-proxy.test.ts +12 -4
  156. package/src/__tests__/server-history-render.test.ts +82 -0
  157. package/src/__tests__/shell-credential-ref.test.ts +95 -3
  158. package/src/__tests__/shell-tool-proxy-mode.test.ts +14 -0
  159. package/src/__tests__/skill-include-graph.test.ts +31 -0
  160. package/src/__tests__/skill-load-feature-flag.test.ts +1 -0
  161. package/src/__tests__/skill-load-tool.test.ts +42 -16
  162. package/src/__tests__/skills.test.ts +39 -0
  163. package/src/__tests__/subagent-call-site-routing.test.ts +78 -16
  164. package/src/__tests__/suggestion-routes.test.ts +3 -3
  165. package/src/__tests__/sync-message-contract.test.ts +63 -0
  166. package/src/__tests__/task-scheduler.test.ts +88 -23
  167. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +0 -42
  168. package/src/__tests__/tool-executor.test.ts +155 -0
  169. package/src/__tests__/update-bulletin-job.test.ts +96 -193
  170. package/src/__tests__/usage-cli.test.ts +11 -73
  171. package/src/__tests__/user-plugin-loader.test.ts +145 -0
  172. package/src/__tests__/vercel-config.test.ts +168 -0
  173. package/src/__tests__/voice-session-bridge.test.ts +3 -0
  174. package/src/__tests__/web-search-catalog-parity.test.ts +86 -0
  175. package/src/__tests__/web-search.test.ts +303 -2
  176. package/src/__tests__/workspace-migration-039-drop-legacy-llm-keys.test.ts +1 -21
  177. package/src/__tests__/workspace-migration-057-repair-stale-gemini-model-ids.test.ts +58 -0
  178. package/src/__tests__/workspace-migration-069-seed-onboarding-threads.test.ts +153 -0
  179. package/src/__tests__/workspace-migration-071-remove-safe-storage-release-note.test.ts +206 -0
  180. package/src/__tests__/workspace-migration-072-seed-reply-suggestion-callsite.test.ts +191 -0
  181. package/src/__tests__/workspace-migration-076-drop-services-inference-mode.test.ts +211 -0
  182. package/src/__tests__/workspace-migration-077-seed-memory-router-callsite.test.ts +174 -0
  183. package/src/__tests__/workspace-migration-079-home-feed-notification-only.test.ts +323 -0
  184. package/src/__tests__/workspace-migration-080-restrict-vercel-api-token-metadata.test.ts +299 -0
  185. package/src/__tests__/workspace-migration-081-backfill-bash-allowed-tools.test.ts +410 -0
  186. package/src/__tests__/workspace-migration-082-backfill-managed-profile-labels.test.ts +268 -0
  187. package/src/__tests__/workspace-migration-safe-storage-limits-release.test.ts +15 -27
  188. package/src/__tests__/workspace-migration-unify-llm-callsite-configs.test.ts +3 -3
  189. package/src/__tests__/workspace-release-notes-feature-flag-guard.test.ts +115 -0
  190. package/src/acp/__tests__/helpers/which-stub.ts +4 -2
  191. package/src/acp/resolve-agent.test.ts +25 -0
  192. package/src/acp/resolve-agent.ts +13 -2
  193. package/src/acp/session-manager.ts +14 -0
  194. package/src/agent/loop.ts +11 -0
  195. package/src/approvals/guardian-decision-primitive.ts +0 -13
  196. package/src/approvals/guardian-request-resolvers.ts +19 -102
  197. package/src/calls/call-constants.ts +5 -8
  198. package/src/calls/call-controller.ts +130 -67
  199. package/src/calls/relay-server.ts +42 -1
  200. package/src/calls/relay-setup-router.ts +36 -0
  201. package/src/calls/types.ts +1 -0
  202. package/src/calls/voice-session-bridge.ts +24 -5
  203. package/src/channels/config.ts +14 -1
  204. package/src/channels/types.ts +1 -0
  205. package/src/cli/AGENTS.md +164 -4
  206. package/src/cli/__tests__/notifications.test.ts +54 -0
  207. package/src/cli/commands/__tests__/avatar.test.ts +540 -0
  208. package/src/cli/commands/__tests__/backup.test.ts +236 -776
  209. package/src/cli/commands/__tests__/cache.test.ts +1 -1
  210. package/src/cli/commands/__tests__/changelog.test.ts +593 -0
  211. package/src/cli/commands/__tests__/channel-verification-sessions.test.ts +503 -0
  212. package/src/cli/commands/__tests__/conversations-import.test.ts +515 -0
  213. package/src/cli/commands/__tests__/domain-register.test.ts +140 -167
  214. package/src/cli/commands/__tests__/domain-status.test.ts +137 -76
  215. package/src/cli/commands/__tests__/email-attachment.test.ts +314 -337
  216. package/src/cli/commands/__tests__/email-core.test.ts +579 -0
  217. package/src/cli/commands/__tests__/image-generation.test.ts +87 -824
  218. package/src/cli/commands/__tests__/inference-send.test.ts +30 -266
  219. package/src/cli/commands/__tests__/inference-session.test.ts +423 -0
  220. package/src/cli/commands/__tests__/memory-v2.test.ts +81 -110
  221. package/src/cli/commands/__tests__/skills.test.ts +563 -0
  222. package/src/cli/commands/__tests__/status.test.ts +249 -0
  223. package/src/cli/commands/__tests__/stt.test.ts +320 -0
  224. package/src/cli/commands/__tests__/tts-synthesize.test.ts +4 -603
  225. package/src/cli/commands/__tests__/tts.test.ts +321 -0
  226. package/src/cli/commands/__tests__/webhooks.test.ts +86 -511
  227. package/src/cli/commands/attachment.ts +8 -3
  228. package/src/cli/commands/audit.ts +95 -64
  229. package/src/cli/commands/auth.ts +61 -58
  230. package/src/cli/commands/avatar.ts +276 -390
  231. package/src/cli/commands/backup.ts +409 -505
  232. package/src/cli/commands/bash.ts +9 -5
  233. package/src/cli/commands/browser.ts +28 -9
  234. package/src/cli/commands/cache.ts +9 -4
  235. package/src/cli/commands/changelog.ts +414 -0
  236. package/src/cli/commands/channel-verification-sessions.ts +238 -317
  237. package/src/cli/commands/clients.ts +8 -3
  238. package/src/cli/commands/completions.ts +9 -9
  239. package/src/cli/commands/config.ts +102 -72
  240. package/src/cli/commands/contacts.ts +575 -696
  241. package/src/cli/commands/conversations-defer.ts +17 -69
  242. package/src/cli/commands/conversations-import.ts +90 -253
  243. package/src/cli/commands/conversations.ts +346 -436
  244. package/src/cli/commands/credential-execution.ts +9 -6
  245. package/src/cli/commands/credentials.ts +456 -736
  246. package/src/cli/commands/domain.ts +128 -206
  247. package/src/cli/commands/email.ts +606 -794
  248. package/src/cli/commands/gateway.ts +8 -1
  249. package/src/cli/commands/image-generation.ts +157 -205
  250. package/src/cli/commands/inference-providers.ts +352 -0
  251. package/src/cli/commands/inference-session.ts +415 -0
  252. package/src/cli/commands/inference.ts +87 -65
  253. package/src/cli/commands/keys.ts +8 -3
  254. package/src/cli/commands/mcp.ts +103 -287
  255. package/src/cli/commands/memory-v2.ts +163 -517
  256. package/src/cli/commands/notifications.ts +33 -7
  257. package/src/cli/commands/oauth/apps.ts +292 -261
  258. package/src/cli/commands/oauth/connect.ts +182 -345
  259. package/src/cli/commands/oauth/disconnect.ts +16 -215
  260. package/src/cli/commands/oauth/index.ts +49 -45
  261. package/src/cli/commands/oauth/mode.ts +43 -199
  262. package/src/cli/commands/oauth/ping.ts +17 -125
  263. package/src/cli/commands/oauth/providers.ts +732 -921
  264. package/src/cli/commands/oauth/request.ts +60 -350
  265. package/src/cli/commands/oauth/shared.ts +11 -121
  266. package/src/cli/commands/oauth/status.ts +31 -121
  267. package/src/cli/commands/oauth/token.ts +13 -55
  268. package/src/cli/commands/pending.ts +19 -10
  269. package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +133 -183
  270. package/src/cli/commands/platform/__tests__/connect.test.ts +66 -181
  271. package/src/cli/commands/platform/__tests__/disconnect.test.ts +71 -227
  272. package/src/cli/commands/platform/__tests__/status.test.ts +169 -287
  273. package/src/cli/commands/platform/connect.ts +16 -80
  274. package/src/cli/commands/platform/disconnect.ts +14 -112
  275. package/src/cli/commands/platform/index.ts +177 -246
  276. package/src/cli/commands/routes.ts +153 -336
  277. package/src/cli/commands/sequence.ts +316 -360
  278. package/src/cli/commands/skills.ts +449 -671
  279. package/src/cli/commands/status.ts +58 -37
  280. package/src/cli/commands/stt.ts +94 -262
  281. package/src/cli/commands/task.ts +14 -40
  282. package/src/cli/commands/trust.ts +8 -3
  283. package/src/cli/commands/tts.ts +162 -167
  284. package/src/cli/commands/ui.ts +35 -42
  285. package/src/cli/commands/usage.ts +188 -126
  286. package/src/cli/commands/watchers.ts +8 -3
  287. package/src/cli/commands/webhooks.ts +99 -193
  288. package/src/cli/lib/__tests__/register-command.test.ts +85 -0
  289. package/src/cli/lib/daemon-credential-client.ts +4 -5
  290. package/src/cli/lib/nested-value.ts +44 -0
  291. package/src/cli/lib/open-browser.ts +36 -0
  292. package/src/cli/lib/register-command.ts +19 -0
  293. package/src/cli/lib/time-ago.ts +34 -0
  294. package/src/cli/program.ts +2 -4
  295. package/src/cli/utils/__tests__/conversation-id.test.ts +66 -0
  296. package/src/cli/utils/__tests__/parse-duration.test.ts +49 -0
  297. package/src/cli/utils/conversation-id.ts +30 -0
  298. package/src/cli/utils/parse-duration.ts +41 -0
  299. package/src/config/acp-defaults.test.ts +5 -1
  300. package/src/config/acp-defaults.ts +11 -4
  301. package/src/config/bundled-skills/acp/TOOLS.json +2 -2
  302. package/src/config/bundled-skills/app-builder/SKILL.md +1 -3
  303. package/src/config/bundled-skills/app-control/TOOLS.json +32 -0
  304. package/src/config/bundled-skills/contacts/SKILL.md +12 -45
  305. package/src/config/bundled-skills/contacts/TOOLS.json +0 -57
  306. package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +0 -12
  307. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +0 -58
  308. package/src/config/bundled-tool-registry.ts +0 -2
  309. package/src/config/feature-flag-registry.json +17 -17
  310. package/src/config/llm-resolver.ts +16 -1
  311. package/src/config/loader.ts +148 -33
  312. package/src/config/raw-config-utils.ts +2 -30
  313. package/src/config/schema.ts +4 -0
  314. package/src/config/schemas/__tests__/memory-v2.test.ts +49 -0
  315. package/src/config/schemas/call-site-catalog.ts +29 -7
  316. package/src/config/schemas/llm-request-logs.ts +57 -0
  317. package/src/config/schemas/llm.ts +52 -2
  318. package/src/config/schemas/memory-retrospective.ts +48 -0
  319. package/src/config/schemas/memory-v2.ts +33 -2
  320. package/src/config/schemas/memory.ts +4 -0
  321. package/src/config/schemas/services.ts +15 -12
  322. package/src/config/seed-inference-profiles.ts +195 -134
  323. package/src/contacts/contact-store.ts +0 -61
  324. package/src/context/window-manager.ts +191 -5
  325. package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +111 -0
  326. package/src/daemon/__tests__/conversation-tool-setup.test.ts +109 -4
  327. package/src/daemon/__tests__/daemon-skill-host.test.ts +10 -4
  328. package/src/daemon/approval-generators.ts +23 -29
  329. package/src/daemon/config-watcher.ts +2 -0
  330. package/src/daemon/conversation-agent-loop-handlers.ts +56 -0
  331. package/src/daemon/conversation-agent-loop.ts +140 -107
  332. package/src/daemon/conversation-error.ts +21 -0
  333. package/src/daemon/conversation-lifecycle.ts +68 -13
  334. package/src/daemon/conversation-process.ts +36 -19
  335. package/src/daemon/conversation-runtime-assembly.ts +14 -5
  336. package/src/daemon/conversation-slash.ts +175 -23
  337. package/src/daemon/conversation-store.ts +17 -10
  338. package/src/daemon/conversation-surfaces.ts +92 -26
  339. package/src/daemon/conversation-tool-setup.ts +33 -19
  340. package/src/daemon/conversation.ts +49 -10
  341. package/src/daemon/external-plugins-bootstrap.ts +18 -8
  342. package/src/daemon/guardian-action-generators.ts +7 -22
  343. package/src/daemon/handlers/config-model.ts +8 -126
  344. package/src/daemon/handlers/config-slack-channel.ts +10 -7
  345. package/src/daemon/handlers/config-vercel.ts +3 -1
  346. package/src/daemon/handlers/shared.ts +26 -0
  347. package/src/daemon/handlers/skills.ts +84 -5
  348. package/src/daemon/history-repair.ts +33 -6
  349. package/src/daemon/host-app-control-proxy.ts +44 -19
  350. package/src/daemon/host-bash-proxy.ts +85 -158
  351. package/src/daemon/host-browser-proxy.ts +97 -36
  352. package/src/daemon/host-cu-proxy.ts +1 -1
  353. package/src/daemon/host-file-proxy.ts +1 -1
  354. package/src/daemon/host-proxy-base.ts +13 -1
  355. package/src/daemon/host-proxy-preactivation.ts +25 -1
  356. package/src/daemon/host-transfer-proxy.ts +2 -2
  357. package/src/daemon/identity-helpers.ts +19 -0
  358. package/src/daemon/lifecycle.ts +128 -114
  359. package/src/daemon/meet-host-supervisor.ts +15 -15
  360. package/src/daemon/memory-v2-startup.ts +62 -14
  361. package/src/daemon/message-protocol.ts +6 -0
  362. package/src/daemon/message-types/bookmarks.ts +18 -0
  363. package/src/daemon/message-types/conversations.ts +12 -9
  364. package/src/daemon/message-types/messages.ts +28 -2
  365. package/src/daemon/message-types/sync.ts +60 -0
  366. package/src/daemon/pkb-reminder-builder.test.ts +54 -13
  367. package/src/daemon/pkb-reminder-builder.ts +21 -7
  368. package/src/daemon/process-message.ts +56 -23
  369. package/src/daemon/server.ts +23 -18
  370. package/src/daemon/shutdown-handlers.ts +0 -2
  371. package/src/daemon/tool-setup-types.ts +9 -0
  372. package/src/daemon/tool-side-effects.ts +6 -4
  373. package/src/daemon/wake-target-adapter.ts +11 -0
  374. package/src/documents/document-store.ts +35 -1
  375. package/src/export/transcript-formatter.ts +61 -2
  376. package/src/filing/filing-service.ts +42 -56
  377. package/src/heartbeat/__tests__/heartbeat-service.test.ts +359 -0
  378. package/src/heartbeat/heartbeat-run-store.ts +2 -1
  379. package/src/heartbeat/heartbeat-service.ts +149 -128
  380. package/src/home/__tests__/feed-types.test.ts +63 -131
  381. package/src/home/__tests__/feed-writer.test.ts +77 -278
  382. package/src/home/__tests__/post-connect-feed.test.ts +9 -12
  383. package/src/home/feed-types.ts +19 -73
  384. package/src/home/feed-writer.ts +25 -156
  385. package/src/home/post-connect-feed.ts +1 -3
  386. package/src/ipc/__tests__/cli-ipc.test.ts +2 -0
  387. package/src/ipc/__tests__/email-ipc.test.ts +506 -0
  388. package/src/ipc/__tests__/exit-helper.test.ts +104 -0
  389. package/src/ipc/__tests__/streaming-client.test.ts +237 -0
  390. package/src/ipc/__tests__/streaming-framing.test.ts +142 -0
  391. package/src/ipc/assistant-server.ts +148 -42
  392. package/src/ipc/cli-client.ts +370 -50
  393. package/src/ipc/routes/db-proxy-transaction.ts +151 -0
  394. package/src/ipc/skill-routes/__tests__/events-ipc.test.ts +60 -0
  395. package/src/ipc/skill-routes/events.ts +30 -3
  396. package/src/ipc/skill-server.ts +99 -42
  397. package/src/live-voice/__tests__/live-voice-session-manager.test.ts +46 -0
  398. package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +1 -0
  399. package/src/live-voice/live-voice-session-manager.ts +11 -4
  400. package/src/live-voice/live-voice-session.ts +14 -6
  401. package/src/memory/__tests__/bookmark-crud.test.ts +258 -0
  402. package/src/memory/__tests__/bookmark-schema.test.ts +181 -0
  403. package/src/memory/__tests__/conversation-types.test.ts +36 -0
  404. package/src/memory/__tests__/find-most-recent-retrospective-for.test.ts +130 -0
  405. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +10 -57
  406. package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +177 -0
  407. package/src/memory/__tests__/memory-retrospective-job.test.ts +328 -0
  408. package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +213 -0
  409. package/src/memory/__tests__/memory-retrospective-trigger-check.test.ts +90 -0
  410. package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +69 -0
  411. package/src/memory/__tests__/memory-v2-concept-frequency.test.ts +3 -0
  412. package/src/memory/bookmark-crud.ts +179 -0
  413. package/src/memory/context-search/__tests__/agent-runner-redaction.test.ts +31 -9
  414. package/src/memory/context-search/agent-protocol.ts +5 -1
  415. package/src/memory/context-search/agent-runner.ts +60 -85
  416. package/src/memory/context-search/limits.ts +1 -4
  417. package/src/memory/context-search/search.ts +23 -113
  418. package/src/memory/context-search/sources/conversations.ts +18 -6
  419. package/src/memory/context-search/sources/memory-v2.ts +40 -31
  420. package/src/memory/context-search/sources/memory.ts +9 -2
  421. package/src/memory/context-search/sources/workspace.ts +13 -10
  422. package/src/memory/context-search/types.ts +1 -1
  423. package/src/memory/conversation-bootstrap.ts +11 -0
  424. package/src/memory/conversation-crud.ts +312 -10
  425. package/src/memory/conversation-queries.ts +9 -5
  426. package/src/memory/conversation-title-service.ts +1 -0
  427. package/src/memory/conversation-types.ts +16 -0
  428. package/src/memory/db-init.ts +14 -0
  429. package/src/memory/embedding-backend.ts +2 -1
  430. package/src/memory/embedding-runtime-manager.ts +1 -2
  431. package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +104 -61
  432. package/src/memory/graph/__tests__/handle-remember-v2.test.ts +11 -26
  433. package/src/memory/graph/__tests__/remember-description.test.ts +55 -0
  434. package/src/memory/graph/conversation-graph-memory.ts +108 -14
  435. package/src/memory/graph/extraction.ts +4 -0
  436. package/src/memory/graph/graph-memory-state-store.ts +16 -3
  437. package/src/memory/graph/graph-search.test.ts +6 -5
  438. package/src/memory/graph/graph-search.ts +3 -4
  439. package/src/memory/graph/retriever.test.ts +12 -7
  440. package/src/memory/graph/retriever.ts +4 -5
  441. package/src/memory/graph/tool-handlers.ts +20 -11
  442. package/src/memory/graph/tools.ts +48 -9
  443. package/src/memory/indexer.ts +18 -2
  444. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +120 -6
  445. package/src/memory/jobs/embed-concept-page.ts +261 -89
  446. package/src/memory/jobs-store.ts +51 -1
  447. package/src/memory/jobs-worker.ts +60 -7
  448. package/src/memory/llm-request-log-source-clickhouse.ts +317 -0
  449. package/src/memory/llm-request-log-source-local.ts +26 -0
  450. package/src/memory/llm-request-log-source.ts +97 -0
  451. package/src/memory/llm-request-log-store.ts +1 -1
  452. package/src/memory/memory-retrospective-constants.ts +13 -0
  453. package/src/memory/memory-retrospective-enqueue.ts +114 -0
  454. package/src/memory/memory-retrospective-job.ts +351 -0
  455. package/src/memory/memory-retrospective-startup-cleanup.ts +108 -0
  456. package/src/memory/memory-retrospective-state.ts +162 -0
  457. package/src/memory/memory-retrospective-trigger-check.ts +91 -0
  458. package/src/memory/memory-v2-activation-log-store.ts +49 -5
  459. package/src/memory/memory-v2-concept-frequency.ts +4 -0
  460. package/src/memory/message-content.ts +38 -1
  461. package/src/memory/migrations/227-add-conversation-inference-profile.ts +6 -1
  462. package/src/memory/migrations/228-rename-inference-profile-snake-case.ts +20 -7
  463. package/src/memory/migrations/229-delete-private-conversations.test.ts +70 -1
  464. package/src/memory/migrations/229-delete-private-conversations.ts +12 -0
  465. package/src/memory/migrations/231-repair-memory-graph-event-dates.ts +16 -2
  466. package/src/memory/migrations/240-conversation-inference-profile-session.ts +25 -0
  467. package/src/memory/migrations/241-activation-state-fk-cascade.ts +50 -0
  468. package/src/memory/migrations/242-message-bookmarks.ts +38 -0
  469. package/src/memory/migrations/243-provider-connections.ts +68 -0
  470. package/src/memory/migrations/244-provider-connection-status-label.ts +23 -0
  471. package/src/memory/migrations/245-memory-retrospective-state.ts +36 -0
  472. package/src/memory/migrations/246-backfill-provider-connection-label.ts +81 -0
  473. package/src/memory/migrations/__tests__/244-provider-connection-status-label.test.ts +84 -0
  474. package/src/memory/migrations/__tests__/245-memory-retrospective-state.test.ts +125 -0
  475. package/src/memory/migrations/__tests__/246-backfill-provider-connection-label.test.ts +192 -0
  476. package/src/memory/migrations/index.ts +7 -0
  477. package/src/memory/pkb/pkb-search.test.ts +6 -5
  478. package/src/memory/pkb/pkb-search.ts +4 -5
  479. package/src/memory/published-pages-store.ts +16 -0
  480. package/src/memory/qdrant-client.ts +3 -0
  481. package/src/memory/schema/bookmarks.ts +38 -0
  482. package/src/memory/schema/conversations.ts +2 -0
  483. package/src/memory/schema/index.ts +2 -0
  484. package/src/memory/schema/inference.ts +29 -0
  485. package/src/memory/schema/memory-core.ts +9 -0
  486. package/src/memory/search/semantic.ts +5 -9
  487. package/src/memory/v2/__tests__/__snapshots__/prompts-router.test.ts.snap +27 -0
  488. package/src/memory/v2/__tests__/activation-store.test.ts +5 -5
  489. package/src/memory/v2/__tests__/activation.test.ts +46 -9
  490. package/src/memory/v2/__tests__/backfill-jobs.test.ts +38 -21
  491. package/src/memory/v2/__tests__/consolidation-job.test.ts +140 -163
  492. package/src/memory/v2/__tests__/edge-index.test.ts +1 -1
  493. package/src/memory/v2/__tests__/frontmatter-sweep.test.ts +111 -0
  494. package/src/memory/v2/__tests__/injection.test.ts +768 -33
  495. package/src/memory/v2/__tests__/migration.test.ts +7 -3
  496. package/src/memory/v2/__tests__/page-index.test.ts +277 -0
  497. package/src/memory/v2/__tests__/page-store.test.ts +14 -1
  498. package/src/memory/v2/__tests__/prompts-router.test.ts +257 -0
  499. package/src/memory/v2/__tests__/qdrant.test.ts +382 -9
  500. package/src/memory/v2/__tests__/reranker.test.ts +4 -4
  501. package/src/memory/v2/__tests__/router.test.ts +516 -0
  502. package/src/memory/v2/__tests__/sim.test.ts +163 -8
  503. package/src/memory/v2/__tests__/skill-store.test.ts +58 -3
  504. package/src/memory/v2/__tests__/static-context.test.ts +8 -35
  505. package/src/memory/v2/__tests__/sweep-job.test.ts +114 -33
  506. package/src/memory/v2/activation-store.ts +34 -5
  507. package/src/memory/v2/activation.ts +40 -27
  508. package/src/memory/v2/backfill-jobs.ts +17 -84
  509. package/src/memory/v2/consolidation-job.ts +92 -86
  510. package/src/memory/v2/frontmatter-sweep.ts +91 -0
  511. package/src/memory/v2/injection.ts +466 -115
  512. package/src/memory/v2/migration.ts +117 -20
  513. package/src/memory/v2/page-index.ts +191 -0
  514. package/src/memory/v2/page-store.ts +42 -0
  515. package/src/memory/v2/prompts/consolidation.ts +14 -7
  516. package/src/memory/v2/prompts/router.ts +192 -0
  517. package/src/memory/v2/qdrant.ts +307 -133
  518. package/src/memory/v2/reranker.ts +14 -7
  519. package/src/memory/v2/router.ts +322 -0
  520. package/src/memory/v2/sim.ts +88 -34
  521. package/src/memory/v2/skill-store.ts +118 -29
  522. package/src/memory/v2/static-context.ts +20 -17
  523. package/src/memory/v2/sweep-job.ts +127 -102
  524. package/src/memory/v2/types.ts +16 -5
  525. package/src/memory/validation.ts +13 -0
  526. package/src/notifications/__tests__/emit-signal-home-feed.test.ts +182 -0
  527. package/src/notifications/__tests__/home-feed-side-effect.test.ts +199 -0
  528. package/src/notifications/__tests__/signal-registry.test.ts +17 -0
  529. package/src/notifications/adapters/platform.ts +171 -0
  530. package/src/notifications/conversation-pairing.ts +2 -2
  531. package/src/notifications/copy-composer.ts +61 -12
  532. package/src/notifications/decision-engine.ts +46 -0
  533. package/src/notifications/destination-resolver.ts +21 -0
  534. package/src/notifications/emit-signal.ts +28 -1
  535. package/src/notifications/home-feed-side-effect.ts +111 -0
  536. package/src/notifications/signal.ts +5 -0
  537. package/src/permissions/checker.ts +12 -0
  538. package/src/permissions/gateway-threshold-reader.ts +116 -8
  539. package/src/permissions/ipc-risk-types.ts +2 -0
  540. package/src/permissions/prompter.ts +86 -96
  541. package/src/permissions/secret-prompter.ts +31 -31
  542. package/src/plugin-api/index.ts +13 -0
  543. package/src/plugin-api/package.json +12 -0
  544. package/src/plugin-api/types.ts +62 -0
  545. package/src/plugins/defaults/injectors.ts +20 -5
  546. package/src/plugins/external-plugin-loader.ts +294 -0
  547. package/src/plugins/types.ts +46 -30
  548. package/src/plugins/user-loader.ts +64 -41
  549. package/src/proactive-artifact/job.test.ts +63 -8
  550. package/src/proactive-artifact/job.ts +20 -2
  551. package/src/proactive-artifact/message-copy.ts +18 -1
  552. package/src/proactive-artifact/trigger-state.test.ts +9 -0
  553. package/src/proactive-artifact/trigger-state.ts +4 -0
  554. package/src/prompts/__tests__/system-prompt.test.ts +105 -0
  555. package/src/prompts/system-prompt.ts +22 -1
  556. package/src/prompts/templates/SOUL.md +13 -28
  557. package/src/prompts/update-bulletin-job.ts +61 -73
  558. package/src/providers/__tests__/dispatch-connection-routing.test.ts +279 -0
  559. package/src/providers/__tests__/inference.test.ts +288 -0
  560. package/src/providers/__tests__/provider-env-vars.test.ts +6 -0
  561. package/src/providers/__tests__/provider-secret-catalog.test.ts +6 -0
  562. package/src/providers/__tests__/retry-callsite.test.ts +14 -32
  563. package/src/providers/__tests__/satellite-connection-routing.test.ts +510 -0
  564. package/src/providers/__tests__/search-provider-catalog.test.ts +80 -0
  565. package/src/providers/anthropic/client.ts +95 -26
  566. package/src/providers/call-site-routing.ts +94 -16
  567. package/src/providers/connection-resolution.ts +163 -0
  568. package/src/providers/inference/__tests__/connections-status-label.test.ts +250 -0
  569. package/src/providers/inference/adapter-factory.ts +173 -0
  570. package/src/providers/inference/auth.ts +112 -0
  571. package/src/providers/inference/backfill.ts +196 -0
  572. package/src/providers/inference/connections.ts +356 -0
  573. package/src/providers/inference/resolve-auth.ts +65 -0
  574. package/src/providers/model-catalog.ts +104 -6
  575. package/src/providers/openai/responses-provider.ts +4 -2
  576. package/src/providers/provider-env-vars.ts +17 -7
  577. package/src/providers/provider-secret-catalog.ts +49 -30
  578. package/src/providers/provider-send-message.ts +41 -20
  579. package/src/providers/registry.ts +143 -159
  580. package/src/providers/retry.ts +18 -10
  581. package/src/providers/search-provider-catalog.ts +121 -0
  582. package/src/runtime/AGENTS.md +18 -5
  583. package/src/runtime/__tests__/background-job-runner.test.ts +357 -0
  584. package/src/runtime/__tests__/pre-first-message-gate.test.ts +82 -0
  585. package/src/runtime/actor-trust-resolver.ts +32 -10
  586. package/src/runtime/agent-wake.ts +35 -6
  587. package/src/runtime/assistant-event-hub.ts +3 -85
  588. package/src/runtime/auth/route-policy.ts +304 -8
  589. package/src/runtime/auth/same-actor.ts +2 -0
  590. package/src/runtime/background-job-runner.ts +339 -0
  591. package/src/runtime/btw-sidechain.ts +1 -0
  592. package/src/runtime/channel-approvals.ts +3 -2
  593. package/src/runtime/guardian-reply-router.ts +0 -10
  594. package/src/runtime/http-router.ts +36 -1
  595. package/src/runtime/http-server.ts +31 -5
  596. package/src/runtime/http-types.ts +2 -0
  597. package/src/runtime/middleware/__tests__/request-logger.test.ts +162 -0
  598. package/src/runtime/middleware/request-logger.ts +62 -1
  599. package/src/runtime/pending-interactions.ts +19 -15
  600. package/src/runtime/pre-first-message-gate.ts +83 -0
  601. package/src/runtime/routes/__tests__/backup-routes.test.ts +8 -1
  602. package/src/runtime/routes/__tests__/bookmark-routes.test.ts +251 -0
  603. package/src/runtime/routes/__tests__/connection-routes-vs-cli-parity.test.ts +142 -0
  604. package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +315 -0
  605. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +189 -0
  606. package/src/runtime/routes/__tests__/home-feed-routes.test.ts +15 -136
  607. package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +736 -0
  608. package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +147 -0
  609. package/src/runtime/routes/__tests__/stt-routes.test.ts +5 -1
  610. package/src/runtime/routes/__tests__/surface-action-routes.test.ts +384 -0
  611. package/src/runtime/routes/__tests__/tts-routes.test.ts +6 -2
  612. package/src/runtime/routes/acp-routes.ts +10 -8
  613. package/src/runtime/routes/app-management-routes.ts +228 -3
  614. package/src/runtime/routes/approval-routes.ts +7 -21
  615. package/src/runtime/routes/audit-routes.ts +43 -0
  616. package/src/runtime/routes/auth-routes.ts +72 -0
  617. package/src/runtime/routes/avatar-routes.ts +273 -20
  618. package/src/runtime/routes/backup-routes.ts +406 -2
  619. package/src/runtime/routes/bookmark-routes.ts +154 -0
  620. package/src/runtime/routes/channel-verification-routes.ts +2 -1
  621. package/src/runtime/routes/consolidation-routes.ts +8 -9
  622. package/src/runtime/routes/contact-routes.ts +0 -160
  623. package/src/runtime/routes/conversation-cli-routes.ts +192 -0
  624. package/src/runtime/routes/conversation-management-routes.ts +30 -43
  625. package/src/runtime/routes/conversation-query-routes.ts +373 -82
  626. package/src/runtime/routes/conversation-routes.ts +31 -10
  627. package/src/runtime/routes/conversations-import-routes.ts +229 -0
  628. package/src/runtime/routes/credential-routes.ts +540 -0
  629. package/src/runtime/routes/debug-bash-routes.ts +2 -0
  630. package/src/runtime/routes/debug-routes.ts +2 -2
  631. package/src/runtime/routes/document-pdf-renderer.ts +5 -1
  632. package/src/runtime/routes/domain-routes.ts +167 -0
  633. package/src/runtime/routes/email-routes.ts +603 -0
  634. package/src/runtime/routes/errors.ts +2 -2
  635. package/src/runtime/routes/events-routes.ts +192 -0
  636. package/src/runtime/routes/filing-routes.ts +2 -3
  637. package/src/runtime/routes/home-feed-routes.ts +6 -78
  638. package/src/runtime/routes/host-app-control-routes.ts +44 -2
  639. package/src/runtime/routes/host-browser-routes.ts +103 -22
  640. package/src/runtime/routes/http-adapter.ts +2 -0
  641. package/src/runtime/routes/identity-routes.ts +5 -0
  642. package/src/runtime/routes/image-generation-routes.ts +99 -0
  643. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +137 -1
  644. package/src/runtime/routes/inbound-stages/background-dispatch.ts +87 -7
  645. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.test.ts +156 -0
  646. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +22 -7
  647. package/src/runtime/routes/index.ts +36 -0
  648. package/src/runtime/routes/inference-profile-session-handler.ts +312 -0
  649. package/src/runtime/routes/inference-profile-session-reaper.ts +98 -0
  650. package/src/runtime/routes/inference-profile-session-routes.ts +146 -0
  651. package/src/runtime/routes/inference-provider-connection-routes.ts +317 -0
  652. package/src/runtime/routes/inference-send-routes.ts +115 -0
  653. package/src/runtime/routes/integrations/twilio.ts +1 -0
  654. package/src/runtime/routes/mcp-auth-routes.ts +283 -9
  655. package/src/runtime/routes/memory-item-routes.test.ts +3 -9
  656. package/src/runtime/routes/memory-item-routes.ts +5 -6
  657. package/src/runtime/routes/memory-v2-routes.ts +105 -404
  658. package/src/runtime/routes/notification-routes.ts +2 -0
  659. package/src/runtime/routes/oauth-apps.ts +112 -7
  660. package/src/runtime/routes/oauth-commands-routes.ts +1007 -0
  661. package/src/runtime/routes/oauth-connect-routes.ts +67 -5
  662. package/src/runtime/routes/oauth-providers.ts +298 -8
  663. package/src/runtime/routes/platform-routes.ts +336 -0
  664. package/src/runtime/routes/playground/inject-failures.ts +2 -1
  665. package/src/runtime/routes/playground/reset-circuit.ts +2 -1
  666. package/src/runtime/routes/playground/state.ts +2 -1
  667. package/src/runtime/routes/publish-routes.ts +221 -0
  668. package/src/runtime/routes/schedule-routes.ts +82 -0
  669. package/src/runtime/routes/sequence-routes.ts +291 -0
  670. package/src/runtime/routes/settings-routes.ts +2 -10
  671. package/src/runtime/routes/skills-routes.ts +31 -1
  672. package/src/runtime/routes/stt-routes.ts +240 -3
  673. package/src/runtime/routes/surface-action-routes.ts +43 -7
  674. package/src/runtime/routes/tts-routes.ts +67 -0
  675. package/src/runtime/routes/types.ts +32 -0
  676. package/src/runtime/routes/user-routes-cli.ts +243 -0
  677. package/src/runtime/routes/webhook-routes.ts +165 -0
  678. package/src/runtime/sync/resource-sync-events.ts +25 -0
  679. package/src/runtime/sync/sync-publisher.test.ts +105 -0
  680. package/src/runtime/sync/sync-publisher.ts +21 -0
  681. package/src/schedule/scheduler.ts +200 -123
  682. package/src/security/__tests__/provider-key-env-fallback.test.ts +12 -6
  683. package/src/security/secret-patterns.ts +3 -0
  684. package/src/sequence/engine.ts +38 -40
  685. package/src/skills/include-graph.ts +35 -13
  686. package/src/subagent/manager.ts +20 -15
  687. package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +206 -0
  688. package/src/tools/browser/browser-execution.ts +15 -4
  689. package/src/tools/browser/cdp-client/__tests__/factory.test.ts +174 -0
  690. package/src/tools/browser/cdp-client/cdp-inspect/__tests__/ws-transport.test.ts +16 -13
  691. package/src/tools/browser/cdp-client/extension-cdp-client.ts +24 -1
  692. package/src/tools/browser/cdp-client/factory.ts +66 -5
  693. package/src/tools/browser/runtime-check.ts +77 -0
  694. package/src/tools/document/document-tool.ts +20 -0
  695. package/src/tools/executor.ts +18 -2
  696. package/src/tools/memory/register.test.ts +10 -8
  697. package/src/tools/memory/register.ts +9 -1
  698. package/src/tools/network/__tests__/web-search.test.ts +156 -0
  699. package/src/tools/network/web-search.ts +280 -37
  700. package/src/tools/permission-checker.ts +28 -5
  701. package/src/tools/skills/load.ts +24 -20
  702. package/src/tools/subagent/spawn.ts +3 -3
  703. package/src/tools/terminal/shell.ts +44 -0
  704. package/src/tools/tool-name-aliases.ts +19 -0
  705. package/src/tools/types.ts +19 -1
  706. package/src/usage/attribution.ts +3 -2
  707. package/src/util/pricing.ts +86 -160
  708. package/src/watcher/__tests__/engine.test.ts +301 -0
  709. package/src/watcher/constants.ts +7 -0
  710. package/src/watcher/engine.ts +90 -90
  711. package/src/workspace/migrations/046-seed-conversation-starters-callsite.ts +6 -9
  712. package/src/workspace/migrations/054-seed-recall-callsite.ts +10 -1
  713. package/src/workspace/migrations/057-repair-stale-gemini-model-ids.ts +28 -4
  714. package/src/workspace/migrations/067-release-notes-safe-storage-limits.ts +4 -62
  715. package/src/workspace/migrations/069-seed-onboarding-threads.ts +34 -0
  716. package/src/workspace/migrations/070-memory-v2-summary-schema-rebuild.ts +31 -0
  717. package/src/workspace/migrations/071-remove-safe-storage-release-note.ts +111 -0
  718. package/src/workspace/migrations/072-seed-reply-suggestion-callsite.ts +104 -0
  719. package/src/workspace/migrations/073-repair-recall-callsite-empty-profile.ts +93 -0
  720. package/src/workspace/migrations/074-drop-deprecated-secret-detection-keys.ts +117 -0
  721. package/src/workspace/migrations/075-memory-v2-bm25-b-default-reembed.ts +61 -0
  722. package/src/workspace/migrations/076-drop-services-inference-mode.ts +62 -0
  723. package/src/workspace/migrations/077-seed-memory-router-callsite.ts +89 -0
  724. package/src/workspace/migrations/078-release-notes-tavily-web-search.ts +66 -0
  725. package/src/workspace/migrations/079-home-feed-notification-only.ts +197 -0
  726. package/src/workspace/migrations/080-restrict-vercel-api-token-metadata.ts +182 -0
  727. package/src/workspace/migrations/081-backfill-bash-allowed-tools-for-injection-credentials.ts +160 -0
  728. package/src/workspace/migrations/082-backfill-managed-profile-labels.ts +154 -0
  729. package/src/workspace/migrations/registry.ts +28 -0
  730. package/src/workspace/migrations/runner.ts +13 -2
  731. package/src/workspace/migrations/types.ts +13 -3
  732. package/src/workspace/provider-commit-message-generator.ts +3 -2
  733. package/src/__tests__/context-search-pkb-source.test.ts +0 -492
  734. package/src/__tests__/credentials-cli.test.ts +0 -1225
  735. package/src/__tests__/memory-admin-recall.test.ts +0 -213
  736. package/src/approvals/__tests__/guardian-feed-event.test.ts +0 -303
  737. package/src/cli/commands/__tests__/email-download.test.ts +0 -260
  738. package/src/cli/commands/__tests__/email-list.test.ts +0 -216
  739. package/src/cli/commands/__tests__/email-register.test.ts +0 -186
  740. package/src/cli/commands/__tests__/email-send.test.ts +0 -416
  741. package/src/cli/commands/__tests__/email-status.test.ts +0 -185
  742. package/src/cli/commands/__tests__/email-unregister.test.ts +0 -168
  743. package/src/cli/commands/__tests__/routes.test.ts +0 -562
  744. package/src/cli/commands/__tests__/stt-transcribe.test.ts +0 -454
  745. package/src/cli/commands/autonomy.ts +0 -365
  746. package/src/cli/commands/memory.ts +0 -424
  747. package/src/cli/commands/oauth/__tests__/connect.test.ts +0 -1201
  748. package/src/cli/commands/oauth/__tests__/disconnect.test.ts +0 -686
  749. package/src/cli/commands/oauth/__tests__/mode.test.ts +0 -632
  750. package/src/cli/commands/oauth/__tests__/ping.test.ts +0 -631
  751. package/src/cli/commands/oauth/__tests__/providers-delete.test.ts +0 -573
  752. package/src/cli/commands/oauth/__tests__/providers-register.test.ts +0 -330
  753. package/src/cli/commands/oauth/__tests__/providers-update.test.ts +0 -521
  754. package/src/cli/commands/oauth/__tests__/status.test.ts +0 -551
  755. package/src/cli/commands/oauth/__tests__/token.test.ts +0 -420
  756. package/src/cli/lib/daemon-avatar-client.ts +0 -37
  757. package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +0 -87
  758. package/src/config/bundled-skills/messaging/tools/__tests__/messaging-feed-events.test.ts +0 -207
  759. package/src/daemon/__tests__/conversation-feed-event.test.ts +0 -304
  760. package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +0 -233
  761. package/src/home/__tests__/assistant-feed-authoring.test.ts +0 -156
  762. package/src/home/__tests__/emit-feed-event.test.ts +0 -169
  763. package/src/home/__tests__/feed-population-integration.test.ts +0 -312
  764. package/src/home/__tests__/feed-scheduler.test.ts +0 -222
  765. package/src/home/__tests__/phase5-exit-criteria.test.ts +0 -229
  766. package/src/home/__tests__/platform-gmail-digest.test.ts +0 -222
  767. package/src/home/__tests__/rollup-producer.test.ts +0 -507
  768. package/src/home/assistant-feed-authoring.ts +0 -135
  769. package/src/home/emit-feed-event.ts +0 -169
  770. package/src/home/feed-scheduler.ts +0 -281
  771. package/src/home/platform-gmail-digest.ts +0 -163
  772. package/src/home/rewrite-command-preview.ts +0 -66
  773. package/src/home/rewrite-feed-title.ts +0 -58
  774. package/src/home/rollup-producer.ts +0 -426
  775. package/src/memory/admin.ts +0 -326
  776. package/src/memory/context-search/sources/pkb.ts +0 -477
  777. package/src/memory/graph/compaction.ts +0 -299
  778. /package/src/cli/{commands → lib}/cache-fs.ts +0 -0
@@ -34,6 +34,7 @@ import {
34
34
  embedWithBackend,
35
35
  generateSparseEmbedding,
36
36
  } from "../embedding-backend.js";
37
+ import { invalidatePageIndex } from "./page-index.js";
37
38
  import {
38
39
  pruneSlugsWithPrefixExcept,
39
40
  upsertConceptPageEmbedding,
@@ -42,6 +43,10 @@ import {
42
43
  augmentMcpSetupDescription,
43
44
  buildSkillContent,
44
45
  } from "./skill-content.js";
46
+ import {
47
+ generateBm25DocEmbedding,
48
+ getConceptPageCorpusStats,
49
+ } from "./sparse-bm25.js";
45
50
  import type { SkillEntry } from "./types.js";
46
51
 
47
52
  const log = getLogger("memory-v2-skill-store");
@@ -54,6 +59,14 @@ const log = getLogger("memory-v2-skill-store");
54
59
  */
55
60
  export const SKILL_SLUG_PREFIX = "skills/";
56
61
 
62
+ /**
63
+ * Payload discriminator written on every skill-seeded Qdrant point. Keeps
64
+ * skill rows distinguishable from user-authored concept pages that happen to
65
+ * be slugged under `skills/...`, so prefix pruning never deletes a hand-
66
+ * authored page sitting in the same namespace.
67
+ */
68
+ const SKILL_PAYLOAD_KIND = "skill";
69
+
57
70
  /** Compose the unified-collection slug for a skill id. */
58
71
  export function skillSlugFor(id: string): string {
59
72
  return `${SKILL_SLUG_PREFIX}${id}`;
@@ -68,10 +81,39 @@ let entries: Map<string, SkillEntry> | null = null;
68
81
 
69
82
  /**
70
83
  * Seed (or re-seed) skill embeddings into the unified concept-page collection.
71
- * Idempotent: safe to call repeatedly. Best-effort: never throws any
72
- * failure leaves the prior `entries` cache in place and logs a warning.
84
+ * Idempotent. Defaults to best-effort (errors are logged but swallowed) for
85
+ * background callers like daemon startup; pass `{ throwOnError: true }` from
86
+ * synchronous CLI-driven paths that need to surface failures to the operator.
73
87
  *
74
- * Steps:
88
+ * Single-flight + coalesced: at most one seed runs at a time, and concurrent
89
+ * callers are coalesced into one follow-up re-snapshot that runs after the
90
+ * in-flight seed completes. Without this, an older snapshot can finish after
91
+ * a newer one and overwrite the newer skill state. Strict callers observe
92
+ * the most recent run's outcome via `lastSeedError`.
93
+ */
94
+ let seedTail: Promise<void> = Promise.resolve();
95
+ let seedPending: Promise<void> | null = null;
96
+ let lastSeedError: unknown = null;
97
+
98
+ export async function seedV2SkillEntries(
99
+ opts: { throwOnError?: boolean } = {},
100
+ ): Promise<void> {
101
+ if (!seedPending) {
102
+ const next = seedTail.then(async () => {
103
+ seedPending = null;
104
+ await runSeedOnce();
105
+ });
106
+ seedTail = next.catch(() => {});
107
+ seedPending = next;
108
+ }
109
+ await seedPending;
110
+ if (opts.throwOnError && lastSeedError) {
111
+ throw lastSeedError;
112
+ }
113
+ }
114
+
115
+ /**
116
+ * Steps (per run):
75
117
  * 1. Enumerate the local skill catalog and resolve each skill's enabled
76
118
  * state (`resolveSkillStates`).
77
119
  * 2. Build a `SkillEntry` per enabled skill, applying the mcp-setup
@@ -90,7 +132,7 @@ let entries: Map<string, SkillEntry> | null = null;
90
132
  * stale points from prior catalog state (e.g. uninstalled skills).
91
133
  * 7. Replace the module-level `entries` cache with the freshly built map.
92
134
  */
93
- export async function seedV2SkillEntries(): Promise<void> {
135
+ async function runSeedOnce(): Promise<void> {
94
136
  try {
95
137
  const config = getConfig();
96
138
  const catalog = loadSkillCatalog();
@@ -137,32 +179,53 @@ export async function seedV2SkillEntries(): Promise<void> {
137
179
  );
138
180
  }
139
181
 
140
- // Embed all content strings in one batched call. Sparse vectors are
141
- // computed in-process (no network).
142
- const embedded = await embedWithBackend(
143
- config,
144
- seeds.map((s) => s.content),
145
- );
146
- const denseVectors = await Promise.all(
147
- embedded.vectors.map((v) =>
148
- applyCorrectionIfCalibrated(v, embedded.provider, embedded.model),
149
- ),
150
- );
151
-
152
- const now = Date.now();
182
+ // Embed all content strings in one batched call when there is anything to
183
+ // embed. Skipping the call when `seeds` is empty avoids throwing on an
184
+ // unavailable embedding backend in the all-disabled case, so pruning and
185
+ // cache replacement still run and clear stale state.
153
186
  const nextEntries = new Map<string, SkillEntry>();
154
- await Promise.all(
155
- seeds.map((seed, i) =>
156
- upsertConceptPageEmbedding({
157
- slug: skillSlugFor(seed.id),
158
- dense: denseVectors[i],
159
- sparse: generateSparseEmbedding(seed.content),
160
- updatedAt: now,
161
- }),
162
- ),
163
- );
164
- for (const seed of seeds) {
165
- nextEntries.set(seed.id, seed);
187
+ if (seeds.length > 0) {
188
+ const embedded = await embedWithBackend(
189
+ config,
190
+ seeds.map((s) => s.content),
191
+ );
192
+ const denseVectors = await Promise.all(
193
+ embedded.vectors.map((v) =>
194
+ applyCorrectionIfCalibrated(v, embedded.provider, embedded.model),
195
+ ),
196
+ );
197
+
198
+ // Skills share the concept-page Qdrant collection, so the sparse vector
199
+ // must use the same stemmed BM25 encoding the concept-page documents
200
+ // carry — otherwise the stemmed BM25 query vectors used by callers (see
201
+ // `simBatch`, `activation.selectCandidates`, recall) hash to different
202
+ // buckets than the stored skill vectors and skip the sparse channel
203
+ // entirely. Fall back to the legacy TF encoder only during the cold-start
204
+ // window before corpus stats finish building.
205
+ const corpusStats = getConceptPageCorpusStats();
206
+ const encodeSparse = (input: string) =>
207
+ corpusStats
208
+ ? generateBm25DocEmbedding(input, corpusStats, {
209
+ k1: config.memory.v2.bm25_k1,
210
+ b: config.memory.v2.bm25_b,
211
+ })
212
+ : generateSparseEmbedding(input);
213
+
214
+ const now = Date.now();
215
+ await Promise.all(
216
+ seeds.map((seed, i) =>
217
+ upsertConceptPageEmbedding({
218
+ slug: skillSlugFor(seed.id),
219
+ dense: denseVectors[i],
220
+ sparse: encodeSparse(seed.content),
221
+ updatedAt: now,
222
+ kind: SKILL_PAYLOAD_KIND,
223
+ }),
224
+ ),
225
+ );
226
+ for (const seed of seeds) {
227
+ nextEntries.set(seed.id, seed);
228
+ }
166
229
  }
167
230
 
168
231
  // Prune stale skill slugs. When the catalog is unavailable (empty array
@@ -173,6 +236,7 @@ export async function seedV2SkillEntries(): Promise<void> {
173
236
  await pruneSlugsWithPrefixExcept(
174
237
  SKILL_SLUG_PREFIX,
175
238
  seeds.map((s) => s.id),
239
+ { kind: SKILL_PAYLOAD_KIND },
176
240
  );
177
241
  } else {
178
242
  log.info(
@@ -182,7 +246,13 @@ export async function seedV2SkillEntries(): Promise<void> {
182
246
 
183
247
  // Atomically replace the cache only after every step above succeeds.
184
248
  entries = nextEntries;
249
+ // Drop the page-index cache so the next router invocation observes the
250
+ // freshly seeded skill set (skill entries share the unified concept-page
251
+ // collection and surface in the same index).
252
+ invalidatePageIndex();
253
+ lastSeedError = null;
185
254
  } catch (err) {
255
+ lastSeedError = err;
186
256
  log.warn({ err }, "Failed to seed v2 skill entries");
187
257
  }
188
258
  }
@@ -208,7 +278,26 @@ export function isSkillSlug(slug: string): boolean {
208
278
  return slug.startsWith(SKILL_SLUG_PREFIX);
209
279
  }
210
280
 
281
+ /**
282
+ * Snapshot of the in-process skill cache, sorted by skill id (ASCII order)
283
+ * for determinism. Returns a freshly allocated array on each call so callers
284
+ * cannot mutate the underlying cache.
285
+ *
286
+ * The cache is replaced atomically by `seedV2SkillEntries`, so a snapshot
287
+ * may be stale once a subsequent seed run completes. Callers that need
288
+ * up-to-the-moment state must re-call this after awaiting the seed.
289
+ */
290
+ export function listSkillEntries(): SkillEntry[] {
291
+ if (!entries) return [];
292
+ return [...entries.values()].sort((a, b) =>
293
+ a.id < b.id ? -1 : a.id > b.id ? 1 : 0,
294
+ );
295
+ }
296
+
211
297
  /** @internal Test-only: clear the module-level cache. */
212
298
  export function _resetSkillStoreForTests(): void {
213
299
  entries = null;
300
+ seedTail = Promise.resolve();
301
+ seedPending = null;
302
+ lastSeedError = null;
214
303
  }
@@ -18,7 +18,6 @@
18
18
  // matching the existing PKB auto-inject pattern.
19
19
 
20
20
  import type { ChannelId } from "../../channels/types.js";
21
- import { isAssistantFeatureFlagEnabled } from "../../config/assistant-feature-flags.js";
22
21
  import { loadConfig } from "../../config/loader.js";
23
22
  import { readPromptFile } from "../../prompts/system-prompt.js";
24
23
  import { getWorkspacePromptPath } from "../../util/platform.js";
@@ -36,9 +35,9 @@ const MEMORY_V2_STATIC_BLOCKS: readonly MemoryV2StaticBlock[] = [
36
35
  ];
37
36
 
38
37
  /**
39
- * Build the v2 static memory block, gated on `memory-v2-enabled` +
40
- * `config.memory.v2.enabled`. Empty/missing files are skipped; returns
41
- * `null` when the gate is off or every file is empty.
38
+ * Build the v2 static memory block, gated on `config.memory.v2.enabled`.
39
+ * Empty/missing files are skipped; returns `null` when the gate is off or
40
+ * every file is empty.
42
41
  */
43
42
  export function readMemoryV2StaticContent(): string | null {
44
43
  let config;
@@ -47,10 +46,7 @@ export function readMemoryV2StaticContent(): string | null {
47
46
  } catch {
48
47
  return null;
49
48
  }
50
- if (
51
- !isAssistantFeatureFlagEnabled("memory-v2-enabled", config) ||
52
- !config.memory.v2.enabled
53
- ) {
49
+ if (!config.memory.v2.enabled) {
54
50
  return null;
55
51
  }
56
52
 
@@ -64,19 +60,26 @@ export function readMemoryV2StaticContent(): string | null {
64
60
  }
65
61
 
66
62
  /**
67
- * Static memory holds the user's aggregate personal pages
68
- * (essentials/threads/recent/buffer). Block injection when a non-guardian
69
- * actor reaches the assistant over a remote channel otherwise the model
70
- * can be prompt-injected into reciting private memory. Internal flows
71
- * (`sourceChannel: "vellum"`) and turns with no trust context pass through
72
- * unchanged; this gate exists only to keep remote untrusted actors out.
63
+ * Trust-class predicate for personal-memory injection. Personal memory
64
+ * spans v2 static blocks (essentials/threads/recent/buffer), the PKB
65
+ * context, and NOW.md all of which can hold private user content. Block
66
+ * injection when a non-guardian actor reaches the assistant over a remote
67
+ * channel otherwise the model can be prompt-injected into reciting
68
+ * private memory. Internal flows (`sourceChannel: "vellum"`) and turns
69
+ * with no trust context pass through unchanged; this gate exists only to
70
+ * keep remote untrusted actors out.
71
+ *
72
+ * This is the trust-only gate. Cadence (first-turn / post-compaction) is
73
+ * applied separately by the caller so that the freshest content remains
74
+ * available for re-injection after a mid-turn reducer-triggered compaction
75
+ * — the initial-injection turn may not have been a `shouldInjectNowAndPkb`
76
+ * turn, but compaction strips the existing personal-memory blocks and we
77
+ * still need the freshest content to re-inject.
73
78
  */
74
- export function shouldLoadMemoryV2Static(args: {
75
- shouldInjectNowAndPkb: boolean;
79
+ export function shouldExposePersonalMemory(args: {
76
80
  sourceChannel: ChannelId | undefined;
77
81
  isTrustedActor: boolean;
78
82
  }): boolean {
79
- if (!args.shouldInjectNowAndPkb) return false;
80
83
  const isRemoteUntrustedActor =
81
84
  args.sourceChannel !== undefined &&
82
85
  args.sourceChannel !== "vellum" &&
@@ -13,21 +13,24 @@
13
13
  * extraction-trigger path. Until then this handler is invoked only by
14
14
  * `memory_v2_sweep` rows enqueued explicitly (tests, future CLI).
15
15
  *
16
- * Skipped entirely when the `memory-v2-enabled` feature flag is off, or when
16
+ * Skipped entirely when `config.memory.v2.enabled` is false, or when
17
17
  * `config.memory.v2.sweep_enabled` is false — keeps the sweep dormant in
18
18
  * v1-only workspaces and in v2 workspaces that haven't opted in, even if a
19
- * stale row sits in the queue at flag-flip time.
19
+ * stale row sits in the queue when v2 is disabled.
20
20
  */
21
21
 
22
22
  import { readFileSync } from "node:fs";
23
23
  import { join } from "node:path";
24
24
 
25
- import { desc, gt } from "drizzle-orm";
25
+ import { and, desc, eq, gt, notInArray } from "drizzle-orm";
26
26
  import { z } from "zod";
27
27
 
28
- import { isAssistantFeatureFlagEnabled } from "../../config/assistant-feature-flags.js";
29
28
  import type { AssistantConfig } from "../../config/types.js";
30
- import { getAssistantName } from "../../daemon/identity-helpers.js";
29
+ import {
30
+ getAssistantName,
31
+ resolveUserName,
32
+ } from "../../daemon/identity-helpers.js";
33
+ import { emitNotificationSignal } from "../../notifications/emit-signal.js";
31
34
  import {
32
35
  extractToolUse,
33
36
  getConfiguredProvider,
@@ -42,11 +45,15 @@ import {
42
45
  formatRememberEntry,
43
46
  } from "../graph/tool-handlers.js";
44
47
  import type { MemoryJob } from "../jobs-store.js";
45
- import { messages } from "../schema.js";
48
+ import { stringifyMessageContent } from "../message-content.js";
49
+ import { conversations, messages } from "../schema.js";
46
50
  import { renderSweepPrompt } from "./prompts/sweep.js";
47
51
 
48
52
  const log = getLogger("memory-v2-sweep");
49
53
 
54
+ /** Stable job identifier surfaced in `activity.failed` notifications. */
55
+ const JOB_NAME = "memory.v2.sweep";
56
+
50
57
  /** Window of conversation history the sweep inspects on each run. */
51
58
  const RECENT_MESSAGES_WINDOW_MS = 30 * 60 * 1000;
52
59
 
@@ -101,74 +108,131 @@ const SweepResultSchema = z.object({
101
108
  * progress without inspecting the filesystem.
102
109
  */
103
110
  export async function memoryV2SweepJob(
104
- _job: MemoryJob,
111
+ job: MemoryJob,
105
112
  config: AssistantConfig,
106
113
  ): Promise<number> {
107
- if (!isAssistantFeatureFlagEnabled("memory-v2-enabled", config)) {
108
- log.debug("memory-v2-enabled flag off; sweep skipped");
114
+ if (!config.memory?.v2?.enabled) {
115
+ log.debug("memory.v2.enabled is false; sweep skipped");
109
116
  return 0;
110
117
  }
111
118
 
112
- if (!config.memory?.v2?.sweep_enabled) {
119
+ if (!config.memory.v2.sweep_enabled) {
113
120
  log.debug("memory.v2.sweep_enabled is false; sweep skipped");
114
121
  return 0;
115
122
  }
116
123
 
117
124
  const workspaceDir = getWorkspaceDir();
118
125
  const memoryDir = join(workspaceDir, "memory");
119
- const recentText = loadRecentMessagesText(Date.now());
120
- if (!recentText) {
121
- log.debug("No recent messages in window; sweep skipped");
122
- return 0;
123
- }
124
126
 
125
- const existingBuffer = readBufferText(memoryDir);
127
+ // Once we're committed to running (past the flag/feature gates), any
128
+ // unexpected error is surfaced via an `activity.failed` notification —
129
+ // mirrors v1 filing's post-migration treatment, but hand-rolled because
130
+ // the sweep makes a single forced-tool `provider.sendMessage` call rather
131
+ // than driving a conversation through `runBackgroundJob`. The function
132
+ // continues to return 0 on caught failures (preserving the existing
133
+ // silent-failure contract); only the notification side-effect is new.
134
+ try {
135
+ const recentText = loadRecentMessagesText(Date.now());
136
+ if (!recentText) {
137
+ log.debug("No recent messages in window; sweep skipped");
138
+ return 0;
139
+ }
140
+
141
+ const existingBuffer = readBufferText(memoryDir);
126
142
 
127
- const provider = await getConfiguredProvider("memoryV2Sweep");
128
- if (!provider) {
129
- log.warn("memoryV2Sweep provider unavailable; sweep skipped");
130
- return 0;
131
- }
143
+ const provider = await getConfiguredProvider("memoryV2Sweep");
144
+ if (!provider) {
145
+ log.warn("memoryV2Sweep provider unavailable; sweep skipped");
146
+ return 0;
147
+ }
132
148
 
133
- const systemPrompt = renderSweepPrompt({
134
- assistantName: getAssistantName(),
135
- userName: resolveUserName(workspaceDir),
136
- });
137
- const userText =
138
- `## existingBuffer\n\n${existingBuffer || "(empty)"}\n\n` +
139
- `## recentMessages\n\n${recentText}`;
149
+ const systemPrompt = renderSweepPrompt({
150
+ assistantName: getAssistantName(),
151
+ userName: resolveUserName(workspaceDir),
152
+ });
153
+ const userText =
154
+ `## existingBuffer\n\n${existingBuffer || "(empty)"}\n\n` +
155
+ `## recentMessages\n\n${recentText}`;
140
156
 
141
- const response = await provider.sendMessage(
142
- [userMessage(userText)],
143
- [SWEEP_TOOL],
144
- systemPrompt,
145
- {
146
- config: {
147
- callSite: "memoryV2Sweep" as const,
148
- tool_choice: { type: "tool" as const, name: SWEEP_TOOL_NAME },
157
+ const response = await provider.sendMessage(
158
+ [userMessage(userText)],
159
+ [SWEEP_TOOL],
160
+ systemPrompt,
161
+ {
162
+ config: {
163
+ callSite: "memoryV2Sweep" as const,
164
+ tool_choice: { type: "tool" as const, name: SWEEP_TOOL_NAME },
165
+ },
149
166
  },
150
- },
151
- );
167
+ );
168
+
169
+ const toolBlock = extractToolUse(response);
170
+ if (!toolBlock || toolBlock.name !== SWEEP_TOOL_NAME) {
171
+ log.debug("Sweep model returned no tool_use block");
172
+ return 0;
173
+ }
174
+ const parsed = SweepResultSchema.safeParse(toolBlock.input);
175
+ if (!parsed.success) {
176
+ log.warn(
177
+ { error: parsed.error.message },
178
+ "Sweep tool input did not match schema",
179
+ );
180
+ return 0;
181
+ }
152
182
 
153
- const toolBlock = extractToolUse(response);
154
- if (!toolBlock || toolBlock.name !== SWEEP_TOOL_NAME) {
155
- log.debug("Sweep model returned no tool_use block");
183
+ const written = appendEntries(memoryDir, parsed.data.entries);
184
+ if (written > 0) {
185
+ log.info({ written }, "Memory v2 sweep wrote new buffer entries");
186
+ }
187
+ return written;
188
+ } catch (err) {
189
+ const errorMessage = err instanceof Error ? err.message : String(err);
190
+ log.error({ err }, "memory v2 sweep failed");
191
+ emitSweepActivityFailed({
192
+ jobId: job.id,
193
+ errorMessage,
194
+ });
156
195
  return 0;
157
196
  }
158
- const parsed = SweepResultSchema.safeParse(toolBlock.input);
159
- if (!parsed.success) {
197
+ }
198
+
199
+ /**
200
+ * Emit an `activity.failed` notification for a failed sweep run. Mirrors
201
+ * the shape `runBackgroundJob` produces for its own failures so the home
202
+ * feed and native notifications stay consistent regardless of which code
203
+ * path executed the work. Fire-and-forget — a notification failure must
204
+ * never break sweep operation.
205
+ */
206
+ function emitSweepActivityFailed(args: {
207
+ jobId: string;
208
+ errorMessage: string;
209
+ }): void {
210
+ const day = new Date().toISOString().slice(0, 10);
211
+ emitNotificationSignal({
212
+ sourceChannel: "scheduler",
213
+ sourceContextId: args.jobId,
214
+ sourceEventName: "activity.failed",
215
+ dedupeKey: `activity-failed:${JOB_NAME}:${day}`,
216
+ contextPayload: {
217
+ jobName: JOB_NAME,
218
+ errorMessage: args.errorMessage,
219
+ errorKind: "exception",
220
+ },
221
+ attentionHints: {
222
+ requiresAction: false,
223
+ urgency: "medium",
224
+ isAsyncBackground: true,
225
+ visibleInSourceNow: false,
226
+ },
227
+ }).catch((emitErr) => {
160
228
  log.warn(
161
- { error: parsed.error.message },
162
- "Sweep tool input did not match schema",
229
+ {
230
+ err: emitErr instanceof Error ? emitErr.message : String(emitErr),
231
+ jobId: args.jobId,
232
+ },
233
+ "Failed to emit activity.failed notification for memory v2 sweep",
163
234
  );
164
- return 0;
165
- }
166
-
167
- const written = appendEntries(memoryDir, parsed.data.entries);
168
- if (written > 0) {
169
- log.info({ written }, "Memory v2 sweep wrote new buffer entries");
170
- }
171
- return written;
235
+ });
172
236
  }
173
237
 
174
238
  /**
@@ -220,14 +284,22 @@ function loadRecentMessagesText(nowMs: number): string {
220
284
  const db = getDb();
221
285
  // Pull newest-first then reverse for chronological output. Bounding the
222
286
  // initial limit (1000) defends against pathological busy windows where a
223
- // naive scan would touch every recent message.
287
+ // naive scan would touch every recent message. Joining conversations and
288
+ // excluding background/scheduled types keeps automation chatter
289
+ // (heartbeats, filing, update bulletins, scheduled jobs) out of buffer.md.
224
290
  const rows = db
225
291
  .select({
226
292
  role: messages.role,
227
293
  content: messages.content,
228
294
  })
229
295
  .from(messages)
230
- .where(gt(messages.createdAt, cutoff))
296
+ .innerJoin(conversations, eq(messages.conversationId, conversations.id))
297
+ .where(
298
+ and(
299
+ gt(messages.createdAt, cutoff),
300
+ notInArray(conversations.conversationType, ["background", "scheduled"]),
301
+ ),
302
+ )
231
303
  .orderBy(desc(messages.createdAt))
232
304
  .limit(1000)
233
305
  .all();
@@ -249,50 +321,3 @@ function loadRecentMessagesText(nowMs: number): string {
249
321
  }
250
322
  return joined;
251
323
  }
252
-
253
- /**
254
- * Coerce stored message content (JSON-serialized `ContentBlock[]` *or* plain
255
- * string in legacy rows) into a single text string. Image / tool blocks are
256
- * dropped — the sweep model only needs the spoken context.
257
- */
258
- function stringifyMessageContent(stored: string): string {
259
- let parsed: unknown;
260
- try {
261
- parsed = JSON.parse(stored);
262
- } catch {
263
- return stored.trim();
264
- }
265
- if (typeof parsed === "string") return parsed.trim();
266
- if (!Array.isArray(parsed)) return "";
267
- const parts: string[] = [];
268
- for (const block of parsed) {
269
- if (
270
- block &&
271
- typeof block === "object" &&
272
- (block as { type?: string }).type === "text" &&
273
- typeof (block as { text?: unknown }).text === "string"
274
- ) {
275
- parts.push((block as { text: string }).text);
276
- }
277
- }
278
- return parts.join("\n").trim();
279
- }
280
-
281
- /**
282
- * Read the guardian's display name from `users/default.md`. We look for the
283
- * markdown-bold "Name" label (matching the IDENTITY.md convention) and fall
284
- * back to `null` on any miss; the prompt template substitutes a generic
285
- * label.
286
- */
287
- function resolveUserName(workspaceDir: string): string | null {
288
- try {
289
- const content = readFileSync(
290
- join(workspaceDir, "users", "default.md"),
291
- "utf-8",
292
- );
293
- const match = content.match(/\*\*Name:\*\*\s*(.+)/);
294
- return match?.[1]?.trim() || null;
295
- } catch {
296
- return null;
297
- }
298
- }
@@ -25,12 +25,23 @@ import { z } from "zod";
25
25
  * `edges:` means "activating A pulls in B" — activation flows A → B but not
26
26
  * B → A. The full graph is the union of every page's `edges:` list — there
27
27
  * is no separate edges-index file. `ref_files` lists paths to attached media
28
- * (images, audio, etc.).
28
+ * (images, audio, etc.). `ref_urls` lists external URL references (e.g.
29
+ * citations, source links).
30
+ *
31
+ * `summary` is a 1-4 sentence prose description of the page. When present,
32
+ * retrieval injects the path + summary instead of the full page so the agent
33
+ * can decide whether to read the file. Optional because legacy pages predating
34
+ * the summary field still parse — those fall back to full-page injection and
35
+ * full-page-only similarity.
29
36
  */
30
- export const ConceptPageFrontmatterSchema = z.object({
31
- edges: z.array(z.string()).default([]),
32
- ref_files: z.array(z.string()).default([]),
33
- });
37
+ export const ConceptPageFrontmatterSchema = z
38
+ .object({
39
+ edges: z.array(z.string()).default([]),
40
+ ref_files: z.array(z.string()).default([]),
41
+ ref_urls: z.array(z.string().url()).default([]),
42
+ summary: z.string().optional(),
43
+ })
44
+ .strict();
34
45
 
35
46
  export type ConceptPageFrontmatter = z.infer<
36
47
  typeof ConceptPageFrontmatterSchema
@@ -8,3 +8,16 @@
8
8
  export function clampUnitInterval(value: number): number {
9
9
  return Math.min(1, Math.max(0, value));
10
10
  }
11
+
12
+ /**
13
+ * Map cosine similarity [-1, 1] into the unit interval [0, 1] via
14
+ * `(x + 1) / 2`, then clamp. Single-channel display normalization for the
15
+ * legacy v1 semantic-search path; do **not** use before hybrid fusion —
16
+ * the affine rescale halves pairwise dense differences and shifts ranking
17
+ * toward sparse. Hybrid fusion (`v2/sim.ts`) instead clamps negative
18
+ * cosines to 0 with `Math.max(0, x)` and lets positive cosines pass
19
+ * through unchanged.
20
+ */
21
+ export function mapCosineToUnit(value: number): number {
22
+ return clampUnitInterval((value + 1) / 2);
23
+ }