@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
@@ -0,0 +1,181 @@
1
+ import { Database } from "bun:sqlite";
2
+ import { describe, expect, test } from "bun:test";
3
+
4
+ import { drizzle } from "drizzle-orm/bun-sqlite";
5
+
6
+ import { getSqliteFrom } from "../db-connection.js";
7
+ import { migrateMessageBookmarks } from "../migrations/242-message-bookmarks.js";
8
+ import * as schema from "../schema.js";
9
+
10
+ interface ColumnRow {
11
+ name: string;
12
+ type: string;
13
+ notnull: number;
14
+ pk: number;
15
+ }
16
+
17
+ interface IndexInfoRow {
18
+ name: string;
19
+ unique: number;
20
+ }
21
+
22
+ interface CountRow {
23
+ n: number;
24
+ }
25
+
26
+ function createTestDb() {
27
+ const sqlite = new Database(":memory:");
28
+ sqlite.exec("PRAGMA journal_mode=WAL");
29
+ sqlite.exec("PRAGMA foreign_keys = ON");
30
+ return drizzle(sqlite, { schema });
31
+ }
32
+
33
+ function bootstrapCheckpointsTable(raw: Database): void {
34
+ raw.exec(/*sql*/ `
35
+ CREATE TABLE IF NOT EXISTS memory_checkpoints (
36
+ key TEXT PRIMARY KEY,
37
+ value TEXT NOT NULL,
38
+ updated_at INTEGER NOT NULL
39
+ )
40
+ `);
41
+ }
42
+
43
+ /**
44
+ * Recreate just enough of the conversations + messages tables to exercise
45
+ * CASCADE behavior. We only need the columns the FKs reference (id) plus
46
+ * NOT NULL columns required to insert a row.
47
+ */
48
+ function bootstrapMessageTables(raw: Database): void {
49
+ raw.exec(/*sql*/ `
50
+ CREATE TABLE IF NOT EXISTS conversations (
51
+ id TEXT PRIMARY KEY,
52
+ title TEXT,
53
+ created_at INTEGER NOT NULL,
54
+ updated_at INTEGER NOT NULL
55
+ )
56
+ `);
57
+ raw.exec(/*sql*/ `
58
+ CREATE TABLE IF NOT EXISTS messages (
59
+ id TEXT PRIMARY KEY,
60
+ conversation_id TEXT NOT NULL REFERENCES conversations(id) ON DELETE CASCADE,
61
+ role TEXT NOT NULL,
62
+ content TEXT NOT NULL,
63
+ created_at INTEGER NOT NULL
64
+ )
65
+ `);
66
+ }
67
+
68
+ function seedConversationAndMessage(
69
+ raw: Database,
70
+ conversationId: string,
71
+ messageId: string,
72
+ ): void {
73
+ const now = Date.now();
74
+ raw
75
+ .query(
76
+ `INSERT INTO conversations (id, title, created_at, updated_at) VALUES (?, ?, ?, ?)`,
77
+ )
78
+ .run(conversationId, "Example", now, now);
79
+ raw
80
+ .query(
81
+ `INSERT INTO messages (id, conversation_id, role, content, created_at) VALUES (?, ?, ?, ?, ?)`,
82
+ )
83
+ .run(messageId, conversationId, "user", "hello", now);
84
+ }
85
+
86
+ function insertBookmark(
87
+ raw: Database,
88
+ id: string,
89
+ messageId: string,
90
+ conversationId: string,
91
+ ): void {
92
+ raw
93
+ .query(
94
+ `INSERT INTO message_bookmarks (id, message_id, conversation_id, created_at) VALUES (?, ?, ?, ?)`,
95
+ )
96
+ .run(id, messageId, conversationId, Date.now());
97
+ }
98
+
99
+ function countBookmarks(raw: Database): number {
100
+ const row = raw
101
+ .query(`SELECT COUNT(*) AS n FROM message_bookmarks`)
102
+ .get() as CountRow | null;
103
+ return row?.n ?? 0;
104
+ }
105
+
106
+ describe("message_bookmarks schema migration", () => {
107
+ test("creates table with expected columns and indexes", () => {
108
+ const db = createTestDb();
109
+ const raw = getSqliteFrom(db);
110
+ bootstrapCheckpointsTable(raw);
111
+ bootstrapMessageTables(raw);
112
+
113
+ migrateMessageBookmarks(db);
114
+
115
+ const columns = raw
116
+ .query(`PRAGMA table_info(message_bookmarks)`)
117
+ .all() as ColumnRow[];
118
+ const byName = new Map(columns.map((c) => [c.name, c]));
119
+ expect(byName.get("id")?.pk).toBe(1);
120
+ expect(byName.get("id")?.type).toBe("TEXT");
121
+ expect(byName.get("message_id")?.notnull).toBe(1);
122
+ expect(byName.get("conversation_id")?.notnull).toBe(1);
123
+ expect(byName.get("created_at")?.notnull).toBe(1);
124
+ expect(byName.get("created_at")?.type).toBe("INTEGER");
125
+
126
+ const indexes = raw
127
+ .query(`PRAGMA index_list(message_bookmarks)`)
128
+ .all() as IndexInfoRow[];
129
+ const indexByName = new Map(indexes.map((i) => [i.name, i]));
130
+ const uniqIndex = indexByName.get("message_bookmarks_message_id_uniq");
131
+ expect(uniqIndex).toBeDefined();
132
+ expect(uniqIndex?.unique).toBe(1);
133
+ expect(indexByName.get("message_bookmarks_created_at_idx")).toBeDefined();
134
+ });
135
+
136
+ test("CASCADE removes bookmark when parent message is deleted", () => {
137
+ const db = createTestDb();
138
+ const raw = getSqliteFrom(db);
139
+ bootstrapCheckpointsTable(raw);
140
+ bootstrapMessageTables(raw);
141
+ migrateMessageBookmarks(db);
142
+
143
+ seedConversationAndMessage(raw, "conv-1", "msg-1");
144
+ insertBookmark(raw, "bm-1", "msg-1", "conv-1");
145
+ expect(countBookmarks(raw)).toBe(1);
146
+
147
+ raw.query(`DELETE FROM messages WHERE id = ?`).run("msg-1");
148
+ expect(countBookmarks(raw)).toBe(0);
149
+ });
150
+
151
+ test("CASCADE removes bookmark when parent conversation is deleted", () => {
152
+ const db = createTestDb();
153
+ const raw = getSqliteFrom(db);
154
+ bootstrapCheckpointsTable(raw);
155
+ bootstrapMessageTables(raw);
156
+ migrateMessageBookmarks(db);
157
+
158
+ seedConversationAndMessage(raw, "conv-2", "msg-2");
159
+ insertBookmark(raw, "bm-2", "msg-2", "conv-2");
160
+ expect(countBookmarks(raw)).toBe(1);
161
+
162
+ raw.query(`DELETE FROM conversations WHERE id = ?`).run("conv-2");
163
+ // Deleting the conversation cascades to messages, which cascades to
164
+ // bookmarks. Either FK alone would suffice; both fire here.
165
+ expect(countBookmarks(raw)).toBe(0);
166
+ });
167
+
168
+ test("unique constraint on message_id rejects a second bookmark", () => {
169
+ const db = createTestDb();
170
+ const raw = getSqliteFrom(db);
171
+ bootstrapCheckpointsTable(raw);
172
+ bootstrapMessageTables(raw);
173
+ migrateMessageBookmarks(db);
174
+
175
+ seedConversationAndMessage(raw, "conv-3", "msg-3");
176
+ insertBookmark(raw, "bm-3a", "msg-3", "conv-3");
177
+
178
+ expect(() => insertBookmark(raw, "bm-3b", "msg-3", "conv-3")).toThrow();
179
+ expect(countBookmarks(raw)).toBe(1);
180
+ });
181
+ });
@@ -0,0 +1,36 @@
1
+ import { describe, expect, test } from "bun:test";
2
+
3
+ import { isBackgroundConversationType } from "../conversation-types.js";
4
+
5
+ describe("isBackgroundConversationType", () => {
6
+ test("returns true for background", () => {
7
+ expect(isBackgroundConversationType("background")).toBe(true);
8
+ });
9
+
10
+ test("returns true for scheduled", () => {
11
+ expect(isBackgroundConversationType("scheduled")).toBe(true);
12
+ });
13
+
14
+ test("returns false for standard", () => {
15
+ expect(isBackgroundConversationType("standard")).toBe(false);
16
+ });
17
+
18
+ test("returns false for null", () => {
19
+ expect(isBackgroundConversationType(null)).toBe(false);
20
+ });
21
+
22
+ test("returns false for undefined", () => {
23
+ expect(isBackgroundConversationType(undefined)).toBe(false);
24
+ });
25
+
26
+ test("returns false for empty string", () => {
27
+ expect(isBackgroundConversationType("")).toBe(false);
28
+ });
29
+
30
+ test.each(["chat", "foo", "BACKGROUND", "Scheduled", " background "])(
31
+ "returns false for unknown string %p",
32
+ (value) => {
33
+ expect(isBackgroundConversationType(value)).toBe(false);
34
+ },
35
+ );
36
+ });
@@ -0,0 +1,130 @@
1
+ import { beforeEach, describe, expect, mock, test } from "bun:test";
2
+
3
+ import { eq } from "drizzle-orm";
4
+
5
+ mock.module("../../util/logger.js", () => ({
6
+ getLogger: () =>
7
+ new Proxy({} as Record<string, unknown>, {
8
+ get: () => () => {},
9
+ }),
10
+ }));
11
+
12
+ import {
13
+ createConversation,
14
+ findMostRecentRetrospectiveFor,
15
+ } from "../conversation-crud.js";
16
+ import { getDb } from "../db-connection.js";
17
+ import { initializeDb } from "../db-init.js";
18
+ import { MEMORY_RETROSPECTIVE_SOURCE } from "../memory-retrospective-constants.js";
19
+ import { conversations } from "../schema.js";
20
+
21
+ initializeDb();
22
+
23
+ function resetTables(): void {
24
+ const db = getDb();
25
+ db.run(`DELETE FROM messages`);
26
+ db.run(`DELETE FROM conversations`);
27
+ }
28
+
29
+ function setForkParent(conversationId: string, parentId: string): void {
30
+ const db = getDb();
31
+ db.update(conversations)
32
+ .set({ forkParentConversationId: parentId })
33
+ .where(eq(conversations.id, conversationId))
34
+ .run();
35
+ }
36
+
37
+ function setCreatedAt(conversationId: string, createdAt: number): void {
38
+ const db = getDb();
39
+ db.update(conversations)
40
+ .set({ createdAt })
41
+ .where(eq(conversations.id, conversationId))
42
+ .run();
43
+ }
44
+
45
+ function createRetro(parentId: string, createdAt: number): { id: string } {
46
+ const retro = createConversation({
47
+ title: "retro",
48
+ source: MEMORY_RETROSPECTIVE_SOURCE,
49
+ });
50
+ setForkParent(retro.id, parentId);
51
+ setCreatedAt(retro.id, createdAt);
52
+ return { id: retro.id };
53
+ }
54
+
55
+ describe("findMostRecentRetrospectiveFor", () => {
56
+ beforeEach(() => {
57
+ resetTables();
58
+ });
59
+
60
+ test("returns null when no retrospective exists anywhere in the fork chain", () => {
61
+ const conv = createConversation("conv");
62
+ expect(findMostRecentRetrospectiveFor(conv.id)).toBeNull();
63
+ });
64
+
65
+ test("returns a direct retrospective rooted at the conversation", () => {
66
+ const conv = createConversation("conv");
67
+ const retro = createRetro(conv.id, 1_000);
68
+
69
+ expect(findMostRecentRetrospectiveFor(conv.id)).toEqual({ id: retro.id });
70
+ });
71
+
72
+ test("returns the most recently created retrospective when multiple exist at the same level", () => {
73
+ const conv = createConversation("conv");
74
+ createRetro(conv.id, 1_000);
75
+ const newer = createRetro(conv.id, 2_000);
76
+ createRetro(conv.id, 500);
77
+
78
+ expect(findMostRecentRetrospectiveFor(conv.id)).toEqual({ id: newer.id });
79
+ });
80
+
81
+ test("walks up the fork chain when the current conversation has no retros", () => {
82
+ const parent = createConversation("parent");
83
+ const parentRetro = createRetro(parent.id, 1_000);
84
+
85
+ const fork = createConversation("fork");
86
+ setForkParent(fork.id, parent.id);
87
+
88
+ expect(findMostRecentRetrospectiveFor(fork.id)).toEqual({
89
+ id: parentRetro.id,
90
+ });
91
+ });
92
+
93
+ test("prefers the fork's own retros over the parent's", () => {
94
+ const parent = createConversation("parent");
95
+ createRetro(parent.id, 5_000);
96
+
97
+ const fork = createConversation("fork");
98
+ setForkParent(fork.id, parent.id);
99
+ const forkRetro = createRetro(fork.id, 1_000);
100
+
101
+ expect(findMostRecentRetrospectiveFor(fork.id)).toEqual({
102
+ id: forkRetro.id,
103
+ });
104
+ });
105
+
106
+ test("walks multiple levels (fork-of-fork) until it finds a retro", () => {
107
+ const grandparent = createConversation("grandparent");
108
+ const grandparentRetro = createRetro(grandparent.id, 1_000);
109
+
110
+ const parent = createConversation("parent");
111
+ setForkParent(parent.id, grandparent.id);
112
+
113
+ const fork = createConversation("fork");
114
+ setForkParent(fork.id, parent.id);
115
+
116
+ expect(findMostRecentRetrospectiveFor(fork.id)).toEqual({
117
+ id: grandparentRetro.id,
118
+ });
119
+ });
120
+
121
+ test("returns null when the entire fork chain has no retros", () => {
122
+ const grandparent = createConversation("grandparent");
123
+ const parent = createConversation("parent");
124
+ setForkParent(parent.id, grandparent.id);
125
+ const fork = createConversation("fork");
126
+ setForkParent(fork.id, parent.id);
127
+
128
+ expect(findMostRecentRetrospectiveFor(fork.id)).toBeNull();
129
+ });
130
+ });
@@ -1,19 +1,16 @@
1
1
  /**
2
2
  * Tests for v1/v2 mutual exclusion in `maybeEnqueueGraphMaintenanceJobs`.
3
3
  *
4
- * The schedule is now mutually exclusive: when both the `memory-v2-enabled`
5
- * flag and `memory.v2.enabled` config are on, only `memory_v2_consolidate`
6
- * is scheduled; otherwise the four v1 entries (decay, consolidate,
7
- * pattern_scan, narrative) fire and the v2 entry does not.
4
+ * The schedule is mutually exclusive: when `memory.v2.enabled` is true,
5
+ * only `memory_v2_consolidate` is scheduled; otherwise the four v1
6
+ * entries (decay, consolidate, pattern_scan, narrative) fire and the v2
7
+ * entry does not.
8
8
  *
9
9
  * Coverage:
10
- * - Flag off → only v1 entries fire (no `memory_v2_consolidate`).
11
- * - Flag on + config off → only v1 entries fire.
12
- * - Flag on + config on, no prior checkpoint only the v2 entry fires.
13
- * - Flag on + config on, recent checkpoint → no v2 row (interval not
14
- * yet elapsed).
15
- * - Flag on + config on, stale checkpoint → v2 row enqueued, checkpoint
16
- * refreshed.
10
+ * - Config off → only v1 entries fire (no `memory_v2_consolidate`).
11
+ * - Config on, no prior checkpoint → only the v2 entry fires.
12
+ * - Config on, recent checkpoint no v2 row (interval not yet elapsed).
13
+ * - Config on, stale checkpoint → v2 row enqueued, checkpoint refreshed.
17
14
  *
18
15
  * The sweep job is intentionally NOT scheduled here: it is wired into the
19
16
  * `graph_extract` debounce in `indexer.ts`. Those triggers are covered by
@@ -27,7 +24,6 @@ import { tmpdir } from "node:os";
27
24
  import { join } from "node:path";
28
25
  import {
29
26
  afterAll,
30
- afterEach,
31
27
  beforeAll,
32
28
  beforeEach,
33
29
  describe,
@@ -69,8 +65,6 @@ const { getDb } = await import("../db-connection.js");
69
65
  const { initializeDb } = await import("../db-init.js");
70
66
  const { resetTestTables } = await import("../raw-query.js");
71
67
  const { memoryJobs } = await import("../schema.js");
72
- const { _setOverridesForTesting } =
73
- await import("../../config/assistant-feature-flags.js");
74
68
  const { applyNestedDefaults } = await import("../../config/loader.js");
75
69
  const { setMemoryCheckpoint, deleteMemoryCheckpoint } =
76
70
  await import("../checkpoints.js");
@@ -111,26 +105,10 @@ beforeEach(() => {
111
105
  resetTestTables("memory_jobs", "memory_checkpoints");
112
106
  });
113
107
 
114
- afterEach(() => {
115
- _setOverridesForTesting({});
116
- });
117
-
118
108
  // ---------------------------------------------------------------------------
119
109
 
120
110
  describe("maybeEnqueueGraphMaintenanceJobs — memory v2 consolidation", () => {
121
- test("does not enqueue consolidate when memory-v2-enabled flag is off", () => {
122
- _setOverridesForTesting({ "memory-v2-enabled": false });
123
- const config = buildConfig({ v2Enabled: true, intervalHours: 1 });
124
-
125
- // Force the interval to look elapsed. If the gate failed open, this
126
- // would be enough to enqueue a job.
127
- maybeEnqueueGraphMaintenanceJobs(config, Date.now());
128
-
129
- expect(countPendingJobs("memory_v2_consolidate")).toBe(0);
130
- });
131
-
132
111
  test("does not enqueue consolidate when config.memory.v2.enabled is off", () => {
133
- _setOverridesForTesting({ "memory-v2-enabled": true });
134
112
  const config = buildConfig({ v2Enabled: false, intervalHours: 1 });
135
113
 
136
114
  maybeEnqueueGraphMaintenanceJobs(config, Date.now());
@@ -138,8 +116,7 @@ describe("maybeEnqueueGraphMaintenanceJobs — memory v2 consolidation", () => {
138
116
  expect(countPendingJobs("memory_v2_consolidate")).toBe(0);
139
117
  });
140
118
 
141
- test("enqueues consolidate when both gates are on and no checkpoint exists", () => {
142
- _setOverridesForTesting({ "memory-v2-enabled": true });
119
+ test("enqueues consolidate when v2 is on and no checkpoint exists", () => {
143
120
  const config = buildConfig({ v2Enabled: true, intervalHours: 1 });
144
121
 
145
122
  maybeEnqueueGraphMaintenanceJobs(config, Date.now());
@@ -153,7 +130,6 @@ describe("maybeEnqueueGraphMaintenanceJobs — memory v2 consolidation", () => {
153
130
  });
154
131
 
155
132
  test("does not enqueue consolidate before the interval has elapsed", () => {
156
- _setOverridesForTesting({ "memory-v2-enabled": true });
157
133
  const config = buildConfig({ v2Enabled: true, intervalHours: 1 });
158
134
 
159
135
  const now = Date.now();
@@ -166,7 +142,6 @@ describe("maybeEnqueueGraphMaintenanceJobs — memory v2 consolidation", () => {
166
142
  });
167
143
 
168
144
  test("enqueues consolidate again once the interval elapses", () => {
169
- _setOverridesForTesting({ "memory-v2-enabled": true });
170
145
  const config = buildConfig({ v2Enabled: true, intervalHours: 1 });
171
146
 
172
147
  const now = Date.now();
@@ -182,7 +157,6 @@ describe("maybeEnqueueGraphMaintenanceJobs — memory v2 consolidation", () => {
182
157
  });
183
158
 
184
159
  test("respects a custom consolidation_interval_hours value", () => {
185
- _setOverridesForTesting({ "memory-v2-enabled": true });
186
160
  const config = buildConfig({ v2Enabled: true, intervalHours: 6 });
187
161
 
188
162
  const now = Date.now();
@@ -206,7 +180,6 @@ describe("maybeEnqueueGraphMaintenanceJobs — memory v2 consolidation", () => {
206
180
  });
207
181
 
208
182
  test("v1 maintenance entries are suppressed when v2 is active", () => {
209
- _setOverridesForTesting({ "memory-v2-enabled": true });
210
183
  const config = buildConfig({ v2Enabled: true, intervalHours: 1 });
211
184
 
212
185
  // No checkpoints set — every entry would be due if it were scheduled.
@@ -225,27 +198,7 @@ describe("maybeEnqueueGraphMaintenanceJobs — memory v2 consolidation", () => {
225
198
  expect(countPendingJobs("memory_v2_consolidate")).toBe(1);
226
199
  });
227
200
 
228
- test("flag-off path fires v1 entries and does not enqueue v2", () => {
229
- _setOverridesForTesting({ "memory-v2-enabled": false });
230
- const config = buildConfig({ v2Enabled: true, intervalHours: 1 });
231
-
232
- deleteMemoryCheckpoint("graph_maintenance:decay:last_run");
233
- deleteMemoryCheckpoint("graph_maintenance:consolidate:last_run");
234
- deleteMemoryCheckpoint("graph_maintenance:pattern_scan:last_run");
235
- deleteMemoryCheckpoint("graph_maintenance:narrative:last_run");
236
- deleteMemoryCheckpoint(CONSOLIDATE_CHECKPOINT_KEY);
237
-
238
- maybeEnqueueGraphMaintenanceJobs(config, Date.now());
239
-
240
- expect(countPendingJobs("graph_decay")).toBe(1);
241
- expect(countPendingJobs("graph_consolidate")).toBe(1);
242
- expect(countPendingJobs("graph_pattern_scan")).toBe(1);
243
- expect(countPendingJobs("graph_narrative_refine")).toBe(1);
244
- expect(countPendingJobs("memory_v2_consolidate")).toBe(0);
245
- });
246
-
247
- test("config-gate-off path fires v1 entries and does not enqueue v2", () => {
248
- _setOverridesForTesting({ "memory-v2-enabled": true });
201
+ test("v2-off path fires v1 entries and does not enqueue v2", () => {
249
202
  const config = buildConfig({ v2Enabled: false, intervalHours: 1 });
250
203
 
251
204
  deleteMemoryCheckpoint("graph_maintenance:decay:last_run");
@@ -0,0 +1,177 @@
1
+ import { beforeEach, describe, expect, mock, test } from "bun:test";
2
+
3
+ mock.module("../../util/logger.js", () => ({
4
+ getLogger: () =>
5
+ new Proxy({} as Record<string, unknown>, {
6
+ get: () => () => {},
7
+ }),
8
+ }));
9
+
10
+ // ---------------------------------------------------------------------------
11
+ // Mock state — reset between tests.
12
+ // ---------------------------------------------------------------------------
13
+
14
+ let flagEnabled = true;
15
+ let sourceTag: string | null = null;
16
+ let getConfigThrows = false;
17
+ const upsertCalls: Array<{
18
+ payload: { conversationId: string };
19
+ runAfter: number;
20
+ }> = [];
21
+
22
+ mock.module("../../config/loader.js", () => ({
23
+ getConfig: () => {
24
+ if (getConfigThrows) throw new Error("boom");
25
+ return {};
26
+ },
27
+ }));
28
+
29
+ mock.module("../../config/assistant-feature-flags.js", () => ({
30
+ isAssistantFeatureFlagEnabled: (_key: string, _config: unknown) =>
31
+ flagEnabled,
32
+ }));
33
+
34
+ mock.module("../conversation-crud.js", () => ({
35
+ getConversationSource: (_id: string) => sourceTag,
36
+ }));
37
+
38
+ mock.module("../jobs-store.js", () => ({
39
+ upsertMemoryRetrospectiveJob: (
40
+ payload: { conversationId: string },
41
+ runAfter: number,
42
+ ) => {
43
+ upsertCalls.push({ payload, runAfter });
44
+ },
45
+ }));
46
+
47
+ mock.module("../../runtime/actor-trust-resolver.js", () => ({
48
+ isUntrustedTrustClass: (trustClass: string | undefined) =>
49
+ trustClass === "trusted_contact" ||
50
+ trustClass === "unknown" ||
51
+ trustClass === undefined,
52
+ }));
53
+
54
+ import {
55
+ enqueueMemoryRetrospectiveIfEnabled,
56
+ enqueueMemoryRetrospectiveOnCompaction,
57
+ isMemoryRetrospectiveConversation,
58
+ } from "../memory-retrospective-enqueue.js";
59
+
60
+ describe("enqueueMemoryRetrospectiveIfEnabled", () => {
61
+ beforeEach(() => {
62
+ flagEnabled = true;
63
+ sourceTag = null;
64
+ getConfigThrows = false;
65
+ upsertCalls.length = 0;
66
+ });
67
+
68
+ test("flag off — no upsert for any trigger", () => {
69
+ flagEnabled = false;
70
+ for (const trigger of [
71
+ "interval",
72
+ "message_count",
73
+ "compaction",
74
+ "lifecycle",
75
+ ] as const) {
76
+ enqueueMemoryRetrospectiveIfEnabled({ conversationId: "c1", trigger });
77
+ }
78
+ expect(upsertCalls).toHaveLength(0);
79
+ });
80
+
81
+ test("flag on, standard source — interval trigger enqueues with runAfter ≈ now", () => {
82
+ const before = Date.now();
83
+ enqueueMemoryRetrospectiveIfEnabled({
84
+ conversationId: "c1",
85
+ trigger: "interval",
86
+ });
87
+ const after = Date.now();
88
+
89
+ expect(upsertCalls).toHaveLength(1);
90
+ const call = upsertCalls[0]!;
91
+ expect(call.payload).toEqual({ conversationId: "c1" });
92
+ expect(call.runAfter).toBeGreaterThanOrEqual(before);
93
+ expect(call.runAfter).toBeLessThanOrEqual(after);
94
+ });
95
+
96
+ test("compaction trigger applies the small debounce", () => {
97
+ const before = Date.now();
98
+ enqueueMemoryRetrospectiveIfEnabled({
99
+ conversationId: "c1",
100
+ trigger: "compaction",
101
+ });
102
+
103
+ expect(upsertCalls).toHaveLength(1);
104
+ const call = upsertCalls[0]!;
105
+ expect(call.runAfter).toBeGreaterThan(before + 100);
106
+ });
107
+
108
+ test("recursion guard — source = 'memory-retrospective' skips enqueue", () => {
109
+ sourceTag = "memory-retrospective";
110
+ enqueueMemoryRetrospectiveIfEnabled({
111
+ conversationId: "c1",
112
+ trigger: "interval",
113
+ });
114
+ expect(upsertCalls).toHaveLength(0);
115
+ });
116
+
117
+ test("getConfig throws — no enqueue, no propagation", () => {
118
+ getConfigThrows = true;
119
+ expect(() =>
120
+ enqueueMemoryRetrospectiveIfEnabled({
121
+ conversationId: "c1",
122
+ trigger: "interval",
123
+ }),
124
+ ).not.toThrow();
125
+ expect(upsertCalls).toHaveLength(0);
126
+ });
127
+ });
128
+
129
+ describe("isMemoryRetrospectiveConversation", () => {
130
+ beforeEach(() => {
131
+ sourceTag = null;
132
+ });
133
+
134
+ test("returns true only for the matching source tag", () => {
135
+ sourceTag = "memory-retrospective";
136
+ expect(isMemoryRetrospectiveConversation("c1")).toBe(true);
137
+ });
138
+
139
+ test("returns false for other source tags", () => {
140
+ sourceTag = "auto-analysis";
141
+ expect(isMemoryRetrospectiveConversation("c1")).toBe(false);
142
+ });
143
+
144
+ test("returns false when source is null", () => {
145
+ sourceTag = null;
146
+ expect(isMemoryRetrospectiveConversation("c1")).toBe(false);
147
+ });
148
+ });
149
+
150
+ describe("enqueueMemoryRetrospectiveOnCompaction", () => {
151
+ beforeEach(() => {
152
+ flagEnabled = true;
153
+ sourceTag = null;
154
+ getConfigThrows = false;
155
+ upsertCalls.length = 0;
156
+ });
157
+
158
+ test("untrusted trust class — no enqueue", () => {
159
+ enqueueMemoryRetrospectiveOnCompaction("c1", "unknown");
160
+ enqueueMemoryRetrospectiveOnCompaction("c1", "trusted_contact");
161
+ enqueueMemoryRetrospectiveOnCompaction("c1", undefined);
162
+ expect(upsertCalls).toHaveLength(0);
163
+ });
164
+
165
+ test("guardian trust + flag on — enqueues with compaction debounce", () => {
166
+ const before = Date.now();
167
+ enqueueMemoryRetrospectiveOnCompaction("c1", "guardian");
168
+ expect(upsertCalls).toHaveLength(1);
169
+ expect(upsertCalls[0]!.runAfter).toBeGreaterThan(before + 100);
170
+ });
171
+
172
+ test("guardian trust + flag off — no enqueue", () => {
173
+ flagEnabled = false;
174
+ enqueueMemoryRetrospectiveOnCompaction("c1", "guardian");
175
+ expect(upsertCalls).toHaveLength(0);
176
+ });
177
+ });