@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
@@ -24,9 +24,7 @@ export function saveGraphMemoryState(
24
24
  /**
25
25
  * Load graph memory state for a conversation, or null if none exists.
26
26
  */
27
- export function loadGraphMemoryState(
28
- conversationId: string,
29
- ): string | null {
27
+ export function loadGraphMemoryState(conversationId: string): string | null {
30
28
  const db = getDb();
31
29
  const row = db
32
30
  .select({ stateJson: conversationGraphMemoryState.stateJson })
@@ -35,3 +33,18 @@ export function loadGraphMemoryState(
35
33
  .get();
36
34
  return row?.stateJson ?? null;
37
35
  }
36
+
37
+ /**
38
+ * Copy the parent conversation's graph memory state row to a new conversation
39
+ * id so the forked conversation resumes with the parent's InContextTracker
40
+ * snapshot (in-context node IDs, per-node turn log, current turn). No-op if
41
+ * the parent has no row yet.
42
+ */
43
+ export function forkGraphMemoryState(
44
+ parentConversationId: string,
45
+ newConversationId: string,
46
+ ): void {
47
+ const stateJson = loadGraphMemoryState(parentConversationId);
48
+ if (stateJson == null) return;
49
+ saveGraphMemoryState(newConversationId, stateJson);
50
+ }
@@ -1,12 +1,13 @@
1
1
  import { beforeEach, describe, expect, mock, test } from "bun:test";
2
2
 
3
3
  import { makeMockLogger } from "../../__tests__/helpers/mock-logger.js";
4
- import { _setOverridesForTesting } from "../../config/assistant-feature-flags.js";
5
4
 
6
- // This test exercises the v1 graph search path. The `memory-v2-enabled` flag
7
- // (registry default `true`) makes graph-search short-circuit to keep traffic
8
- // off the legacy collection — disable it so the v1 path stays under test.
9
- _setOverridesForTesting({ "memory-v2-enabled": false });
5
+ // This test exercises the v1 graph search path. `config.memory.v2.enabled`
6
+ // (default `true`) makes graph-search short-circuit to keep traffic off
7
+ // the legacy collection — force it off so the v1 path stays under test.
8
+ mock.module("../../config/loader.js", () => ({
9
+ getConfig: () => ({ memory: { v2: { enabled: false } } }),
10
+ }));
10
11
 
11
12
  mock.module("../../util/logger.js", () => ({
12
13
  getLogger: () => makeMockLogger(),
@@ -5,7 +5,6 @@
5
5
  import { getConfig } from "../../config/loader.js";
6
6
  import type { AssistantConfig } from "../../config/types.js";
7
7
  import { getLogger } from "../../util/logger.js";
8
- import { isMemoryV2ReadActive } from "../context-search/sources/memory-v2.js";
9
8
  import { selectedBackendSupportsMultimodal } from "../embedding-backend.js";
10
9
  import type { EmbeddingInput } from "../embedding-types.js";
11
10
  import { embedAndUpsert } from "../job-utils.js";
@@ -46,11 +45,11 @@ export async function searchGraphNodes(
46
45
  sparseVector?: QdrantSparseVector,
47
46
  dateRange?: { afterMs?: number; beforeMs?: number },
48
47
  ): Promise<GraphSearchResult[]> {
49
- // v2 owns the read path when both gates are on. The v1 `memory` collection
50
- // is in active retirement and a corrupted sparse segment can OOM-crash the
48
+ // v2 owns the read path when enabled. The v1 `memory` collection is in
49
+ // active retirement and a corrupted sparse segment can OOM-crash the
51
50
  // shared Qdrant process — short-circuiting here keeps v1 background work
52
51
  // and stale callers from taking v2 down with them.
53
- if (isMemoryV2ReadActive(getConfig())) return [];
52
+ if (getConfig().memory.v2.enabled) return [];
54
53
 
55
54
  if (isQdrantBreakerOpen()) {
56
55
  log.warn("Qdrant circuit breaker open, skipping graph search");
@@ -71,7 +71,6 @@ mock.module("../../providers/provider-send-message.js", () => ({
71
71
  extractToolUse: () => null,
72
72
  }));
73
73
 
74
- import { _setOverridesForTesting } from "../../config/assistant-feature-flags.js";
75
74
  import { DEFAULT_CONFIG } from "../../config/defaults.js";
76
75
  import type { AssistantConfig } from "../../config/types.js";
77
76
  import { resetDb } from "../db-connection.js";
@@ -82,12 +81,16 @@ import { loadContextMemory, retrieveForTurn } from "./retriever.js";
82
81
  import { createNode } from "./store.js";
83
82
  import type { NewNode } from "./types.js";
84
83
 
85
- // These tests exercise v1 retrieval. v2 takeover (both `memory-v2-enabled`
86
- // flag *and* `memory.v2.enabled` schema field) makes `loadContextMemory`
87
- // short-circuit, so disable the flag here to keep the v1 path under test.
88
- _setOverridesForTesting({ "memory-v2-enabled": false });
89
-
90
- const TEST_CONFIG: AssistantConfig = { ...DEFAULT_CONFIG };
84
+ // These tests exercise v1 retrieval. `memory.v2.enabled` (default `true`)
85
+ // makes `loadContextMemory` short-circuit, so disable it here to keep the
86
+ // v1 path under test.
87
+ const TEST_CONFIG: AssistantConfig = {
88
+ ...DEFAULT_CONFIG,
89
+ memory: {
90
+ ...DEFAULT_CONFIG.memory,
91
+ v2: { ...DEFAULT_CONFIG.memory.v2, enabled: false },
92
+ },
93
+ };
91
94
 
92
95
  function makeCapabilityNode(content: string, capId: string): NewNode {
93
96
  const now = Date.now();
@@ -407,8 +410,10 @@ describe("loadContextMemory — dual-query capability ranking", () => {
407
410
 
408
411
  // Build a config where capabilityReserve=1 so the ranking code actually
409
412
  // prunes (it only prunes when capabilityNodes.length > capabilityReserve).
413
+ // memory.v2.enabled=false to keep the v1 retrieval path under test.
410
414
  const DUAL_QUERY_CONFIG: AssistantConfig = structuredClone(DEFAULT_CONFIG);
411
415
  DUAL_QUERY_CONFIG.memory.retrieval.injection.contextLoad.capabilityReserve = 1;
416
+ DUAL_QUERY_CONFIG.memory.v2.enabled = false;
412
417
 
413
418
  // Keyword-routed embed: any text that contains a topic keyword returns a
414
419
  // one-hot vector identifying that topic. Anything else falls back to a
@@ -14,7 +14,6 @@ import {
14
14
  } from "../../providers/provider-send-message.js";
15
15
  import type { ContentBlock, ImageContent } from "../../providers/types.js";
16
16
  import { getLogger } from "../../util/logger.js";
17
- import { isMemoryV2ReadActive } from "../context-search/sources/memory-v2.js";
18
17
  import { embedWithRetry } from "../embed.js";
19
18
  import {
20
19
  generateSparseEmbedding,
@@ -426,12 +425,12 @@ interface ContextLoadResult {
426
425
  export async function loadContextMemory(
427
426
  opts: ContextLoadOpts,
428
427
  ): Promise<ContextLoadResult> {
429
- // v2 owns the read path when both gates are on. The v1 collection is in
430
- // active retirement and querying it can OOM-crash Qdrant via a corrupted
431
- // sparse segment, so we skip the embedding work and downstream searches
428
+ // v2 owns the read path when enabled. The v1 collection is in active
429
+ // retirement and querying it can OOM-crash Qdrant via a corrupted sparse
430
+ // segment, so we skip the embedding work and downstream searches
432
431
  // entirely. Caller (`runContextLoad`) sees zero nodes and routes to the
433
432
  // v2 activation pipeline.
434
- if (isMemoryV2ReadActive(opts.config)) {
433
+ if (opts.config.memory.v2.enabled) {
435
434
  return {
436
435
  nodes: [],
437
436
  serendipityNodes: [],
@@ -2,14 +2,13 @@
2
2
  // Memory Tool handlers
3
3
  //
4
4
  // remember: save facts to the PKB (buffer.md + daily archive) under the v1
5
- // path, or to memory/buffer.md + memory/archive/<today>.md when the
6
- // `memory-v2-enabled` feature flag is on.
5
+ // path, or to memory/buffer.md + memory/archive/<today>.md when memory v2 is
6
+ // active.
7
7
  // ---------------------------------------------------------------------------
8
8
 
9
9
  import { appendFileSync, existsSync, mkdirSync } from "node:fs";
10
10
  import { join } from "node:path";
11
11
 
12
- import { isAssistantFeatureFlagEnabled } from "../../config/assistant-feature-flags.js";
13
12
  import type { AssistantConfig } from "../../config/types.js";
14
13
  import { getLogger } from "../../util/logger.js";
15
14
  import { getWorkspaceDir } from "../../util/platform.js";
@@ -46,7 +45,7 @@ export function handleRemember(
46
45
  const now = new Date();
47
46
  const entry = formatRememberEntry(input.content.trim(), now);
48
47
 
49
- if (isAssistantFeatureFlagEnabled("memory-v2-enabled", config)) {
48
+ if (config.memory.v2.enabled) {
50
49
  appendBufferAndArchive({
51
50
  rootDir: join(workspaceDir, "memory"),
52
51
  entry,
@@ -70,6 +69,22 @@ export function handleRemember(
70
69
  return { success: true, message: "Saved to knowledge base." };
71
70
  }
72
71
 
72
+ /**
73
+ * Format `now` as a buffer-entry timestamp (`Mon D, h:mm AM/PM`). Exported so
74
+ * the memory v2 consolidation job can present its cutoff in the same shape
75
+ * the buffer entries use, making the agent's "timestamp ≥ cutoff" comparison
76
+ * unambiguous at minute precision.
77
+ */
78
+ export function formatBufferTimestamp(now: Date): string {
79
+ const month = now.toLocaleString("en-US", { month: "short" });
80
+ const day = now.getDate();
81
+ const hours = now.getHours();
82
+ const minutes = String(now.getMinutes()).padStart(2, "0");
83
+ const ampm = hours >= 12 ? "PM" : "AM";
84
+ const displayHour = hours % 12 || 12;
85
+ return `${month} ${day}, ${displayHour}:${minutes} ${ampm}`;
86
+ }
87
+
73
88
  /**
74
89
  * Build a timestamped bullet entry for `buffer.md` / `archive/<date>.md`.
75
90
  *
@@ -81,13 +96,7 @@ export function handleRemember(
81
96
  * entries identically to user-facing `remember()` calls.
82
97
  */
83
98
  export function formatRememberEntry(content: string, now: Date): string {
84
- const month = now.toLocaleString("en-US", { month: "short" });
85
- const day = now.getDate();
86
- const hours = now.getHours();
87
- const minutes = String(now.getMinutes()).padStart(2, "0");
88
- const ampm = hours >= 12 ? "PM" : "AM";
89
- const displayHour = hours % 12 || 12;
90
- return `- [${month} ${day}, ${displayHour}:${minutes} ${ampm}] ${content}\n`;
99
+ return `- [${formatBufferTimestamp(now)}] ${content}\n`;
91
100
  }
92
101
 
93
102
  /**
@@ -2,6 +2,8 @@
2
2
  // Memory Tool definitions for agentic recall and remember.
3
3
  // ---------------------------------------------------------------------------
4
4
 
5
+ import { isAssistantFeatureFlagEnabled } from "../../config/assistant-feature-flags.js";
6
+ import type { AssistantConfig } from "../../config/types.js";
5
7
  import type { ToolDefinition } from "../../providers/types.js";
6
8
  import {
7
9
  ALL_RECALL_SOURCES,
@@ -12,13 +14,13 @@ import {
12
14
  const RECALL_DEPTHS = ["fast", "standard", "deep"] as const;
13
15
 
14
16
  /**
15
- * Explicit local information search across memory, PKB, conversations, and
17
+ * Explicit local information search across memory, conversations, and
16
18
  * workspace files.
17
19
  */
18
20
  export const graphRecallDefinition: ToolDefinition = {
19
21
  name: "recall",
20
22
  description:
21
- 'Search local information the moment you feel uncertain. Use recall for memory, the personal knowledge base, past conversations, and workspace files — before you guess, before you ask, before you hedge. Auto-injection is incomplete by design; it surfaces patterns, not the specifics you need to answer well. If you catch yourself reaching for "I think", "I believe", "if I remember", "didn\'t we", "last time" — that\'s the signal. Recall. If the user references someone, a place, a decision, a document, or prior work you should be able to find locally — recall. Call it multiple times per conversation if the turn warrants it. Be specific in your query for best results.',
23
+ 'Search local information the moment you feel uncertain. Use recall for memory, past conversations, and workspace files — before you guess, before you ask, before you hedge. Auto-injection is incomplete by design; it surfaces patterns, not the specifics you need to answer well. If you catch yourself reaching for "I think", "I believe", "if I remember", "didn\'t we", "last time" — that\'s the signal. Recall. If the user references someone, a place, a decision, a document, or prior work you should be able to find locally — recall. Call it multiple times per conversation if the turn warrants it. Be specific in your query for best results.',
22
24
  input_schema: {
23
25
  type: "object",
24
26
  properties: {
@@ -34,7 +36,7 @@ export const graphRecallDefinition: ToolDefinition = {
34
36
  enum: [...ALL_RECALL_SOURCES],
35
37
  },
36
38
  description:
37
- "Optional local sources to search. Omit to search memory, PKB, conversations, and workspace files.",
39
+ "Optional local sources to search. Omit to search memory, conversations, and workspace files.",
38
40
  },
39
41
  max_results: {
40
42
  type: "integer",
@@ -53,18 +55,55 @@ export const graphRecallDefinition: ToolDefinition = {
53
55
  },
54
56
  };
55
57
 
58
+ /**
59
+ * Default (high-pressure) `remember` tool description. Used when the
60
+ * `memory-retrospective` feature flag is OFF. The volume-shaming language
61
+ * ("almost every turn", "most frequently used tool") drives aggressive
62
+ * in-conversation capture for users who don't have the retrospective
63
+ * backstop enabled.
64
+ */
65
+ const REMEMBER_DESCRIPTION_DEFAULT =
66
+ "Remember anything concrete: facts, preferences, corrections, plans, felt moments, names, dates, decisions. Default to remembering. Never wait until end of conversation. Corrections are highest priority — call remember the same turn the correction lands. **CRITICAL:** You should be calling remember on almost every turn. This should be your most frequently used tool.";
67
+
68
+ /**
69
+ * Relaxed `remember` tool description used when `memory-retrospective` is
70
+ * ON. The retrospective pass catches what isn't captured in the moment, so
71
+ * the in-conversation pressure eases to a judgment framing: pause when
72
+ * something feels worth marking, not because the volume is required.
73
+ */
74
+ const REMEMBER_DESCRIPTION_RELAXED =
75
+ "Remember anything concrete the user shared: corrections, plans, decisions, felt moments, names, dates, commitments, preferences. Corrections are the highest priority — call `remember` the same turn the correction lands. You don't have to call this on every turn; a retrospective pass reviews the conversation after each message-count / time interval and saves what you didn't capture. Use judgment: pause and remember when something feels worth marking, not because the volume is required.";
76
+
77
+ /**
78
+ * Return the description that should appear in the `remember` tool
79
+ * registration for the current config. The variant is selected by the
80
+ * `memory-retrospective` assistant feature flag. Exposed as a function so
81
+ * the tool registrar can compute the value at registration time without
82
+ * importing config layers into the static definition.
83
+ */
84
+ export function getRememberDescription(config: AssistantConfig): string {
85
+ return isAssistantFeatureFlagEnabled("memory-retrospective", config)
86
+ ? REMEMBER_DESCRIPTION_RELAXED
87
+ : REMEMBER_DESCRIPTION_DEFAULT;
88
+ }
89
+
56
90
  /**
57
91
  * Save a fact to the assistant's knowledge base. The fact is appended to
58
92
  * `buffer.md` (immediately available in the next conversation) and the daily
59
- * archive (permanent date-indexed record). With the `memory-v2-enabled`
60
- * feature flag on, writes go under `memory/`; otherwise they go under
61
- * `pkb/`. Consolidation of the buffer into longer-form storage runs as a
62
- * separate periodic job in both modes.
93
+ * archive (permanent date-indexed record). When `memory.v2.enabled` is true,
94
+ * writes go under `memory/`; otherwise they go under `pkb/`. Consolidation
95
+ * of the buffer into longer-form storage runs as a separate periodic job in
96
+ * both modes.
97
+ *
98
+ * The static `description` field carries the default (high-pressure) text
99
+ * so any direct importer that doesn't go through `getRememberDescription`
100
+ * still gets a valid tool definition. The registered `RememberTool` in
101
+ * `tools/memory/register.ts` overrides this at registration time with the
102
+ * flag-aware variant.
63
103
  */
64
104
  export const graphRememberDefinition: ToolDefinition = {
65
105
  name: "remember",
66
- description:
67
- "Remember anything concrete: facts, preferences, corrections, plans, felt moments, names, dates, decisions. Default to remembering. Never wait until end of conversation. Corrections are highest priority — call remember the same turn the correction lands. **CRITICAL:** You should be calling remember on almost every turn. This should be your most frequently used tool.",
106
+ description: REMEMBER_DESCRIPTION_DEFAULT,
68
107
  input_schema: {
69
108
  type: "object",
70
109
  properties: {
@@ -9,10 +9,11 @@ import { getLogger } from "../util/logger.js";
9
9
  import { enqueueAutoAnalysisIfEnabled } from "./auto-analysis-enqueue.js";
10
10
  import { isAutoAnalysisConversation } from "./auto-analysis-guard.js";
11
11
  import { getMemoryCheckpoint, setMemoryCheckpoint } from "./checkpoints.js";
12
- import { isMemoryV2ReadActive } from "./context-search/sources/memory-v2.js";
13
12
  import { getDb } from "./db-connection.js";
14
13
  import { selectedBackendSupportsMultimodal } from "./embedding-backend.js";
15
14
  import { enqueueMemoryJob, upsertDebouncedJob } from "./jobs-store.js";
15
+ import { isMemoryRetrospectiveConversation } from "./memory-retrospective-enqueue.js";
16
+ import { maybeEnqueueRetrospective } from "./memory-retrospective-trigger-check.js";
16
17
  import {
17
18
  extractMediaBlockMeta,
18
19
  extractTextFromStoredMessageContent,
@@ -190,7 +191,7 @@ export async function indexMessageNow(
190
191
  }
191
192
 
192
193
  const v2Config =
193
- triggerConfig != null && isMemoryV2ReadActive(triggerConfig)
194
+ triggerConfig != null && triggerConfig.memory.v2.enabled
194
195
  ? triggerConfig
195
196
  : null;
196
197
 
@@ -284,6 +285,21 @@ export async function indexMessageNow(
284
285
  });
285
286
  }
286
287
  }
288
+
289
+ // ── Memory retrospective triggers ─────────────────────────────────
290
+ // Independent of auto-analyze: the retrospective is a focused,
291
+ // memory-only pass that re-reads messages since its last successful
292
+ // run and saves what the in-conversation `remember` calls didn't
293
+ // capture. Triggers (interval / message_count) are evaluated by
294
+ // `maybeEnqueueRetrospective`, which also enforces the per-conversation
295
+ // cooldown gate against retry storms. Recursion guard skips the
296
+ // memory-retrospective background conversation itself.
297
+ if (
298
+ triggerConfig != null &&
299
+ !isMemoryRetrospectiveConversation(input.conversationId)
300
+ ) {
301
+ maybeEnqueueRetrospective(input.conversationId, triggerConfig);
302
+ }
287
303
  }
288
304
 
289
305
  // ── Conversation summarization (independent of extraction) ────────
@@ -86,6 +86,10 @@ const upsertCalls: Array<{
86
86
  slug: string;
87
87
  dense: number[];
88
88
  sparse: { indices: number[]; values: number[] };
89
+ summary?: {
90
+ dense: number[];
91
+ sparse: { indices: number[]; values: number[] };
92
+ };
89
93
  updatedAt: number;
90
94
  }> = [];
91
95
 
@@ -96,6 +100,10 @@ mock.module("../../v2/qdrant.js", () => ({
96
100
  slug: string;
97
101
  dense: number[];
98
102
  sparse: { indices: number[]; values: number[] };
103
+ summary?: {
104
+ dense: number[];
105
+ sparse: { indices: number[]; values: number[] };
106
+ };
99
107
  updatedAt: number;
100
108
  }) => {
101
109
  upsertCalls.push(params);
@@ -195,7 +203,7 @@ describe("embedConceptPageJob — happy path", () => {
195
203
  test("reads the page, embeds it, and upserts to the v2 collection", async () => {
196
204
  await writePage(tmpWorkspace, {
197
205
  slug: "alice-prefers-vs-code",
198
- frontmatter: { edges: [], ref_files: [] },
206
+ frontmatter: { edges: [], ref_files: [], ref_urls: [] },
199
207
  body: "Alice prefers VS Code over Vim.\nShe ships at end of day.\n",
200
208
  });
201
209
 
@@ -223,7 +231,7 @@ describe("embedConceptPageJob — happy path", () => {
223
231
  test("populates the SQLite embedding cache row keyed on (concept_page, slug)", async () => {
224
232
  await writePage(tmpWorkspace, {
225
233
  slug: "bob-uses-zsh",
226
- frontmatter: { edges: [], ref_files: [] },
234
+ frontmatter: { edges: [], ref_files: [], ref_urls: [] },
227
235
  body: "Bob uses zsh.\n",
228
236
  });
229
237
 
@@ -242,11 +250,117 @@ describe("embedConceptPageJob — happy path", () => {
242
250
  });
243
251
  });
244
252
 
253
+ describe("embedConceptPageJob — summary embedding", () => {
254
+ test("embeds the summary when present and forwards summary vectors to upsert", async () => {
255
+ await writePage(tmpWorkspace, {
256
+ slug: "summarized-page",
257
+ frontmatter: {
258
+ edges: [],
259
+ ref_files: [],
260
+ ref_urls: [],
261
+ summary: "A short prose summary that retrieval indexes separately.",
262
+ },
263
+ body: "Long-form body content.\n",
264
+ });
265
+
266
+ await embedConceptPageJob(
267
+ makeJob({ slug: "summarized-page" }),
268
+ TEST_CONFIG,
269
+ );
270
+
271
+ // Body and summary are batched into one backend call (saves a round-trip).
272
+ expect(embedWithBackendCalls).toHaveLength(1);
273
+ expect(embedWithBackendCalls[0].inputs).toHaveLength(2);
274
+ expect(upsertCalls).toHaveLength(1);
275
+ const call = upsertCalls[0];
276
+ expect(call.slug).toBe("summarized-page");
277
+ expect(call.dense).toEqual([0.1, 0.2, 0.3, 0.4]);
278
+ expect(call.sparse).toBeDefined();
279
+ expect(call.summary?.dense).toEqual([0.1, 0.2, 0.3, 0.4]);
280
+ expect(call.summary?.sparse).toBeDefined();
281
+ });
282
+
283
+ test("skips summary embedding when the page has no summary in frontmatter", async () => {
284
+ await writePage(tmpWorkspace, {
285
+ slug: "legacy-page",
286
+ frontmatter: { edges: [], ref_files: [], ref_urls: [] },
287
+ body: "Body only — no summary in frontmatter.\n",
288
+ });
289
+
290
+ await embedConceptPageJob(makeJob({ slug: "legacy-page" }), TEST_CONFIG);
291
+
292
+ // Only the body was embedded.
293
+ expect(embedWithBackendCalls).toHaveLength(1);
294
+ expect(upsertCalls).toHaveLength(1);
295
+ const call = upsertCalls[0];
296
+ expect(call.summary).toBeUndefined();
297
+ });
298
+
299
+ test("skips summary embedding when the summary is whitespace-only", async () => {
300
+ // Whitespace-only summaries (` `, `\n`) are equivalent to absent — the
301
+ // embedding backend would reject the empty input downstream anyway.
302
+ await writePage(tmpWorkspace, {
303
+ slug: "whitespace-summary",
304
+ frontmatter: {
305
+ edges: [],
306
+ ref_files: [],
307
+ ref_urls: [],
308
+ summary: " ",
309
+ },
310
+ body: "Body content.\n",
311
+ });
312
+
313
+ await embedConceptPageJob(
314
+ makeJob({ slug: "whitespace-summary" }),
315
+ TEST_CONFIG,
316
+ );
317
+
318
+ expect(embedWithBackendCalls).toHaveLength(1);
319
+ expect(upsertCalls[0].summary).toBeUndefined();
320
+ });
321
+
322
+ test("body and summary cache rows are independent (summary edit doesn't invalidate body)", async () => {
323
+ // Write a page with a summary, run the job to prime caches.
324
+ await writePage(tmpWorkspace, {
325
+ slug: "cached-summary",
326
+ frontmatter: {
327
+ edges: [],
328
+ ref_files: [],
329
+ ref_urls: [],
330
+ summary: "First version of the summary.",
331
+ },
332
+ body: "Stable body that never changes.\n",
333
+ });
334
+ await embedConceptPageJob(makeJob({ slug: "cached-summary" }), TEST_CONFIG);
335
+ // Body + summary batched into a single backend call on first run.
336
+ expect(embedWithBackendCalls).toHaveLength(1);
337
+ expect(embedWithBackendCalls[0].inputs).toHaveLength(2);
338
+
339
+ // Edit only the summary — body stays identical, only the summary text
340
+ // changes. Re-running the job should hit the body cache (no re-embed)
341
+ // but recompute the summary embedding.
342
+ await writePage(tmpWorkspace, {
343
+ slug: "cached-summary",
344
+ frontmatter: {
345
+ edges: [],
346
+ ref_files: [],
347
+ ref_urls: [],
348
+ summary: "Second version of the summary, different wording.",
349
+ },
350
+ body: "Stable body that never changes.\n",
351
+ });
352
+ await embedConceptPageJob(makeJob({ slug: "cached-summary" }), TEST_CONFIG);
353
+ // One additional backend call with only the summary text — body hit the cache.
354
+ expect(embedWithBackendCalls).toHaveLength(2);
355
+ expect(embedWithBackendCalls[1].inputs).toHaveLength(1);
356
+ });
357
+ });
358
+
245
359
  describe("embedConceptPageJob — cache hit", () => {
246
360
  test("reuses the cached dense vector when content hash matches", async () => {
247
361
  await writePage(tmpWorkspace, {
248
362
  slug: "alice-prefers-vs-code",
249
- frontmatter: { edges: [], ref_files: [] },
363
+ frontmatter: { edges: [], ref_files: [], ref_urls: [] },
250
364
  body: "Stable content.\n",
251
365
  });
252
366
 
@@ -271,7 +385,7 @@ describe("embedConceptPageJob — cache hit", () => {
271
385
  test("re-embeds when the body changes (content hash mismatch)", async () => {
272
386
  await writePage(tmpWorkspace, {
273
387
  slug: "alice-prefers-vs-code",
274
- frontmatter: { edges: [], ref_files: [] },
388
+ frontmatter: { edges: [], ref_files: [], ref_urls: [] },
275
389
  body: "First content.\n",
276
390
  });
277
391
  await embedConceptPageJob(
@@ -282,7 +396,7 @@ describe("embedConceptPageJob — cache hit", () => {
282
396
  // Rewrite with different body.
283
397
  await writePage(tmpWorkspace, {
284
398
  slug: "alice-prefers-vs-code",
285
- frontmatter: { edges: [], ref_files: [] },
399
+ frontmatter: { edges: [], ref_files: [], ref_urls: [] },
286
400
  body: "Second content (different).\n",
287
401
  });
288
402
  await embedConceptPageJob(
@@ -337,7 +451,7 @@ describe("enqueueEmbedConceptPageJob", () => {
337
451
  test("round-trip: enqueued job dispatches through embedConceptPageJob", async () => {
338
452
  await writePage(tmpWorkspace, {
339
453
  slug: "round-trip-slug",
340
- frontmatter: { edges: [], ref_files: [] },
454
+ frontmatter: { edges: [], ref_files: [], ref_urls: [] },
341
455
  body: "Round-trip body.\n",
342
456
  });
343
457