@vellumai/assistant 0.8.4 → 0.8.6

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 (802) hide show
  1. package/AGENTS.md +33 -1
  2. package/ARCHITECTURE.md +3 -3
  3. package/bunfig.toml +6 -1
  4. package/docs/browser-use-architecture-phase2.md +1 -1
  5. package/docs/credential-execution-service.md +6 -6
  6. package/docs/plugins.md +4 -3
  7. package/knip.json +2 -1
  8. package/node_modules/@vellumai/skill-host-contracts/src/client.ts +12 -13
  9. package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +4 -1
  10. package/node_modules/@vellumai/skill-host-contracts/src/tool-types.ts +16 -14
  11. package/openapi.yaml +2748 -216
  12. package/package.json +1 -1
  13. package/src/__tests__/actor-token-service.test.ts +3 -2
  14. package/src/__tests__/agent-loop-exit-reason.test.ts +102 -9
  15. package/src/__tests__/agent-loop-override-profile.test.ts +2 -1
  16. package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +1 -0
  17. package/src/__tests__/agent-wake-override-profile.test.ts +1 -0
  18. package/src/__tests__/always-loaded-tools-guard.test.ts +2 -2
  19. package/src/__tests__/annotate-risk-options.test.ts +1 -0
  20. package/src/__tests__/anthropic-provider.test.ts +34 -37
  21. package/src/__tests__/approval-cascade.test.ts +1 -0
  22. package/src/__tests__/approval-routes-http.test.ts +9 -13
  23. package/src/__tests__/assert-not-live-db.ts +79 -0
  24. package/src/__tests__/assistant-event-hub-self-exclusion.test.ts +293 -0
  25. package/src/__tests__/assistant-feature-flags-integration.test.ts +12 -28
  26. package/src/__tests__/audit-log-rotation.test.ts +72 -18
  27. package/src/__tests__/auto-analysis-end-to-end.test.ts +6 -6
  28. package/src/__tests__/background-workers-disk-pressure.test.ts +8 -11
  29. package/src/__tests__/browser-skill-endstate.test.ts +3 -3
  30. package/src/__tests__/btw-routes.test.ts +5 -5
  31. package/src/__tests__/call-controller.test.ts +3 -3
  32. package/src/__tests__/cancel-resolves-conversation-key.test.ts +1 -1
  33. package/src/__tests__/channel-approval-routes.test.ts +3 -2
  34. package/src/__tests__/channel-guardian.test.ts +6 -5
  35. package/src/__tests__/channel-readiness-slack-remote.test.ts +175 -0
  36. package/src/__tests__/channel-reply-delivery.test.ts +35 -0
  37. package/src/__tests__/channel-retry-sweep.test.ts +320 -3
  38. package/src/__tests__/checker.test.ts +18 -27
  39. package/src/__tests__/compaction-events.test.ts +2 -0
  40. package/src/__tests__/compaction-trail-store.test.ts +264 -0
  41. package/src/__tests__/compactor-call-site-logging.test.ts +215 -0
  42. package/src/__tests__/compactor-preserved-tail-count.test.ts +1 -0
  43. package/src/__tests__/computer-use-skill-manifest-regression.test.ts +12 -16
  44. package/src/__tests__/computer-use-tools.test.ts +14 -18
  45. package/src/__tests__/config-loader-backfill.test.ts +13 -28
  46. package/src/__tests__/config-loader-corrupt.test.ts +5 -5
  47. package/src/__tests__/config-loader-platform-defaults.test.ts +93 -26
  48. package/src/__tests__/config-loader-quarantine-bulletin.test.ts +3 -3
  49. package/src/__tests__/config-managed-gemini-defaults.test.ts +3 -4
  50. package/src/__tests__/config-schema.test.ts +10 -10
  51. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +0 -1
  52. package/src/__tests__/connection-model-compat.test.ts +83 -0
  53. package/src/__tests__/contacts-tools.test.ts +3 -2
  54. package/src/__tests__/context-token-estimator.test.ts +22 -0
  55. package/src/__tests__/conversation-abort-tool-results.test.ts +5 -0
  56. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +2 -1
  57. package/src/__tests__/conversation-agent-loop-handlers-max-tokens.test.ts +55 -0
  58. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +2 -1
  59. package/src/__tests__/conversation-agent-loop-overflow.test.ts +231 -2
  60. package/src/__tests__/conversation-agent-loop.test.ts +581 -54
  61. package/src/__tests__/conversation-analysis-routes.test.ts +1 -0
  62. package/src/__tests__/conversation-app-control-instantiation.test.ts +31 -24
  63. package/src/__tests__/conversation-app-control-lifecycle.test.ts +1 -0
  64. package/src/__tests__/conversation-attention-store.test.ts +101 -0
  65. package/src/__tests__/conversation-attention-telegram.test.ts +3 -2
  66. package/src/__tests__/conversation-clear-safety.test.ts +25 -25
  67. package/src/__tests__/conversation-confirmation-signals.test.ts +1 -0
  68. package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +1 -1
  69. package/src/__tests__/conversation-disk-view-integration.test.ts +2 -2
  70. package/src/__tests__/conversation-error.test.ts +61 -0
  71. package/src/__tests__/conversation-fork-crud.test.ts +239 -15
  72. package/src/__tests__/conversation-fork-route.test.ts +3 -2
  73. package/src/__tests__/conversation-history-web-search.test.ts +1 -0
  74. package/src/__tests__/conversation-inference-profile-list.test.ts +3 -2
  75. package/src/__tests__/conversation-inference-profile-route.test.ts +3 -2
  76. package/src/__tests__/conversation-lifecycle.test.ts +53 -11
  77. package/src/__tests__/conversation-list-source.test.ts +3 -2
  78. package/src/__tests__/conversation-load-history-repair.test.ts +2 -1
  79. package/src/__tests__/{conversation-load-cleaned-at.test.ts → conversation-load-history-stripped.test.ts} +14 -13
  80. package/src/__tests__/conversation-pairing.test.ts +53 -0
  81. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +26 -7
  82. package/src/__tests__/conversation-process-callsite.test.ts +1 -0
  83. package/src/__tests__/conversation-provider-retry-repair.test.ts +6 -0
  84. package/src/__tests__/conversation-queue.test.ts +333 -291
  85. package/src/__tests__/conversation-routes-disk-view.test.ts +112 -18
  86. package/src/__tests__/conversation-routes-guardian-reply.test.ts +33 -8
  87. package/src/__tests__/conversation-routes-slash-commands.test.ts +68 -2
  88. package/src/__tests__/conversation-runtime-assembly.test.ts +78 -0
  89. package/src/__tests__/conversation-skill-tools.test.ts +40 -147
  90. package/src/__tests__/conversation-slash-queue.test.ts +84 -32
  91. package/src/__tests__/conversation-slash-unknown.test.ts +5 -0
  92. package/src/__tests__/conversation-speed-override.test.ts +1 -0
  93. package/src/__tests__/conversation-store.test.ts +1 -1
  94. package/src/__tests__/conversation-surfaces-action-delivery.test.ts +46 -0
  95. package/src/__tests__/conversation-surfaces-data-persist.test.ts +1 -0
  96. package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +6 -3
  97. package/src/__tests__/conversation-surfaces-standalone.test.ts +6 -3
  98. package/src/__tests__/conversation-surfaces-state-update.test.ts +3 -3
  99. package/src/__tests__/conversation-surfaces-table-action.test.ts +7 -17
  100. package/src/__tests__/conversation-sync-tags.test.ts +218 -35
  101. package/src/__tests__/conversation-title-service.test.ts +1 -0
  102. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +30 -0
  103. package/src/__tests__/conversation-usage.test.ts +1 -0
  104. package/src/__tests__/conversation-workspace-cache-state.test.ts +2 -0
  105. package/src/__tests__/conversation-workspace-injection.test.ts +6 -1
  106. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +6 -1
  107. package/src/__tests__/credential-broker-browser-fill.test.ts +3 -3
  108. package/src/__tests__/credential-broker-server-use.test.ts +5 -5
  109. package/src/__tests__/credential-execution-client.test.ts +72 -1
  110. package/src/__tests__/credential-execution-feature-gates.test.ts +19 -19
  111. package/src/__tests__/credential-execution-tools.test.ts +6 -6
  112. package/src/__tests__/credential-health-service.test.ts +252 -3
  113. package/src/__tests__/credential-security-invariants.test.ts +6 -5
  114. package/src/__tests__/credential-vault-unit.test.ts +21 -21
  115. package/src/__tests__/credential-vault.test.ts +5 -5
  116. package/src/__tests__/cross-provider-web-search.test.ts +56 -2
  117. package/src/__tests__/db-connection-isolation.test.ts +7 -6
  118. package/src/__tests__/db-conversation-fork-lineage-migration.test.ts +8 -10
  119. package/src/__tests__/db-conversation-inference-profile-migration.test.ts +7 -10
  120. package/src/__tests__/db-llm-request-log-provider-migration.test.ts +9 -15
  121. package/src/__tests__/db-test-helpers.ts +58 -0
  122. package/src/__tests__/disk-pressure-guard.test.ts +58 -41
  123. package/src/__tests__/disk-pressure-lifecycle.test.ts +13 -10
  124. package/src/__tests__/disk-pressure-routes.test.ts +0 -33
  125. package/src/__tests__/disk-pressure-tools.test.ts +0 -4
  126. package/src/__tests__/dm-persistence.test.ts +26 -40
  127. package/src/__tests__/document-create-dedupe.test.ts +189 -0
  128. package/src/__tests__/document-find-replace.test.ts +3 -2
  129. package/src/__tests__/document-tool-security.test.ts +81 -2
  130. package/src/__tests__/dynamic-page-surface.test.ts +2 -2
  131. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +5 -4
  132. package/src/__tests__/email-html-renderer.test.ts +12 -0
  133. package/src/__tests__/encrypted-store-test-helpers.ts +56 -0
  134. package/src/__tests__/encrypted-store.test.ts +11 -9
  135. package/src/__tests__/feature-flag-test-helpers.ts +53 -0
  136. package/src/__tests__/filing-service.test.ts +1 -0
  137. package/src/__tests__/first-greeting.test.ts +62 -12
  138. package/src/__tests__/gateway-flag-listener.test.ts +236 -0
  139. package/src/__tests__/gemini-provider.test.ts +104 -0
  140. package/src/__tests__/guardian-action-sweep.test.ts +3 -2
  141. package/src/__tests__/guardian-dispatch.test.ts +0 -1
  142. package/src/__tests__/guardian-outbound-http.test.ts +10 -7
  143. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +48 -3
  144. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +2 -1
  145. package/src/__tests__/heartbeat-disk-pressure.test.ts +5 -0
  146. package/src/__tests__/heartbeat-service.test.ts +5 -0
  147. package/src/__tests__/helpers/mock-logger.ts +26 -0
  148. package/src/__tests__/host-bash-routes.test.ts +1 -0
  149. package/src/__tests__/host-cu-routes-targeted.test.ts +1 -0
  150. package/src/__tests__/host-file-routes-targeted.test.ts +1 -0
  151. package/src/__tests__/host-shell-tool.test.ts +6 -5
  152. package/src/__tests__/host-transfer-routes-targeted.test.ts +1 -0
  153. package/src/__tests__/http-conversation-lineage.test.ts +3 -2
  154. package/src/__tests__/http-user-message-parity.test.ts +29 -7
  155. package/src/__tests__/identity-intro-cache.test.ts +133 -22
  156. package/src/__tests__/inbound-slack-persistence.test.ts +44 -72
  157. package/src/__tests__/inference-profile-reaper.test.ts +3 -2
  158. package/src/__tests__/inference-profile-session-ipc.test.ts +3 -2
  159. package/src/__tests__/init-feature-flag-overrides.test.ts +5 -6
  160. package/src/__tests__/injector-disk-pressure.test.ts +3 -17
  161. package/src/__tests__/inline-skill-load-permissions.test.ts +4 -4
  162. package/src/__tests__/list-messages-hidden-metadata.test.ts +80 -0
  163. package/src/__tests__/list-messages-tool-merge.test.ts +70 -11
  164. package/src/__tests__/llm-context-normalization.test.ts +42 -0
  165. package/src/__tests__/llm-request-log-call-site.test.ts +136 -0
  166. package/src/__tests__/llm-request-log-source-clickhouse.test.ts +26 -0
  167. package/src/__tests__/llm-resolver.test.ts +408 -9
  168. package/src/__tests__/llm-schema.test.ts +1 -1
  169. package/src/__tests__/llm-usage-store.test.ts +66 -0
  170. package/src/__tests__/logger.test.ts +89 -0
  171. package/src/__tests__/manual-token-reconciliation.test.ts +76 -1
  172. package/src/__tests__/mcp-abort-signal.test.ts +16 -2
  173. package/src/__tests__/mcp-client-auth.test.ts +14 -0
  174. package/src/__tests__/media-generate-image.test.ts +31 -0
  175. package/src/__tests__/memory-v2-static-injector.test.ts +7 -7
  176. package/src/__tests__/messaging-send-tool.test.ts +1 -0
  177. package/src/__tests__/migration-import-from-url.test.ts +3 -3
  178. package/src/__tests__/mock-gateway-ipc.ts +18 -2
  179. package/src/__tests__/model-intents.test.ts +4 -6
  180. package/src/__tests__/native-web-search.test.ts +30 -2
  181. package/src/__tests__/notification-deep-link.test.ts +62 -0
  182. package/src/__tests__/notification-guardian-path.test.ts +0 -1
  183. package/src/__tests__/oauth-commands-routes.test.ts +37 -0
  184. package/src/__tests__/oauth-provider-visibility.test.ts +8 -8
  185. package/src/__tests__/oauth-store.test.ts +3 -2
  186. package/src/__tests__/onboarding-template-contract.test.ts +4 -3
  187. package/src/__tests__/openai-provider.test.ts +54 -9
  188. package/src/__tests__/openai-responses-provider.test.ts +176 -14
  189. package/src/__tests__/openrouter-provider-only.test.ts +27 -5
  190. package/src/__tests__/outbound-slack-persistence.test.ts +46 -1
  191. package/src/__tests__/pending-interactions-resolved-event.test.ts +0 -1
  192. package/src/__tests__/persistence-pipeline.test.ts +139 -1
  193. package/src/__tests__/persistence-secret-redaction.test.ts +83 -12
  194. package/src/__tests__/platform-bash-auto-approve.test.ts +2 -2
  195. package/src/__tests__/platform.test.ts +2 -2
  196. package/src/__tests__/plugin-api-tool-definition.test.ts +92 -0
  197. package/src/__tests__/plugin-bootstrap.test.ts +11 -13
  198. package/src/__tests__/plugin-tool-contribution.test.ts +50 -40
  199. package/src/__tests__/plugin-types.test.ts +3 -2
  200. package/src/__tests__/prechat-onboarding-contract.test.ts +131 -98
  201. package/src/__tests__/pricing.test.ts +12 -0
  202. package/src/__tests__/process-message-background-slack.test.ts +21 -16
  203. package/src/__tests__/process-message-display-content.test.ts +19 -22
  204. package/src/__tests__/provider-catalog-visibility.test.ts +9 -9
  205. package/src/__tests__/provider-platform-proxy-integration.test.ts +216 -4
  206. package/src/__tests__/provider-registry-ollama.test.ts +45 -22
  207. package/src/__tests__/prune-jobs-changes-parser.test.ts +61 -0
  208. package/src/__tests__/recording-handler.test.ts +1 -0
  209. package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +1 -0
  210. package/src/__tests__/registry.test.ts +84 -84
  211. package/src/__tests__/relay-server.test.ts +10 -10
  212. package/src/__tests__/require-fresh-approval.test.ts +2 -2
  213. package/src/__tests__/runtime-attachment-metadata.test.ts +3 -2
  214. package/src/__tests__/runtime-events-sse-bilingual.test.ts +154 -0
  215. package/src/__tests__/schedule-store.test.ts +16 -1
  216. package/src/__tests__/scheduler-reuse-conversation.test.ts +48 -3
  217. package/src/__tests__/secret-ingress-http.test.ts +5 -1
  218. package/src/__tests__/secure-keys.test.ts +3 -3
  219. package/src/__tests__/send-endpoint-busy.test.ts +81 -42
  220. package/src/__tests__/server-history-render.test.ts +4 -1
  221. package/src/__tests__/shell-tool-proxy-mode.test.ts +1 -1
  222. package/src/__tests__/skill-feature-flags-integration.test.ts +8 -10
  223. package/src/__tests__/skill-feature-flags.test.ts +16 -18
  224. package/src/__tests__/skill-load-feature-flag.test.ts +5 -5
  225. package/src/__tests__/skill-projection-feature-flag.test.ts +48 -37
  226. package/src/__tests__/skill-projection.benchmark.test.ts +7 -13
  227. package/src/__tests__/skill-tool-factory.test.ts +97 -96
  228. package/src/__tests__/slack-channel-config.test.ts +3 -3
  229. package/src/__tests__/subagent-call-site-routing.test.ts +11 -3
  230. package/src/__tests__/subagent-disposal.test.ts +27 -8
  231. package/src/__tests__/subagent-fork-notifications.test.ts +24 -9
  232. package/src/__tests__/subagent-fork-spawn.test.ts +13 -4
  233. package/src/__tests__/subagent-manager-notify.test.ts +20 -8
  234. package/src/__tests__/subagent-notify-parent.test.ts +6 -5
  235. package/src/__tests__/subagent-spawn-tool-fork.test.ts +58 -0
  236. package/src/__tests__/subagent-tools.test.ts +2 -1
  237. package/src/__tests__/suggestion-routes.test.ts +2 -0
  238. package/src/__tests__/sync-message-contract.test.ts +59 -0
  239. package/src/__tests__/system-prompt.test.ts +183 -131
  240. package/src/__tests__/terminal-tools.test.ts +1 -1
  241. package/src/__tests__/test-preload-verifier.ts +68 -0
  242. package/src/__tests__/test-preload.ts +32 -39
  243. package/src/__tests__/tool-approval-handler.test.ts +1 -5
  244. package/src/__tests__/tool-execute-pipeline.test.ts +2 -2
  245. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +2 -5
  246. package/src/__tests__/tool-executor-lifecycle-events.test.ts +35 -12
  247. package/src/__tests__/tool-executor.test.ts +64 -72
  248. package/src/__tests__/tool-grant-request-escalation.test.ts +1 -6
  249. package/src/__tests__/tool-preview-lifecycle.test.ts +1 -0
  250. package/src/__tests__/tool-result-metadata-plumbing.test.ts +1 -0
  251. package/src/__tests__/trusted-contact-approval-notifier.test.ts +0 -1
  252. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +1 -6
  253. package/src/__tests__/trusted-contact-multichannel.test.ts +0 -1
  254. package/src/__tests__/twilio-routes.test.ts +3 -2
  255. package/src/__tests__/ui-file-upload-surface.test.ts +2 -2
  256. package/src/__tests__/usage-routes.test.ts +3 -0
  257. package/src/__tests__/validate-input.test.ts +381 -0
  258. package/src/__tests__/verification-control-plane-policy.test.ts +3 -2
  259. package/src/__tests__/voice-scoped-grant-consumer.test.ts +2 -1
  260. package/src/__tests__/voice-session-bridge.test.ts +37 -28
  261. package/src/__tests__/workspace-git-service.test.ts +6 -5
  262. package/src/__tests__/workspace-migration-089-move-memory-tree-out-of-v3.test.ts +86 -0
  263. package/src/__tests__/workspace-migration-090-memory-router-cost-optimized-profile.test.ts +326 -0
  264. package/src/__tests__/workspace-migration-091-retighten-migration-onboarding-thread.test.ts +166 -0
  265. package/src/acp/__tests__/prepare-agent-env.test.ts +146 -0
  266. package/src/acp/prepare-agent-env.ts +78 -0
  267. package/src/acp/session-manager.ts +6 -7
  268. package/src/agent/loop.ts +88 -0
  269. package/src/api/README.md +127 -0
  270. package/src/api/constants/call-sites.ts +27 -0
  271. package/src/api/events/assistant-outbound-attachment.ts +51 -0
  272. package/src/api/events/assistant-text-delta.ts +32 -0
  273. package/src/api/events/assistant-turn-start.ts +33 -0
  274. package/src/api/events/document-comment-created.ts +48 -0
  275. package/src/api/events/document-comment-deleted.ts +24 -0
  276. package/src/api/events/document-comment-reopened.ts +25 -0
  277. package/src/api/events/document-comment-resolved.ts +27 -0
  278. package/src/api/events/generation-cancelled.ts +24 -0
  279. package/src/api/events/generation-handoff.ts +41 -0
  280. package/src/api/events/message-complete.ts +42 -0
  281. package/src/api/events/open-url.ts +30 -0
  282. package/src/api/events/relationship-state-updated.ts +25 -0
  283. package/src/api/events/tool-use-start.ts +32 -0
  284. package/src/api/index.ts +129 -0
  285. package/src/api/package.json +10 -0
  286. package/src/api/responses/llm-context-response.ts +39 -0
  287. package/src/api/responses/llm-request-log-entry.ts +93 -0
  288. package/src/api/responses/memory-recall-log.ts +65 -0
  289. package/src/api/responses/memory-v2-activation-log.ts +78 -0
  290. package/src/background-wake/background-wake-routes.test.ts +868 -0
  291. package/src/background-wake/platform-client.test.ts +308 -0
  292. package/src/background-wake/platform-client.ts +167 -0
  293. package/src/background-wake/publisher.ts +91 -0
  294. package/src/background-wake/runtime-registry.ts +24 -0
  295. package/src/background-wake/wake-intent-hooks.test.ts +282 -0
  296. package/src/calls/guardian-dispatch.ts +1 -0
  297. package/src/calls/voice-session-bridge.ts +4 -4
  298. package/src/cli/commands/__tests__/browser.test.ts +23 -5
  299. package/src/cli/commands/__tests__/conversations-slack.test.ts +16 -0
  300. package/src/cli/commands/__tests__/domain-register.test.ts +110 -0
  301. package/src/cli/commands/__tests__/domain-status.test.ts +33 -33
  302. package/src/cli/commands/__tests__/inference-send.test.ts +108 -5
  303. package/src/cli/commands/__tests__/memory-v2-compare-render.test.ts +98 -0
  304. package/src/cli/commands/__tests__/memory-v2.test.ts +1 -0
  305. package/src/cli/commands/__tests__/memory-v3-render.test.ts +340 -0
  306. package/src/cli/commands/__tests__/notifications.test.ts +184 -40
  307. package/src/cli/commands/browser.ts +247 -0
  308. package/src/cli/commands/channels/__tests__/channels.test.ts +143 -0
  309. package/src/cli/commands/channels/index.ts +229 -0
  310. package/src/cli/commands/domain.ts +91 -41
  311. package/src/cli/commands/inference.ts +93 -40
  312. package/src/cli/commands/memory-v2-compare-render.ts +115 -0
  313. package/src/cli/commands/memory-v2.ts +176 -1
  314. package/src/cli/commands/memory-v3-render.ts +491 -0
  315. package/src/cli/commands/memory-v3.ts +567 -0
  316. package/src/cli/commands/notifications.ts +365 -55
  317. package/src/cli/lib/open-browser.ts +7 -2
  318. package/src/cli/program.ts +4 -0
  319. package/src/config/assistant-feature-flags.ts +39 -46
  320. package/src/config/bundled-skills/document-editor/SKILL.md +16 -3
  321. package/src/config/bundled-skills/document-editor/TOOLS.json +18 -0
  322. package/src/config/bundled-skills/document-editor/tools/document-open.ts +12 -0
  323. package/src/config/bundled-skills/image-studio/SKILL.md +4 -0
  324. package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +2 -2
  325. package/src/config/bundled-skills/media-processing/tools/ingest-media.ts +13 -8
  326. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +10 -3
  327. package/src/config/bundled-skills/phone-calls/references/TRANSCRIPTS.md +16 -14
  328. package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +7 -2
  329. package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +7 -2
  330. package/src/config/bundled-skills/schedule/SKILL.md +1 -1
  331. package/src/config/bundled-skills/schedule/TOOLS.json +2 -2
  332. package/src/config/bundled-skills/settings/tools/open-system-settings.ts +1 -0
  333. package/src/config/bundled-tool-registry.ts +2 -0
  334. package/src/config/call-site-defaults.ts +8 -7
  335. package/src/config/feature-flag-cache.ts +86 -0
  336. package/src/config/feature-flag-registry.json +33 -17
  337. package/src/config/llm-context-resolution.ts +10 -1
  338. package/src/config/llm-resolver.ts +121 -15
  339. package/src/config/loader.ts +4 -5
  340. package/src/config/schemas/__tests__/memory-v2.test.ts +228 -1
  341. package/src/config/schemas/call-site-catalog.ts +21 -7
  342. package/src/config/schemas/heartbeat.ts +1 -1
  343. package/src/config/schemas/llm.ts +102 -2
  344. package/src/config/schemas/memory-v2.ts +272 -0
  345. package/src/config/schemas/memory.ts +2 -1
  346. package/src/config/schemas/services.ts +6 -2
  347. package/src/config/seed-inference-profiles.ts +36 -16
  348. package/src/context/compactor.ts +52 -0
  349. package/src/context/token-estimator.ts +10 -5
  350. package/src/conversations/__tests__/message-consolidation.test.ts +350 -0
  351. package/src/conversations/message-consolidation.ts +404 -0
  352. package/src/credential-execution/executable-discovery.ts +40 -0
  353. package/src/credential-execution/process-manager.ts +6 -2
  354. package/src/credential-health/credential-health-service.ts +125 -40
  355. package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +3 -6
  356. package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +13 -15
  357. package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +2 -3
  358. package/src/daemon/__tests__/daemon-skill-host.test.ts +2 -0
  359. package/src/daemon/__tests__/meet-manifest-loader.test.ts +25 -12
  360. package/src/daemon/__tests__/native-web-search-metadata.test.ts +1 -0
  361. package/src/daemon/__tests__/switch-inference-profile-tool.test.ts +107 -0
  362. package/src/daemon/__tests__/web-search-status-text.test.ts +1 -0
  363. package/src/daemon/conversation-agent-loop-handlers.ts +390 -80
  364. package/src/daemon/conversation-agent-loop.ts +244 -90
  365. package/src/daemon/conversation-error.ts +64 -6
  366. package/src/daemon/conversation-lifecycle.ts +27 -22
  367. package/src/daemon/conversation-messaging.ts +84 -43
  368. package/src/daemon/conversation-process.ts +74 -37
  369. package/src/daemon/conversation-runtime-assembly.ts +38 -17
  370. package/src/daemon/conversation-skill-tools.ts +14 -30
  371. package/src/daemon/conversation-surfaces.ts +69 -34
  372. package/src/daemon/conversation-tool-setup.ts +77 -32
  373. package/src/daemon/conversation-usage.ts +2 -0
  374. package/src/daemon/conversation.ts +40 -75
  375. package/src/daemon/daemon-control.ts +1 -1
  376. package/src/daemon/daemon-skill-host.ts +9 -2
  377. package/src/daemon/disk-pressure-guard.ts +39 -29
  378. package/src/daemon/first-greeting.ts +31 -13
  379. package/src/daemon/handlers/config-model.test.ts +1 -0
  380. package/src/daemon/handlers/conversations.ts +11 -3
  381. package/src/daemon/handlers/shared.ts +6 -1
  382. package/src/daemon/host-browser-proxy.ts +5 -5
  383. package/src/daemon/host-cu-proxy.ts +4 -4
  384. package/src/daemon/host-file-proxy.ts +4 -4
  385. package/src/daemon/host-proxy-base.ts +4 -4
  386. package/src/daemon/host-transfer-proxy.ts +10 -10
  387. package/src/daemon/lifecycle.ts +29 -26
  388. package/src/daemon/mcp-reload-service.ts +1 -1
  389. package/src/daemon/meet-manifest-loader.ts +11 -24
  390. package/src/daemon/message-types/conversations.ts +22 -27
  391. package/src/daemon/message-types/document-comments.ts +8 -44
  392. package/src/daemon/message-types/home.ts +2 -14
  393. package/src/daemon/message-types/integrations.ts +2 -7
  394. package/src/daemon/message-types/messages.ts +25 -48
  395. package/src/daemon/message-types/subagents.ts +6 -0
  396. package/src/daemon/message-types/sync.ts +14 -0
  397. package/src/daemon/process-message.ts +9 -9
  398. package/src/daemon/providers-setup.ts +1 -1
  399. package/src/daemon/server.ts +16 -0
  400. package/src/daemon/shutdown-handlers.ts +24 -5
  401. package/src/daemon/switch-inference-profile-tool.ts +62 -0
  402. package/src/daemon/tool-setup-types.ts +7 -0
  403. package/src/daemon/wake-target-adapter.ts +10 -0
  404. package/src/documents/document-store.ts +38 -0
  405. package/src/export/__tests__/transcript-formatter.test.ts +1 -0
  406. package/src/heartbeat/__tests__/heartbeat-service.test.ts +30 -1
  407. package/src/heartbeat/heartbeat-service.ts +63 -0
  408. package/src/home/__tests__/feed-writer.test.ts +161 -0
  409. package/src/home/__tests__/post-connect-feed.test.ts +1 -0
  410. package/src/home/__tests__/suggested-prompts.test.ts +55 -59
  411. package/src/home/feed-writer.ts +146 -7
  412. package/src/home/home-greeting.ts +0 -9
  413. package/src/home/suggested-prompts.ts +27 -154
  414. package/src/ipc/__tests__/cli-ipc.test.ts +1 -0
  415. package/src/ipc/gateway-client.test.ts +4 -1
  416. package/src/ipc/gateway-flag-listener.ts +123 -0
  417. package/src/ipc/skill-routes/__tests__/memory.test.ts +1 -0
  418. package/src/ipc/skill-routes/__tests__/registries.test.ts +36 -7
  419. package/src/ipc/skill-routes/memory.ts +4 -3
  420. package/src/ipc/skill-routes/registries.ts +35 -40
  421. package/src/memory/__tests__/db-async-query.test.ts +165 -0
  422. package/src/memory/__tests__/db-maintenance.test.ts +115 -0
  423. package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +242 -0
  424. package/src/memory/__tests__/jobs-store-job-classes.test.ts +28 -1
  425. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +26 -5
  426. package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +1 -0
  427. package/src/memory/__tests__/memory-retrospective-job.test.ts +8 -0
  428. package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +1 -0
  429. package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +31 -0
  430. package/src/memory/auto-analysis-enqueue.ts +5 -1
  431. package/src/memory/conversation-attention-store.ts +17 -3
  432. package/src/memory/conversation-crud.ts +423 -182
  433. package/src/memory/conversation-starters-cadence.ts +3 -1
  434. package/src/memory/conversation-title-service.ts +19 -3
  435. package/src/memory/db-async-query.ts +214 -0
  436. package/src/memory/db-connection.ts +29 -19
  437. package/src/memory/db-init.ts +14 -0
  438. package/src/memory/db-maintenance.ts +30 -21
  439. package/src/memory/db-singleton.ts +77 -0
  440. package/src/memory/delivery-channels.ts +82 -0
  441. package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +2 -4
  442. package/src/memory/graph/bootstrap.ts +8 -1
  443. package/src/memory/graph/capability-seed.ts +7 -3
  444. package/src/memory/graph/conversation-graph-memory.ts +100 -17
  445. package/src/memory/graph/extraction.ts +1 -5
  446. package/src/memory/graph/graph-search.ts +7 -1
  447. package/src/memory/graph/retriever.test.ts +3 -3
  448. package/src/memory/indexer.ts +28 -18
  449. package/src/memory/job-handlers/cleanup.ts +76 -18
  450. package/src/memory/job-handlers/conversation-starters.ts +1 -4
  451. package/src/memory/job-handlers/embedding.test.ts +3 -2
  452. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +5 -2
  453. package/src/memory/jobs/embed-pkb-file.ts +6 -1
  454. package/src/memory/jobs-store.ts +14 -0
  455. package/src/memory/jobs-worker.ts +66 -22
  456. package/src/memory/llm-request-log-source-clickhouse.ts +122 -2
  457. package/src/memory/llm-request-log-source-local.ts +31 -0
  458. package/src/memory/llm-request-log-source.ts +40 -2
  459. package/src/memory/llm-request-log-store.ts +228 -1
  460. package/src/memory/llm-usage-store.ts +24 -0
  461. package/src/memory/memory-retrospective-enqueue.ts +8 -1
  462. package/src/memory/memory-retrospective-job.ts +5 -0
  463. package/src/memory/memory-v2-activation-log-store.ts +110 -7
  464. package/src/memory/migrations/260-rename-cleaned-at.ts +44 -0
  465. package/src/memory/migrations/261-llm-usage-add-raw-usage.ts +36 -0
  466. package/src/memory/migrations/262-memory-v3-coactivation.ts +57 -0
  467. package/src/memory/migrations/263-memory-v3-auto-edges.ts +50 -0
  468. package/src/memory/migrations/264-llm-request-log-call-site.ts +29 -0
  469. package/src/memory/migrations/265-drop-provider-connection-status.ts +26 -0
  470. package/src/memory/migrations/266-messages-client-message-id.ts +43 -0
  471. package/src/memory/migrations/index.ts +19 -0
  472. package/src/memory/migrations/registry.ts +33 -0
  473. package/src/memory/schema/conversations.ts +10 -2
  474. package/src/memory/schema/inference.ts +0 -1
  475. package/src/memory/schema/infrastructure.ts +21 -0
  476. package/src/memory/tool-usage-store.ts +36 -8
  477. package/src/memory/v2/__tests__/backfill-jobs.test.ts +5 -2
  478. package/src/memory/v2/__tests__/consolidation-job.test.ts +1 -0
  479. package/src/memory/v2/__tests__/harness-compare.test.ts +186 -0
  480. package/src/memory/v2/__tests__/harness-metrics.test.ts +83 -0
  481. package/src/memory/v2/__tests__/harness-oracle.test.ts +257 -0
  482. package/src/memory/v2/__tests__/harness-replay-input.test.ts +230 -0
  483. package/src/memory/v2/__tests__/harness-runner.test.ts +135 -0
  484. package/src/memory/v2/__tests__/injection.test.ts +127 -98
  485. package/src/memory/v2/__tests__/qdrant.test.ts +36 -0
  486. package/src/memory/v2/__tests__/router.test.ts +171 -3
  487. package/src/memory/v2/__tests__/sweep-job.test.ts +6 -3
  488. package/src/memory/v2/harness/compare.ts +57 -0
  489. package/src/memory/v2/harness/metrics.ts +128 -0
  490. package/src/memory/v2/harness/oracle.ts +145 -0
  491. package/src/memory/v2/harness/replay-input.ts +240 -0
  492. package/src/memory/v2/harness/retriever.ts +74 -0
  493. package/src/memory/v2/harness/router-retriever.ts +43 -0
  494. package/src/memory/v2/harness/runner.ts +112 -0
  495. package/src/memory/v2/harness/trace.ts +64 -0
  496. package/src/memory/v2/injection.ts +21 -15
  497. package/src/memory/v2/prompts/router.ts +26 -1
  498. package/src/memory/v2/qdrant.ts +14 -2
  499. package/src/memory/v2/router.ts +171 -18
  500. package/src/memory/v3/__tests__/coactivation-store.test.ts +422 -0
  501. package/src/memory/v3/__tests__/consolidation-job.test.ts +466 -0
  502. package/src/memory/v3/__tests__/coretrieval-seed.test.ts +270 -0
  503. package/src/memory/v3/__tests__/edge-learning-job.test.ts +324 -0
  504. package/src/memory/v3/__tests__/edges.test.ts +706 -0
  505. package/src/memory/v3/__tests__/filter.test.ts +560 -0
  506. package/src/memory/v3/__tests__/gate.test.ts +637 -0
  507. package/src/memory/v3/__tests__/index-composition.test.ts +291 -0
  508. package/src/memory/v3/__tests__/loop.test.ts +775 -0
  509. package/src/memory/v3/__tests__/retriever.test.ts +226 -0
  510. package/src/memory/v3/__tests__/scouts.test.ts +489 -0
  511. package/src/memory/v3/__tests__/shadow-diff.test.ts +225 -0
  512. package/src/memory/v3/__tests__/shadow-middleware.test.ts +398 -0
  513. package/src/memory/v3/__tests__/system-prompts.test.ts +154 -0
  514. package/src/memory/v3/__tests__/traversal.test.ts +508 -0
  515. package/src/memory/v3/__tests__/tree-index.test.ts +280 -0
  516. package/src/memory/v3/__tests__/tree-store.test.ts +529 -0
  517. package/src/memory/v3/__tests__/tree-walk.test.ts +784 -0
  518. package/src/memory/v3/__tests__/validate.test.ts +277 -0
  519. package/src/memory/v3/auto-edges.ts +223 -0
  520. package/src/memory/v3/coactivation-store.ts +124 -0
  521. package/src/memory/v3/consolidation-job.ts +323 -0
  522. package/src/memory/v3/coretrieval-seed.ts +240 -0
  523. package/src/memory/v3/edge-learning-job.ts +160 -0
  524. package/src/memory/v3/edges.ts +286 -0
  525. package/src/memory/v3/filter.ts +286 -0
  526. package/src/memory/v3/gate.ts +349 -0
  527. package/src/memory/v3/index-composition.ts +126 -0
  528. package/src/memory/v3/llm-capture.ts +46 -0
  529. package/src/memory/v3/loop.ts +430 -0
  530. package/src/memory/v3/maintenance.ts +144 -0
  531. package/src/memory/v3/prompt-context.ts +33 -0
  532. package/src/memory/v3/prompts/consolidation.ts +458 -0
  533. package/src/memory/v3/prompts/system-prompts.ts +196 -0
  534. package/src/memory/v3/retriever.ts +33 -0
  535. package/src/memory/v3/scouts.ts +431 -0
  536. package/src/memory/v3/shadow-diff.ts +287 -0
  537. package/src/memory/v3/shadow-middleware.ts +347 -0
  538. package/src/memory/v3/traversal.ts +211 -0
  539. package/src/memory/v3/tree-index.ts +237 -0
  540. package/src/memory/v3/tree-store.ts +394 -0
  541. package/src/memory/v3/tree-walk.ts +356 -0
  542. package/src/memory/v3/types.ts +65 -0
  543. package/src/memory/v3/validate.ts +323 -0
  544. package/src/notifications/__tests__/emit-signal-home-feed.test.ts +1 -0
  545. package/src/notifications/__tests__/home-feed-side-effect.test.ts +1 -0
  546. package/src/notifications/adapters/macos.ts +18 -1
  547. package/src/notifications/adapters/platform.ts +1 -1
  548. package/src/notifications/adapters/slack.ts +45 -11
  549. package/src/notifications/broadcaster.ts +114 -63
  550. package/src/notifications/conversation-pairing.ts +23 -3
  551. package/src/notifications/decision-engine.ts +1 -4
  552. package/src/notifications/decisions-store.ts +32 -1
  553. package/src/notifications/deliveries-store.ts +45 -0
  554. package/src/notifications/edit-notification.ts +201 -0
  555. package/src/notifications/emit-signal.ts +40 -50
  556. package/src/notifications/signal.ts +10 -0
  557. package/src/notifications/types.ts +37 -0
  558. package/src/oauth/byo-connection.test.ts +67 -3
  559. package/src/oauth/byo-connection.ts +32 -5
  560. package/src/oauth/connect-orchestrator.ts +9 -0
  561. package/src/oauth/connection-resolver.test.ts +76 -0
  562. package/src/oauth/connection-resolver.ts +49 -10
  563. package/src/oauth/manual-token-connection.ts +51 -3
  564. package/src/oauth/seed-providers.ts +3 -0
  565. package/src/permissions/approval-policy.test.ts +19 -5
  566. package/src/permissions/approval-policy.ts +14 -3
  567. package/src/permissions/checker.ts +21 -8
  568. package/src/permissions/prompter.ts +3 -3
  569. package/src/permissions/question-prompter.ts +5 -2
  570. package/src/permissions/secret-prompter.ts +2 -2
  571. package/src/platform/client.test.ts +24 -1
  572. package/src/platform/client.ts +8 -0
  573. package/src/platform/feature-gate.ts +15 -0
  574. package/src/plugin-api/index.ts +4 -0
  575. package/src/plugin-api/types.ts +7 -33
  576. package/src/plugins/defaults/index.ts +6 -0
  577. package/src/plugins/defaults/injectors.ts +20 -19
  578. package/src/plugins/defaults/persistence.ts +25 -6
  579. package/src/plugins/external-plugin-loader.ts +5 -68
  580. package/src/plugins/types.ts +68 -29
  581. package/src/proactive-artifact/aux-message-injector.ts +17 -4
  582. package/src/proactive-artifact/job.test.ts +1 -0
  583. package/src/prompts/__tests__/system-prompt.test.ts +4 -4
  584. package/src/prompts/__tests__/task-progress-hint-section.test.ts +3 -9
  585. package/src/prompts/persona-resolver.ts +36 -21
  586. package/src/prompts/sections.ts +39 -7
  587. package/src/prompts/system-prompt.ts +84 -221
  588. package/src/prompts/template-detection.ts +10 -4
  589. package/src/prompts/templates/BOOTSTRAP.md +9 -13
  590. package/src/prompts/templates/IDENTITY.md +0 -2
  591. package/src/prompts/templates/system-sections.ts +230 -8
  592. package/src/providers/__tests__/connection-model-compat.test.ts +233 -0
  593. package/src/providers/__tests__/registry-native-web-search.test.ts +122 -0
  594. package/src/providers/__tests__/retry-callsite.test.ts +85 -5
  595. package/src/providers/anthropic/client.ts +32 -66
  596. package/src/providers/call-site-routing.ts +42 -6
  597. package/src/providers/connection-model-compat.ts +61 -0
  598. package/src/providers/connection-resolution.ts +47 -14
  599. package/src/providers/fireworks/client.ts +1 -0
  600. package/src/providers/gemini/client.ts +70 -6
  601. package/src/providers/inference/__tests__/adapter-factory-openai-compatible.test.ts +0 -2
  602. package/src/providers/inference/__tests__/base-url-security.test.ts +2 -3
  603. package/src/providers/inference/__tests__/{connections-status-label.test.ts → connections-label.test.ts} +12 -111
  604. package/src/providers/inference/adapter-factory.ts +3 -0
  605. package/src/providers/inference/auth.ts +0 -8
  606. package/src/providers/inference/connections.ts +3 -66
  607. package/src/providers/inference/resolve-auth.ts +2 -3
  608. package/src/providers/minimax/client.ts +106 -0
  609. package/src/providers/model-catalog.ts +78 -1
  610. package/src/providers/model-intents.ts +4 -4
  611. package/src/providers/openai/__tests__/api-error-detail.test.ts +120 -0
  612. package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +157 -5
  613. package/src/providers/openai/chat-completions-provider.ts +116 -15
  614. package/src/providers/openai/codex-models.ts +20 -0
  615. package/src/providers/openai/responses-provider.ts +87 -30
  616. package/src/providers/openrouter/client.ts +13 -8
  617. package/src/providers/provider-send-message.ts +20 -5
  618. package/src/providers/registry.ts +48 -8
  619. package/src/providers/retry.ts +50 -7
  620. package/src/providers/search-provider-catalog.ts +17 -9
  621. package/src/providers/thinking-config.ts +26 -1
  622. package/src/providers/types.ts +9 -0
  623. package/src/providers/usage-tracking.ts +2 -0
  624. package/src/runtime/AGENTS.md +2 -2
  625. package/src/runtime/__tests__/agent-wake.test.ts +1 -0
  626. package/src/runtime/__tests__/background-job-runner.test.ts +1 -0
  627. package/src/runtime/access-request-helper.ts +1 -0
  628. package/src/runtime/agent-wake.ts +1 -0
  629. package/src/runtime/assistant-event-hub.ts +76 -6
  630. package/src/runtime/auth/route-policy.ts +46 -0
  631. package/src/runtime/btw-sidechain.ts +0 -6
  632. package/src/runtime/channel-readiness-service.ts +68 -0
  633. package/src/runtime/channel-reply-delivery.ts +23 -0
  634. package/src/runtime/channel-retry-sweep.ts +47 -14
  635. package/src/runtime/confirmation-request-guardian-bridge.ts +1 -1
  636. package/src/runtime/http-types.ts +0 -2
  637. package/src/runtime/migrations/vbundle-builder.ts +12 -4
  638. package/src/runtime/pending-interactions.ts +0 -1
  639. package/src/runtime/routes/__tests__/bookmark-routes.test.ts +1 -0
  640. package/src/runtime/routes/__tests__/conversation-compaction-routes.test.ts +406 -0
  641. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +204 -0
  642. package/src/runtime/routes/__tests__/heartbeat-routes.test.ts +1 -1
  643. package/src/runtime/routes/__tests__/home-feed-routes.test.ts +209 -1
  644. package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +13 -50
  645. package/src/runtime/routes/__tests__/memory-v2-simulate-route.test.ts +76 -9
  646. package/src/runtime/routes/__tests__/memory-v3-simulate-params.test.ts +35 -0
  647. package/src/runtime/routes/__tests__/plugins-routes.test.ts +512 -0
  648. package/src/runtime/routes/__tests__/slack-channel-routes.test.ts +3 -2
  649. package/src/runtime/routes/__tests__/surface-content-routes.test.ts +294 -0
  650. package/src/runtime/routes/__tests__/task-routes.test.ts +48 -3
  651. package/src/runtime/routes/acp-routes-list.test.ts +3 -0
  652. package/src/runtime/routes/acp-routes.test.ts +255 -6
  653. package/src/runtime/routes/acp-routes.ts +8 -1
  654. package/src/runtime/routes/app-management-routes.ts +111 -4
  655. package/src/runtime/routes/avatar-routes.ts +10 -10
  656. package/src/runtime/routes/background-wake-routes.ts +356 -0
  657. package/src/runtime/routes/browser-tabs-routes.ts +200 -0
  658. package/src/runtime/routes/btw-routes.ts +4 -10
  659. package/src/runtime/routes/conversation-analysis-routes.ts +6 -0
  660. package/src/runtime/routes/conversation-cli-routes.ts +1 -1
  661. package/src/runtime/routes/conversation-compaction-routes.ts +263 -0
  662. package/src/runtime/routes/conversation-list-routes.ts +159 -4
  663. package/src/runtime/routes/conversation-management-routes.ts +108 -26
  664. package/src/runtime/routes/conversation-query-routes.ts +200 -44
  665. package/src/runtime/routes/conversation-routes.ts +409 -521
  666. package/src/runtime/routes/conversation-starter-routes.ts +6 -3
  667. package/src/runtime/routes/conversations-import-routes.ts +19 -6
  668. package/src/runtime/routes/disk-pressure-routes.ts +1 -1
  669. package/src/runtime/routes/documents-routes.ts +10 -1
  670. package/src/runtime/routes/domain-routes.ts +60 -10
  671. package/src/runtime/routes/email-routes.ts +5 -2
  672. package/src/runtime/routes/events-routes.ts +54 -10
  673. package/src/runtime/routes/group-routes.ts +35 -8
  674. package/src/runtime/routes/home-feed-routes.ts +129 -0
  675. package/src/runtime/routes/host-browser-routes.ts +10 -2
  676. package/src/runtime/routes/host-cu-routes.ts +2 -2
  677. package/src/runtime/routes/identity-intro-cache.ts +61 -16
  678. package/src/runtime/routes/identity-routes.ts +30 -9
  679. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +96 -3
  680. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +530 -6
  681. package/src/runtime/routes/inbound-stages/background-dispatch.ts +57 -8
  682. package/src/runtime/routes/index.ts +10 -0
  683. package/src/runtime/routes/inference-profile-session-handler.ts +22 -12
  684. package/src/runtime/routes/inference-profile-session-routes.ts +7 -1
  685. package/src/runtime/routes/inference-provider-connection-routes.ts +5 -26
  686. package/src/runtime/routes/integrations/vercel.ts +15 -0
  687. package/src/runtime/routes/llm-call-sites-routes.ts +32 -5
  688. package/src/runtime/routes/llm-context-normalization.ts +7 -2
  689. package/src/runtime/routes/memory-item-routes.ts +8 -3
  690. package/src/runtime/routes/memory-v2-routes.ts +215 -5
  691. package/src/runtime/routes/memory-v3-routes.ts +474 -0
  692. package/src/runtime/routes/migration-routes.ts +32 -28
  693. package/src/runtime/routes/notification-routes.ts +63 -1
  694. package/src/runtime/routes/oauth-commands-routes.ts +6 -1
  695. package/src/runtime/routes/plugins-routes.ts +337 -0
  696. package/src/runtime/routes/rename-conversation-routes.ts +6 -2
  697. package/src/runtime/routes/secret-routes.ts +25 -5
  698. package/src/runtime/routes/settings-routes.ts +12 -11
  699. package/src/runtime/routes/slack-channel-routes.ts +5 -4
  700. package/src/runtime/routes/surface-action-routes.ts +1 -38
  701. package/src/runtime/routes/surface-content-routes.ts +12 -5
  702. package/src/runtime/routes/surface-conversation-resolver.ts +65 -0
  703. package/src/runtime/routes/wipe-conversation-routes.ts +3 -0
  704. package/src/runtime/routes/workspace-routes.ts +25 -10
  705. package/src/runtime/services/__tests__/analyze-conversation.test.ts +2 -0
  706. package/src/runtime/slack-dm-text-delivery.ts +177 -0
  707. package/src/runtime/sync/resource-sync-events.ts +106 -38
  708. package/src/runtime/sync/sync-publisher.test.ts +49 -0
  709. package/src/runtime/sync/sync-publisher.ts +2 -1
  710. package/src/runtime/tool-grant-request-helper.ts +1 -0
  711. package/src/runtime/verification-outbound-actions.ts +73 -1
  712. package/src/schedule/schedule-store.ts +8 -1
  713. package/src/schedule/scheduler.ts +111 -15
  714. package/src/security/__tests__/provider-key-env-fallback.test.ts +3 -3
  715. package/src/security/encrypted-store.ts +7 -16
  716. package/src/security/store-path-override.ts +61 -0
  717. package/src/signals/user-message.ts +5 -8
  718. package/src/skills/validate-input.ts +177 -0
  719. package/src/subagent/manager.ts +13 -13
  720. package/src/subagent/types.ts +6 -0
  721. package/src/tasks/tool-sanitizer.ts +2 -2
  722. package/src/telemetry/types.ts +12 -0
  723. package/src/telemetry/usage-telemetry-reporter.test.ts +48 -0
  724. package/src/telemetry/usage-telemetry-reporter.ts +1 -0
  725. package/src/tools/acp/spawn.test.ts +119 -0
  726. package/src/tools/acp/spawn.ts +15 -2
  727. package/src/tools/apps/definitions.ts +36 -28
  728. package/src/tools/ask-question/ask-question-tool.test.ts +3 -3
  729. package/src/tools/ask-question/ask-question-tool.ts +38 -45
  730. package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +2 -8
  731. package/src/tools/browser/__tests__/pinned-tabs.test.ts +70 -0
  732. package/src/tools/browser/browser-execution.ts +16 -3
  733. package/src/tools/browser/cdp-client/__tests__/browser-tabs-factory.test.ts +402 -0
  734. package/src/tools/browser/cdp-client/__tests__/types.test.ts +3 -0
  735. package/src/tools/browser/cdp-client/cdp-inspect-client.ts +12 -0
  736. package/src/tools/browser/cdp-client/extension-cdp-client.ts +27 -1
  737. package/src/tools/browser/cdp-client/factory.ts +100 -17
  738. package/src/tools/browser/cdp-client/local-cdp-client.ts +12 -0
  739. package/src/tools/browser/cdp-client/types.ts +65 -0
  740. package/src/tools/browser/pinned-tabs.ts +96 -40
  741. package/src/tools/computer-use/definitions.ts +282 -336
  742. package/src/tools/credential-execution/make-authenticated-request.ts +3 -9
  743. package/src/tools/credential-execution/manage-secure-command-tool.ts +3 -9
  744. package/src/tools/credential-execution/run-authenticated-command.ts +3 -9
  745. package/src/tools/credentials/vault.ts +3 -9
  746. package/src/tools/document/document-tool.ts +189 -7
  747. package/src/tools/execution-target.ts +18 -23
  748. package/src/tools/executor.ts +24 -56
  749. package/src/tools/filesystem/edit.ts +3 -9
  750. package/src/tools/filesystem/list.ts +3 -9
  751. package/src/tools/filesystem/read.ts +3 -9
  752. package/src/tools/filesystem/write.ts +3 -9
  753. package/src/tools/host-filesystem/edit.test.ts +1 -0
  754. package/src/tools/host-filesystem/edit.ts +3 -9
  755. package/src/tools/host-filesystem/read.test.ts +1 -0
  756. package/src/tools/host-filesystem/read.ts +3 -9
  757. package/src/tools/host-filesystem/transfer.test.ts +31 -6
  758. package/src/tools/host-filesystem/transfer.ts +3 -9
  759. package/src/tools/host-filesystem/write.test.ts +1 -0
  760. package/src/tools/host-filesystem/write.ts +3 -9
  761. package/src/tools/host-terminal/host-shell.ts +3 -9
  762. package/src/tools/mcp/mcp-tool-factory.ts +1 -10
  763. package/src/tools/memory/register.test.ts +1 -1
  764. package/src/tools/memory/register.ts +4 -9
  765. package/src/tools/network/__tests__/managed-search-proxy.test.ts +282 -0
  766. package/src/tools/network/__tests__/web-search.test.ts +211 -3
  767. package/src/tools/network/managed-search-proxy.ts +183 -0
  768. package/src/tools/network/web-fetch.ts +3 -9
  769. package/src/tools/network/web-search.ts +224 -76
  770. package/src/tools/policy-context.ts +3 -1
  771. package/src/tools/registry.ts +150 -123
  772. package/src/tools/schedule/create.ts +1 -1
  773. package/src/tools/schema-transforms.ts +1 -1
  774. package/src/tools/skills/execute.ts +3 -9
  775. package/src/tools/skills/load.ts +3 -9
  776. package/src/tools/skills/skill-tool-factory.ts +18 -44
  777. package/src/tools/subagent/notify-parent.ts +3 -9
  778. package/src/tools/subagent/spawn.ts +3 -0
  779. package/src/tools/system/request-permission.ts +3 -9
  780. package/src/tools/terminal/shell.ts +3 -9
  781. package/src/tools/tool-approval-handler.ts +10 -4
  782. package/src/tools/tool-defaults.ts +94 -0
  783. package/src/tools/tool-name-aliases.ts +72 -14
  784. package/src/tools/types.ts +32 -101
  785. package/src/tools/ui-surface/definitions.ts +104 -108
  786. package/src/types/onboarding-context.ts +6 -0
  787. package/src/usage/attribution.ts +32 -1
  788. package/src/usage/pricing.ts +23 -0
  789. package/src/usage/types.ts +12 -0
  790. package/src/util/browser.ts +7 -2
  791. package/src/util/logger.ts +16 -7
  792. package/src/util/platform.ts +7 -2
  793. package/src/util/sqlite3-runtime.ts +65 -0
  794. package/src/workspace/migrations/086-revert-stale-gemini-mis-rewrites.ts +1 -0
  795. package/src/workspace/migrations/089-move-memory-tree-out-of-v3.ts +86 -0
  796. package/src/workspace/migrations/090-memory-router-cost-optimized-profile.ts +109 -0
  797. package/src/workspace/migrations/091-retighten-migration-onboarding-thread.ts +41 -0
  798. package/src/workspace/migrations/registry.ts +6 -0
  799. package/src/__tests__/compaction-strip-metadata-clear.test.ts +0 -206
  800. package/src/__tests__/message-complete-display-id.test.ts +0 -175
  801. package/src/daemon/query-complexity-router.ts +0 -75
  802. package/src/prompts/cache-boundary.ts +0 -8
@@ -9,7 +9,7 @@ import { and, eq, inArray, sql } from "drizzle-orm";
9
9
 
10
10
  import { getLogger } from "../util/logger.js";
11
11
  import { getDb } from "./db-connection.js";
12
- import { enqueueMemoryJob } from "./jobs-store.js";
12
+ import { enqueueMemoryJob, isMemoryEnabled } from "./jobs-store.js";
13
13
  import { rawGet } from "./raw-query.js";
14
14
  import { memoryCheckpoints, memoryJobs } from "./schema.js";
15
15
 
@@ -20,6 +20,8 @@ const log = getLogger("conversation-starters-cadence");
20
20
  * generating a fresh batch of conversation starters.
21
21
  */
22
22
  export function maybeEnqueueConversationStartersJob(scopeId: string): void {
23
+ if (!isMemoryEnabled()) return;
24
+
23
25
  const db = getDb();
24
26
 
25
27
  // Count total active memory items
@@ -331,10 +331,10 @@ function buildTitlePrompt(
331
331
  }
332
332
 
333
333
  if (userMessage) {
334
- parts.push(`User: ${userMessage}`);
334
+ parts.push(`User: ${stripThinkingTags(userMessage)}`);
335
335
  }
336
336
  if (assistantResponse) {
337
- parts.push(`Assistant: ${assistantResponse}`);
337
+ parts.push(`Assistant: ${stripThinkingTags(assistantResponse)}`);
338
338
  }
339
339
 
340
340
  return parts.join("\n");
@@ -378,12 +378,28 @@ function truncateTitle(title: string): string {
378
378
  function normalizeTitle(raw: string): string {
379
379
  let title = raw.trim().replace(/^["']|["']$/g, "");
380
380
  title = stripMarkdown(title);
381
+ title = stripThinkingTags(title);
381
382
  if (META_FAILURE_TITLES.has(title.toLowerCase())) {
382
383
  return "";
383
384
  }
384
385
  return truncateTitle(title);
385
386
  }
386
387
 
388
+ /** Strip thinking tags so they don't bleed into generated titles. */
389
+ function stripThinkingTags(text: string): string {
390
+ return text
391
+ .replace(/<thinking>[\s\S]*?<\/thinking>/gi, "")
392
+ .replace(/<thought>[\s\S]*?<\/thought>/gi, "")
393
+ .replace(/<think>[\s\S]*?<\/think>/gi, "")
394
+ .replace(/<thought>/gi, "")
395
+ .replace(/<\/thought>/gi, "")
396
+ .replace(/<thinking>/gi, "")
397
+ .replace(/<\/thinking>/gi, "")
398
+ .replace(/<think>/gi, "")
399
+ .replace(/<\/think>/gi, "")
400
+ .replace(/<:[^>]*>/gi, "");
401
+ }
402
+
387
403
  /** Strip common markdown formatting so titles render as plain text. */
388
404
  function stripMarkdown(text: string): string {
389
405
  return text
@@ -458,7 +474,7 @@ function buildRegenerationPrompt(recentMessages: MessageRow[]): string {
458
474
  const text = extractTextForTitle(msg.content);
459
475
  if (!text) continue;
460
476
  const role = msg.role === "user" ? "User" : "Assistant";
461
- parts.push(`${role}: ${text}`);
477
+ parts.push(`${role}: ${stripThinkingTags(text)}`);
462
478
  }
463
479
 
464
480
  return parts.join("\n");
@@ -0,0 +1,214 @@
1
+ /**
2
+ * Run a SQL statement asynchronously, without blocking the daemon's
3
+ * main event loop.
4
+ *
5
+ * `bun:sqlite` is synchronous, so any long-running statement on the
6
+ * shared in-process connection stalls the event loop for the full
7
+ * duration of the statement. For multi-minute operations like `VACUUM`
8
+ * on a multi-GB database, this stalls every other piece of I/O —
9
+ * including the healthz handler — and on platform that has been
10
+ * observed to fail liveness probes and crashloop the pod.
11
+ *
12
+ * Backend selection:
13
+ * 1. **`sqlite3` CLI subprocess (preferred).** Spawn a child process
14
+ * that opens its own SQLite connection, runs the statement, and
15
+ * exits. The daemon's event loop is free for the full duration.
16
+ * SQLite's own file-locking arbitrates between the subprocess and
17
+ * the still-running in-process connection.
18
+ * 2. **In-process `bun:sqlite` (fallback).** Synchronous, blocking.
19
+ * Only fires when no `sqlite3` binary is on the host. This is the
20
+ * same behavior the daemon had before this abstraction existed,
21
+ * and is acceptable on desktop where no liveness probe is going to
22
+ * kill the process for a long stall.
23
+ *
24
+ * Use this for statements known to be slow (`VACUUM`, `ANALYZE`,
25
+ * `PRAGMA optimize`, large bulk `DELETE`/`UPDATE`). Fast queries (a few
26
+ * ms) should keep using the in-process drizzle / `bun:sqlite` handle
27
+ * directly — the subprocess overhead would dominate.
28
+ */
29
+ import { getLogger } from "../util/logger.js";
30
+ import { getDbPath } from "../util/platform.js";
31
+ import { findSqlite3 } from "../util/sqlite3-runtime.js";
32
+ import { getSqlite } from "./db-connection.js";
33
+
34
+ const log = getLogger("db-async-query");
35
+
36
+ /**
37
+ * Default wall-clock cap for an async statement. A real `VACUUM` on a
38
+ * multi-GB database can legitimately take many minutes; the cap is
39
+ * here to bound a runaway subprocess (e.g. one stuck on a stale file
40
+ * lock). Override per call via `runAsyncSqlite(sql, { timeoutMs })`.
41
+ */
42
+ const DEFAULT_TIMEOUT_MS = 60 * 60 * 1000; // 1 hour
43
+
44
+ export type AsyncSqliteBackend = "sqlite3-cli" | "in-process-blocking";
45
+
46
+ export interface AsyncSqliteResult {
47
+ ok: boolean;
48
+ backend: AsyncSqliteBackend;
49
+ error: string | null;
50
+ elapsedMs: number;
51
+ stdout?: string;
52
+ stderr?: string;
53
+ timedOut?: boolean;
54
+ }
55
+
56
+ export interface RunAsyncSqliteOptions {
57
+ /** Override the default 1 h subprocess timeout. */
58
+ timeoutMs?: number;
59
+ /**
60
+ * Force a specific backend. Test-only; production callers should let
61
+ * the runtime pick.
62
+ */
63
+ forceBackend?: AsyncSqliteBackend;
64
+ }
65
+
66
+ let warnedAboutFallback = false;
67
+
68
+ export async function runAsyncSqlite(
69
+ sql: string,
70
+ options: RunAsyncSqliteOptions = {},
71
+ ): Promise<AsyncSqliteResult> {
72
+ const forced = options.forceBackend;
73
+ const sqlite3Path =
74
+ forced === "in-process-blocking" ? undefined : findSqlite3();
75
+
76
+ if (sqlite3Path && forced !== "in-process-blocking") {
77
+ return runViaCli(sqlite3Path, sql, options.timeoutMs ?? DEFAULT_TIMEOUT_MS);
78
+ }
79
+
80
+ if (!warnedAboutFallback) {
81
+ warnedAboutFallback = true;
82
+ log.warn(
83
+ "No sqlite3 CLI found on host — falling back to in-process blocking " +
84
+ "execution for slow SQLite statements. Install sqlite3 to keep the " +
85
+ "event loop responsive during VACUUM and other long operations.",
86
+ );
87
+ }
88
+ return runInProcessBlocking(sql);
89
+ }
90
+
91
+ /** For tests: reset the once-only fallback warning. */
92
+ export function _resetFallbackWarning(): void {
93
+ warnedAboutFallback = false;
94
+ }
95
+
96
+ async function runViaCli(
97
+ sqlite3Path: string,
98
+ sql: string,
99
+ timeoutMs: number,
100
+ ): Promise<AsyncSqliteResult> {
101
+ const startMs = Date.now();
102
+ const dbPath = getDbPath();
103
+
104
+ log.info(
105
+ { sqlite3Path, dbPath, timeoutMs, sqlPreview: sql.slice(0, 80) },
106
+ "Running async SQL via sqlite3 CLI subprocess",
107
+ );
108
+
109
+ // Pass the SQL via stdin rather than -cmd so newlines and quoting are
110
+ // never an issue regardless of the statement complexity.
111
+ const proc = Bun.spawn({
112
+ cmd: [sqlite3Path, dbPath],
113
+ stdin: "pipe",
114
+ stdout: "pipe",
115
+ stderr: "pipe",
116
+ });
117
+
118
+ // Write the SQL and close stdin so sqlite3 sees EOF and exits.
119
+ proc.stdin.write(sql + "\n");
120
+ await proc.stdin.end();
121
+
122
+ // Begin draining the streams immediately so the subprocess never
123
+ // blocks on a full pipe buffer.
124
+ const stdoutPromise = new Response(proc.stdout).text();
125
+ const stderrPromise = new Response(proc.stderr).text();
126
+
127
+ let timedOut = false;
128
+ const timer = setTimeout(() => {
129
+ timedOut = true;
130
+ proc.kill("SIGKILL");
131
+ }, timeoutMs);
132
+ if (typeof timer.unref === "function") timer.unref();
133
+
134
+ const exitCode = await proc.exited;
135
+ clearTimeout(timer);
136
+
137
+ const stdout = await stdoutPromise;
138
+ const stderr = await stderrPromise;
139
+ const elapsedMs = Date.now() - startMs;
140
+
141
+ if (timedOut) {
142
+ log.error(
143
+ { timeoutMs, elapsedMs, stderr: stderr.slice(0, 2000) },
144
+ "Async SQL subprocess timed out — killed",
145
+ );
146
+ return {
147
+ ok: false,
148
+ backend: "sqlite3-cli",
149
+ error: `sqlite3 subprocess timed out after ${timeoutMs}ms`,
150
+ elapsedMs,
151
+ stdout,
152
+ stderr,
153
+ timedOut: true,
154
+ };
155
+ }
156
+ if (exitCode !== 0) {
157
+ log.error(
158
+ { exitCode, elapsedMs, stderr: stderr.slice(0, 2000) },
159
+ "Async SQL subprocess failed",
160
+ );
161
+ return {
162
+ ok: false,
163
+ backend: "sqlite3-cli",
164
+ error: `sqlite3 exited with code ${exitCode}: ${stderr.slice(0, 500)}`,
165
+ elapsedMs,
166
+ stdout,
167
+ stderr,
168
+ };
169
+ }
170
+ return {
171
+ ok: true,
172
+ backend: "sqlite3-cli",
173
+ error: null,
174
+ elapsedMs,
175
+ stdout,
176
+ stderr,
177
+ };
178
+ }
179
+
180
+ async function runInProcessBlocking(sql: string): Promise<AsyncSqliteResult> {
181
+ const startMs = Date.now();
182
+ try {
183
+ const sqlite = getSqlite();
184
+ sqlite.exec(sql);
185
+ // Synthesize `stdout` to match what the CLI backend would emit
186
+ // when the caller chained `SELECT changes();` at the end of their
187
+ // SQL. `bun:sqlite`'s `exec()` discards SELECT results, so without
188
+ // this synthesis, callers that read `stdout` to get the row count
189
+ // (the prune jobs in cleanup.ts, for one) would see `undefined`
190
+ // and treat the run as "no rows deleted" — silently dropping the
191
+ // re-enqueue gate on every fallback host. Captured atomically with
192
+ // exec (same synchronous slice — no other code can run between
193
+ // these two lines), so the count is accurate for the SQL we just
194
+ // ran. Harmless for callers that don't read stdout.
195
+ const changes = (
196
+ sqlite.query("SELECT changes() AS c").get() as { c: number }
197
+ ).c;
198
+ return {
199
+ ok: true,
200
+ backend: "in-process-blocking",
201
+ error: null,
202
+ elapsedMs: Date.now() - startMs,
203
+ stdout: `${changes}\n`,
204
+ };
205
+ } catch (err) {
206
+ const message = err instanceof Error ? err.message : String(err);
207
+ return {
208
+ ok: false,
209
+ backend: "in-process-blocking",
210
+ error: message,
211
+ elapsedMs: Date.now() - startMs,
212
+ };
213
+ }
214
+ }
@@ -6,12 +6,15 @@ import { Database } from "bun:sqlite";
6
6
  import { drizzle } from "drizzle-orm/bun-sqlite";
7
7
 
8
8
  import { ensureDataDir, getDbPath } from "../util/platform.js";
9
+ import {
10
+ clearStoredDb,
11
+ getStoredDb,
12
+ setStoredDb,
13
+ } from "./db-singleton.js";
9
14
  import * as schema from "./schema.js";
10
15
 
11
16
  export type DrizzleDb = ReturnType<typeof drizzle<typeof schema>>;
12
17
 
13
- let db: DrizzleDb | null = null;
14
-
15
18
  function canonicalizePathThroughExistingParent(path: string): string {
16
19
  const resolvedPath = resolve(path);
17
20
  const pendingSegments: string[] = [];
@@ -71,18 +74,20 @@ function assertTestDbIsIsolated(): void {
71
74
  }
72
75
 
73
76
  export function getDb(): DrizzleDb {
74
- if (!db) {
75
- assertTestDbIsIsolated();
76
- ensureDataDir();
77
- const sqlite = new Database(getDbPath());
78
- sqlite.exec("PRAGMA journal_mode=WAL");
79
- sqlite.exec("PRAGMA synchronous=FULL");
80
- sqlite.exec("PRAGMA busy_timeout=5000");
81
- sqlite.exec("PRAGMA foreign_keys = ON");
82
- sqlite.exec("PRAGMA cache_size=-256000");
83
- sqlite.exec("PRAGMA temp_store=MEMORY");
84
- db = drizzle(sqlite, { schema });
85
- }
77
+ const existing = getStoredDb<DrizzleDb>();
78
+ if (existing) return existing;
79
+
80
+ assertTestDbIsIsolated();
81
+ ensureDataDir();
82
+ const sqlite = new Database(getDbPath());
83
+ sqlite.exec("PRAGMA journal_mode=WAL");
84
+ sqlite.exec("PRAGMA synchronous=FULL");
85
+ sqlite.exec("PRAGMA busy_timeout=5000");
86
+ sqlite.exec("PRAGMA foreign_keys = ON");
87
+ sqlite.exec("PRAGMA cache_size=-256000");
88
+ sqlite.exec("PRAGMA temp_store=MEMORY");
89
+ const db = drizzle(sqlite, { schema });
90
+ setStoredDb(db, () => sqlite.close());
86
91
  return db;
87
92
  }
88
93
 
@@ -107,10 +112,15 @@ export function getSqliteFrom(drizzleDb: DrizzleDb): Database {
107
112
  return (drizzleDb as unknown as { $client: Database }).$client;
108
113
  }
109
114
 
110
- /** Reset the db singleton. Used by tests to ensure isolation between test files. */
115
+ /**
116
+ * Reset the db singleton. Used by production callers that need to close
117
+ * the live connection so the file can be replaced (post-migration,
118
+ * post-restore, post-vbundle-import) and on graceful shutdown.
119
+ *
120
+ * Tests should use `resetDbForTesting()` from
121
+ * `__tests__/db-test-helpers.ts` instead so they don't depend on this
122
+ * module's heavy import chain (`drizzle-orm/bun-sqlite`).
123
+ */
111
124
  export function resetDb(): void {
112
- if (db) {
113
- getSqliteFrom(db).close();
114
- db = null;
115
- }
125
+ clearStoredDb();
116
126
  }
@@ -96,6 +96,7 @@ import {
96
96
  migrateDropMemoryItemsTables,
97
97
  migrateDropMemorySegmentFts,
98
98
  migrateDropOrphanedMediaTables,
99
+ migrateDropProviderConnectionStatus,
99
100
  migrateDropRemindersTable,
100
101
  migrateDropSetupSkillIdColumn,
101
102
  migrateDropSimplifiedMemory,
@@ -118,9 +119,11 @@ import {
118
119
  migrateInviteCodeHashColumn,
119
120
  migrateInviteContactId,
120
121
  migrateLlmRequestLogAgentLoopExitReason,
122
+ migrateLlmRequestLogCallSite,
121
123
  migrateLlmRequestLogMessageId,
122
124
  migrateLlmRequestLogProvider,
123
125
  migrateLlmRequestLogsCreatedAtIndex,
126
+ migrateLlmUsageAddRawUsage,
124
127
  migrateLlmUsageAttribution,
125
128
  migrateMemoryGraphImageRefs,
126
129
  migrateMemoryItemSupersession,
@@ -128,7 +131,10 @@ import {
128
131
  migrateMemoryRetrospectiveState,
129
132
  migrateMemoryV2ActivationLogs,
130
133
  migrateMemoryV2InjectionEvents,
134
+ migrateMemoryV3AutoEdges,
135
+ migrateMemoryV3Coactivation,
131
136
  migrateMessageBookmarks,
137
+ migrateMessagesClientMessageId,
132
138
  migrateMessagesConversationCreatedAtIndex,
133
139
  migrateMessagesFtsBackfill,
134
140
  migrateNormalizePhoneIdentities,
@@ -155,6 +161,7 @@ import {
155
161
  migrateProviderConnectionStatusLabel,
156
162
  migrateReminderRoutingIntent,
157
163
  migrateRemindersToSchedules,
164
+ migrateRenameCleanedAt,
158
165
  migrateRenameConversationTypeColumn,
159
166
  migrateRenameCreatedBySessionIdColumns,
160
167
  migrateRenameFollowupsThreadIdColumn,
@@ -452,6 +459,13 @@ export function initializeDb(): void {
452
459
  migrateStripBaseUrlNonOpenaiCompatible,
453
460
  migrateOnboardingEventsPriorAssistants,
454
461
  migrateConversationCleanedAt,
462
+ migrateRenameCleanedAt,
463
+ migrateLlmUsageAddRawUsage,
464
+ migrateMemoryV3Coactivation,
465
+ migrateMemoryV3AutoEdges,
466
+ migrateLlmRequestLogCallSite,
467
+ migrateDropProviderConnectionStatus,
468
+ migrateMessagesClientMessageId,
455
469
  ];
456
470
 
457
471
  // Run each migration step, catching and logging individual failures so one
@@ -3,6 +3,7 @@ import { statSync } from "node:fs";
3
3
  import { getLogger } from "../util/logger.js";
4
4
  import { getDbPath } from "../util/platform.js";
5
5
  import { getMemoryCheckpoint, setMemoryCheckpoint } from "./checkpoints.js";
6
+ import { runAsyncSqlite } from "./db-async-query.js";
6
7
  import { getSqlite } from "./db-connection.js";
7
8
 
8
9
  const log = getLogger("db-maintenance");
@@ -11,7 +12,7 @@ const DB_MAINTENANCE_CHECKPOINT_KEY = "db_maintenance:last_run";
11
12
  const DB_MAINTENANCE_INTERVAL_MS = 24 * 60 * 60 * 1000; // 24 hours
12
13
 
13
14
  interface DbStats {
14
- pageSizeBytes: number;
15
+ pageSize: number;
15
16
  pageCount: number;
16
17
  freelistCount: number;
17
18
  fileSizeBytes: number | null;
@@ -19,7 +20,7 @@ interface DbStats {
19
20
 
20
21
  function getDbStats(): DbStats {
21
22
  const sqlite = getSqlite();
22
- const pageSizeBytes = (
23
+ const pageSize = (
23
24
  sqlite.query("PRAGMA page_size").get() as { page_size: number }
24
25
  ).page_size;
25
26
  const pageCount = (
@@ -34,10 +35,10 @@ function getDbStats(): DbStats {
34
35
  } catch {
35
36
  /* non-fatal */
36
37
  }
37
- return { pageSizeBytes, pageCount, freelistCount, fileSizeBytes };
38
+ return { pageSize, pageCount, freelistCount, fileSizeBytes };
38
39
  }
39
40
 
40
- function runDbMaintenance(): void {
41
+ async function runDbMaintenance(): Promise<void> {
41
42
  const before = getDbStats();
42
43
  const freelistPct =
43
44
  before.pageCount > 0
@@ -54,22 +55,24 @@ function runDbMaintenance(): void {
54
55
  "Starting database maintenance",
55
56
  );
56
57
 
57
- try {
58
- getSqlite().exec("VACUUM");
59
- } catch (err) {
60
- log.warn({ err }, "VACUUM failed (non-fatal)");
61
- try {
62
- getSqlite().exec("PRAGMA optimize");
63
- } catch (optErr) {
64
- log.warn({ err: optErr }, "PRAGMA optimize failed (non-fatal)");
65
- }
66
- return;
58
+ // VACUUM is the long-running one — minutes on a multi-GB DB. PRAGMA
59
+ // optimize is fast but routed through the same async path for
60
+ // consistency and to keep both off the main thread when the CLI
61
+ // backend is available.
62
+ const vacuumResult = await runAsyncSqlite("VACUUM");
63
+ if (!vacuumResult.ok) {
64
+ log.warn(
65
+ { error: vacuumResult.error, backend: vacuumResult.backend },
66
+ "VACUUM failed (non-fatal)",
67
+ );
67
68
  }
68
69
 
69
- try {
70
- getSqlite().exec("PRAGMA optimize");
71
- } catch (err) {
72
- log.warn({ err }, "PRAGMA optimize failed (non-fatal)");
70
+ const optimizeResult = await runAsyncSqlite("PRAGMA optimize");
71
+ if (!optimizeResult.ok) {
72
+ log.warn(
73
+ { error: optimizeResult.error, backend: optimizeResult.backend },
74
+ "PRAGMA optimize failed (non-fatal)",
75
+ );
73
76
  }
74
77
 
75
78
  const after = getDbStats();
@@ -81,17 +84,23 @@ function runDbMaintenance(): void {
81
84
 
82
85
  log.info(
83
86
  {
87
+ backend: vacuumResult.backend,
88
+ vacuumOk: vacuumResult.ok,
89
+ optimizeOk: optimizeResult.ok,
90
+ vacuumElapsedMs: vacuumResult.elapsedMs,
91
+ optimizeElapsedMs: optimizeResult.elapsedMs,
84
92
  beforePageCount: before.pageCount,
85
93
  afterPageCount: after.pageCount,
86
94
  reclaimedPages,
87
- reclaimedBytes,
95
+ beforeFileSizeBytes: before.fileSizeBytes,
88
96
  afterFileSizeBytes: after.fileSizeBytes,
97
+ reclaimedBytes,
89
98
  },
90
99
  "Database maintenance complete",
91
100
  );
92
101
  }
93
102
 
94
- export function maybeRunDbMaintenance(nowMs = Date.now()): void {
103
+ export async function maybeRunDbMaintenance(nowMs = Date.now()): Promise<void> {
95
104
  const lastRun = parseInt(
96
105
  getMemoryCheckpoint(DB_MAINTENANCE_CHECKPOINT_KEY) ?? "0",
97
106
  10,
@@ -99,7 +108,7 @@ export function maybeRunDbMaintenance(nowMs = Date.now()): void {
99
108
  if (nowMs - lastRun < DB_MAINTENANCE_INTERVAL_MS) return;
100
109
 
101
110
  try {
102
- runDbMaintenance();
111
+ await runDbMaintenance();
103
112
  } catch (err) {
104
113
  log.error({ err }, "Database maintenance failed unexpectedly");
105
114
  }
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Holds the assistant DB connection singleton and its close callback.
3
+ *
4
+ * Lives in its own module (rather than alongside the resolver in
5
+ * `db-connection.ts`) so test code can reset the singleton without
6
+ * importing `db-connection.ts` — which transitively pulls
7
+ * `drizzle-orm/bun-sqlite`. Stdlib-only by design: this file must remain
8
+ * safe to import from the test preload's load-time chain, where a broken
9
+ * `node_modules` symlink has historically tripped the env override
10
+ * (see DB ghost #3, /workspace/journal/2026-05-25-db-ghost-3-recovery.md).
11
+ *
12
+ * State is held on `globalThis.vellumAssistant.dbSingleton` so test
13
+ * helpers in `__tests__/` can read/write it WITHOUT importing this
14
+ * module — they declare the same slot shape locally and access the
15
+ * globalThis namespace directly. See
16
+ * `__tests__/db-test-helpers.ts` for the test-side mirror; the slot
17
+ * shape MUST stay in sync between the two.
18
+ *
19
+ * The stored value is typed as `unknown` so this file never has to import
20
+ * Drizzle types. Callers in `db-connection.ts` narrow via the type
21
+ * parameter on `getStoredDb<DrizzleDb>()`.
22
+ *
23
+ * Consumers:
24
+ * - `db-connection.ts` (opens/owns the connection)
25
+ * - production callers that need to close the active connection
26
+ * (migration routes, vbundle import, backup/restore, daemon shutdown)
27
+ * - `__tests__/db-test-helpers.ts` (per-test reset, via globalThis)
28
+ */
29
+
30
+ type DbSlot = {
31
+ db: unknown;
32
+ closer: (() => void) | null;
33
+ };
34
+
35
+ type VellumAssistantNamespace = {
36
+ dbSingleton?: DbSlot;
37
+ };
38
+
39
+ function slot(): DbSlot {
40
+ const g = globalThis as { vellumAssistant?: VellumAssistantNamespace };
41
+ const ns = (g.vellumAssistant ??= {});
42
+ return (ns.dbSingleton ??= { db: null, closer: null });
43
+ }
44
+
45
+ /** Read the current singleton, narrowed to `T`. `null` means not yet opened. */
46
+ export function getStoredDb<T>(): T | null {
47
+ return slot().db as T | null;
48
+ }
49
+
50
+ /**
51
+ * Store a freshly-opened connection and the closer to run on
52
+ * `clearStoredDb()`. The closer must be self-contained — it is invoked
53
+ * inside a try/catch, so partial failures are swallowed (best-effort
54
+ * close on shutdown / restore paths).
55
+ */
56
+ export function setStoredDb<T>(newDb: T, close: () => void): void {
57
+ const s = slot();
58
+ s.db = newDb;
59
+ s.closer = close;
60
+ }
61
+
62
+ /**
63
+ * Close the active connection (if any) via the stored closer, then drop
64
+ * both. Idempotent: safe to call when no connection is stored.
65
+ */
66
+ export function clearStoredDb(): void {
67
+ const s = slot();
68
+ if (s.closer) {
69
+ try {
70
+ s.closer();
71
+ } catch {
72
+ /* best-effort close */
73
+ }
74
+ }
75
+ s.db = null;
76
+ s.closer = null;
77
+ }
@@ -10,6 +10,36 @@ import { eq } from "drizzle-orm";
10
10
  import { getDb } from "./db-connection.js";
11
11
  import { channelInboundEvents } from "./schema.js";
12
12
 
13
+ const SLACK_DM_LIVE_DELIVERED_TEXT_RESPONSE_INDEXES =
14
+ "slackDmLiveDeliveredTextResponseIndexes";
15
+
16
+ function parseRawPayload(
17
+ rawPayload: string | null,
18
+ ): Record<string, unknown> | undefined {
19
+ if (!rawPayload) return undefined;
20
+ try {
21
+ const parsed = JSON.parse(rawPayload) as unknown;
22
+ if (
23
+ parsed === null ||
24
+ typeof parsed !== "object" ||
25
+ Array.isArray(parsed)
26
+ ) {
27
+ return undefined;
28
+ }
29
+ return parsed as Record<string, unknown>;
30
+ } catch {
31
+ return undefined;
32
+ }
33
+ }
34
+
35
+ function normalizePositiveIntegerIndexes(value: unknown): number[] {
36
+ if (!Array.isArray(value)) return [];
37
+ const indexes = value.filter(
38
+ (item): item is number => Number.isSafeInteger(item) && item > 0,
39
+ );
40
+ return [...new Set(indexes)].sort((a, b) => a - b);
41
+ }
42
+
13
43
  // ── Pending verification reply helpers ───────────────────────────────
14
44
  //
15
45
  // When a guardian verification succeeds but the confirmation reply fails
@@ -100,6 +130,58 @@ export function updateDeliveredSegmentCount(
100
130
  .run();
101
131
  }
102
132
 
133
+ export function getSlackDmLiveDeliveredTextResponseIndexes(
134
+ eventId: string,
135
+ ): number[] {
136
+ const db = getDb();
137
+ const row = db
138
+ .select({ rawPayload: channelInboundEvents.rawPayload })
139
+ .from(channelInboundEvents)
140
+ .where(eq(channelInboundEvents.id, eventId))
141
+ .get();
142
+ const payload = parseRawPayload(row?.rawPayload ?? null);
143
+ if (!payload) return [];
144
+ return normalizePositiveIntegerIndexes(
145
+ payload[SLACK_DM_LIVE_DELIVERED_TEXT_RESPONSE_INDEXES],
146
+ );
147
+ }
148
+
149
+ export function addSlackDmLiveDeliveredTextResponseIndex(
150
+ eventId: string,
151
+ responseIndex: number,
152
+ ): void {
153
+ if (!Number.isSafeInteger(responseIndex) || responseIndex <= 0) return;
154
+
155
+ const db = getDb();
156
+ db.transaction((tx) => {
157
+ const row = tx
158
+ .select({ rawPayload: channelInboundEvents.rawPayload })
159
+ .from(channelInboundEvents)
160
+ .where(eq(channelInboundEvents.id, eventId))
161
+ .get();
162
+ if (!row?.rawPayload) return;
163
+
164
+ const payload = parseRawPayload(row.rawPayload);
165
+ if (!payload) return;
166
+ const indexes = normalizePositiveIntegerIndexes(
167
+ payload[SLACK_DM_LIVE_DELIVERED_TEXT_RESPONSE_INDEXES],
168
+ );
169
+ if (!indexes.includes(responseIndex)) indexes.push(responseIndex);
170
+ indexes.sort((a, b) => a - b);
171
+
172
+ tx.update(channelInboundEvents)
173
+ .set({
174
+ rawPayload: JSON.stringify({
175
+ ...payload,
176
+ [SLACK_DM_LIVE_DELIVERED_TEXT_RESPONSE_INDEXES]: indexes,
177
+ }),
178
+ updatedAt: Date.now(),
179
+ })
180
+ .where(eq(channelInboundEvents.id, eventId))
181
+ .run();
182
+ });
183
+ }
184
+
103
185
  // ── Deliver-once guard for terminal reply idempotency ────────────────
104
186
  //
105
187
  // When both the main poll (processChannelMessageWithApprovals) and the