@vellumai/assistant 0.8.3 → 0.8.5

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 (665) hide show
  1. package/ARCHITECTURE.md +2 -2
  2. package/docker-entrypoint.sh +0 -1
  3. package/docs/browser-use-architecture-phase2.md +1 -1
  4. package/knip.json +2 -1
  5. package/node_modules/@vellumai/gateway-client/src/types.ts +2 -0
  6. package/openapi.yaml +1492 -100
  7. package/package.json +1 -1
  8. package/src/__tests__/agent-loop-exit-reason.test.ts +4 -5
  9. package/src/__tests__/agent-loop-override-profile.test.ts +1 -1
  10. package/src/__tests__/agent-loop.test.ts +88 -3
  11. package/src/__tests__/anthropic-provider.test.ts +302 -33
  12. package/src/__tests__/approval-cascade.test.ts +1 -1
  13. package/src/__tests__/assistant-event-hub-self-exclusion.test.ts +293 -0
  14. package/src/__tests__/assistant-feature-flags-integration.test.ts +3 -3
  15. package/src/__tests__/audit-log-rotation.test.ts +70 -16
  16. package/src/__tests__/background-workers-disk-pressure.test.ts +4 -3
  17. package/src/__tests__/btw-routes.test.ts +2 -3
  18. package/src/__tests__/call-controller.test.ts +0 -1
  19. package/src/__tests__/cancel-resolves-conversation-key.test.ts +1 -1
  20. package/src/__tests__/channel-delivery-store.test.ts +193 -0
  21. package/src/__tests__/channel-guardian.test.ts +3 -3
  22. package/src/__tests__/channel-reply-delivery.test.ts +284 -5
  23. package/src/__tests__/channel-retry-sweep.test.ts +274 -1
  24. package/src/__tests__/checker.test.ts +6 -15
  25. package/src/__tests__/compaction-events.test.ts +2 -1
  26. package/src/__tests__/compactor-call-site-logging.test.ts +214 -0
  27. package/src/__tests__/compactor-preserved-tail-count.test.ts +110 -0
  28. package/src/__tests__/computer-use-skill-manifest-regression.test.ts +5 -11
  29. package/src/__tests__/computer-use-tools.test.ts +2 -4
  30. package/src/__tests__/config-watcher.test.ts +1 -1
  31. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +0 -1
  32. package/src/__tests__/context-token-estimator.test.ts +91 -1
  33. package/src/__tests__/conversation-abort-tool-results.test.ts +1 -1
  34. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +1 -1
  35. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +55 -4
  36. package/src/__tests__/conversation-agent-loop-overflow.test.ts +228 -8
  37. package/src/__tests__/conversation-agent-loop.test.ts +188 -129
  38. package/src/__tests__/conversation-app-control-instantiation.test.ts +2 -5
  39. package/src/__tests__/conversation-app-control-lifecycle.test.ts +1 -1
  40. package/src/__tests__/conversation-clean-command.test.ts +137 -0
  41. package/src/__tests__/conversation-clear-safety.test.ts +25 -25
  42. package/src/__tests__/conversation-confirmation-signals.test.ts +1 -1
  43. package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +1 -1
  44. package/src/__tests__/conversation-disk-view-integration.test.ts +2 -2
  45. package/src/__tests__/conversation-error.test.ts +31 -0
  46. package/src/__tests__/conversation-fork-crud.test.ts +324 -0
  47. package/src/__tests__/conversation-lifecycle.test.ts +53 -12
  48. package/src/__tests__/conversation-load-history-repair.test.ts +1 -1
  49. package/src/__tests__/conversation-load-history-stripped.test.ts +279 -0
  50. package/src/__tests__/conversation-pairing.test.ts +2 -2
  51. package/src/__tests__/conversation-process-callsite.test.ts +1 -1
  52. package/src/__tests__/conversation-provider-retry-repair.test.ts +2 -1
  53. package/src/__tests__/conversation-queue.test.ts +1 -1
  54. package/src/__tests__/conversation-routes-disk-view.test.ts +109 -0
  55. package/src/__tests__/conversation-routes-slash-commands.test.ts +35 -0
  56. package/src/__tests__/conversation-runtime-assembly.test.ts +264 -81
  57. package/src/__tests__/conversation-seed-composer.test.ts +66 -4
  58. package/src/__tests__/conversation-skill-tools.test.ts +2 -5
  59. package/src/__tests__/conversation-slash-commands.test.ts +36 -8
  60. package/src/__tests__/conversation-slash-queue.test.ts +1 -1
  61. package/src/__tests__/conversation-slash-unknown.test.ts +1 -1
  62. package/src/__tests__/conversation-speed-override.test.ts +1 -1
  63. package/src/__tests__/conversation-store.test.ts +1 -1
  64. package/src/__tests__/conversation-surfaces-task-progress.test.ts +220 -0
  65. package/src/__tests__/conversation-sync-tags.test.ts +99 -32
  66. package/src/__tests__/conversation-workspace-cache-state.test.ts +2 -1
  67. package/src/__tests__/conversation-workspace-injection.test.ts +5 -1
  68. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +5 -1
  69. package/src/__tests__/credential-execution-feature-gates.test.ts +9 -7
  70. package/src/__tests__/credential-execution-tools.test.ts +6 -6
  71. package/src/__tests__/credential-security-invariants.test.ts +7 -0
  72. package/src/__tests__/credential-vault-unit.test.ts +2 -2
  73. package/src/__tests__/cu-unified-flow.test.ts +10 -1
  74. package/src/__tests__/dm-backfill.test.ts +64 -0
  75. package/src/__tests__/dm-persistence.test.ts +33 -0
  76. package/src/__tests__/document-find-replace.test.ts +501 -0
  77. package/src/__tests__/dynamic-page-surface.test.ts +2 -2
  78. package/src/__tests__/email-html-renderer.test.ts +12 -0
  79. package/src/__tests__/first-greeting.test.ts +23 -2
  80. package/src/__tests__/gateway-flag-listener.test.ts +237 -0
  81. package/src/__tests__/gemini-provider.test.ts +78 -0
  82. package/src/__tests__/guardian-dispatch.test.ts +0 -1
  83. package/src/__tests__/guardian-outbound-http.test.ts +7 -5
  84. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +1 -1
  85. package/src/__tests__/headless-browser-navigate.test.ts +172 -0
  86. package/src/__tests__/heartbeat-disk-pressure.test.ts +4 -0
  87. package/src/__tests__/heartbeat-service.test.ts +4 -0
  88. package/src/__tests__/host-bash-proxy.test.ts +6 -0
  89. package/src/__tests__/host-browser-proxy.test.ts +10 -0
  90. package/src/__tests__/host-cu-proxy.test.ts +8 -1
  91. package/src/__tests__/host-file-proxy.test.ts +8 -1
  92. package/src/__tests__/host-shell-tool.test.ts +1 -1
  93. package/src/__tests__/host-transfer-proxy.test.ts +8 -1
  94. package/src/__tests__/identity-routes.test.ts +57 -0
  95. package/src/__tests__/inbound-slack-persistence.test.ts +3 -0
  96. package/src/__tests__/init-feature-flag-overrides.test.ts +5 -6
  97. package/src/__tests__/injector-chain.test.ts +2 -0
  98. package/src/__tests__/injector-document-comments.test.ts +378 -0
  99. package/src/__tests__/injector-pkb-v2-silenced.test.ts +4 -25
  100. package/src/__tests__/list-messages-attachments.test.ts +21 -17
  101. package/src/__tests__/list-messages-hidden-metadata.test.ts +217 -0
  102. package/src/__tests__/list-messages-page-latest.test.ts +130 -14
  103. package/src/__tests__/list-messages-tool-merge.test.ts +77 -17
  104. package/src/__tests__/llm-context-normalization.test.ts +0 -2
  105. package/src/__tests__/llm-request-log-call-site.test.ts +136 -0
  106. package/src/__tests__/llm-request-log-source-clickhouse.test.ts +26 -0
  107. package/src/__tests__/llm-resolver.test.ts +161 -9
  108. package/src/__tests__/llm-usage-store.test.ts +66 -0
  109. package/src/__tests__/log-export-routes.test.ts +99 -2
  110. package/src/__tests__/logger.test.ts +89 -0
  111. package/src/__tests__/mcp-abort-signal.test.ts +2 -2
  112. package/src/__tests__/media-generate-image.test.ts +31 -0
  113. package/src/__tests__/memory-v2-static-injector.test.ts +7 -7
  114. package/src/__tests__/message-queue-steer.test.ts +114 -0
  115. package/src/__tests__/model-intents.test.ts +2 -4
  116. package/src/__tests__/notification-guardian-path.test.ts +0 -1
  117. package/src/__tests__/onboarding-template-contract.test.ts +1 -1
  118. package/src/__tests__/openai-provider.test.ts +151 -0
  119. package/src/__tests__/openai-responses-provider.test.ts +118 -16
  120. package/src/__tests__/outbound-slack-persistence.test.ts +187 -20
  121. package/src/__tests__/pending-interactions-resolved-event.test.ts +189 -0
  122. package/src/__tests__/platform-bash-auto-approve.test.ts +2 -2
  123. package/src/__tests__/platform.test.ts +2 -5
  124. package/src/__tests__/plugin-api-tool-definition.test.ts +92 -0
  125. package/src/__tests__/plugin-bootstrap.test.ts +2 -2
  126. package/src/__tests__/plugin-source-watcher.test.ts +302 -0
  127. package/src/__tests__/plugin-tool-contribution.test.ts +13 -6
  128. package/src/__tests__/plugin-types.test.ts +3 -2
  129. package/src/__tests__/prechat-onboarding-contract.test.ts +131 -98
  130. package/src/__tests__/pricing.test.ts +12 -0
  131. package/src/__tests__/process-message-background-slack.test.ts +1 -51
  132. package/src/__tests__/process-message-display-content.test.ts +21 -16
  133. package/src/__tests__/prune-jobs-changes-parser.test.ts +61 -0
  134. package/src/__tests__/registry.test.ts +2 -8
  135. package/src/__tests__/require-fresh-approval.test.ts +2 -2
  136. package/src/__tests__/runtime-events-sse-bilingual.test.ts +154 -0
  137. package/src/__tests__/server-history-render.test.ts +83 -4
  138. package/src/__tests__/shell-tool-proxy-mode.test.ts +1 -1
  139. package/src/__tests__/skill-feature-flags.test.ts +2 -2
  140. package/src/__tests__/skill-projection-feature-flag.test.ts +4 -7
  141. package/src/__tests__/skill-projection.benchmark.test.ts +2 -6
  142. package/src/__tests__/skill-tool-factory.test.ts +1 -1
  143. package/src/__tests__/steer-tool-repair.test.ts +249 -0
  144. package/src/__tests__/subagent-notify-parent.test.ts +1 -1
  145. package/src/__tests__/suggestion-routes.test.ts +1 -0
  146. package/src/__tests__/sync-message-contract.test.ts +59 -0
  147. package/src/__tests__/system-prompt.test.ts +161 -124
  148. package/src/__tests__/terminal-tools.test.ts +12 -2
  149. package/src/__tests__/thinking-block-replay.test.ts +113 -0
  150. package/src/__tests__/thread-backfill.test.ts +370 -22
  151. package/src/__tests__/tool-approval-handler.test.ts +1 -5
  152. package/src/__tests__/tool-execute-pipeline.test.ts +2 -2
  153. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +2 -5
  154. package/src/__tests__/tool-executor-lifecycle-events.test.ts +15 -5
  155. package/src/__tests__/tool-executor.test.ts +89 -53
  156. package/src/__tests__/tool-grant-request-escalation.test.ts +1 -6
  157. package/src/__tests__/tool-result-metadata-plumbing.test.ts +167 -0
  158. package/src/__tests__/trusted-contact-approval-notifier.test.ts +0 -1
  159. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +1 -6
  160. package/src/__tests__/trusted-contact-multichannel.test.ts +0 -1
  161. package/src/__tests__/twilio-routes.test.ts +1 -1
  162. package/src/__tests__/ui-file-upload-surface.test.ts +2 -2
  163. package/src/__tests__/usage-routes.test.ts +3 -0
  164. package/src/__tests__/verification-control-plane-policy.test.ts +2 -2
  165. package/src/__tests__/web-fetch.test.ts +2 -2
  166. package/src/__tests__/workspace-git-service.test.ts +94 -10
  167. package/src/__tests__/workspace-migration-088-deprecate-background-conversation-override.test.ts +158 -0
  168. package/src/__tests__/workspace-migration-089-move-memory-tree-out-of-v3.test.ts +86 -0
  169. package/src/acp/__tests__/prepare-agent-env.test.ts +146 -0
  170. package/src/acp/prepare-agent-env.ts +78 -0
  171. package/src/acp/session-manager.ts +1 -1
  172. package/src/agent/attachments.ts +1 -0
  173. package/src/agent/loop.ts +65 -20
  174. package/src/api/README.md +5 -0
  175. package/src/api/index.ts +4 -0
  176. package/src/api/package.json +10 -0
  177. package/src/background-wake/background-wake-routes.test.ts +233 -0
  178. package/src/background-wake/next-wake.test.ts +289 -0
  179. package/src/background-wake/next-wake.ts +172 -0
  180. package/src/background-wake/runtime-registry.ts +24 -0
  181. package/src/browser/operations.ts +15 -0
  182. package/src/cli/commands/__tests__/browser.test.ts +23 -5
  183. package/src/cli/commands/__tests__/conversations-slack.test.ts +572 -0
  184. package/src/cli/commands/__tests__/domain-register.test.ts +110 -0
  185. package/src/cli/commands/__tests__/domain-status.test.ts +33 -33
  186. package/src/cli/commands/__tests__/inference-send.test.ts +108 -5
  187. package/src/cli/commands/__tests__/memory-v2-compare-render.test.ts +98 -0
  188. package/src/cli/commands/__tests__/memory-v2.test.ts +10 -12
  189. package/src/cli/commands/__tests__/memory-v3-render.test.ts +340 -0
  190. package/src/cli/commands/browser.ts +247 -0
  191. package/src/cli/commands/conversations.ts +128 -1
  192. package/src/cli/commands/domain.ts +91 -41
  193. package/src/cli/commands/inference-providers.ts +147 -1
  194. package/src/cli/commands/inference.ts +93 -40
  195. package/src/cli/commands/memory-v2-compare-render.ts +115 -0
  196. package/src/cli/commands/memory-v2.ts +483 -0
  197. package/src/cli/commands/memory-v3-render.ts +344 -0
  198. package/src/cli/commands/memory-v3.ts +316 -0
  199. package/src/cli/commands/notifications.ts +24 -2
  200. package/src/cli/program.ts +2 -0
  201. package/src/cli/utils/conversation-id.ts +17 -5
  202. package/src/config/assistant-feature-flags.ts +21 -9
  203. package/src/config/bundled-skills/app-builder/SKILL.md +2 -2
  204. package/src/config/bundled-skills/document-editor/SKILL.md +124 -0
  205. package/src/config/bundled-skills/document-editor/TOOLS.json +258 -0
  206. package/src/config/bundled-skills/document-editor/tools/comment-list.ts +12 -0
  207. package/src/config/bundled-skills/document-editor/tools/comment-reply.ts +12 -0
  208. package/src/config/bundled-skills/document-editor/tools/comment-resolve.ts +12 -0
  209. package/src/config/bundled-skills/document-editor/tools/document-find.ts +12 -0
  210. package/src/config/bundled-skills/document-editor/tools/document-open.ts +12 -0
  211. package/src/config/bundled-skills/document-editor/tools/document-replace-text.ts +12 -0
  212. package/src/config/bundled-skills/image-studio/SKILL.md +4 -0
  213. package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +2 -2
  214. package/src/config/bundled-skills/media-processing/SKILL.md +8 -0
  215. package/src/config/bundled-skills/media-processing/tools/ingest-media.ts +13 -8
  216. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +10 -3
  217. package/src/config/bundled-skills/phone-calls/references/TRANSCRIPTS.md +16 -14
  218. package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +7 -2
  219. package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +7 -2
  220. package/src/config/bundled-skills/schedule/SKILL.md +8 -0
  221. package/src/config/bundled-tool-registry.ts +24 -12
  222. package/src/config/call-site-defaults.ts +20 -0
  223. package/src/config/feature-flag-registry.json +115 -3
  224. package/src/config/llm-resolver.ts +16 -2
  225. package/src/config/schemas/__tests__/memory-v2.test.ts +217 -1
  226. package/src/config/schemas/call-site-catalog.ts +35 -0
  227. package/src/config/schemas/llm.ts +14 -0
  228. package/src/config/schemas/memory-v2.ts +294 -1
  229. package/src/config/schemas/memory.ts +2 -1
  230. package/src/context/compactor.ts +60 -1
  231. package/src/context/token-estimator.ts +47 -4
  232. package/src/context/window-manager.ts +25 -0
  233. package/src/conversations/__tests__/message-consolidation.test.ts +350 -0
  234. package/src/conversations/message-consolidation.ts +404 -0
  235. package/src/credential-health/credential-health-service.ts +34 -19
  236. package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +1 -1
  237. package/src/daemon/__tests__/conversation-tool-setup.test.ts +66 -6
  238. package/src/daemon/__tests__/meet-manifest-loader.test.ts +1 -1
  239. package/src/daemon/__tests__/native-web-search-metadata.test.ts +357 -0
  240. package/src/daemon/__tests__/web-search-status-text.test.ts +287 -0
  241. package/src/daemon/conversation-agent-loop-handlers.ts +155 -36
  242. package/src/daemon/conversation-agent-loop.ts +307 -88
  243. package/src/daemon/conversation-error.ts +31 -1
  244. package/src/daemon/conversation-lifecycle.ts +149 -118
  245. package/src/daemon/conversation-messaging.ts +3 -0
  246. package/src/daemon/conversation-process.ts +273 -0
  247. package/src/daemon/conversation-queue-manager.ts +14 -0
  248. package/src/daemon/conversation-runtime-assembly.ts +145 -84
  249. package/src/daemon/conversation-slash.ts +37 -5
  250. package/src/daemon/conversation-surfaces.ts +45 -2
  251. package/src/daemon/conversation-tool-setup.ts +70 -3
  252. package/src/daemon/conversation-usage.ts +2 -0
  253. package/src/daemon/conversation.ts +54 -32
  254. package/src/daemon/disk-pressure-guard.ts +14 -2
  255. package/src/daemon/first-greeting.ts +10 -0
  256. package/src/daemon/handlers/__tests__/config-a2a-accept.test.ts +498 -0
  257. package/src/daemon/handlers/config-a2a.ts +160 -0
  258. package/src/daemon/handlers/config-model.test.ts +2 -0
  259. package/src/daemon/handlers/conversations.ts +90 -3
  260. package/src/daemon/handlers/shared.ts +92 -29
  261. package/src/daemon/host-bash-proxy.ts +1 -1
  262. package/src/daemon/host-browser-proxy.ts +5 -5
  263. package/src/daemon/host-cu-proxy.ts +5 -5
  264. package/src/daemon/host-file-proxy.ts +5 -5
  265. package/src/daemon/host-proxy-base.ts +4 -4
  266. package/src/daemon/host-transfer-proxy.ts +11 -11
  267. package/src/daemon/lifecycle.ts +40 -23
  268. package/src/daemon/meet-manifest-loader.ts +1 -7
  269. package/src/daemon/message-protocol.ts +4 -0
  270. package/src/daemon/message-types/conversations.ts +14 -9
  271. package/src/daemon/message-types/document-comments.ts +50 -0
  272. package/src/daemon/message-types/home.ts +1 -13
  273. package/src/daemon/message-types/messages.ts +66 -7
  274. package/src/daemon/message-types/surfaces.ts +3 -1
  275. package/src/daemon/message-types/sync.ts +14 -0
  276. package/src/daemon/message-types/web-activity.ts +57 -0
  277. package/src/daemon/plugin-source-watcher.ts +135 -3
  278. package/src/daemon/process-message.ts +69 -12
  279. package/src/daemon/shutdown-handlers.ts +24 -5
  280. package/src/daemon/switch-inference-profile-tool.ts +52 -0
  281. package/src/daemon/tool-setup-types.ts +13 -0
  282. package/src/daemon/trust-context.ts +6 -0
  283. package/src/documents/document-comments-store.test.ts +338 -0
  284. package/src/documents/document-comments-store.ts +237 -0
  285. package/src/documents/document-store.ts +202 -0
  286. package/src/events/relationship-state-updated.ts +25 -0
  287. package/src/heartbeat/__tests__/heartbeat-service.test.ts +1 -2
  288. package/src/heartbeat/heartbeat-service.ts +1 -0
  289. package/src/home/__tests__/suggested-prompts.test.ts +33 -2
  290. package/src/home/feed-types.ts +6 -1
  291. package/src/home/home-content-refresh.ts +52 -0
  292. package/src/home/home-greeting-cache.ts +69 -0
  293. package/src/home/home-greeting.ts +85 -0
  294. package/src/home/suggested-prompts.ts +168 -9
  295. package/src/ipc/gateway-flag-listener.ts +123 -0
  296. package/src/ipc/skill-routes/registries.ts +8 -12
  297. package/src/memory/__tests__/db-async-query.test.ts +165 -0
  298. package/src/memory/__tests__/db-maintenance.test.ts +115 -0
  299. package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +241 -0
  300. package/src/memory/__tests__/jobs-store-job-classes.test.ts +28 -1
  301. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +135 -2
  302. package/src/memory/__tests__/memory-retrospective-job.test.ts +327 -6
  303. package/src/memory/auto-analysis-enqueue.ts +5 -1
  304. package/src/memory/conversation-crud.ts +191 -100
  305. package/src/memory/conversation-starters-cadence.ts +3 -1
  306. package/src/memory/conversation-title-service.ts +19 -3
  307. package/src/memory/db-async-query.ts +214 -0
  308. package/src/memory/db-init.ts +26 -0
  309. package/src/memory/db-maintenance.ts +30 -21
  310. package/src/memory/delivery-crud.ts +41 -0
  311. package/src/memory/delivery-status.ts +141 -15
  312. package/src/memory/external-conversation-store.ts +32 -1
  313. package/src/memory/graph/bootstrap.ts +8 -1
  314. package/src/memory/graph/capability-seed.ts +7 -3
  315. package/src/memory/graph/conversation-graph-memory.ts +100 -17
  316. package/src/memory/graph/extraction.ts +1 -5
  317. package/src/memory/graph/graph-search.ts +7 -1
  318. package/src/memory/indexer.ts +28 -18
  319. package/src/memory/job-handlers/cleanup.ts +76 -18
  320. package/src/memory/job-handlers/conversation-starters.ts +1 -4
  321. package/src/memory/jobs/embed-pkb-file.ts +6 -1
  322. package/src/memory/jobs-store.ts +14 -0
  323. package/src/memory/jobs-worker.ts +68 -15
  324. package/src/memory/llm-request-log-source-clickhouse.ts +42 -2
  325. package/src/memory/llm-request-log-source-local.ts +7 -0
  326. package/src/memory/llm-request-log-source.ts +9 -2
  327. package/src/memory/llm-request-log-store.ts +43 -1
  328. package/src/memory/llm-usage-store.ts +24 -0
  329. package/src/memory/memory-retrospective-constants.ts +28 -0
  330. package/src/memory/memory-retrospective-enqueue.ts +11 -3
  331. package/src/memory/memory-retrospective-job.ts +413 -18
  332. package/src/memory/memory-retrospective-startup-cleanup.ts +3 -3
  333. package/src/memory/memory-v2-activation-log-store.ts +41 -14
  334. package/src/memory/migrations/100-core-tables.ts +1 -0
  335. package/src/memory/migrations/109-external-conversation-bindings.ts +1 -0
  336. package/src/memory/migrations/253-conversation-last-notified-profile.ts +15 -0
  337. package/src/memory/migrations/253-document-comments.ts +47 -0
  338. package/src/memory/migrations/254-external-conversation-binding-chat-name.ts +43 -0
  339. package/src/memory/migrations/255-channel-inbound-delivery-attempts.ts +24 -0
  340. package/src/memory/migrations/256-memory-v2-injection-events.ts +113 -0
  341. package/src/memory/migrations/257-strip-base-url-non-openai-compatible.ts +22 -0
  342. package/src/memory/migrations/258-onboarding-events-prior-assistants.ts +13 -0
  343. package/src/memory/migrations/259-conversation-cleaned-at.ts +33 -0
  344. package/src/memory/migrations/260-rename-cleaned-at.ts +44 -0
  345. package/src/memory/migrations/261-llm-usage-add-raw-usage.ts +36 -0
  346. package/src/memory/migrations/262-memory-v3-coactivation.ts +57 -0
  347. package/src/memory/migrations/263-memory-v3-auto-edges.ts +50 -0
  348. package/src/memory/migrations/264-llm-request-log-call-site.ts +29 -0
  349. package/src/memory/migrations/index.ts +34 -0
  350. package/src/memory/migrations/registry.ts +58 -0
  351. package/src/memory/onboarding-events-store.ts +7 -0
  352. package/src/memory/schema/calls.ts +1 -0
  353. package/src/memory/schema/conversations.ts +3 -0
  354. package/src/memory/schema/infrastructure.ts +22 -0
  355. package/src/memory/tool-usage-store.ts +36 -8
  356. package/src/memory/v2/__tests__/consolidation-job.test.ts +1 -0
  357. package/src/memory/v2/__tests__/harness-compare.test.ts +186 -0
  358. package/src/memory/v2/__tests__/harness-metrics.test.ts +74 -0
  359. package/src/memory/v2/__tests__/harness-oracle.test.ts +257 -0
  360. package/src/memory/v2/__tests__/harness-replay-input.test.ts +225 -0
  361. package/src/memory/v2/__tests__/harness-runner.test.ts +109 -0
  362. package/src/memory/v2/__tests__/injection-events.test.ts +318 -0
  363. package/src/memory/v2/__tests__/injection.test.ts +158 -112
  364. package/src/memory/v2/__tests__/page-index.test.ts +365 -1
  365. package/src/memory/v2/__tests__/qdrant.test.ts +36 -0
  366. package/src/memory/v2/__tests__/router.test.ts +660 -4
  367. package/src/memory/v2/consolidation-job.ts +14 -0
  368. package/src/memory/v2/harness/compare.ts +57 -0
  369. package/src/memory/v2/harness/metrics.ts +124 -0
  370. package/src/memory/v2/harness/oracle.ts +145 -0
  371. package/src/memory/v2/harness/replay-input.ts +224 -0
  372. package/src/memory/v2/harness/retriever.ts +74 -0
  373. package/src/memory/v2/harness/router-retriever.ts +43 -0
  374. package/src/memory/v2/harness/runner.ts +106 -0
  375. package/src/memory/v2/harness/trace.ts +58 -0
  376. package/src/memory/v2/injection-events.ts +101 -0
  377. package/src/memory/v2/injection.ts +42 -25
  378. package/src/memory/v2/page-index.ts +209 -7
  379. package/src/memory/v2/page-store.ts +18 -0
  380. package/src/memory/v2/prompts/router.ts +26 -1
  381. package/src/memory/v2/qdrant.ts +14 -2
  382. package/src/memory/v2/router.ts +369 -62
  383. package/src/memory/v3/__tests__/coactivation-store.test.ts +422 -0
  384. package/src/memory/v3/__tests__/consolidation-job.test.ts +468 -0
  385. package/src/memory/v3/__tests__/edge-learning-job.test.ts +324 -0
  386. package/src/memory/v3/__tests__/edges.test.ts +563 -0
  387. package/src/memory/v3/__tests__/filter.test.ts +512 -0
  388. package/src/memory/v3/__tests__/gate.test.ts +574 -0
  389. package/src/memory/v3/__tests__/index-composition.test.ts +233 -0
  390. package/src/memory/v3/__tests__/loop.test.ts +530 -0
  391. package/src/memory/v3/__tests__/retriever.test.ts +226 -0
  392. package/src/memory/v3/__tests__/scouts.test.ts +440 -0
  393. package/src/memory/v3/__tests__/shadow-middleware.test.ts +312 -0
  394. package/src/memory/v3/__tests__/system-prompts.test.ts +154 -0
  395. package/src/memory/v3/__tests__/traversal.test.ts +469 -0
  396. package/src/memory/v3/__tests__/tree-index.test.ts +280 -0
  397. package/src/memory/v3/__tests__/tree-store.test.ts +529 -0
  398. package/src/memory/v3/__tests__/tree-walk.test.ts +707 -0
  399. package/src/memory/v3/__tests__/validate.test.ts +245 -0
  400. package/src/memory/v3/auto-edges.ts +223 -0
  401. package/src/memory/v3/coactivation-store.ts +124 -0
  402. package/src/memory/v3/consolidation-job.ts +323 -0
  403. package/src/memory/v3/edge-learning-job.ts +160 -0
  404. package/src/memory/v3/edges.ts +249 -0
  405. package/src/memory/v3/filter.ts +281 -0
  406. package/src/memory/v3/gate.ts +334 -0
  407. package/src/memory/v3/index-composition.ts +113 -0
  408. package/src/memory/v3/llm-capture.ts +46 -0
  409. package/src/memory/v3/loop.ts +382 -0
  410. package/src/memory/v3/maintenance.ts +144 -0
  411. package/src/memory/v3/prompt-context.ts +33 -0
  412. package/src/memory/v3/prompts/consolidation.ts +458 -0
  413. package/src/memory/v3/prompts/system-prompts.ts +196 -0
  414. package/src/memory/v3/retriever.ts +33 -0
  415. package/src/memory/v3/scouts.ts +420 -0
  416. package/src/memory/v3/shadow-middleware.ts +305 -0
  417. package/src/memory/v3/traversal.ts +206 -0
  418. package/src/memory/v3/tree-index.ts +237 -0
  419. package/src/memory/v3/tree-store.ts +394 -0
  420. package/src/memory/v3/tree-walk.ts +351 -0
  421. package/src/memory/v3/types.ts +65 -0
  422. package/src/memory/v3/validate.ts +300 -0
  423. package/src/messaging/providers/index.ts +7 -1
  424. package/src/messaging/providers/slack/__tests__/adapter-mention-rendering.test.ts +329 -3
  425. package/src/messaging/providers/slack/__tests__/adapter-token-routing.test.ts +34 -1
  426. package/src/messaging/providers/slack/adapter.ts +178 -25
  427. package/src/messaging/providers/slack/api.test.ts +54 -0
  428. package/src/messaging/providers/slack/api.ts +119 -3
  429. package/src/messaging/providers/slack/client.ts +12 -0
  430. package/src/messaging/providers/slack/deep-link.ts +20 -1
  431. package/src/messaging/providers/slack/message-metadata.test.ts +48 -0
  432. package/src/messaging/providers/slack/message-metadata.ts +156 -0
  433. package/src/messaging/providers/slack/render-transcript.test.ts +107 -75
  434. package/src/messaging/providers/slack/render-transcript.ts +176 -49
  435. package/src/messaging/providers/slack/send.test.ts +77 -0
  436. package/src/messaging/providers/slack/send.ts +8 -2
  437. package/src/messaging/providers/slack/types.ts +14 -0
  438. package/src/notifications/__tests__/emit-signal-home-feed.test.ts +4 -1
  439. package/src/notifications/__tests__/home-feed-side-effect.test.ts +116 -54
  440. package/src/notifications/adapters/macos.ts +18 -1
  441. package/src/notifications/adapters/platform.ts +1 -1
  442. package/src/notifications/conversation-seed-composer.ts +14 -2
  443. package/src/notifications/decision-engine.ts +1 -4
  444. package/src/notifications/deferred-emit.ts +135 -0
  445. package/src/notifications/emit-signal.ts +38 -50
  446. package/src/notifications/home-feed-side-effect.ts +60 -30
  447. package/src/oauth/connect-orchestrator.ts +3 -0
  448. package/src/oauth/credential-token-resolver.ts +2 -0
  449. package/src/oauth/manual-token-connection.ts +19 -0
  450. package/src/oauth/oauth-store.ts +12 -0
  451. package/src/oauth/seed-providers.ts +22 -0
  452. package/src/permissions/prompter.ts +8 -5
  453. package/src/permissions/question-prompter.ts +5 -2
  454. package/src/permissions/secret-prompter.ts +6 -3
  455. package/src/plugin-api/index.ts +4 -0
  456. package/src/plugin-api/types.ts +7 -33
  457. package/src/plugins/defaults/index.ts +6 -0
  458. package/src/plugins/defaults/injectors.ts +100 -20
  459. package/src/plugins/external-plugin-loader.ts +5 -68
  460. package/src/plugins/types.ts +11 -16
  461. package/src/proactive-artifact/aux-message-injector.ts +17 -4
  462. package/src/prompts/__tests__/system-prompt.test.ts +46 -2
  463. package/src/prompts/__tests__/task-progress-hint-section.test.ts +3 -9
  464. package/src/prompts/normalize-onboarding.ts +40 -0
  465. package/src/prompts/persona-resolver.ts +36 -21
  466. package/src/prompts/sections.ts +69 -19
  467. package/src/prompts/system-prompt.ts +118 -216
  468. package/src/prompts/template-detection.ts +37 -0
  469. package/src/prompts/templates/BOOTSTRAP-CONTENT-AUTOMATION.md +141 -0
  470. package/src/prompts/templates/BOOTSTRAP.md +10 -2
  471. package/src/prompts/templates/VOICE.md +3 -0
  472. package/src/prompts/templates/system-sections.ts +281 -9
  473. package/src/providers/__tests__/connection-model-compat.test.ts +234 -0
  474. package/src/providers/__tests__/retry-callsite.test.ts +85 -5
  475. package/src/providers/anthropic/client.ts +159 -66
  476. package/src/providers/call-site-routing.ts +14 -2
  477. package/src/providers/connection-model-compat.ts +38 -0
  478. package/src/providers/connection-resolution.ts +16 -2
  479. package/src/providers/fireworks/client.ts +20 -2
  480. package/src/providers/gemini/client.ts +49 -6
  481. package/src/providers/inference/__tests__/base-url-route-validation.test.ts +342 -0
  482. package/src/providers/inference/__tests__/base-url-security.test.ts +189 -0
  483. package/src/providers/inference/__tests__/codex-token-refresh.test.ts +254 -0
  484. package/src/providers/inference/adapter-factory.ts +18 -1
  485. package/src/providers/inference/auth.ts +3 -3
  486. package/src/providers/inference/codex-token-refresh.ts +128 -0
  487. package/src/providers/inference/resolve-auth.ts +49 -6
  488. package/src/providers/minimax/client.ts +106 -0
  489. package/src/providers/model-catalog.ts +91 -1
  490. package/src/providers/model-intents.ts +1 -1
  491. package/src/providers/openai/chat-completions-provider.ts +63 -23
  492. package/src/providers/openai/codex-models.ts +18 -0
  493. package/src/providers/openai/responses-provider.ts +86 -23
  494. package/src/providers/openrouter/client.ts +5 -1
  495. package/src/providers/provider-send-message.ts +7 -1
  496. package/src/providers/retry.ts +34 -3
  497. package/src/providers/thinking-config.ts +26 -1
  498. package/src/providers/types.ts +25 -0
  499. package/src/providers/usage-tracking.ts +2 -0
  500. package/src/runtime/AGENTS.md +2 -2
  501. package/src/runtime/__tests__/agent-wake.test.ts +214 -0
  502. package/src/runtime/__tests__/background-job-runner.test.ts +128 -0
  503. package/src/runtime/agent-wake.ts +152 -56
  504. package/src/runtime/assistant-event-hub.ts +76 -6
  505. package/src/runtime/auth/route-policy.ts +43 -3
  506. package/src/runtime/background-job-runner.ts +26 -0
  507. package/src/runtime/btw-sidechain.ts +0 -6
  508. package/src/runtime/channel-reply-delivery.ts +182 -47
  509. package/src/runtime/channel-retry-sweep.ts +141 -16
  510. package/src/runtime/http-types.ts +7 -6
  511. package/src/runtime/migrations/vbundle-builder.ts +10 -3
  512. package/src/runtime/pending-interactions.ts +50 -8
  513. package/src/runtime/routes/__tests__/content-source-routes.test.ts +162 -0
  514. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +161 -1
  515. package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +14 -0
  516. package/src/runtime/routes/__tests__/memory-v2-simulate-route.test.ts +290 -0
  517. package/src/runtime/routes/__tests__/plugins-routes.test.ts +512 -0
  518. package/src/runtime/routes/__tests__/sanity-routes.test.ts +280 -0
  519. package/src/runtime/routes/__tests__/slack-channel-routes.test.ts +266 -0
  520. package/src/runtime/routes/acp-routes.test.ts +255 -6
  521. package/src/runtime/routes/acp-routes.ts +8 -1
  522. package/src/runtime/routes/approval-routes.ts +4 -1
  523. package/src/runtime/routes/avatar-routes.ts +10 -10
  524. package/src/runtime/routes/background-wake-routes.ts +188 -0
  525. package/src/runtime/routes/browser-tabs-routes.ts +200 -0
  526. package/src/runtime/routes/btw-routes.ts +0 -6
  527. package/src/runtime/routes/chatgpt-subscription-auth-routes.ts +246 -0
  528. package/src/runtime/routes/content-source-routes.ts +78 -0
  529. package/src/runtime/routes/conversation-cli-routes.ts +147 -2
  530. package/src/runtime/routes/conversation-list-routes.ts +12 -4
  531. package/src/runtime/routes/conversation-management-routes.ts +77 -20
  532. package/src/runtime/routes/conversation-query-routes.ts +196 -31
  533. package/src/runtime/routes/conversation-routes.ts +472 -425
  534. package/src/runtime/routes/conversation-starter-routes.ts +6 -3
  535. package/src/runtime/routes/disk-pressure-routes.ts +1 -1
  536. package/src/runtime/routes/document-comments-routes.ts +287 -0
  537. package/src/runtime/routes/documents-routes.ts +33 -0
  538. package/src/runtime/routes/domain-routes.ts +60 -10
  539. package/src/runtime/routes/email-routes.ts +5 -2
  540. package/src/runtime/routes/events-routes.ts +54 -10
  541. package/src/runtime/routes/group-routes.ts +24 -8
  542. package/src/runtime/routes/home-feed-routes.ts +6 -3
  543. package/src/runtime/routes/host-app-control-routes.ts +1 -1
  544. package/src/runtime/routes/host-browser-routes.ts +17 -2
  545. package/src/runtime/routes/host-cu-routes.ts +2 -2
  546. package/src/runtime/routes/identity-routes.ts +21 -0
  547. package/src/runtime/routes/inbound-message-handler.ts +288 -58
  548. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +96 -3
  549. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +365 -6
  550. package/src/runtime/routes/inbound-stages/background-dispatch.ts +283 -82
  551. package/src/runtime/routes/index.ts +20 -4
  552. package/src/runtime/routes/inference-profile-session-handler.ts +22 -12
  553. package/src/runtime/routes/inference-profile-session-routes.ts +7 -1
  554. package/src/runtime/routes/inference-provider-connection-routes.ts +63 -7
  555. package/src/runtime/routes/integrations/a2a.ts +60 -1
  556. package/src/runtime/routes/llm-call-sites-routes.ts +32 -5
  557. package/src/runtime/routes/log-export-routes.ts +39 -0
  558. package/src/runtime/routes/memory-item-routes.ts +8 -3
  559. package/src/runtime/routes/memory-v2-routes.ts +427 -0
  560. package/src/runtime/routes/memory-v3-routes.ts +316 -0
  561. package/src/runtime/routes/migration-routes.ts +21 -24
  562. package/src/runtime/routes/notification-routes.ts +19 -2
  563. package/src/runtime/routes/plugins-routes.ts +337 -0
  564. package/src/runtime/routes/question-routes.ts +4 -1
  565. package/src/runtime/routes/rename-conversation-routes.ts +6 -2
  566. package/src/runtime/routes/sanity-routes.ts +159 -0
  567. package/src/runtime/routes/secret-routes.ts +25 -5
  568. package/src/runtime/routes/settings-routes.ts +12 -11
  569. package/src/runtime/routes/slack-channel-routes.ts +188 -0
  570. package/src/runtime/routes/workspace-routes.ts +25 -10
  571. package/src/runtime/services/conversation-serializer.ts +30 -4
  572. package/src/runtime/sync/resource-sync-events.ts +106 -38
  573. package/src/runtime/sync/sync-publisher.test.ts +49 -0
  574. package/src/runtime/sync/sync-publisher.ts +2 -1
  575. package/src/runtime/verification-outbound-actions.ts +73 -1
  576. package/src/schedule/integration-status.ts +3 -1
  577. package/src/security/__tests__/oauth2-device-code.test.ts +479 -0
  578. package/src/security/oauth2-device-code.ts +307 -0
  579. package/src/security/oauth2.ts +26 -9
  580. package/src/security/secure-keys.ts +5 -0
  581. package/src/skills/catalog-install.ts +6 -2
  582. package/src/telemetry/types.ts +12 -0
  583. package/src/telemetry/usage-telemetry-reporter.test.ts +48 -0
  584. package/src/telemetry/usage-telemetry-reporter.ts +1 -0
  585. package/src/tools/acp/spawn.test.ts +119 -0
  586. package/src/tools/acp/spawn.ts +15 -2
  587. package/src/tools/apps/definitions.ts +2 -8
  588. package/src/tools/ask-question/ask-question-tool.test.ts +3 -3
  589. package/src/tools/ask-question/ask-question-tool.ts +38 -45
  590. package/src/tools/browser/__tests__/pinned-tabs.test.ts +150 -0
  591. package/src/tools/browser/browser-execution.ts +106 -0
  592. package/src/tools/browser/cdp-client/__tests__/browser-tabs-factory.test.ts +402 -0
  593. package/src/tools/browser/cdp-client/__tests__/factory.test.ts +28 -0
  594. package/src/tools/browser/cdp-client/__tests__/types.test.ts +4 -0
  595. package/src/tools/browser/cdp-client/cdp-inspect-client.ts +22 -0
  596. package/src/tools/browser/cdp-client/extension-cdp-client.ts +42 -2
  597. package/src/tools/browser/cdp-client/factory.ts +171 -4
  598. package/src/tools/browser/cdp-client/local-cdp-client.ts +21 -0
  599. package/src/tools/browser/cdp-client/types.ts +101 -0
  600. package/src/tools/browser/pinned-tabs.ts +146 -0
  601. package/src/tools/computer-use/definitions.ts +22 -78
  602. package/src/tools/credential-execution/make-authenticated-request.ts +3 -9
  603. package/src/tools/credential-execution/manage-secure-command-tool.ts +3 -9
  604. package/src/tools/credential-execution/run-authenticated-command.ts +3 -9
  605. package/src/tools/credentials/vault.ts +3 -9
  606. package/src/tools/document/document-comment-tool.test.ts +379 -0
  607. package/src/tools/document/document-comment-tool.ts +156 -0
  608. package/src/tools/document/document-tool.ts +187 -2
  609. package/src/tools/execution-target.ts +21 -23
  610. package/src/tools/executor.ts +6 -1
  611. package/src/tools/filesystem/edit.ts +3 -9
  612. package/src/tools/filesystem/list.ts +3 -9
  613. package/src/tools/filesystem/read.ts +3 -9
  614. package/src/tools/filesystem/write.ts +3 -9
  615. package/src/tools/host-filesystem/edit.ts +3 -9
  616. package/src/tools/host-filesystem/read.ts +3 -9
  617. package/src/tools/host-filesystem/transfer.ts +3 -9
  618. package/src/tools/host-filesystem/write.ts +3 -9
  619. package/src/tools/host-terminal/host-shell.ts +3 -9
  620. package/src/tools/mcp/mcp-tool-factory.ts +1 -8
  621. package/src/tools/memory/register.test.ts +1 -1
  622. package/src/tools/memory/register.ts +4 -9
  623. package/src/tools/network/__tests__/web-fetch-metadata.test.ts +229 -0
  624. package/src/tools/network/__tests__/web-search-metadata.test.ts +346 -0
  625. package/src/tools/network/domain-normalize.ts +17 -0
  626. package/src/tools/network/web-fetch.ts +216 -73
  627. package/src/tools/network/web-search.ts +216 -98
  628. package/src/tools/registry.ts +7 -23
  629. package/src/tools/schema-transforms.ts +1 -1
  630. package/src/tools/skills/execute.ts +3 -9
  631. package/src/tools/skills/load.ts +3 -9
  632. package/src/tools/skills/skill-tool-factory.ts +1 -8
  633. package/src/tools/subagent/notify-parent.ts +3 -9
  634. package/src/tools/system/request-permission.ts +3 -9
  635. package/src/tools/terminal/safe-env.ts +3 -2
  636. package/src/tools/terminal/shell.ts +3 -9
  637. package/src/tools/tool-approval-handler.ts +19 -12
  638. package/src/tools/tool-defaults.ts +94 -0
  639. package/src/tools/types.ts +31 -98
  640. package/src/tools/ui-surface/definitions.ts +9 -23
  641. package/src/types/onboarding-context.ts +4 -0
  642. package/src/usage/pricing.ts +23 -0
  643. package/src/usage/types.ts +12 -0
  644. package/src/util/__tests__/favicon.test.ts +84 -0
  645. package/src/util/favicon.ts +40 -0
  646. package/src/util/logger.ts +16 -7
  647. package/src/util/platform.ts +7 -7
  648. package/src/util/sqlite3-runtime.ts +65 -0
  649. package/src/workspace/git-service.ts +75 -4
  650. package/src/workspace/migrations/086-revert-stale-gemini-mis-rewrites.ts +1 -0
  651. package/src/workspace/migrations/088-deprecate-background-conversation-override.ts +103 -0
  652. package/src/workspace/migrations/089-move-memory-tree-out-of-v3.ts +86 -0
  653. package/src/workspace/migrations/registry.ts +4 -0
  654. package/src/__tests__/compaction-strip-metadata-clear.test.ts +0 -206
  655. package/src/__tests__/message-complete-display-id.test.ts +0 -175
  656. package/src/config/bundled-skills/document/SKILL.md +0 -54
  657. package/src/config/bundled-skills/document/TOOLS.json +0 -106
  658. package/src/daemon/seed-files.ts +0 -18
  659. package/src/prompts/cache-boundary.ts +0 -8
  660. package/src/runtime/routes/interface-routes.ts +0 -43
  661. /package/src/config/bundled-skills/{document → document-editor}/tools/document-create.ts +0 -0
  662. /package/src/config/bundled-skills/{document → document-editor}/tools/document-delete.ts +0 -0
  663. /package/src/config/bundled-skills/{document → document-editor}/tools/document-list.ts +0 -0
  664. /package/src/config/bundled-skills/{document → document-editor}/tools/document-read.ts +0 -0
  665. /package/src/config/bundled-skills/{document → document-editor}/tools/document-update.ts +0 -0
@@ -7,7 +7,7 @@
7
7
  * list APIs.
8
8
  */
9
9
 
10
- import { and, eq, inArray, isNull } from "drizzle-orm";
10
+ import { and, eq, inArray, isNull, sql } from "drizzle-orm";
11
11
 
12
12
  import { getDb } from "./db-connection.js";
13
13
  import { externalConversationBindings } from "./schema.js";
@@ -16,6 +16,7 @@ export interface ExternalConversationBinding {
16
16
  conversationId: string;
17
17
  sourceChannel: string;
18
18
  externalChatId: string;
19
+ externalChatName?: string | null;
19
20
  externalThreadId?: string | null;
20
21
  externalUserId?: string | null;
21
22
  displayName?: string | null;
@@ -30,6 +31,7 @@ export interface UpsertBindingInput {
30
31
  conversationId: string;
31
32
  sourceChannel: string;
32
33
  externalChatId: string;
34
+ externalChatName?: string | null;
33
35
  externalThreadId?: string | null;
34
36
  externalUserId?: string | null;
35
37
  displayName?: string | null;
@@ -43,6 +45,13 @@ function normalizeExternalThreadId(
43
45
  return trimmed ? trimmed : null;
44
46
  }
45
47
 
48
+ function normalizeExternalChatName(
49
+ externalChatName?: string | null,
50
+ ): string | null {
51
+ const trimmed = externalChatName?.trim();
52
+ return trimmed ? trimmed : null;
53
+ }
54
+
46
55
  /**
47
56
  * Insert or update an external conversation binding on conflict (conversationId).
48
57
  * On conflict, updates channel metadata and timestamps.
@@ -51,6 +60,7 @@ export function upsertBinding(input: UpsertBindingInput): void {
51
60
  const db = getDb();
52
61
  const now = Date.now();
53
62
  const externalThreadId = normalizeExternalThreadId(input.externalThreadId);
63
+ const externalChatName = normalizeExternalChatName(input.externalChatName);
54
64
 
55
65
  // If a stale binding exists for this channel/chat/thread tuple under a
56
66
  // different conversationId, remove it first so the unique index is not violated.
@@ -75,6 +85,7 @@ export function upsertBinding(input: UpsertBindingInput): void {
75
85
  conversationId: input.conversationId,
76
86
  sourceChannel: input.sourceChannel,
77
87
  externalChatId: input.externalChatId,
88
+ externalChatName,
78
89
  externalThreadId,
79
90
  externalUserId: input.externalUserId ?? null,
80
91
  displayName: input.displayName ?? null,
@@ -88,6 +99,9 @@ export function upsertBinding(input: UpsertBindingInput): void {
88
99
  set: {
89
100
  sourceChannel: input.sourceChannel,
90
101
  externalChatId: input.externalChatId,
102
+ externalChatName:
103
+ externalChatName ??
104
+ sql`${externalConversationBindings.externalChatName}`,
91
105
  externalThreadId,
92
106
  externalUserId: input.externalUserId ?? null,
93
107
  displayName: input.displayName ?? null,
@@ -158,6 +172,23 @@ export function upsertOutboundBinding(input: {
158
172
  .run();
159
173
  }
160
174
 
175
+ export function updateExternalChatName(
176
+ conversationId: string,
177
+ externalChatName: string,
178
+ ): void {
179
+ const db = getDb();
180
+ const trimmedName = externalChatName.trim();
181
+ if (!trimmedName) return;
182
+
183
+ db.update(externalConversationBindings)
184
+ .set({
185
+ externalChatName: trimmedName,
186
+ updatedAt: Date.now(),
187
+ })
188
+ .where(eq(externalConversationBindings.conversationId, conversationId))
189
+ .run();
190
+ }
191
+
161
192
  /**
162
193
  * Look up an external binding by conversation ID.
163
194
  */
@@ -20,7 +20,11 @@ import { getLogger } from "../../util/logger.js";
20
20
  import { getWorkspaceDir } from "../../util/platform.js";
21
21
  import { getMemoryCheckpoint, setMemoryCheckpoint } from "../checkpoints.js";
22
22
  import { getDb } from "../db-connection.js";
23
- import { enqueueMemoryJob, hasActiveJobOfType } from "../jobs-store.js";
23
+ import {
24
+ enqueueMemoryJob,
25
+ hasActiveJobOfType,
26
+ isMemoryEnabled,
27
+ } from "../jobs-store.js";
24
28
  import { initQdrantClient, resolveQdrantUrl } from "../qdrant-client.js";
25
29
  import { rawAll, rawGet, rawRun } from "../raw-query.js";
26
30
  import { conversations, memoryGraphNodes, memorySegments } from "../schema.js";
@@ -342,6 +346,8 @@ export function maybeEnqueueGraphBootstrap(): void {
342
346
  // Don't enqueue if already in progress
343
347
  if (hasActiveJobOfType("graph_bootstrap")) return;
344
348
 
349
+ if (!isMemoryEnabled()) return;
350
+
345
351
  log.info(
346
352
  { segmentCount, hasJournalFiles },
347
353
  "Graph empty with historical data — enqueueing bootstrap",
@@ -392,6 +398,7 @@ const KIND_TO_PREFIX: Record<string, string> = {
392
398
  */
393
399
  export function migrateToolCreatedItems(): void {
394
400
  if (getMemoryCheckpoint(MIGRATE_ITEMS_CHECKPOINT)) return;
401
+ if (!isMemoryEnabled()) return;
395
402
 
396
403
  const kinds = Object.keys(KIND_TO_PREFIX);
397
404
  const placeholders = kinds.map(() => "?").join(", ");
@@ -23,7 +23,7 @@ import {
23
23
  } from "../../skills/skill-memory.js";
24
24
  import { getLogger } from "../../util/logger.js";
25
25
  import { getDb } from "../db-connection.js";
26
- import { enqueueMemoryJob } from "../jobs-store.js";
26
+ import { enqueueMemoryJob, isMemoryEnabled } from "../jobs-store.js";
27
27
  import { memoryGraphNodes } from "../schema.js";
28
28
  import { createNode } from "./store.js";
29
29
 
@@ -268,7 +268,9 @@ function upsertCapabilityNode(sourceKey: string, content: string): void {
268
268
  })
269
269
  .where(eq(memoryGraphNodes.id, existing.id))
270
270
  .run();
271
- enqueueMemoryJob("embed_graph_node", { nodeId: existing.id });
271
+ if (isMemoryEnabled()) {
272
+ enqueueMemoryJob("embed_graph_node", { nodeId: existing.id });
273
+ }
272
274
  return;
273
275
  }
274
276
 
@@ -301,7 +303,9 @@ function upsertCapabilityNode(sourceKey: string, content: string): void {
301
303
  scopeId: "default",
302
304
  });
303
305
 
304
- enqueueMemoryJob("embed_graph_node", { nodeId: node.id });
306
+ if (isMemoryEnabled()) {
307
+ enqueueMemoryJob("embed_graph_node", { nodeId: node.id });
308
+ }
305
309
  log.info({ sourceKey, nodeId: node.id }, "Created capability graph node");
306
310
  }
307
311
 
@@ -35,6 +35,7 @@ import {
35
35
  type InjectMemoryV2Mode,
36
36
  } from "../v2/injection.js";
37
37
  import { loadNowText } from "../v2/now-text.js";
38
+ import type { RouterTurnPair } from "../v2/router.js";
38
39
  import {
39
40
  loadGraphMemoryState,
40
41
  saveGraphMemoryState,
@@ -440,8 +441,11 @@ export class ConversationGraphMemory {
440
441
  messages,
441
442
  config,
442
443
  "context-load",
444
+ // Context-load runs before the messages array necessarily contains
445
+ // the just-arrived user turn (post-compaction restore, turn 1
446
+ // sketch), so override with the resolved user text rather than
447
+ // walking back through `messages`.
443
448
  rawUserText ?? userQuery ?? "",
444
- "",
445
449
  signal,
446
450
  );
447
451
 
@@ -605,8 +609,7 @@ export class ConversationGraphMemory {
605
609
  messages,
606
610
  config,
607
611
  "per-turn",
608
- userLast,
609
- assistantLast,
612
+ null,
610
613
  signal,
611
614
  );
612
615
  if (v2.routed) {
@@ -762,8 +765,14 @@ export class ConversationGraphMemory {
762
765
  messages: Message[],
763
766
  config: AssistantConfig,
764
767
  mode: InjectMemoryV2Mode,
765
- userMessage: string,
766
- assistantMessage: string,
768
+ /**
769
+ * Override for the just-arrived user message text. Used by
770
+ * `runContextLoad` where the conversation history may not yet contain
771
+ * the user message that triggered the load (e.g. turn 1 / post-
772
+ * compaction restoration). When provided, the extracted pairs array
773
+ * is replaced with `[{ assistantMessage: "", userMessage: override }]`.
774
+ */
775
+ userMessageOverride: string | null,
767
776
  signal: AbortSignal,
768
777
  ): Promise<{
769
778
  routed: boolean;
@@ -776,13 +785,17 @@ export class ConversationGraphMemory {
776
785
 
777
786
  const nowText = await loadNowText(getWorkspaceDir());
778
787
  const currentTurn = this.tracker.getTurn();
788
+ const historicalPairs = config.memory.v2.router.historical_pairs;
789
+ const recentTurnPairs =
790
+ userMessageOverride !== null
791
+ ? [{ assistantMessage: "", userMessage: userMessageOverride }]
792
+ : extractRecentTurnPairs(messages, historicalPairs);
779
793
 
780
794
  const result = await injectMemoryV2Block({
781
795
  database: getDb(),
782
796
  conversationId: this.conversationId,
783
797
  currentTurn,
784
- userMessage,
785
- assistantMessage,
798
+ recentTurnPairs,
786
799
  nowText,
787
800
  messageId: `${this.conversationId}:turn:${currentTurn}`,
788
801
  mode,
@@ -808,16 +821,22 @@ export class ConversationGraphMemory {
808
821
 
809
822
  /**
810
823
  * Count the leading content blocks on a user message that were added by
811
- * `injectMemoryBlock`. Memory-injected images use a 3-block pattern
812
- * (opening `<memory_image>` text + image + closing `</memory_image>` text),
813
- * followed by a `<memory>…</memory>` text block (legacy `<memory __injected>` is also accepted).
814
- * The bare `<memory>` form is matched only when the block also ends with
815
- * `\n</memory>`, so user-authored content that happens to begin with
816
- * `<memory>` (for example, a message discussing the XML-like markup) is not
817
- * mistaken for an injected prefix and stripped on re-injection. A legacy
818
- * 2-block image pattern (no closing tag) is also accepted for backward
819
- * compatibility. The injection prefix is always contiguous at the start,
820
- * so we stop at the first non-memory block.
824
+ * `injectMemoryBlock` or the `memory-v2-static` injector. Memory-injected
825
+ * images use a 3-block pattern (opening `<memory_image>` text + image +
826
+ * closing `</memory_image>` text), followed by a `<memory>…</memory>` text
827
+ * block (legacy `<memory __injected>` is also accepted). The static
828
+ * memory-v2 block uses `<info>…</info>` and is also counted here so that
829
+ * `after-memory-prefix` splices for subsequent injectors (e.g. `now-md`)
830
+ * land after both the dynamic and static blocks.
831
+ *
832
+ * The bare `<memory>` and `<info>` forms are matched only when the block
833
+ * also ends with the corresponding closing tag, so user-authored content
834
+ * that happens to begin with `<memory>` or `<info>` (for example, a
835
+ * message discussing the XML-like markup) is not mistaken for an injected
836
+ * prefix and stripped on re-injection. A legacy 2-block image pattern (no
837
+ * closing tag) is also accepted for backward compatibility. The injection
838
+ * prefix is always contiguous at the start, so we stop at the first
839
+ * non-memory block.
821
840
  */
822
841
  export function countMemoryPrefixBlocks(content: ContentBlock[]): number {
823
842
  let firstNonMemory = 0;
@@ -829,6 +848,8 @@ export function countMemoryPrefixBlocks(content: ContentBlock[]): number {
829
848
  block.type === "text" &&
830
849
  ((block.text.startsWith("<memory>\n") &&
831
850
  block.text.endsWith("\n</memory>")) ||
851
+ (block.text.startsWith("<info>\n") &&
852
+ block.text.endsWith("\n</info>")) ||
832
853
  block.text.startsWith("<memory __injected>\n"))
833
854
  ) {
834
855
  firstNonMemory++;
@@ -991,3 +1012,65 @@ function readRawUserText(message: Message | undefined): string | null {
991
1012
  if (texts.length === 0) return null;
992
1013
  return texts.join(" ");
993
1014
  }
1015
+
1016
+ /**
1017
+ * Walk back through the conversation history and collect the most recent
1018
+ * `K` `(assistant, user)` turn pairs for the router prompt. Each pair
1019
+ * represents the assistant's reply followed by the user message that
1020
+ * came after — the last pair's `userMessage` is the just-arrived turn
1021
+ * that triggered this call.
1022
+ *
1023
+ * Behavior at K=1 is bit-identical to the pre-knob signature: one pair
1024
+ * with the prior assistant reply + the just-arrived user message.
1025
+ *
1026
+ * Edge cases:
1027
+ * - If history has fewer than K full pairs available (e.g. early in a
1028
+ * conversation), returns however many pairs were found, oldest first.
1029
+ * The oldest pair may have `assistantMessage: ""` when there is a
1030
+ * user message with no preceding assistant reply — `runRouterBatch`
1031
+ * skips the `[assistant]:` line in that case.
1032
+ * - Non-text content (tool_use, tool_result, images) is collapsed by
1033
+ * joining all text blocks within a single message with spaces. This
1034
+ * matches the v1-style extraction the router has used since K=1.
1035
+ */
1036
+ function extractRecentTurnPairs(
1037
+ messages: Message[],
1038
+ k: number,
1039
+ ): RouterTurnPair[] {
1040
+ const messageText = (msg: Message): string =>
1041
+ msg.content
1042
+ .filter(
1043
+ (b): b is Extract<typeof b, { type: "text" }> => b.type === "text",
1044
+ )
1045
+ .map((b) => b.text)
1046
+ .join(" ");
1047
+
1048
+ const pairs: RouterTurnPair[] = [];
1049
+ let pendingUser: string | null = null;
1050
+ for (let i = messages.length - 1; i >= 0 && pairs.length < k; i--) {
1051
+ const msg = messages[i];
1052
+ if (msg.role === "user" && pendingUser === null) {
1053
+ pendingUser = messageText(msg);
1054
+ } else if (msg.role === "assistant" && pendingUser !== null) {
1055
+ pairs.unshift({
1056
+ assistantMessage: messageText(msg),
1057
+ userMessage: pendingUser,
1058
+ });
1059
+ pendingUser = null;
1060
+ }
1061
+ }
1062
+ // Conversation start: a user message with no preceding assistant reply
1063
+ // still belongs in the prompt as the just-arrived turn. Emit it with an
1064
+ // empty `assistantMessage` so `runRouterBatch` renders only `[user]:`.
1065
+ if (pendingUser !== null && pairs.length < k) {
1066
+ pairs.unshift({ assistantMessage: "", userMessage: pendingUser });
1067
+ }
1068
+ // Defensive fallback: the router contract requires a non-empty array.
1069
+ // This only fires when `messages` has no user-text content at all
1070
+ // (currently impossible since the agent loop always appends a user
1071
+ // turn before invoking the v2 path, but cheap to keep correct).
1072
+ if (pairs.length === 0) {
1073
+ pairs.push({ assistantMessage: "", userMessage: "" });
1074
+ }
1075
+ return pairs;
1076
+ }
@@ -12,7 +12,6 @@ import { join } from "node:path";
12
12
  import { and, asc, desc, eq, gt } from "drizzle-orm";
13
13
 
14
14
  import type { AssistantConfig } from "../../config/types.js";
15
- import { resolveGuardianPersona } from "../../prompts/persona-resolver.js";
16
15
  import { buildCoreIdentityContext } from "../../prompts/system-prompt.js";
17
16
  import {
18
17
  extractToolUse,
@@ -1026,10 +1025,7 @@ export async function runGraphExtraction(
1026
1025
  const candidateNodeIds = new Set(candidateNodes.map((n) => n.id));
1027
1026
 
1028
1027
  // 4. Build prompt
1029
- const userPersona = resolveGuardianPersona();
1030
- const identityContext = buildCoreIdentityContext({
1031
- userPersona: userPersona ?? undefined,
1032
- });
1028
+ const identityContext = buildCoreIdentityContext();
1033
1029
 
1034
1030
  const activeSet = opts?.activeContextNodeIds
1035
1031
  ? new Set(opts.activeContextNodeIds)
@@ -9,7 +9,11 @@ import { selectedBackendSupportsMultimodal } from "../embedding-backend.js";
9
9
  import type { EmbeddingInput } from "../embedding-types.js";
10
10
  import { embedAndUpsert } from "../job-utils.js";
11
11
  import { asString } from "../job-utils.js";
12
- import { enqueueMemoryJob, type MemoryJob } from "../jobs-store.js";
12
+ import {
13
+ enqueueMemoryJob,
14
+ isMemoryEnabled,
15
+ type MemoryJob,
16
+ } from "../jobs-store.js";
13
17
  import { isQdrantBreakerOpen } from "../qdrant-circuit-breaker.js";
14
18
  import { withQdrantBreaker } from "../qdrant-circuit-breaker.js";
15
19
  import {
@@ -238,6 +242,7 @@ export async function embedGraphNodeJob(
238
242
  * Enqueue an embedding job for a graph node (async, for live conversations).
239
243
  */
240
244
  export function enqueueGraphNodeEmbed(nodeId: string): void {
245
+ if (!isMemoryEnabled()) return;
241
246
  enqueueMemoryJob("embed_graph_node", { nodeId });
242
247
  }
243
248
 
@@ -282,5 +287,6 @@ export async function embedGraphTriggerJob(
282
287
  * Enqueue a trigger embedding job.
283
288
  */
284
289
  export function enqueueGraphTriggerEmbed(triggerId: string): void {
290
+ if (!isMemoryEnabled()) return;
285
291
  enqueueMemoryJob("graph_trigger_embed", { triggerId });
286
292
  }
@@ -11,7 +11,11 @@ import { isAutoAnalysisConversation } from "./auto-analysis-guard.js";
11
11
  import { getMemoryCheckpoint, setMemoryCheckpoint } from "./checkpoints.js";
12
12
  import { getDb } from "./db-connection.js";
13
13
  import { selectedBackendSupportsMultimodal } from "./embedding-backend.js";
14
- import { enqueueMemoryJob, upsertDebouncedJob } from "./jobs-store.js";
14
+ import {
15
+ enqueueMemoryJob,
16
+ isMemoryEnabled,
17
+ upsertDebouncedJob,
18
+ } from "./jobs-store.js";
15
19
  import { isMemoryRetrospectiveConversation } from "./memory-retrospective-enqueue.js";
16
20
  import { maybeEnqueueRetrospective } from "./memory-retrospective-trigger-check.js";
17
21
  import {
@@ -139,20 +143,22 @@ export async function indexMessageNow(
139
143
 
140
144
  if (existing?.contentHash === hash) {
141
145
  skippedEmbedJobs++;
142
- } else {
146
+ } else if (isMemoryEnabled()) {
143
147
  enqueueMemoryJob("embed_segment", { segmentId }, Date.now(), tx);
144
148
  }
145
149
  }
146
150
 
147
151
  // Enqueue embed_attachment jobs for image content blocks when the
148
152
  // embedding provider supports multimodal (Gemini only).
149
- for (const block of mediaBlocks) {
150
- enqueueMemoryJob(
151
- "embed_attachment",
152
- { messageId: input.messageId, blockIndex: block.index },
153
- Date.now(),
154
- tx,
155
- );
153
+ if (isMemoryEnabled()) {
154
+ for (const block of mediaBlocks) {
155
+ enqueueMemoryJob(
156
+ "embed_attachment",
157
+ { messageId: input.messageId, blockIndex: block.index },
158
+ Date.now(),
159
+ tx,
160
+ );
161
+ }
156
162
  }
157
163
  });
158
164
 
@@ -221,14 +227,16 @@ export async function indexMessageNow(
221
227
  extractRunAfter = graphBatchFired
222
228
  ? Date.now()
223
229
  : Date.now() + idleTimeoutMs;
224
- upsertDebouncedJob(
225
- "graph_extract",
226
- {
227
- conversationId: input.conversationId,
228
- scopeId: input.scopeId ?? "default",
229
- },
230
- extractRunAfter,
231
- );
230
+ if (isMemoryEnabled()) {
231
+ upsertDebouncedJob(
232
+ "graph_extract",
233
+ {
234
+ conversationId: input.conversationId,
235
+ scopeId: input.scopeId ?? "default",
236
+ },
237
+ extractRunAfter,
238
+ );
239
+ }
232
240
  } else {
233
241
  extractRunAfter = Date.now() + idleTimeoutMs;
234
242
  }
@@ -309,7 +317,7 @@ export async function indexMessageNow(
309
317
  // jobs-worker.ts. Debounced on the same idle timeout — no threshold
310
318
  // trigger needed since summaries compress the whole conversation, not
311
319
  // incremental batches.
312
- if (v2Config == null) {
320
+ if (v2Config == null && isMemoryEnabled()) {
313
321
  upsertDebouncedJob(
314
322
  "build_conversation_summary",
315
323
  { conversationId: input.conversationId },
@@ -372,10 +380,12 @@ export async function indexMessageNow(
372
380
  }
373
381
 
374
382
  export function enqueueBackfillJob(force = false): string {
383
+ if (!isMemoryEnabled()) return "";
375
384
  return enqueueMemoryJob("backfill", { force });
376
385
  }
377
386
 
378
387
  export function enqueueRebuildIndexJob(): string {
388
+ if (!isMemoryEnabled()) return "";
379
389
  return enqueueMemoryJob("rebuild_index", {});
380
390
  }
381
391
 
@@ -1,8 +1,9 @@
1
1
  import type { AssistantConfig } from "../../config/types.js";
2
2
  import { getLogger } from "../../util/logger.js";
3
+ import { runAsyncSqlite } from "../db-async-query.js";
3
4
  import { getDb } from "../db-connection.js";
4
5
  import { enqueueMemoryJob, type MemoryJob } from "../jobs-store.js";
5
- import { rawAll, rawChanges, rawRun } from "../raw-query.js";
6
+ import { rawAll, rawRun } from "../raw-query.js";
6
7
 
7
8
  const log = getLogger("memory-jobs-worker");
8
9
 
@@ -13,11 +14,18 @@ const PRUNE_LOG_BATCH_LIMIT = 1000;
13
14
  * Delete LLM request/response logs older than the configured retention period.
14
15
  * Processes in batches to avoid long DB locks and excessive WAL growth.
15
16
  * Re-enqueues itself if more rows remain.
17
+ *
18
+ * The DELETE is dispatched through `runAsyncSqlite` so it runs in a
19
+ * sqlite3 subprocess (when available) and does not block the daemon's
20
+ * main event loop. The two bind parameters (`cutoffMs`, batch limit)
21
+ * are integers — they're inlined directly into the SQL after a
22
+ * `Math.floor` + `Number.isFinite` guard so there is no string
23
+ * interpolation surface.
16
24
  */
17
- export function pruneOldLlmRequestLogsJob(
25
+ export async function pruneOldLlmRequestLogsJob(
18
26
  job: MemoryJob,
19
27
  config: AssistantConfig,
20
- ): void {
28
+ ): Promise<void> {
21
29
  const rawRetention = job.payload.retentionMs;
22
30
  const retentionMs =
23
31
  rawRetention === null
@@ -31,14 +39,29 @@ export function pruneOldLlmRequestLogsJob(
31
39
  // null means "keep forever" — skip pruning entirely
32
40
  if (retentionMs === null || retentionMs === undefined) return;
33
41
 
34
- const cutoffMs = Date.now() - retentionMs;
35
-
36
- rawRun(
37
- `DELETE FROM llm_request_logs WHERE rowid IN (SELECT rowid FROM llm_request_logs WHERE created_at < ? LIMIT ?)`,
38
- cutoffMs,
39
- PRUNE_LOG_BATCH_LIMIT,
42
+ const cutoffMs = Math.floor(Date.now() - retentionMs);
43
+ if (!Number.isFinite(cutoffMs)) return;
44
+
45
+ // Inline the cutoff and batch limit (both integers, both validated)
46
+ // and chain `SELECT changes()` so we can read the row count from the
47
+ // subprocess's stdout. The sqlite3 CLI prints `changes()` as a bare
48
+ // integer on its own line in default output mode; the in-process
49
+ // fallback backend in `db-async-query.ts` synthesizes the same shape
50
+ // by capturing `changes()` atomically after `exec()`. Both backends
51
+ // end up on the parser path below.
52
+ const result = await runAsyncSqlite(
53
+ `DELETE FROM llm_request_logs WHERE rowid IN (SELECT rowid FROM llm_request_logs WHERE created_at < ${cutoffMs} LIMIT ${PRUNE_LOG_BATCH_LIMIT});
54
+ SELECT changes();`,
40
55
  );
41
- const deleted = rawChanges();
56
+ if (!result.ok) {
57
+ log.warn(
58
+ { error: result.error, backend: result.backend },
59
+ "pruneOldLlmRequestLogsJob: DELETE failed",
60
+ );
61
+ return;
62
+ }
63
+
64
+ const deleted = parseDeletedCount(result.stdout);
42
65
 
43
66
  if (deleted >= PRUNE_LOG_BATCH_LIMIT) {
44
67
  enqueueMemoryJob("prune_old_llm_request_logs", { retentionMs });
@@ -58,11 +81,14 @@ export function pruneOldLlmRequestLogsJob(
58
81
  * Delete trace events older than the configured retention period.
59
82
  * Processes in batches to avoid long DB locks and excessive WAL growth.
60
83
  * Re-enqueues itself if more rows remain.
84
+ *
85
+ * Same async dispatch + integer inlining shape as
86
+ * {@link pruneOldLlmRequestLogsJob}.
61
87
  */
62
- export function pruneOldTraceEventsJob(
88
+ export async function pruneOldTraceEventsJob(
63
89
  job: MemoryJob,
64
90
  config: AssistantConfig,
65
- ): void {
91
+ ): Promise<void> {
66
92
  const rawRetention = job.payload.retentionDays;
67
93
  const retentionDays =
68
94
  typeof rawRetention === "number" &&
@@ -74,14 +100,22 @@ export function pruneOldTraceEventsJob(
74
100
  // 0 means disabled
75
101
  if (retentionDays === 0) return;
76
102
 
77
- const cutoffMs = Date.now() - retentionDays * 86_400_000;
103
+ const cutoffMs = Math.floor(Date.now() - retentionDays * 86_400_000);
104
+ if (!Number.isFinite(cutoffMs)) return;
78
105
 
79
- rawRun(
80
- `DELETE FROM trace_events WHERE rowid IN (SELECT rowid FROM trace_events WHERE created_at < ? LIMIT ?)`,
81
- cutoffMs,
82
- PRUNE_LOG_BATCH_LIMIT,
106
+ const result = await runAsyncSqlite(
107
+ `DELETE FROM trace_events WHERE rowid IN (SELECT rowid FROM trace_events WHERE created_at < ${cutoffMs} LIMIT ${PRUNE_LOG_BATCH_LIMIT});
108
+ SELECT changes();`,
83
109
  );
84
- const deleted = rawChanges();
110
+ if (!result.ok) {
111
+ log.warn(
112
+ { error: result.error, backend: result.backend },
113
+ "pruneOldTraceEventsJob: DELETE failed",
114
+ );
115
+ return;
116
+ }
117
+
118
+ const deleted = parseDeletedCount(result.stdout);
85
119
 
86
120
  if (deleted >= PRUNE_LOG_BATCH_LIMIT) {
87
121
  enqueueMemoryJob("prune_old_trace_events", { retentionDays });
@@ -97,6 +131,30 @@ export function pruneOldTraceEventsJob(
97
131
  );
98
132
  }
99
133
 
134
+ /**
135
+ * Parse the `SELECT changes()` result emitted by the sqlite3 CLI after
136
+ * the prune DELETE. Returns 0 if stdout is missing or unparseable —
137
+ * callers treat that the same as "no rows deleted, do not re-enqueue".
138
+ *
139
+ * In the CLI's default output mode the value is a bare integer on its
140
+ * own line. We tolerate trailing whitespace/blank lines and pick the
141
+ * last numeric line so any incidental output (warnings, etc.) above it
142
+ * doesn't throw the parse off.
143
+ */
144
+ export function _parseDeletedCount(stdout: string | undefined): number {
145
+ return parseDeletedCount(stdout);
146
+ }
147
+
148
+ function parseDeletedCount(stdout: string | undefined): number {
149
+ if (!stdout) return 0;
150
+ const lines = stdout.split(/\r?\n/).filter((s) => s.trim().length > 0);
151
+ for (let i = lines.length - 1; i >= 0; i--) {
152
+ const n = parseInt(lines[i].trim(), 10);
153
+ if (Number.isFinite(n) && n >= 0) return n;
154
+ }
155
+ return 0;
156
+ }
157
+
100
158
  /**
101
159
  * Delete conversations that have had no activity (updatedAt) for longer than
102
160
  * the configured retention period. Processes in batches so a single job doesn't
@@ -9,7 +9,6 @@ import { and, desc, eq, sql } from "drizzle-orm";
9
9
  import { v4 as uuid } from "uuid";
10
10
 
11
11
  import { loadSkillCatalog } from "../../config/skills.js";
12
- import { resolveGuardianPersona } from "../../prompts/persona-resolver.js";
13
12
  import { buildCoreIdentityContext } from "../../prompts/system-prompt.js";
14
13
  import {
15
14
  createTimeout,
@@ -200,9 +199,7 @@ async function generateStarters(scopeId: string): Promise<GeneratedStarter[]> {
200
199
 
201
200
  // Truncate identity context to prevent oversized prompts when SOUL.md /
202
201
  // IDENTITY.md / users/<slug>.md are large.
203
- const rawIdentityContext = buildCoreIdentityContext({
204
- userPersona: resolveGuardianPersona(),
205
- });
202
+ const rawIdentityContext = buildCoreIdentityContext();
206
203
  const identityContext = rawIdentityContext
207
204
  ? truncate(rawIdentityContext, 2000, "\n…[truncated]")
208
205
  : null;
@@ -1,6 +1,10 @@
1
1
  import type { AssistantConfig } from "../../config/types.js";
2
2
  import { asString } from "../job-utils.js";
3
- import { enqueueMemoryJob, type MemoryJob } from "../jobs-store.js";
3
+ import {
4
+ enqueueMemoryJob,
5
+ isMemoryEnabled,
6
+ type MemoryJob,
7
+ } from "../jobs-store.js";
4
8
  import { indexPkbFile } from "../pkb/pkb-index.js";
5
9
 
6
10
  /**
@@ -46,6 +50,7 @@ export async function embedPkbFileJob(
46
50
  * Enqueue an `embed_pkb_file` job (async, fire-and-forget).
47
51
  */
48
52
  export function enqueuePkbIndexJob(input: EmbedPkbFileJobInput): string {
53
+ if (!isMemoryEnabled()) return "";
49
54
  return enqueueMemoryJob("embed_pkb_file", {
50
55
  pkbRoot: input.pkbRoot,
51
56
  absPath: input.absPath,