@vellumai/assistant 0.8.0 → 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 (692) hide show
  1. package/AGENTS.md +11 -0
  2. package/Dockerfile +5 -4
  3. package/README.md +2 -2
  4. package/docker-entrypoint.sh +16 -0
  5. package/eslint-rules/__tests__/cli-no-daemon-internals.test.ts +420 -0
  6. package/eslint-rules/cli-no-daemon-internals.js +283 -0
  7. package/eslint.config.mjs +12 -0
  8. package/knip.json +2 -1
  9. package/node_modules/@vellumai/skill-host-contracts/src/client.ts +10 -1
  10. package/openapi.yaml +4847 -1698
  11. package/package.json +3 -1
  12. package/scripts/generate-openapi.ts +52 -4
  13. package/scripts/sync-llm-catalog.ts +165 -0
  14. package/scripts/sync-web-search-catalog.ts +107 -0
  15. package/src/__tests__/actor-trust-resolver-address-fallback.test.ts +169 -0
  16. package/src/__tests__/agent-loop-override-profile.test.ts +26 -1
  17. package/src/__tests__/anthropic-provider.test.ts +92 -2
  18. package/src/__tests__/app-control-flow.test.ts +7 -0
  19. package/src/__tests__/assistant-events-sse-shed.test.ts +232 -0
  20. package/src/__tests__/avatar-identity-sync.test.ts +87 -0
  21. package/src/__tests__/background-workers-disk-pressure.test.ts +11 -22
  22. package/src/__tests__/btw-routes.test.ts +1 -0
  23. package/src/__tests__/call-site-routing-provider.test.ts +172 -45
  24. package/src/__tests__/cancel-resolves-conversation-key.test.ts +44 -3
  25. package/src/__tests__/channel-policy.test.ts +12 -0
  26. package/src/__tests__/checker.test.ts +89 -0
  27. package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +35 -7
  28. package/src/__tests__/compact-event-conversation-id-guard.test.ts +33 -5
  29. package/src/__tests__/compaction-strip-metadata-clear.test.ts +26 -1
  30. package/src/__tests__/config-loader-backfill.test.ts +526 -102
  31. package/src/__tests__/config-loader-corrupt.test.ts +68 -0
  32. package/src/__tests__/config-loader-platform-defaults.test.ts +77 -23
  33. package/src/__tests__/config-schema-cmd.test.ts +63 -29
  34. package/src/__tests__/config-schema.test.ts +14 -3
  35. package/src/__tests__/config-set-platform-guard.test.ts +75 -152
  36. package/src/__tests__/config-set-route.test.ts +198 -0
  37. package/src/__tests__/config-watcher.test.ts +6 -0
  38. package/src/__tests__/contacts-tools.test.ts +51 -199
  39. package/src/__tests__/context-search-agent-protocol.test.ts +21 -2
  40. package/src/__tests__/context-search-agent-runner.test.ts +22 -138
  41. package/src/__tests__/context-search-conversations-source.test.ts +42 -16
  42. package/src/__tests__/context-search-fanout.test.ts +20 -157
  43. package/src/__tests__/context-search-memory-v2-source.test.ts +3 -3
  44. package/src/__tests__/context-search-types.test.ts +7 -2
  45. package/src/__tests__/context-window-manager.test.ts +389 -1
  46. package/src/__tests__/conversation-agent-loop-overflow.test.ts +1 -0
  47. package/src/__tests__/conversation-crud-inference-profile.test.ts +100 -0
  48. package/src/__tests__/conversation-error.test.ts +38 -0
  49. package/src/__tests__/conversation-fork-crud.test.ts +241 -1
  50. package/src/__tests__/conversation-inference-profile-route.test.ts +14 -14
  51. package/src/__tests__/conversation-init.benchmark.test.ts +1 -0
  52. package/src/__tests__/conversation-lifecycle.test.ts +124 -0
  53. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +100 -1
  54. package/src/__tests__/conversation-process-callsite.test.ts +21 -1
  55. package/src/__tests__/conversation-runtime-assembly.test.ts +4 -4
  56. package/src/__tests__/conversation-slash-commands.test.ts +194 -2
  57. package/src/__tests__/conversation-surfaces-app-control.test.ts +323 -3
  58. package/src/__tests__/credential-security-invariants.test.ts +5 -6
  59. package/src/__tests__/daemon-credential-client.test.ts +56 -1
  60. package/src/__tests__/db-activation-state-fk-cascade.test.ts +132 -0
  61. package/src/__tests__/db-conversation-inference-profile-migration.test.ts +37 -0
  62. package/src/__tests__/db-memory-graph-event-date-repair.test.ts +43 -20
  63. package/src/__tests__/db-proxy-transaction.test.ts +206 -0
  64. package/src/__tests__/external-plugin-loader.test.ts +458 -0
  65. package/src/__tests__/filing-service.test.ts +23 -3
  66. package/src/__tests__/fixtures/mock-chrome-extension.ts +5 -0
  67. package/src/__tests__/gateway-only-guard.test.ts +0 -1
  68. package/src/__tests__/graph-extraction-event-date.test.ts +34 -0
  69. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +0 -8
  70. package/src/__tests__/heartbeat-disk-pressure.test.ts +21 -8
  71. package/src/__tests__/heartbeat-service.test.ts +50 -233
  72. package/src/__tests__/history-repair.test.ts +89 -0
  73. package/src/__tests__/host-app-control-proxy.test.ts +109 -1
  74. package/src/__tests__/host-app-control-routes.test.ts +247 -1
  75. package/src/__tests__/host-browser-proxy.test.ts +416 -20
  76. package/src/__tests__/host-browser-routes.test.ts +325 -33
  77. package/src/__tests__/host-proxy-preactivation.test.ts +211 -0
  78. package/src/__tests__/inference-no-mode-boot-e2e.test.ts +246 -0
  79. package/src/__tests__/inference-profile-reaper.test.ts +154 -0
  80. package/src/__tests__/inference-profile-session-handler.test.ts +398 -0
  81. package/src/__tests__/inference-profile-session-ipc.test.ts +236 -0
  82. package/src/__tests__/inline-skill-load-permissions.test.ts +6 -1
  83. package/src/__tests__/install-skill-routing.test.ts +2 -2
  84. package/src/__tests__/lifecycle-memory-v2-seed.test.ts +15 -0
  85. package/src/__tests__/llm-callsite-catalog.test.ts +20 -1
  86. package/src/__tests__/llm-catalog-parity.test.ts +146 -0
  87. package/src/__tests__/llm-request-log-source-clickhouse.test.ts +188 -0
  88. package/src/__tests__/llm-request-log-source-factory.test.ts +124 -0
  89. package/src/__tests__/llm-resolver.test.ts +46 -0
  90. package/src/__tests__/managed-profile-guard.test.ts +131 -2
  91. package/src/__tests__/mcp-auth-routes.test.ts +1 -0
  92. package/src/__tests__/mcp-cli.test.ts +182 -220
  93. package/src/__tests__/mcp-health-check.test.ts +56 -27
  94. package/src/__tests__/memory-jobs-worker-lanes.test.ts +18 -11
  95. package/src/__tests__/message-complete-display-id.test.ts +175 -0
  96. package/src/__tests__/notification-platform-adapter.test.ts +229 -0
  97. package/src/__tests__/oauth-cli.test.ts +38 -2009
  98. package/src/__tests__/oauth-commands-routes.test.ts +711 -0
  99. package/src/__tests__/oauth-connect-routes.test.ts +174 -11
  100. package/src/__tests__/oauth-providers-routes.test.ts +14 -10
  101. package/src/__tests__/openai-responses-cutover-guard.test.ts +33 -12
  102. package/src/__tests__/openai-responses-provider.test.ts +17 -0
  103. package/src/__tests__/plugin-bootstrap.test.ts +31 -2
  104. package/src/__tests__/plugin-route-contribution.test.ts +31 -3
  105. package/src/__tests__/plugin-tool-contribution.test.ts +31 -3
  106. package/src/__tests__/plugin-types.test.ts +13 -11
  107. package/src/__tests__/process-message-background-slack.test.ts +46 -0
  108. package/src/__tests__/profile-entry-status.test.ts +43 -0
  109. package/src/__tests__/provider-managed-proxy-integration.test.ts +12 -4
  110. package/src/__tests__/provider-registry-ollama.test.ts +12 -4
  111. package/src/__tests__/provider-send-message-override-profile.test.ts +10 -4
  112. package/src/__tests__/relay-server.test.ts +118 -0
  113. package/src/__tests__/retry-thinking-tool-choice.test.ts +15 -0
  114. package/src/__tests__/schedule-retry.test.ts +56 -4
  115. package/src/__tests__/schedule-routes.test.ts +104 -0
  116. package/src/__tests__/scheduler-disk-pressure.test.ts +0 -4
  117. package/src/__tests__/scheduler-recurrence.test.ts +87 -34
  118. package/src/__tests__/scheduler-reuse-conversation.test.ts +161 -5
  119. package/src/__tests__/scheduler-wake.test.ts +0 -63
  120. package/src/__tests__/secret-allowlist.test.ts +1 -0
  121. package/src/__tests__/secret-routes-managed-proxy.test.ts +12 -4
  122. package/src/__tests__/shell-credential-ref.test.ts +95 -3
  123. package/src/__tests__/shell-tool-proxy-mode.test.ts +14 -0
  124. package/src/__tests__/skill-load-feature-flag.test.ts +1 -0
  125. package/src/__tests__/skill-load-tool.test.ts +2 -4
  126. package/src/__tests__/subagent-call-site-routing.test.ts +78 -16
  127. package/src/__tests__/suggestion-routes.test.ts +3 -3
  128. package/src/__tests__/sync-message-contract.test.ts +63 -0
  129. package/src/__tests__/task-scheduler.test.ts +88 -23
  130. package/src/__tests__/update-bulletin-job.test.ts +96 -193
  131. package/src/__tests__/usage-cli.test.ts +11 -73
  132. package/src/__tests__/user-plugin-loader.test.ts +145 -0
  133. package/src/__tests__/vercel-config.test.ts +168 -0
  134. package/src/__tests__/web-search-catalog-parity.test.ts +86 -0
  135. package/src/__tests__/web-search.test.ts +303 -2
  136. package/src/__tests__/workspace-migration-039-drop-legacy-llm-keys.test.ts +1 -21
  137. package/src/__tests__/workspace-migration-057-repair-stale-gemini-model-ids.test.ts +58 -0
  138. package/src/__tests__/workspace-migration-069-seed-onboarding-threads.test.ts +53 -20
  139. package/src/__tests__/workspace-migration-072-seed-reply-suggestion-callsite.test.ts +191 -0
  140. package/src/__tests__/workspace-migration-076-drop-services-inference-mode.test.ts +211 -0
  141. package/src/__tests__/workspace-migration-077-seed-memory-router-callsite.test.ts +174 -0
  142. package/src/__tests__/workspace-migration-079-home-feed-notification-only.test.ts +323 -0
  143. package/src/__tests__/workspace-migration-080-restrict-vercel-api-token-metadata.test.ts +299 -0
  144. package/src/__tests__/workspace-migration-081-backfill-bash-allowed-tools.test.ts +410 -0
  145. package/src/__tests__/workspace-migration-082-backfill-managed-profile-labels.test.ts +268 -0
  146. package/src/__tests__/workspace-migration-unify-llm-callsite-configs.test.ts +3 -3
  147. package/src/__tests__/workspace-release-notes-feature-flag-guard.test.ts +115 -0
  148. package/src/acp/__tests__/helpers/which-stub.ts +4 -2
  149. package/src/acp/resolve-agent.test.ts +25 -0
  150. package/src/acp/resolve-agent.ts +13 -2
  151. package/src/acp/session-manager.ts +14 -0
  152. package/src/approvals/guardian-request-resolvers.ts +32 -87
  153. package/src/calls/relay-server.ts +35 -0
  154. package/src/calls/relay-setup-router.ts +36 -0
  155. package/src/calls/types.ts +1 -0
  156. package/src/calls/voice-session-bridge.ts +23 -4
  157. package/src/channels/config.ts +14 -1
  158. package/src/channels/types.ts +1 -0
  159. package/src/cli/AGENTS.md +164 -4
  160. package/src/cli/__tests__/notifications.test.ts +54 -0
  161. package/src/cli/commands/__tests__/avatar.test.ts +540 -0
  162. package/src/cli/commands/__tests__/backup.test.ts +236 -776
  163. package/src/cli/commands/__tests__/cache.test.ts +1 -1
  164. package/src/cli/commands/__tests__/changelog.test.ts +593 -0
  165. package/src/cli/commands/__tests__/channel-verification-sessions.test.ts +503 -0
  166. package/src/cli/commands/__tests__/conversations-import.test.ts +515 -0
  167. package/src/cli/commands/__tests__/domain-register.test.ts +140 -167
  168. package/src/cli/commands/__tests__/domain-status.test.ts +137 -76
  169. package/src/cli/commands/__tests__/email-attachment.test.ts +314 -337
  170. package/src/cli/commands/__tests__/email-core.test.ts +579 -0
  171. package/src/cli/commands/__tests__/image-generation.test.ts +87 -824
  172. package/src/cli/commands/__tests__/inference-send.test.ts +30 -266
  173. package/src/cli/commands/__tests__/inference-session.test.ts +423 -0
  174. package/src/cli/commands/__tests__/memory-v2.test.ts +81 -110
  175. package/src/cli/commands/__tests__/skills.test.ts +563 -0
  176. package/src/cli/commands/__tests__/status.test.ts +249 -0
  177. package/src/cli/commands/__tests__/stt.test.ts +320 -0
  178. package/src/cli/commands/__tests__/tts-synthesize.test.ts +4 -603
  179. package/src/cli/commands/__tests__/tts.test.ts +321 -0
  180. package/src/cli/commands/__tests__/webhooks.test.ts +86 -511
  181. package/src/cli/commands/attachment.ts +8 -3
  182. package/src/cli/commands/audit.ts +95 -64
  183. package/src/cli/commands/auth.ts +61 -58
  184. package/src/cli/commands/avatar.ts +276 -390
  185. package/src/cli/commands/backup.ts +409 -505
  186. package/src/cli/commands/bash.ts +9 -5
  187. package/src/cli/commands/browser.ts +28 -9
  188. package/src/cli/commands/cache.ts +9 -4
  189. package/src/cli/commands/changelog.ts +414 -0
  190. package/src/cli/commands/channel-verification-sessions.ts +238 -317
  191. package/src/cli/commands/clients.ts +8 -3
  192. package/src/cli/commands/completions.ts +9 -9
  193. package/src/cli/commands/config.ts +102 -72
  194. package/src/cli/commands/contacts.ts +575 -696
  195. package/src/cli/commands/conversations-defer.ts +17 -69
  196. package/src/cli/commands/conversations-import.ts +90 -253
  197. package/src/cli/commands/conversations.ts +346 -436
  198. package/src/cli/commands/credential-execution.ts +9 -6
  199. package/src/cli/commands/credentials.ts +456 -736
  200. package/src/cli/commands/domain.ts +128 -206
  201. package/src/cli/commands/email.ts +606 -794
  202. package/src/cli/commands/gateway.ts +8 -1
  203. package/src/cli/commands/image-generation.ts +157 -205
  204. package/src/cli/commands/inference-providers.ts +352 -0
  205. package/src/cli/commands/inference-session.ts +415 -0
  206. package/src/cli/commands/inference.ts +87 -65
  207. package/src/cli/commands/keys.ts +8 -3
  208. package/src/cli/commands/mcp.ts +103 -287
  209. package/src/cli/commands/memory-v2.ts +162 -516
  210. package/src/cli/commands/notifications.ts +33 -7
  211. package/src/cli/commands/oauth/apps.ts +292 -261
  212. package/src/cli/commands/oauth/connect.ts +176 -297
  213. package/src/cli/commands/oauth/disconnect.ts +16 -215
  214. package/src/cli/commands/oauth/index.ts +49 -45
  215. package/src/cli/commands/oauth/mode.ts +43 -199
  216. package/src/cli/commands/oauth/ping.ts +17 -125
  217. package/src/cli/commands/oauth/providers.ts +732 -921
  218. package/src/cli/commands/oauth/request.ts +60 -350
  219. package/src/cli/commands/oauth/shared.ts +11 -121
  220. package/src/cli/commands/oauth/status.ts +31 -121
  221. package/src/cli/commands/oauth/token.ts +13 -55
  222. package/src/cli/commands/pending.ts +19 -10
  223. package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +133 -183
  224. package/src/cli/commands/platform/__tests__/connect.test.ts +66 -181
  225. package/src/cli/commands/platform/__tests__/disconnect.test.ts +71 -227
  226. package/src/cli/commands/platform/__tests__/status.test.ts +169 -287
  227. package/src/cli/commands/platform/connect.ts +16 -80
  228. package/src/cli/commands/platform/disconnect.ts +14 -112
  229. package/src/cli/commands/platform/index.ts +177 -246
  230. package/src/cli/commands/routes.ts +153 -336
  231. package/src/cli/commands/sequence.ts +316 -360
  232. package/src/cli/commands/skills.ts +449 -671
  233. package/src/cli/commands/status.ts +58 -37
  234. package/src/cli/commands/stt.ts +94 -262
  235. package/src/cli/commands/task.ts +14 -40
  236. package/src/cli/commands/trust.ts +8 -3
  237. package/src/cli/commands/tts.ts +162 -167
  238. package/src/cli/commands/ui.ts +35 -42
  239. package/src/cli/commands/usage.ts +188 -126
  240. package/src/cli/commands/watchers.ts +8 -3
  241. package/src/cli/commands/webhooks.ts +99 -193
  242. package/src/cli/lib/__tests__/register-command.test.ts +85 -0
  243. package/src/cli/lib/daemon-credential-client.ts +4 -5
  244. package/src/cli/lib/nested-value.ts +44 -0
  245. package/src/cli/lib/open-browser.ts +36 -0
  246. package/src/cli/lib/register-command.ts +19 -0
  247. package/src/cli/lib/time-ago.ts +34 -0
  248. package/src/cli/program.ts +2 -4
  249. package/src/cli/utils/__tests__/conversation-id.test.ts +66 -0
  250. package/src/cli/utils/__tests__/parse-duration.test.ts +49 -0
  251. package/src/cli/utils/conversation-id.ts +30 -0
  252. package/src/cli/utils/parse-duration.ts +41 -0
  253. package/src/config/acp-defaults.test.ts +5 -1
  254. package/src/config/acp-defaults.ts +11 -4
  255. package/src/config/bundled-skills/acp/TOOLS.json +2 -2
  256. package/src/config/bundled-skills/app-control/TOOLS.json +32 -0
  257. package/src/config/bundled-skills/contacts/SKILL.md +12 -45
  258. package/src/config/bundled-skills/contacts/TOOLS.json +0 -57
  259. package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +0 -12
  260. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +0 -58
  261. package/src/config/bundled-tool-registry.ts +0 -2
  262. package/src/config/feature-flag-registry.json +16 -0
  263. package/src/config/llm-resolver.ts +16 -1
  264. package/src/config/loader.ts +76 -14
  265. package/src/config/raw-config-utils.ts +2 -30
  266. package/src/config/schema.ts +4 -0
  267. package/src/config/schemas/__tests__/memory-v2.test.ts +49 -0
  268. package/src/config/schemas/call-site-catalog.ts +29 -7
  269. package/src/config/schemas/llm-request-logs.ts +57 -0
  270. package/src/config/schemas/llm.ts +52 -2
  271. package/src/config/schemas/memory-retrospective.ts +48 -0
  272. package/src/config/schemas/memory-v2.ts +32 -1
  273. package/src/config/schemas/memory.ts +4 -0
  274. package/src/config/schemas/services.ts +15 -12
  275. package/src/config/seed-inference-profiles.ts +195 -134
  276. package/src/contacts/contact-store.ts +0 -61
  277. package/src/context/window-manager.ts +191 -5
  278. package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +79 -0
  279. package/src/daemon/__tests__/conversation-tool-setup.test.ts +109 -4
  280. package/src/daemon/__tests__/daemon-skill-host.test.ts +10 -4
  281. package/src/daemon/approval-generators.ts +23 -29
  282. package/src/daemon/config-watcher.ts +2 -0
  283. package/src/daemon/conversation-agent-loop-handlers.ts +24 -0
  284. package/src/daemon/conversation-agent-loop.ts +127 -97
  285. package/src/daemon/conversation-error.ts +21 -0
  286. package/src/daemon/conversation-lifecycle.ts +46 -5
  287. package/src/daemon/conversation-process.ts +36 -19
  288. package/src/daemon/conversation-runtime-assembly.ts +14 -5
  289. package/src/daemon/conversation-slash.ts +175 -23
  290. package/src/daemon/conversation-store.ts +17 -10
  291. package/src/daemon/conversation-surfaces.ts +76 -12
  292. package/src/daemon/conversation-tool-setup.ts +24 -14
  293. package/src/daemon/conversation.ts +48 -9
  294. package/src/daemon/external-plugins-bootstrap.ts +18 -8
  295. package/src/daemon/guardian-action-generators.ts +7 -22
  296. package/src/daemon/handlers/config-model.ts +8 -126
  297. package/src/daemon/handlers/config-slack-channel.ts +10 -7
  298. package/src/daemon/handlers/config-vercel.ts +3 -1
  299. package/src/daemon/handlers/skills.ts +84 -5
  300. package/src/daemon/history-repair.ts +33 -6
  301. package/src/daemon/host-app-control-proxy.ts +44 -19
  302. package/src/daemon/host-bash-proxy.ts +85 -158
  303. package/src/daemon/host-browser-proxy.ts +96 -35
  304. package/src/daemon/host-proxy-base.ts +13 -1
  305. package/src/daemon/host-proxy-preactivation.ts +25 -1
  306. package/src/daemon/identity-helpers.ts +19 -0
  307. package/src/daemon/lifecycle.ts +42 -43
  308. package/src/daemon/meet-host-supervisor.ts +15 -15
  309. package/src/daemon/memory-v2-startup.ts +9 -2
  310. package/src/daemon/message-protocol.ts +6 -0
  311. package/src/daemon/message-types/bookmarks.ts +18 -0
  312. package/src/daemon/message-types/conversations.ts +12 -9
  313. package/src/daemon/message-types/messages.ts +9 -1
  314. package/src/daemon/message-types/sync.ts +60 -0
  315. package/src/daemon/pkb-reminder-builder.test.ts +54 -13
  316. package/src/daemon/pkb-reminder-builder.ts +21 -7
  317. package/src/daemon/process-message.ts +56 -23
  318. package/src/daemon/server.ts +23 -18
  319. package/src/daemon/shutdown-handlers.ts +0 -2
  320. package/src/daemon/tool-setup-types.ts +9 -0
  321. package/src/daemon/tool-side-effects.ts +6 -4
  322. package/src/daemon/wake-target-adapter.ts +11 -0
  323. package/src/export/transcript-formatter.ts +61 -2
  324. package/src/filing/filing-service.ts +40 -53
  325. package/src/heartbeat/__tests__/heartbeat-service.test.ts +359 -0
  326. package/src/heartbeat/heartbeat-run-store.ts +2 -1
  327. package/src/heartbeat/heartbeat-service.ts +148 -127
  328. package/src/home/__tests__/feed-types.test.ts +63 -131
  329. package/src/home/__tests__/feed-writer.test.ts +77 -278
  330. package/src/home/__tests__/post-connect-feed.test.ts +9 -12
  331. package/src/home/feed-types.ts +19 -73
  332. package/src/home/feed-writer.ts +25 -156
  333. package/src/home/post-connect-feed.ts +1 -3
  334. package/src/ipc/__tests__/cli-ipc.test.ts +2 -0
  335. package/src/ipc/__tests__/email-ipc.test.ts +506 -0
  336. package/src/ipc/__tests__/exit-helper.test.ts +104 -0
  337. package/src/ipc/__tests__/streaming-client.test.ts +237 -0
  338. package/src/ipc/__tests__/streaming-framing.test.ts +142 -0
  339. package/src/ipc/assistant-server.ts +55 -6
  340. package/src/ipc/cli-client.ts +370 -50
  341. package/src/ipc/routes/db-proxy-transaction.ts +151 -0
  342. package/src/ipc/skill-routes/__tests__/events-ipc.test.ts +60 -0
  343. package/src/ipc/skill-routes/events.ts +30 -3
  344. package/src/live-voice/__tests__/live-voice-session-manager.test.ts +46 -0
  345. package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +1 -0
  346. package/src/live-voice/live-voice-session-manager.ts +11 -4
  347. package/src/live-voice/live-voice-session.ts +14 -6
  348. package/src/memory/__tests__/bookmark-crud.test.ts +258 -0
  349. package/src/memory/__tests__/bookmark-schema.test.ts +181 -0
  350. package/src/memory/__tests__/conversation-types.test.ts +36 -0
  351. package/src/memory/__tests__/find-most-recent-retrospective-for.test.ts +130 -0
  352. package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +177 -0
  353. package/src/memory/__tests__/memory-retrospective-job.test.ts +328 -0
  354. package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +213 -0
  355. package/src/memory/__tests__/memory-retrospective-trigger-check.test.ts +90 -0
  356. package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +69 -0
  357. package/src/memory/__tests__/memory-v2-concept-frequency.test.ts +3 -0
  358. package/src/memory/bookmark-crud.ts +179 -0
  359. package/src/memory/context-search/__tests__/agent-runner-redaction.test.ts +31 -9
  360. package/src/memory/context-search/agent-protocol.ts +5 -1
  361. package/src/memory/context-search/agent-runner.ts +60 -85
  362. package/src/memory/context-search/limits.ts +1 -4
  363. package/src/memory/context-search/search.ts +23 -113
  364. package/src/memory/context-search/sources/conversations.ts +18 -6
  365. package/src/memory/context-search/sources/memory-v2.ts +39 -14
  366. package/src/memory/context-search/sources/memory.ts +7 -0
  367. package/src/memory/context-search/sources/workspace.ts +13 -10
  368. package/src/memory/context-search/types.ts +1 -1
  369. package/src/memory/conversation-bootstrap.ts +11 -0
  370. package/src/memory/conversation-crud.ts +312 -10
  371. package/src/memory/conversation-queries.ts +9 -5
  372. package/src/memory/conversation-title-service.ts +1 -0
  373. package/src/memory/conversation-types.ts +16 -0
  374. package/src/memory/db-init.ts +14 -0
  375. package/src/memory/embedding-backend.ts +2 -1
  376. package/src/memory/embedding-runtime-manager.ts +1 -2
  377. package/src/memory/graph/__tests__/remember-description.test.ts +55 -0
  378. package/src/memory/graph/conversation-graph-memory.ts +76 -5
  379. package/src/memory/graph/extraction.ts +4 -0
  380. package/src/memory/graph/graph-memory-state-store.ts +16 -3
  381. package/src/memory/graph/tool-handlers.ts +17 -7
  382. package/src/memory/graph/tools.ts +44 -5
  383. package/src/memory/indexer.ts +17 -0
  384. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +13 -15
  385. package/src/memory/jobs/embed-concept-page.ts +45 -9
  386. package/src/memory/jobs-store.ts +51 -1
  387. package/src/memory/jobs-worker.ts +52 -3
  388. package/src/memory/llm-request-log-source-clickhouse.ts +317 -0
  389. package/src/memory/llm-request-log-source-local.ts +26 -0
  390. package/src/memory/llm-request-log-source.ts +97 -0
  391. package/src/memory/llm-request-log-store.ts +1 -1
  392. package/src/memory/memory-retrospective-constants.ts +13 -0
  393. package/src/memory/memory-retrospective-enqueue.ts +114 -0
  394. package/src/memory/memory-retrospective-job.ts +351 -0
  395. package/src/memory/memory-retrospective-startup-cleanup.ts +108 -0
  396. package/src/memory/memory-retrospective-state.ts +162 -0
  397. package/src/memory/memory-retrospective-trigger-check.ts +91 -0
  398. package/src/memory/memory-v2-activation-log-store.ts +49 -5
  399. package/src/memory/memory-v2-concept-frequency.ts +4 -0
  400. package/src/memory/message-content.ts +38 -1
  401. package/src/memory/migrations/227-add-conversation-inference-profile.ts +6 -1
  402. package/src/memory/migrations/228-rename-inference-profile-snake-case.ts +20 -7
  403. package/src/memory/migrations/229-delete-private-conversations.test.ts +70 -1
  404. package/src/memory/migrations/229-delete-private-conversations.ts +12 -0
  405. package/src/memory/migrations/231-repair-memory-graph-event-dates.ts +16 -2
  406. package/src/memory/migrations/240-conversation-inference-profile-session.ts +25 -0
  407. package/src/memory/migrations/241-activation-state-fk-cascade.ts +50 -0
  408. package/src/memory/migrations/242-message-bookmarks.ts +38 -0
  409. package/src/memory/migrations/243-provider-connections.ts +68 -0
  410. package/src/memory/migrations/244-provider-connection-status-label.ts +23 -0
  411. package/src/memory/migrations/245-memory-retrospective-state.ts +36 -0
  412. package/src/memory/migrations/246-backfill-provider-connection-label.ts +81 -0
  413. package/src/memory/migrations/__tests__/244-provider-connection-status-label.test.ts +84 -0
  414. package/src/memory/migrations/__tests__/245-memory-retrospective-state.test.ts +125 -0
  415. package/src/memory/migrations/__tests__/246-backfill-provider-connection-label.test.ts +192 -0
  416. package/src/memory/migrations/index.ts +7 -0
  417. package/src/memory/published-pages-store.ts +16 -0
  418. package/src/memory/schema/bookmarks.ts +38 -0
  419. package/src/memory/schema/conversations.ts +2 -0
  420. package/src/memory/schema/index.ts +2 -0
  421. package/src/memory/schema/inference.ts +29 -0
  422. package/src/memory/schema/memory-core.ts +9 -0
  423. package/src/memory/search/semantic.ts +1 -4
  424. package/src/memory/v2/__tests__/__snapshots__/prompts-router.test.ts.snap +27 -0
  425. package/src/memory/v2/__tests__/activation-store.test.ts +5 -5
  426. package/src/memory/v2/__tests__/activation.test.ts +11 -4
  427. package/src/memory/v2/__tests__/backfill-jobs.test.ts +38 -21
  428. package/src/memory/v2/__tests__/consolidation-job.test.ts +123 -135
  429. package/src/memory/v2/__tests__/edge-index.test.ts +1 -1
  430. package/src/memory/v2/__tests__/frontmatter-sweep.test.ts +111 -0
  431. package/src/memory/v2/__tests__/injection.test.ts +628 -10
  432. package/src/memory/v2/__tests__/migration.test.ts +7 -3
  433. package/src/memory/v2/__tests__/page-index.test.ts +277 -0
  434. package/src/memory/v2/__tests__/page-store.test.ts +14 -1
  435. package/src/memory/v2/__tests__/prompts-router.test.ts +257 -0
  436. package/src/memory/v2/__tests__/qdrant.test.ts +72 -0
  437. package/src/memory/v2/__tests__/reranker.test.ts +4 -4
  438. package/src/memory/v2/__tests__/router.test.ts +516 -0
  439. package/src/memory/v2/__tests__/sim.test.ts +45 -1
  440. package/src/memory/v2/__tests__/skill-store.test.ts +58 -3
  441. package/src/memory/v2/__tests__/static-context.test.ts +7 -22
  442. package/src/memory/v2/__tests__/sweep-job.test.ts +95 -0
  443. package/src/memory/v2/activation-store.ts +34 -5
  444. package/src/memory/v2/activation.ts +40 -27
  445. package/src/memory/v2/backfill-jobs.ts +17 -84
  446. package/src/memory/v2/consolidation-job.ts +85 -78
  447. package/src/memory/v2/frontmatter-sweep.ts +91 -0
  448. package/src/memory/v2/injection.ts +440 -109
  449. package/src/memory/v2/migration.ts +117 -20
  450. package/src/memory/v2/page-index.ts +191 -0
  451. package/src/memory/v2/page-store.ts +3 -0
  452. package/src/memory/v2/prompts/consolidation.ts +9 -7
  453. package/src/memory/v2/prompts/router.ts +192 -0
  454. package/src/memory/v2/qdrant.ts +100 -87
  455. package/src/memory/v2/reranker.ts +14 -7
  456. package/src/memory/v2/router.ts +322 -0
  457. package/src/memory/v2/sim.ts +25 -12
  458. package/src/memory/v2/skill-store.ts +118 -29
  459. package/src/memory/v2/static-context.ts +16 -9
  460. package/src/memory/v2/sweep-job.ts +122 -96
  461. package/src/memory/v2/types.ts +10 -6
  462. package/src/memory/validation.ts +13 -0
  463. package/src/notifications/__tests__/emit-signal-home-feed.test.ts +182 -0
  464. package/src/notifications/__tests__/home-feed-side-effect.test.ts +199 -0
  465. package/src/notifications/__tests__/signal-registry.test.ts +17 -0
  466. package/src/notifications/adapters/platform.ts +171 -0
  467. package/src/notifications/conversation-pairing.ts +2 -2
  468. package/src/notifications/copy-composer.ts +15 -0
  469. package/src/notifications/destination-resolver.ts +21 -0
  470. package/src/notifications/emit-signal.ts +28 -1
  471. package/src/notifications/home-feed-side-effect.ts +111 -0
  472. package/src/notifications/signal.ts +5 -0
  473. package/src/permissions/checker.ts +12 -0
  474. package/src/permissions/ipc-risk-types.ts +2 -0
  475. package/src/plugin-api/index.ts +13 -0
  476. package/src/plugin-api/package.json +12 -0
  477. package/src/plugin-api/types.ts +62 -0
  478. package/src/plugins/defaults/injectors.ts +19 -3
  479. package/src/plugins/external-plugin-loader.ts +294 -0
  480. package/src/plugins/types.ts +46 -30
  481. package/src/plugins/user-loader.ts +64 -41
  482. package/src/proactive-artifact/job.test.ts +12 -4
  483. package/src/proactive-artifact/job.ts +4 -0
  484. package/src/proactive-artifact/trigger-state.test.ts +9 -0
  485. package/src/proactive-artifact/trigger-state.ts +4 -0
  486. package/src/prompts/__tests__/system-prompt.test.ts +105 -0
  487. package/src/prompts/system-prompt.ts +22 -1
  488. package/src/prompts/update-bulletin-job.ts +61 -73
  489. package/src/providers/__tests__/dispatch-connection-routing.test.ts +279 -0
  490. package/src/providers/__tests__/inference.test.ts +288 -0
  491. package/src/providers/__tests__/provider-env-vars.test.ts +6 -0
  492. package/src/providers/__tests__/provider-secret-catalog.test.ts +6 -0
  493. package/src/providers/__tests__/retry-callsite.test.ts +14 -32
  494. package/src/providers/__tests__/satellite-connection-routing.test.ts +510 -0
  495. package/src/providers/__tests__/search-provider-catalog.test.ts +80 -0
  496. package/src/providers/anthropic/client.ts +95 -26
  497. package/src/providers/call-site-routing.ts +94 -16
  498. package/src/providers/connection-resolution.ts +163 -0
  499. package/src/providers/inference/__tests__/connections-status-label.test.ts +250 -0
  500. package/src/providers/inference/adapter-factory.ts +173 -0
  501. package/src/providers/inference/auth.ts +112 -0
  502. package/src/providers/inference/backfill.ts +196 -0
  503. package/src/providers/inference/connections.ts +356 -0
  504. package/src/providers/inference/resolve-auth.ts +65 -0
  505. package/src/providers/model-catalog.ts +104 -6
  506. package/src/providers/openai/responses-provider.ts +4 -2
  507. package/src/providers/provider-env-vars.ts +17 -7
  508. package/src/providers/provider-secret-catalog.ts +49 -30
  509. package/src/providers/provider-send-message.ts +41 -20
  510. package/src/providers/registry.ts +143 -159
  511. package/src/providers/retry.ts +18 -10
  512. package/src/providers/search-provider-catalog.ts +121 -0
  513. package/src/runtime/AGENTS.md +18 -5
  514. package/src/runtime/__tests__/background-job-runner.test.ts +357 -0
  515. package/src/runtime/__tests__/pre-first-message-gate.test.ts +82 -0
  516. package/src/runtime/actor-trust-resolver.ts +32 -10
  517. package/src/runtime/agent-wake.ts +35 -6
  518. package/src/runtime/assistant-event-hub.ts +3 -85
  519. package/src/runtime/auth/route-policy.ts +303 -8
  520. package/src/runtime/auth/same-actor.ts +2 -0
  521. package/src/runtime/background-job-runner.ts +339 -0
  522. package/src/runtime/btw-sidechain.ts +1 -0
  523. package/src/runtime/http-router.ts +36 -1
  524. package/src/runtime/http-server.ts +31 -5
  525. package/src/runtime/http-types.ts +2 -0
  526. package/src/runtime/middleware/__tests__/request-logger.test.ts +162 -0
  527. package/src/runtime/middleware/request-logger.ts +62 -1
  528. package/src/runtime/pre-first-message-gate.ts +83 -0
  529. package/src/runtime/routes/__tests__/backup-routes.test.ts +8 -1
  530. package/src/runtime/routes/__tests__/bookmark-routes.test.ts +251 -0
  531. package/src/runtime/routes/__tests__/connection-routes-vs-cli-parity.test.ts +142 -0
  532. package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +315 -0
  533. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +189 -0
  534. package/src/runtime/routes/__tests__/home-feed-routes.test.ts +15 -136
  535. package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +736 -0
  536. package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +4 -4
  537. package/src/runtime/routes/__tests__/stt-routes.test.ts +5 -1
  538. package/src/runtime/routes/__tests__/surface-action-routes.test.ts +384 -0
  539. package/src/runtime/routes/__tests__/tts-routes.test.ts +6 -2
  540. package/src/runtime/routes/acp-routes.ts +10 -8
  541. package/src/runtime/routes/app-management-routes.ts +228 -3
  542. package/src/runtime/routes/approval-routes.ts +0 -18
  543. package/src/runtime/routes/audit-routes.ts +43 -0
  544. package/src/runtime/routes/auth-routes.ts +72 -0
  545. package/src/runtime/routes/avatar-routes.ts +273 -20
  546. package/src/runtime/routes/backup-routes.ts +406 -2
  547. package/src/runtime/routes/bookmark-routes.ts +154 -0
  548. package/src/runtime/routes/channel-verification-routes.ts +2 -1
  549. package/src/runtime/routes/contact-routes.ts +0 -160
  550. package/src/runtime/routes/conversation-cli-routes.ts +192 -0
  551. package/src/runtime/routes/conversation-management-routes.ts +30 -43
  552. package/src/runtime/routes/conversation-query-routes.ts +334 -86
  553. package/src/runtime/routes/conversation-routes.ts +31 -10
  554. package/src/runtime/routes/conversations-import-routes.ts +229 -0
  555. package/src/runtime/routes/credential-routes.ts +540 -0
  556. package/src/runtime/routes/debug-routes.ts +2 -2
  557. package/src/runtime/routes/document-pdf-renderer.ts +5 -1
  558. package/src/runtime/routes/domain-routes.ts +167 -0
  559. package/src/runtime/routes/email-routes.ts +603 -0
  560. package/src/runtime/routes/errors.ts +2 -2
  561. package/src/runtime/routes/events-routes.ts +192 -0
  562. package/src/runtime/routes/home-feed-routes.ts +6 -78
  563. package/src/runtime/routes/host-app-control-routes.ts +44 -2
  564. package/src/runtime/routes/host-browser-routes.ts +103 -22
  565. package/src/runtime/routes/http-adapter.ts +2 -0
  566. package/src/runtime/routes/identity-routes.ts +5 -0
  567. package/src/runtime/routes/image-generation-routes.ts +99 -0
  568. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +137 -1
  569. package/src/runtime/routes/inbound-stages/background-dispatch.ts +87 -7
  570. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.test.ts +156 -0
  571. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +22 -4
  572. package/src/runtime/routes/index.ts +36 -0
  573. package/src/runtime/routes/inference-profile-session-handler.ts +312 -0
  574. package/src/runtime/routes/inference-profile-session-reaper.ts +98 -0
  575. package/src/runtime/routes/inference-profile-session-routes.ts +146 -0
  576. package/src/runtime/routes/inference-provider-connection-routes.ts +317 -0
  577. package/src/runtime/routes/inference-send-routes.ts +115 -0
  578. package/src/runtime/routes/integrations/twilio.ts +1 -0
  579. package/src/runtime/routes/mcp-auth-routes.ts +283 -9
  580. package/src/runtime/routes/memory-v2-routes.ts +13 -398
  581. package/src/runtime/routes/notification-routes.ts +2 -0
  582. package/src/runtime/routes/oauth-apps.ts +112 -7
  583. package/src/runtime/routes/oauth-commands-routes.ts +1007 -0
  584. package/src/runtime/routes/oauth-connect-routes.ts +67 -5
  585. package/src/runtime/routes/oauth-providers.ts +298 -8
  586. package/src/runtime/routes/platform-routes.ts +336 -0
  587. package/src/runtime/routes/playground/inject-failures.ts +2 -1
  588. package/src/runtime/routes/playground/reset-circuit.ts +2 -1
  589. package/src/runtime/routes/playground/state.ts +2 -1
  590. package/src/runtime/routes/publish-routes.ts +221 -0
  591. package/src/runtime/routes/schedule-routes.ts +82 -0
  592. package/src/runtime/routes/sequence-routes.ts +291 -0
  593. package/src/runtime/routes/settings-routes.ts +2 -10
  594. package/src/runtime/routes/skills-routes.ts +31 -1
  595. package/src/runtime/routes/stt-routes.ts +240 -3
  596. package/src/runtime/routes/surface-action-routes.ts +43 -7
  597. package/src/runtime/routes/tts-routes.ts +67 -0
  598. package/src/runtime/routes/types.ts +32 -0
  599. package/src/runtime/routes/user-routes-cli.ts +243 -0
  600. package/src/runtime/routes/webhook-routes.ts +165 -0
  601. package/src/runtime/sync/resource-sync-events.ts +25 -0
  602. package/src/runtime/sync/sync-publisher.test.ts +105 -0
  603. package/src/runtime/sync/sync-publisher.ts +21 -0
  604. package/src/schedule/scheduler.ts +200 -123
  605. package/src/security/__tests__/provider-key-env-fallback.test.ts +12 -6
  606. package/src/security/secret-patterns.ts +3 -0
  607. package/src/sequence/engine.ts +38 -40
  608. package/src/subagent/manager.ts +20 -15
  609. package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +206 -0
  610. package/src/tools/browser/browser-execution.ts +15 -4
  611. package/src/tools/browser/cdp-client/__tests__/factory.test.ts +174 -0
  612. package/src/tools/browser/cdp-client/cdp-inspect/__tests__/ws-transport.test.ts +16 -13
  613. package/src/tools/browser/cdp-client/extension-cdp-client.ts +24 -1
  614. package/src/tools/browser/cdp-client/factory.ts +66 -5
  615. package/src/tools/browser/runtime-check.ts +77 -0
  616. package/src/tools/memory/register.test.ts +3 -3
  617. package/src/tools/memory/register.ts +9 -1
  618. package/src/tools/network/__tests__/web-search.test.ts +156 -0
  619. package/src/tools/network/web-search.ts +280 -37
  620. package/src/tools/permission-checker.ts +13 -5
  621. package/src/tools/subagent/spawn.ts +3 -3
  622. package/src/tools/terminal/shell.ts +44 -0
  623. package/src/usage/attribution.ts +3 -2
  624. package/src/util/pricing.ts +86 -160
  625. package/src/watcher/__tests__/engine.test.ts +301 -0
  626. package/src/watcher/constants.ts +7 -0
  627. package/src/watcher/engine.ts +90 -90
  628. package/src/workspace/migrations/046-seed-conversation-starters-callsite.ts +6 -9
  629. package/src/workspace/migrations/054-seed-recall-callsite.ts +10 -1
  630. package/src/workspace/migrations/057-repair-stale-gemini-model-ids.ts +28 -4
  631. package/src/workspace/migrations/069-seed-onboarding-threads.ts +8 -2
  632. package/src/workspace/migrations/072-seed-reply-suggestion-callsite.ts +104 -0
  633. package/src/workspace/migrations/073-repair-recall-callsite-empty-profile.ts +93 -0
  634. package/src/workspace/migrations/074-drop-deprecated-secret-detection-keys.ts +117 -0
  635. package/src/workspace/migrations/075-memory-v2-bm25-b-default-reembed.ts +61 -0
  636. package/src/workspace/migrations/076-drop-services-inference-mode.ts +62 -0
  637. package/src/workspace/migrations/077-seed-memory-router-callsite.ts +89 -0
  638. package/src/workspace/migrations/078-release-notes-tavily-web-search.ts +66 -0
  639. package/src/workspace/migrations/079-home-feed-notification-only.ts +197 -0
  640. package/src/workspace/migrations/080-restrict-vercel-api-token-metadata.ts +182 -0
  641. package/src/workspace/migrations/081-backfill-bash-allowed-tools-for-injection-credentials.ts +160 -0
  642. package/src/workspace/migrations/082-backfill-managed-profile-labels.ts +154 -0
  643. package/src/workspace/migrations/registry.ts +22 -0
  644. package/src/workspace/migrations/runner.ts +13 -2
  645. package/src/workspace/migrations/types.ts +13 -3
  646. package/src/workspace/provider-commit-message-generator.ts +3 -2
  647. package/src/__tests__/context-search-pkb-source.test.ts +0 -498
  648. package/src/__tests__/credentials-cli.test.ts +0 -1225
  649. package/src/__tests__/memory-admin-recall.test.ts +0 -213
  650. package/src/approvals/__tests__/guardian-feed-event.test.ts +0 -303
  651. package/src/cli/commands/__tests__/email-download.test.ts +0 -260
  652. package/src/cli/commands/__tests__/email-list.test.ts +0 -216
  653. package/src/cli/commands/__tests__/email-register.test.ts +0 -186
  654. package/src/cli/commands/__tests__/email-send.test.ts +0 -416
  655. package/src/cli/commands/__tests__/email-status.test.ts +0 -185
  656. package/src/cli/commands/__tests__/email-unregister.test.ts +0 -168
  657. package/src/cli/commands/__tests__/routes.test.ts +0 -562
  658. package/src/cli/commands/__tests__/stt-transcribe.test.ts +0 -454
  659. package/src/cli/commands/autonomy.ts +0 -365
  660. package/src/cli/commands/memory.ts +0 -424
  661. package/src/cli/commands/oauth/__tests__/connect.test.ts +0 -947
  662. package/src/cli/commands/oauth/__tests__/disconnect.test.ts +0 -686
  663. package/src/cli/commands/oauth/__tests__/mode.test.ts +0 -632
  664. package/src/cli/commands/oauth/__tests__/ping.test.ts +0 -631
  665. package/src/cli/commands/oauth/__tests__/providers-delete.test.ts +0 -573
  666. package/src/cli/commands/oauth/__tests__/providers-register.test.ts +0 -330
  667. package/src/cli/commands/oauth/__tests__/providers-update.test.ts +0 -521
  668. package/src/cli/commands/oauth/__tests__/status.test.ts +0 -551
  669. package/src/cli/commands/oauth/__tests__/token.test.ts +0 -420
  670. package/src/cli/lib/daemon-avatar-client.ts +0 -37
  671. package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +0 -87
  672. package/src/config/bundled-skills/messaging/tools/__tests__/messaging-feed-events.test.ts +0 -207
  673. package/src/daemon/__tests__/conversation-feed-event.test.ts +0 -304
  674. package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +0 -233
  675. package/src/home/__tests__/assistant-feed-authoring.test.ts +0 -156
  676. package/src/home/__tests__/emit-feed-event.test.ts +0 -169
  677. package/src/home/__tests__/feed-population-integration.test.ts +0 -312
  678. package/src/home/__tests__/feed-scheduler.test.ts +0 -222
  679. package/src/home/__tests__/phase5-exit-criteria.test.ts +0 -229
  680. package/src/home/__tests__/platform-gmail-digest.test.ts +0 -222
  681. package/src/home/__tests__/rollup-producer.test.ts +0 -507
  682. package/src/home/assistant-feed-authoring.ts +0 -135
  683. package/src/home/emit-feed-event.ts +0 -169
  684. package/src/home/feed-scheduler.ts +0 -281
  685. package/src/home/platform-gmail-digest.ts +0 -163
  686. package/src/home/rewrite-command-preview.ts +0 -66
  687. package/src/home/rewrite-feed-title.ts +0 -58
  688. package/src/home/rollup-producer.ts +0 -426
  689. package/src/memory/admin.ts +0 -326
  690. package/src/memory/context-search/sources/pkb.ts +0 -476
  691. package/src/memory/graph/compaction.ts +0 -299
  692. /package/src/cli/{commands → lib}/cache-fs.ts +0 -0
@@ -39,11 +39,13 @@ interface UpsertCall {
39
39
  dense: number[];
40
40
  sparse: { indices: number[]; values: number[] };
41
41
  updatedAt: number;
42
+ kind?: string;
42
43
  }
43
44
 
44
45
  interface PruneCall {
45
46
  prefix: string;
46
47
  activeSuffixes: readonly string[];
48
+ options?: { kind?: string };
47
49
  }
48
50
 
49
51
  interface TestState {
@@ -118,8 +120,9 @@ mock.module("../qdrant.js", () => ({
118
120
  pruneSlugsWithPrefixExcept: async (
119
121
  prefix: string,
120
122
  activeSuffixes: readonly string[],
123
+ options?: { kind?: string },
121
124
  ) => {
122
- state.pruneCalls.push({ prefix, activeSuffixes });
125
+ state.pruneCalls.push({ prefix, activeSuffixes, options });
123
126
  },
124
127
  }));
125
128
 
@@ -131,8 +134,12 @@ mock.module("../../../skills/catalog-cache.js", () => ({
131
134
  }));
132
135
 
133
136
  // Imported AFTER all mocks are wired so the module under test sees the stubs.
134
- const { seedV2SkillEntries, getSkillCapability, _resetSkillStoreForTests } =
135
- await import("../skill-store.js");
137
+ const {
138
+ seedV2SkillEntries,
139
+ getSkillCapability,
140
+ listSkillEntries,
141
+ _resetSkillStoreForTests,
142
+ } = await import("../skill-store.js");
136
143
 
137
144
  // ---------------------------------------------------------------------------
138
145
  // Helpers
@@ -467,3 +474,51 @@ describe("getSkillCapability", () => {
467
474
  expect(getSkillCapability("does-not-exist")).toBeNull();
468
475
  });
469
476
  });
477
+
478
+ describe("listSkillEntries", () => {
479
+ test("returns [] when the cache is empty (pre-seed)", () => {
480
+ expect(listSkillEntries()).toEqual([]);
481
+ });
482
+
483
+ test("returns entries sorted by id after seeding", async () => {
484
+ // Insert in non-sorted order to prove the sort happens on read.
485
+ const skillB = makeSummary({ id: "example-skill-b" });
486
+ const skillA = makeSummary({ id: "example-skill-a" });
487
+ state.catalog = [skillB, skillA];
488
+ state.resolved = [
489
+ { summary: skillB, state: "enabled" },
490
+ { summary: skillA, state: "enabled" },
491
+ ];
492
+ state.embedReturn = [
493
+ [0.1, 0.2, 0.3],
494
+ [0.4, 0.5, 0.6],
495
+ ];
496
+
497
+ await seedV2SkillEntries();
498
+
499
+ const list = listSkillEntries();
500
+ expect(list).toHaveLength(2);
501
+ expect(list.map((e) => e.id)).toEqual([
502
+ "example-skill-a",
503
+ "example-skill-b",
504
+ ]);
505
+ });
506
+
507
+ test("mutating the returned array does not affect subsequent calls", async () => {
508
+ const skillA = makeSummary({ id: "example-skill-a" });
509
+ state.catalog = [skillA];
510
+ state.resolved = [{ summary: skillA, state: "enabled" }];
511
+ state.embedReturn = [[0.1, 0.2, 0.3]];
512
+
513
+ await seedV2SkillEntries();
514
+
515
+ const first = listSkillEntries();
516
+ expect(first).toHaveLength(1);
517
+ first.length = 0;
518
+ first.push({ id: "injected", content: "junk" });
519
+
520
+ const second = listSkillEntries();
521
+ expect(second).toHaveLength(1);
522
+ expect(second[0].id).toBe("example-skill-a");
523
+ });
524
+ });
@@ -45,7 +45,7 @@ mock.module("../../../config/loader.js", () => ({
45
45
  setNestedValue: () => {},
46
46
  }));
47
47
 
48
- const { readMemoryV2StaticContent, shouldLoadMemoryV2Static } =
48
+ const { readMemoryV2StaticContent, shouldExposePersonalMemory } =
49
49
  await import("../static-context.js");
50
50
 
51
51
  const MEMORY_FILES = [
@@ -140,21 +140,10 @@ describe("readMemoryV2StaticContent", () => {
140
140
  });
141
141
  });
142
142
 
143
- describe("shouldLoadMemoryV2Static", () => {
144
- test("blocks all turns until the cadence gate fires", () => {
145
- expect(
146
- shouldLoadMemoryV2Static({
147
- shouldInjectNowAndPkb: false,
148
- sourceChannel: "vellum",
149
- isTrustedActor: true,
150
- }),
151
- ).toBe(false);
152
- });
153
-
143
+ describe("shouldExposePersonalMemory", () => {
154
144
  test("allows guardian-trusted local conversations", () => {
155
145
  expect(
156
- shouldLoadMemoryV2Static({
157
- shouldInjectNowAndPkb: true,
146
+ shouldExposePersonalMemory({
158
147
  sourceChannel: "vellum",
159
148
  isTrustedActor: true,
160
149
  }),
@@ -163,8 +152,7 @@ describe("shouldLoadMemoryV2Static", () => {
163
152
 
164
153
  test("allows local-channel conversations even when trust class is unknown (analyze runs, dev)", () => {
165
154
  expect(
166
- shouldLoadMemoryV2Static({
167
- shouldInjectNowAndPkb: true,
155
+ shouldExposePersonalMemory({
168
156
  sourceChannel: "vellum",
169
157
  isTrustedActor: false,
170
158
  }),
@@ -173,8 +161,7 @@ describe("shouldLoadMemoryV2Static", () => {
173
161
 
174
162
  test("allows turns with no trust context (work-item task runs, internal background)", () => {
175
163
  expect(
176
- shouldLoadMemoryV2Static({
177
- shouldInjectNowAndPkb: true,
164
+ shouldExposePersonalMemory({
178
165
  sourceChannel: undefined,
179
166
  isTrustedActor: false,
180
167
  }),
@@ -192,8 +179,7 @@ describe("shouldLoadMemoryV2Static", () => {
192
179
  test("allows guardian-trusted remote channels (user's own phone/Slack)", () => {
193
180
  for (const channel of REMOTE_CHANNELS) {
194
181
  expect(
195
- shouldLoadMemoryV2Static({
196
- shouldInjectNowAndPkb: true,
182
+ shouldExposePersonalMemory({
197
183
  sourceChannel: channel,
198
184
  isTrustedActor: true,
199
185
  }),
@@ -204,8 +190,7 @@ describe("shouldLoadMemoryV2Static", () => {
204
190
  test("blocks non-guardian remote-channel actors (the leak this gate exists to prevent)", () => {
205
191
  for (const channel of REMOTE_CHANNELS) {
206
192
  expect(
207
- shouldLoadMemoryV2Static({
208
- shouldInjectNowAndPkb: true,
193
+ shouldExposePersonalMemory({
209
194
  sourceChannel: channel,
210
195
  isTrustedActor: false,
211
196
  }),
@@ -62,6 +62,23 @@ mock.module("../../../providers/provider-send-message.js", () => ({
62
62
  response.content.find((b): b is ToolUseContent => b.type === "tool_use"),
63
63
  }));
64
64
 
65
+ // emitNotificationSignal spy — captures every notification the sweep emits
66
+ // so the failure-path test can assert on `activity.failed` shape and dedupe.
67
+ const emitCalls: Array<Record<string, unknown>> = [];
68
+
69
+ mock.module("../../../notifications/emit-signal.js", () => ({
70
+ emitNotificationSignal: async (params: Record<string, unknown>) => {
71
+ emitCalls.push(params);
72
+ return {
73
+ signalId: "sig-1",
74
+ deduplicated: false,
75
+ dispatched: true,
76
+ reason: "ok",
77
+ deliveryResults: [],
78
+ };
79
+ },
80
+ }));
81
+
65
82
  // Workspace setup — temp dir per test run, pinned via VELLUM_WORKSPACE_DIR
66
83
  // so `getWorkspaceDir()` resolves to the tmpdir.
67
84
  let tmpWorkspace: string;
@@ -166,6 +183,7 @@ function extractFirstUserText(msgs: { content: unknown }[]): string {
166
183
  function seedMessages(
167
184
  conversationId: string,
168
185
  rows: Array<{ role: string; content: string; offsetMs: number }>,
186
+ conversationType: "standard" | "background" | "scheduled" = "standard",
169
187
  ): void {
170
188
  const db = getDb();
171
189
  const now = Date.now();
@@ -175,6 +193,7 @@ function seedMessages(
175
193
  title: null,
176
194
  createdAt: now - 60_000,
177
195
  updatedAt: now,
196
+ conversationType,
178
197
  })
179
198
  .run();
180
199
  for (let i = 0; i < rows.length; i++) {
@@ -200,6 +219,7 @@ beforeEach(() => {
200
219
  mkdirSync(join(tmpWorkspace, "memory"), { recursive: true });
201
220
  providerCalls.length = 0;
202
221
  providerStub = null;
222
+ emitCalls.length = 0;
203
223
  });
204
224
 
205
225
  // ---------------------------------------------------------------------------
@@ -417,6 +437,81 @@ describe("memoryV2SweepJob — recent messages", () => {
417
437
 
418
438
  expect(written).toBe(0);
419
439
  });
440
+
441
+ test("emits an activity.failed notification when provider.sendMessage throws", async () => {
442
+ // Simulate a transient provider failure once we're past the early
443
+ // bail checks. The sweep must (a) preserve the existing silent-failure
444
+ // contract by returning 0, and (b) surface the failure via the
445
+ // centralized notifications pipeline so the user sees it instead of
446
+ // the failure being silently swallowed.
447
+ providerStub = {
448
+ name: "stub",
449
+ sendMessage: async () => {
450
+ throw new Error("simulated provider failure");
451
+ },
452
+ };
453
+
454
+ const written = await memoryV2SweepJob(makeJob(), CONFIG);
455
+
456
+ expect(written).toBe(0);
457
+ expect(emitCalls).toHaveLength(1);
458
+ const emitted = emitCalls[0]!;
459
+ expect(emitted.sourceEventName).toBe("activity.failed");
460
+ expect(emitted.sourceChannel).toBe("scheduler");
461
+ const day = new Date().toISOString().slice(0, 10);
462
+ expect(emitted.dedupeKey).toBe(`activity-failed:memory.v2.sweep:${day}`);
463
+ const contextPayload = emitted.contextPayload as Record<string, unknown>;
464
+ expect(contextPayload.jobName).toBe("memory.v2.sweep");
465
+ expect(contextPayload.errorKind).toBe("exception");
466
+ expect(contextPayload.errorMessage).toContain("simulated provider failure");
467
+ });
468
+ });
469
+
470
+ describe("memoryV2SweepJob — background/scheduled conversation filter", () => {
471
+ test("excludes background/scheduled conversation content from sweep input", async () => {
472
+ seedMessages(
473
+ `conv-bg-${++convCounter}`,
474
+ [
475
+ {
476
+ role: "assistant",
477
+ content:
478
+ "[heartbeat] internal automation chatter that should not leak",
479
+ offsetMs: -60_000,
480
+ },
481
+ ],
482
+ "background",
483
+ );
484
+ seedMessages(
485
+ `conv-sched-${++convCounter}`,
486
+ [
487
+ {
488
+ role: "assistant",
489
+ content:
490
+ "[scheduled] scheduled-job chatter that should not leak either",
491
+ offsetMs: -45_000,
492
+ },
493
+ ],
494
+ "scheduled",
495
+ );
496
+ seedMessages(`conv-user-${++convCounter}`, [
497
+ {
498
+ role: "user",
499
+ content: "Bob mentioned he prefers dark mode.",
500
+ offsetMs: -30_000,
501
+ },
502
+ ]);
503
+
504
+ providerStub = makeEntriesProvider(["Bob prefers dark mode."]);
505
+
506
+ const written = await memoryV2SweepJob(makeJob(), CONFIG);
507
+
508
+ expect(written).toBe(1);
509
+ expect(providerCalls).toHaveLength(1);
510
+ const [{ userText }] = providerCalls;
511
+ expect(userText).toContain("Bob mentioned he prefers dark mode.");
512
+ expect(userText).not.toContain("internal automation chatter");
513
+ expect(userText).not.toContain("scheduled-job chatter");
514
+ });
420
515
  });
421
516
 
422
517
  function todaysArchiveBasename(now: Date = new Date()): string {
@@ -82,15 +82,44 @@ export async function save(
82
82
  * The child row inherits everInjected as-is so previously-attached slugs are
83
83
  * not re-injected on the child's first turn — matching the v1 semantics where
84
84
  * a fork carries over all in-context memories.
85
+ *
86
+ * Synchronous so it can run inside the bun:sqlite transaction that wraps
87
+ * `forkConversation()` — keeping the state copy atomic with the message and
88
+ * attachment copies.
85
89
  */
86
- export async function fork(
90
+ export function forkActivationState(
87
91
  database: DrizzleDb,
88
92
  parentConversationId: string,
89
93
  newConversationId: string,
90
- ): Promise<void> {
91
- const parent = await hydrate(database, parentConversationId);
92
- if (!parent) return;
93
- await save(database, newConversationId, parent);
94
+ ): void {
95
+ const row = database
96
+ .select()
97
+ .from(activationState)
98
+ .where(eq(activationState.conversationId, parentConversationId))
99
+ .get();
100
+ if (!row) return;
101
+
102
+ database
103
+ .insert(activationState)
104
+ .values({
105
+ conversationId: newConversationId,
106
+ messageId: row.messageId,
107
+ stateJson: row.stateJson,
108
+ everInjectedJson: row.everInjectedJson,
109
+ currentTurn: row.currentTurn,
110
+ updatedAt: row.updatedAt,
111
+ })
112
+ .onConflictDoUpdate({
113
+ target: activationState.conversationId,
114
+ set: {
115
+ messageId: row.messageId,
116
+ stateJson: row.stateJson,
117
+ everInjectedJson: row.everInjectedJson,
118
+ currentTurn: row.currentTurn,
119
+ updatedAt: row.updatedAt,
120
+ },
121
+ })
122
+ .run();
94
123
  }
95
124
 
96
125
  /**
@@ -36,15 +36,13 @@
36
36
 
37
37
  import type { AssistantConfig } from "../../config/types.js";
38
38
  import { applyCorrectionIfCalibrated } from "../anisotropy.js";
39
- import {
40
- embedWithBackend,
41
- generateSparseEmbedding,
42
- } from "../embedding-backend.js";
39
+ import { embedWithBackend } from "../embedding-backend.js";
43
40
  import { clampUnitInterval } from "../validation.js";
44
41
  import type { EdgeIndex } from "./edge-index.js";
45
42
  import { hybridQueryConceptPages } from "./qdrant.js";
46
43
  import { rerankCandidates } from "./reranker.js";
47
44
  import { simBatch } from "./sim.js";
45
+ import { generateBm25QueryEmbedding } from "./sparse-bm25.js";
48
46
  import type { ActivationState, EverInjectedEntry } from "./types.js";
49
47
 
50
48
  /**
@@ -125,12 +123,13 @@ export async function selectCandidates(
125
123
 
126
124
  // (2) ANN top-50 against the concatenated turn text. Pure whitespace joins
127
125
  // (no separators) keep the embedding behavior aligned with how callers
128
- // would naturally read the three texts together.
126
+ // would naturally read the three texts together. Whitespace-only channels
127
+ // contribute no semantic content, so trim before deciding whether to embed.
129
128
  const annQueryText = [userText, assistantText, nowText]
130
- .filter((s) => s.length > 0)
129
+ .filter((s) => s.trim().length > 0)
131
130
  .join("\n");
132
131
 
133
- if (annQueryText.length > 0) {
132
+ if (annQueryText.trim().length > 0) {
134
133
  throwIfAborted(signal);
135
134
  const denseResult = await embedWithBackend(config, [annQueryText], {
136
135
  signal,
@@ -141,7 +140,7 @@ export async function selectCandidates(
141
140
  denseResult.model,
142
141
  );
143
142
  throwIfAborted(signal);
144
- const sparse = generateSparseEmbedding(annQueryText);
143
+ const sparse = generateBm25QueryEmbedding(annQueryText);
145
144
  const limit =
146
145
  config.memory.v2.ann_candidate_limit ?? UNLIMITED_ANN_CANDIDATE_LIMIT;
147
146
  const hits = await hybridQueryConceptPages(dense, sparse, limit);
@@ -202,17 +201,19 @@ interface ComputeOwnActivationResult {
202
201
  * + c_user · sim_u + c_assistant · sim_a + c_now · sim_n
203
202
  * + c_user · α · r_norm_u + c_assistant · α · r_norm_a
204
203
  * over the candidate set, where the rerank terms only fire for slugs that
205
- * land in the unified top-K-by-pre-rerank-A_o window. Returns a sparse map
206
- * keyed by slug; slugs whose computed value rounds to 0 are still included
207
- * so callers can see the candidate set explicitly. Also returns a per-slug
208
- * breakdown of the raw inputs (decayed prior + raw sims + rerank deltas) so
209
- * callers can render contribution diagnostics without re-running the math.
204
+ * land in the unified top-K window. The pool is ranked by the rerank-eligible
205
+ * channels alone (`c_user · sim_u + c_assistant · sim_a`) so prior- or
206
+ * NOW-heavy slugs which can't gain from rerank don't starve out
207
+ * genuinely user/assistant-relevant slugs. Returns a sparse map keyed by
208
+ * slug; slugs whose computed value rounds to 0 are still included so callers
209
+ * can see the candidate set explicitly. Also returns a per-slug breakdown of
210
+ * the raw inputs (decayed prior + raw sims + rerank deltas) so callers can
211
+ * render contribution diagnostics without re-running the math.
210
212
  *
211
213
  * The three `simBatch` calls run concurrently — they hit independent named
212
214
  * vectors and embed independent query texts. Cross-encoder rerank then runs
213
- * once on the unified top-K (selected by pre-rerank A_o, not per-channel
214
- * fused sim) so an entry strong in both channels can't double-boost itself
215
- * past entries that only land in one channel.
215
+ * once on the unified top-K so an entry strong in both channels can't
216
+ * double-boost itself past entries that only land in one channel.
216
217
  */
217
218
  export async function computeOwnActivation(
218
219
  params: ComputeOwnActivationParams,
@@ -248,8 +249,16 @@ export async function computeOwnActivation(
248
249
  simU: number;
249
250
  simA: number;
250
251
  simN: number;
251
- /** Pre-rerank A_o; ranking signal for the unified rerank pool. */
252
+ /** Pre-rerank A_o; full sum used for the final activation value. */
252
253
  preRerank: number;
254
+ /**
255
+ * Ranking signal for the unified rerank pool — only the channels that
256
+ * actually participate in rerank (user + assistant). Excluding
257
+ * `priorContribution` and `c_now * simN` prevents prior- or NOW-heavy
258
+ * slugs from consuming the rerank budget despite being ineligible for
259
+ * cross-encoder gains.
260
+ */
261
+ rerankPoolScore: number;
253
262
  }
254
263
  const inputs: SlugInputs[] = slugList.map((slug) => {
255
264
  const prev = priorState?.state[slug] ?? 0;
@@ -257,23 +266,24 @@ export async function computeOwnActivation(
257
266
  const simA = simAssistant.get(slug) ?? 0;
258
267
  const simN = simNow.get(slug) ?? 0;
259
268
  const priorContribution = d * prev;
269
+ const rerankPoolScore = c_user * simU + c_assistant * simA;
260
270
  return {
261
271
  slug,
262
272
  priorContribution,
263
273
  simU,
264
274
  simA,
265
275
  simN,
266
- preRerank:
267
- priorContribution + c_user * simU + c_assistant * simA + c_now * simN,
276
+ preRerank: priorContribution + rerankPoolScore + c_now * simN,
277
+ rerankPoolScore,
268
278
  };
269
279
  });
270
280
 
271
- // Unified top-K by pre-rerank A_o. Both channels rerank against the **same**
272
- // slug set, so a slug strong on user can't crowd out one strong on assistant
273
- // by virtue of appearing in both per-channel top-Ks. Both channel queries
274
- // ride in a single `rerankCandidates` call so the worker tokenizes and
275
- // forward-passes them together — half the per-call overhead of two
276
- // serialised round-trips.
281
+ // Unified top-K by rerank-eligible signal only. Both channels rerank against
282
+ // the **same** slug set, so a slug strong on user can't crowd out one strong
283
+ // on assistant by virtue of appearing in both per-channel top-Ks. Both
284
+ // channel queries ride in a single `rerankCandidates` call so the worker
285
+ // tokenizes and forward-passes them together — half the per-call overhead
286
+ // of two serialised round-trips.
277
287
  let userRerankBoost: ReadonlyMap<string, number> = new Map();
278
288
  let assistantRerankBoost: ReadonlyMap<string, number> = new Map();
279
289
  let inPoolSet: ReadonlySet<string> = new Set();
@@ -282,17 +292,20 @@ export async function computeOwnActivation(
282
292
  throwIfAborted(signal);
283
293
  const topSlugs = inputs
284
294
  .slice()
285
- .sort((a, b) => b.preRerank - a.preRerank)
295
+ .sort((a, b) => b.rerankPoolScore - a.rerankPoolScore)
286
296
  .slice(0, rerankCfg.top_k)
287
297
  .map((e) => e.slug);
288
298
  if (topSlugs.length > 0) {
289
- inPoolSet = new Set(topSlugs);
290
299
  const [userScores, assistantScores] = await rerankCandidates(
291
300
  [userText, assistantText],
292
301
  topSlugs,
293
302
  config,
294
303
  );
295
304
  throwIfAborted(signal);
305
+ // Build the pool from slugs the cross-encoder actually scored, so a
306
+ // backend failure (which yields empty maps) doesn't mislabel candidates
307
+ // as `inRerankPool` in the inspector.
308
+ inPoolSet = new Set([...userScores.keys(), ...assistantScores.keys()]);
296
309
  userRerankBoost = normalizeRerankScores(userScores, rerankCfg.alpha);
297
310
  assistantRerankBoost = normalizeRerankScores(
298
311
  assistantScores,
@@ -7,8 +7,7 @@
7
7
  //
8
8
  // - `memory_v2_migrate` — one-shot v1→v2 synthesis (PR 16).
9
9
  // - `memory_v2_reembed` — fan out an `embed_concept_page` job
10
- // per slug, plus four reserved-slug jobs for the meta files
11
- // (`__essentials__`, `__threads__`, `__recent__`, `__buffer__`).
10
+ // per concept-page slug.
12
11
  // - `memory_v2_activation_recompute` — recompute persisted activation
13
12
  // state for every conversation, no rendering. Used after consolidation
14
13
  // replaces or deletes pages that other conversations still reference.
@@ -19,9 +18,6 @@
19
18
  // the same code paths exercised by tests of those modules run unchanged when
20
19
  // a backfill kicks them off.
21
20
 
22
- import { readFile } from "node:fs/promises";
23
- import { join } from "node:path";
24
-
25
21
  import type { AssistantConfig } from "../../config/types.js";
26
22
  import { getLogger } from "../../util/logger.js";
27
23
  import { getWorkspaceDir } from "../../util/platform.js";
@@ -30,6 +26,7 @@ import { listConversations } from "../conversation-queries.js";
30
26
  import { getDb } from "../db-connection.js";
31
27
  import { enqueueEmbedConceptPageJob } from "../jobs/embed-concept-page.js";
32
28
  import type { MemoryJob } from "../jobs-store.js";
29
+ import { stringifyMessageContent } from "../message-content.js";
33
30
  import {
34
31
  computeOwnActivation,
35
32
  selectCandidates,
@@ -41,25 +38,11 @@ import {
41
38
  MigrationAlreadyAppliedError,
42
39
  runMemoryV2Migration,
43
40
  } from "./migration.js";
41
+ import { loadNowText } from "./now-text.js";
44
42
  import { listPages } from "./page-store.js";
45
43
 
46
44
  const log = getLogger("memory-v2-backfill");
47
45
 
48
- /**
49
- * Reserved slugs the reembed job enqueues alongside the concept-page slugs.
50
- * These name the four prose meta files (essentials/threads/recent/buffer)
51
- * loaded into the system prompt by PR 11. Embedding them is forward-looking
52
- * — the existing `embed-concept-page` handler treats unknown slugs as
53
- * deletions (a no-op when no embedding exists), so enqueueing here is safe
54
- * regardless of whether the meta files are ever embedded for retrieval.
55
- */
56
- export const META_FILE_SLUGS = [
57
- "__essentials__",
58
- "__threads__",
59
- "__recent__",
60
- "__buffer__",
61
- ] as const;
62
-
63
46
  // ---------------------------------------------------------------------------
64
47
  // memory_v2_migrate — wraps runMemoryV2Migration
65
48
  // ---------------------------------------------------------------------------
@@ -106,16 +89,22 @@ export async function memoryV2MigrateJob(
106
89
  }
107
90
 
108
91
  // ---------------------------------------------------------------------------
109
- // memory_v2_reembed — fan out embed jobs for every page + meta file
92
+ // memory_v2_reembed — fan out embed jobs for every concept page
110
93
  // ---------------------------------------------------------------------------
111
94
 
112
95
  /**
113
- * Job handler: enqueue an `embed_concept_page` job per concept-page slug, plus
114
- * one job per reserved meta-file slug ({@link META_FILE_SLUGS}).
96
+ * Job handler: enqueue an `embed_concept_page` job per concept-page slug.
97
+ *
98
+ * Returns the total number of jobs enqueued. Callers (and tests) use the
99
+ * return value to assert progress without inspecting the job table directly.
115
100
  *
116
- * Returns the total number of jobs enqueued `concept-page count + 4`.
117
- * Callers (and tests) use the return value to assert progress without
118
- * inspecting the job table directly.
101
+ * Note on meta files: `essentials.md` / `threads.md` / `recent.md` /
102
+ * `buffer.md` are direct-injected into the system prompt every turn via
103
+ * `_autoinject.md`. They are NOT enqueued for embedding here — their slugs
104
+ * (`__essentials__` etc.) contain underscores that the concept-page slug
105
+ * validator rejects (`[a-z0-9][a-z0-9-]*`), and they live at `memory/<name>.md`
106
+ * rather than `memory/concepts/<name>.md`, so path resolution would also miss.
107
+ * Embedding them would be redundant with the direct injection regardless.
119
108
  */
120
109
  export async function memoryV2ReembedJob(
121
110
  _job: MemoryJob,
@@ -127,16 +116,12 @@ export async function memoryV2ReembedJob(
127
116
  for (const slug of slugs) {
128
117
  enqueueEmbedConceptPageJob({ slug });
129
118
  }
130
- for (const slug of META_FILE_SLUGS) {
131
- enqueueEmbedConceptPageJob({ slug });
132
- }
133
119
 
134
- const total = slugs.length + META_FILE_SLUGS.length;
135
120
  log.info(
136
- { conceptPages: slugs.length, metaFiles: META_FILE_SLUGS.length, total },
121
+ { conceptPages: slugs.length, total: slugs.length },
137
122
  "Memory v2 reembed enqueued",
138
123
  );
139
- return total;
124
+ return slugs.length;
140
125
  }
141
126
 
142
127
  // ---------------------------------------------------------------------------
@@ -303,55 +288,3 @@ function lastExchangeTexts(conversationId: string): {
303
288
  }
304
289
  return { userText, assistantText };
305
290
  }
306
-
307
- /**
308
- * Coerce stored message content (JSON-serialized `ContentBlock[]` *or* plain
309
- * string in legacy rows) into a single text string. Image / tool blocks are
310
- * dropped — recompute only needs the spoken text.
311
- */
312
- function stringifyMessageContent(stored: string): string {
313
- let parsed: unknown;
314
- try {
315
- parsed = JSON.parse(stored);
316
- } catch {
317
- return stored.trim();
318
- }
319
- if (typeof parsed === "string") return parsed.trim();
320
- if (!Array.isArray(parsed)) return "";
321
- const parts: string[] = [];
322
- for (const block of parsed) {
323
- if (
324
- block &&
325
- typeof block === "object" &&
326
- (block as { type?: string }).type === "text" &&
327
- typeof (block as { text?: unknown }).text === "string"
328
- ) {
329
- parts.push((block as { text: string }).text);
330
- }
331
- }
332
- return parts.join("\n").trim();
333
- }
334
-
335
- /**
336
- * Read the prose meta files that compose the "NOW" context the activation
337
- * pipeline correlates against. Mirrors the autoload order in
338
- * `system-prompt.ts` so the same prose drives both injection and recompute.
339
- * Missing or unreadable files are treated as empty.
340
- */
341
- async function loadNowText(workspaceDir: string): Promise<string> {
342
- const filenames = ["essentials.md", "threads.md", "recent.md"];
343
- const reads = await Promise.all(
344
- filenames.map(async (filename) => {
345
- try {
346
- const text = await readFile(
347
- join(workspaceDir, "memory", filename),
348
- "utf-8",
349
- );
350
- return text.trim();
351
- } catch {
352
- return "";
353
- }
354
- }),
355
- );
356
- return reads.filter((part) => part.length > 0).join("\n\n");
357
- }