@vellumai/assistant 0.10.4 → 0.10.5-dev.202607022329.d89bf2f

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 (866) hide show
  1. package/ARCHITECTURE.md +94 -91
  2. package/Dockerfile +5 -16
  3. package/README.md +7 -10
  4. package/bun.lock +0 -4
  5. package/docs/architecture/security.md +20 -20
  6. package/docs/stt-provider-onboarding.md +4 -5
  7. package/docs/trusted-contact-access.md +7 -7
  8. package/eslint-rules/cli-no-daemon-internals.js +4 -0
  9. package/eslint.config.mjs +7 -1
  10. package/knip.json +0 -1
  11. package/node_modules/@vellumai/gateway-client/src/__tests__/contact-read-contracts.test.ts +36 -0
  12. package/node_modules/@vellumai/gateway-client/src/__tests__/invite-contract.test.ts +233 -0
  13. package/node_modules/@vellumai/gateway-client/src/__tests__/trust-verdict-contract.test.ts +40 -0
  14. package/node_modules/@vellumai/gateway-client/src/gateway-ipc-contracts.ts +20 -8
  15. package/node_modules/@vellumai/gateway-client/src/inbound-contract.ts +10 -0
  16. package/node_modules/@vellumai/gateway-client/src/index.ts +33 -0
  17. package/node_modules/@vellumai/gateway-client/src/invite-contract.ts +216 -0
  18. package/node_modules/@vellumai/gateway-client/src/outbound-contract.ts +91 -0
  19. package/node_modules/@vellumai/gateway-client/src/trust-verdict-contract.ts +39 -3
  20. package/node_modules/@vellumai/service-contracts/src/__tests__/ingress.test.ts +0 -8
  21. package/node_modules/@vellumai/service-contracts/src/__tests__/package-boundary.test.ts +1 -5
  22. package/node_modules/@vellumai/service-contracts/src/twilio-ingress.ts +3 -14
  23. package/openapi.yaml +1073 -225
  24. package/package.json +1 -4
  25. package/scripts/test.sh +35 -13
  26. package/src/__tests__/access-request-seed-content-blocks.test.ts +60 -4
  27. package/src/__tests__/acp-session.test.ts +4 -1
  28. package/src/__tests__/actor-trust-resolver-address-fallback.test.ts +0 -6
  29. package/src/__tests__/add-message-preassigned-id.test.ts +56 -0
  30. package/src/__tests__/agent-loop-set-system-prompt.test.ts +139 -0
  31. package/src/__tests__/app-conversation-ids-backfill.test.ts +3 -0
  32. package/src/__tests__/app-source-watcher.test.ts +11 -0
  33. package/src/__tests__/approval-interception-trust-gates.test.ts +148 -3
  34. package/src/__tests__/assistant-attachments.test.ts +62 -4
  35. package/src/__tests__/assistant-id-boundary-guard.test.ts +0 -1
  36. package/src/__tests__/attachments-store-heic-normalize.test.ts +230 -0
  37. package/src/__tests__/attachments-store.test.ts +3 -0
  38. package/src/__tests__/background-shell-bash.test.ts +34 -0
  39. package/src/__tests__/background-shell-host-bash.test.ts +12 -0
  40. package/src/__tests__/background-tool-registry.test.ts +97 -0
  41. package/src/__tests__/background-tool-routes.test.ts +72 -1
  42. package/src/__tests__/background-workers-disk-pressure.test.ts +2 -1
  43. package/src/__tests__/btw-routes.test.ts +57 -3
  44. package/src/__tests__/call-controller.test.ts +474 -84
  45. package/src/__tests__/call-domain.test.ts +48 -1
  46. package/src/__tests__/call-pointer-messages.test.ts +57 -19
  47. package/src/__tests__/call-pointer-no-hardcoded-copy.guard.test.ts +2 -6
  48. package/src/__tests__/call-routes-http.test.ts +15 -14
  49. package/src/__tests__/call-setup-flow-invite.test.ts +568 -0
  50. package/src/__tests__/call-setup-flow-midcall-trust.test.ts +231 -0
  51. package/src/__tests__/call-setup-flow-name-capture.test.ts +754 -0
  52. package/src/__tests__/call-setup-flow-verification.test.ts +925 -0
  53. package/src/__tests__/call-setup-flow.test.ts +311 -0
  54. package/src/__tests__/cancel-resolves-conversation-key.test.ts +0 -1
  55. package/src/__tests__/channel-guardian.test.ts +4 -7
  56. package/src/__tests__/channel-readiness-service.test.ts +0 -6
  57. package/src/__tests__/channel-readiness-slack-remote.test.ts +0 -4
  58. package/src/__tests__/channel-retry-sweep.test.ts +76 -64
  59. package/src/__tests__/channel-setup-panel-ack.test.ts +184 -0
  60. package/src/__tests__/clear-all-lexical.test.ts +90 -0
  61. package/src/__tests__/compactor-media-strip.test.ts +177 -0
  62. package/src/__tests__/config-loader-backfill.test.ts +5 -5
  63. package/src/__tests__/config-schema.test.ts +17 -0
  64. package/src/__tests__/contact-store-interaction-info.test.ts +27 -70
  65. package/src/__tests__/contacts-relay-reads.test.ts +188 -23
  66. package/src/__tests__/contacts-tools.test.ts +42 -1
  67. package/src/__tests__/contacts-write.test.ts +181 -0
  68. package/src/__tests__/context-search-conversations-source.test.ts +220 -81
  69. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +1 -0
  70. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +1 -0
  71. package/src/__tests__/conversation-agent-loop-overflow.test.ts +1 -0
  72. package/src/__tests__/conversation-agent-loop.test.ts +39 -0
  73. package/src/__tests__/conversation-analysis-routes.test.ts +1 -1
  74. package/src/__tests__/conversation-app-control-instantiation.test.ts +2 -0
  75. package/src/__tests__/conversation-clear-safety.test.ts +0 -1
  76. package/src/__tests__/conversation-crud-enabled-plugins.test.ts +60 -0
  77. package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +0 -1
  78. package/src/__tests__/conversation-disk-view.test.ts +1 -0
  79. package/src/__tests__/conversation-enabledplugins-route.test.ts +184 -0
  80. package/src/__tests__/conversation-error.test.ts +0 -18
  81. package/src/__tests__/conversation-fork-crud.test.ts +67 -0
  82. package/src/__tests__/conversation-history-web-search.test.ts +7 -137
  83. package/src/__tests__/conversation-initial-prompt.test.ts +110 -0
  84. package/src/__tests__/conversation-loop-db-lock-resilience.test.ts +191 -0
  85. package/src/__tests__/conversation-process-callsite.test.ts +37 -0
  86. package/src/__tests__/conversation-queue.test.ts +149 -0
  87. package/src/__tests__/conversation-routes-enabled-plugins.test.ts +392 -0
  88. package/src/__tests__/conversation-routes-guardian-reply.test.ts +84 -0
  89. package/src/__tests__/conversation-routes-hidden-queue.test.ts +407 -0
  90. package/src/__tests__/conversation-runtime-assembly.test.ts +36 -16
  91. package/src/__tests__/conversation-skill-tools.test.ts +73 -0
  92. package/src/__tests__/conversation-wipe.test.ts +20 -5
  93. package/src/__tests__/credential-prompt-route.test.ts +69 -0
  94. package/src/__tests__/credential-security-invariants.test.ts +1 -3
  95. package/src/__tests__/db-drop-messages-fts.test.ts +115 -0
  96. package/src/__tests__/deterministic-verification-control-plane.test.ts +1 -62
  97. package/src/__tests__/edit-propagation.test.ts +56 -2
  98. package/src/__tests__/empty-state-greeting-cache.test.ts +9 -0
  99. package/src/__tests__/gateway-only-enforcement.test.ts +15 -110
  100. package/src/__tests__/guardian-expiry-notifier.test.ts +1 -0
  101. package/src/__tests__/guardian-question-mode.test.ts +57 -0
  102. package/src/__tests__/guardian-verification-voice-binding.test.ts +1 -1
  103. package/src/__tests__/guardian-wait-controller.test.ts +619 -0
  104. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +33 -2
  105. package/src/__tests__/heic-fixture.ts +55 -0
  106. package/src/__tests__/helpers/seed-contact-channel.ts +0 -2
  107. package/src/__tests__/http-conversation-lineage.test.ts +6 -1
  108. package/src/__tests__/image-conversion.test.ts +170 -0
  109. package/src/__tests__/inbound-invite-redemption.test.ts +72 -341
  110. package/src/__tests__/introduction-card-resolver.test.ts +354 -0
  111. package/src/__tests__/invite-redeemed-ipc.test.ts +97 -0
  112. package/src/__tests__/invite-routes-http.test.ts +246 -420
  113. package/src/__tests__/job-handler-registration-guard.test.ts +104 -0
  114. package/src/__tests__/lexical-index-dual-write.test.ts +426 -0
  115. package/src/__tests__/lifecycle-memory-v2-seed.test.ts +2 -2
  116. package/src/__tests__/list-messages-attachments.test.ts +159 -0
  117. package/src/__tests__/list-messages-background-tool-completion.test.ts +141 -0
  118. package/src/__tests__/list-messages-queued.test.ts +25 -0
  119. package/src/__tests__/managed-store.test.ts +129 -1
  120. package/src/__tests__/media-stream-audio-transcode.test.ts +113 -0
  121. package/src/__tests__/media-stream-output.test.ts +350 -19
  122. package/src/__tests__/media-stream-server-integration.test.ts +943 -169
  123. package/src/__tests__/media-stream-stt-session.test.ts +498 -1
  124. package/src/__tests__/memory-jobs-worker-lanes.test.ts +2 -2
  125. package/src/__tests__/model-intents.test.ts +1 -1
  126. package/src/__tests__/mtime-cache.test.ts +19 -0
  127. package/src/__tests__/non-member-access-request.test.ts +349 -3
  128. package/src/__tests__/notification-decision-fallback.test.ts +104 -8
  129. package/src/__tests__/notification-decision-strategy.test.ts +57 -8
  130. package/src/__tests__/onboarding-template-contract.test.ts +27 -43
  131. package/src/__tests__/openai-provider.test.ts +33 -0
  132. package/src/__tests__/openai-responses-provider.test.ts +40 -0
  133. package/src/__tests__/persistence-layering-guard.test.ts +29 -20
  134. package/src/__tests__/persona-resolver.test.ts +56 -2
  135. package/src/__tests__/personal-memory-auth-bypass.test.ts +62 -0
  136. package/src/__tests__/phone.test.ts +1 -15
  137. package/src/__tests__/plugin-bootstrap.test.ts +25 -196
  138. package/src/__tests__/plugin-disabled-state.test.ts +33 -0
  139. package/src/__tests__/plugin-effective-enabled-set.test.ts +227 -0
  140. package/src/__tests__/plugin-event-hub-facade.test.ts +323 -0
  141. package/src/__tests__/plugin-import-boundary-guard.test.ts +156 -42
  142. package/src/__tests__/plugin-injector-contribution.test.ts +4 -20
  143. package/src/__tests__/plugin-pipeline.test.ts +63 -1
  144. package/src/__tests__/plugin-route-contribution.test.ts +62 -115
  145. package/src/__tests__/plugin-tool-contribution.test.ts +0 -22
  146. package/src/__tests__/plugin-types.test.ts +0 -1
  147. package/src/__tests__/pointer-conversation-trust.test.ts +38 -6
  148. package/src/__tests__/pre-model-call-sanitize.test.ts +1 -1
  149. package/src/__tests__/prune-old-tool-invocations-job.test.ts +97 -0
  150. package/src/__tests__/public-ingress-urls.test.ts +0 -48
  151. package/src/__tests__/qdrant-collection-migration.test.ts +145 -2
  152. package/src/__tests__/reaction-intercept-member-verdict-warm.test.ts +0 -1
  153. package/src/__tests__/resolve-trust-class.test.ts +28 -10
  154. package/src/__tests__/scaffold-managed-skill-tool.test.ts +137 -0
  155. package/src/__tests__/schedule-retry.test.ts +38 -14
  156. package/src/__tests__/schedule-routes-workflow-validation.test.ts +3 -3
  157. package/src/__tests__/schedule-routes.test.ts +14 -6
  158. package/src/__tests__/schedule-store.test.ts +3 -1
  159. package/src/__tests__/scheduler-disk-pressure.test.ts +17 -6
  160. package/src/__tests__/scheduler-recurrence.test.ts +57 -107
  161. package/src/__tests__/scheduler-reuse-conversation.test.ts +51 -46
  162. package/src/__tests__/scheduler-wake.test.ts +13 -23
  163. package/src/__tests__/scheduler-worker-standdown.test.ts +220 -0
  164. package/src/__tests__/secret-routes-platform-proxy.test.ts +1 -1
  165. package/src/__tests__/shell-observability.test.ts +1 -0
  166. package/src/__tests__/skill-boundary-guard.test.ts +3 -4
  167. package/src/__tests__/skill-load-plugin-scope.test.ts +238 -0
  168. package/src/__tests__/skill-projection-feature-flag.test.ts +2 -0
  169. package/src/__tests__/skill-script-runner-host.test.ts +53 -0
  170. package/src/__tests__/skill-script-runner-sandbox.test.ts +5 -2
  171. package/src/__tests__/skill-tool-factory.test.ts +73 -1
  172. package/src/__tests__/slack-app-setup-skill-regression.test.ts +37 -14
  173. package/src/__tests__/slack-inbound-verification.test.ts +36 -0
  174. package/src/__tests__/slack-notification-approval-card.test.ts +89 -2
  175. package/src/__tests__/slack-reaction-canonical-approval.test.ts +51 -1
  176. package/src/__tests__/stt-hints.test.ts +2 -256
  177. package/src/__tests__/subagent-allowlist-validation.test.ts +47 -0
  178. package/src/__tests__/subagent-call-site-routing.test.ts +72 -0
  179. package/src/__tests__/subagent-fork-notifications.test.ts +14 -2
  180. package/src/__tests__/subagent-persistence.test.ts +122 -0
  181. package/src/__tests__/subagent-spawn-and-await.test.ts +1 -0
  182. package/src/__tests__/subagent-terminal-message.test.ts +99 -0
  183. package/src/__tests__/subagent-tool-gate-mode.test.ts +78 -1
  184. package/src/__tests__/system-prompt.test.ts +17 -118
  185. package/src/__tests__/task-scheduler.test.ts +68 -89
  186. package/src/__tests__/telephony-credential-preflight.test.ts +312 -0
  187. package/src/__tests__/telephony-tts-guard.test.ts +538 -0
  188. package/src/__tests__/title-generate-hook.test.ts +16 -0
  189. package/src/__tests__/tool-approval-handler.test.ts +87 -1
  190. package/src/__tests__/tool-approval-seed-content-blocks.test.ts +45 -20
  191. package/src/__tests__/tool-grant-request-escalation.test.ts +39 -0
  192. package/src/__tests__/trust-context-guards.test.ts +21 -10
  193. package/src/__tests__/trusted-contact-multichannel.test.ts +4 -0
  194. package/src/__tests__/twilio-provider.test.ts +17 -17
  195. package/src/__tests__/twilio-routes-twiml.test.ts +6 -543
  196. package/src/__tests__/twilio-routes.test.ts +257 -387
  197. package/src/__tests__/twilio-validation.test.ts +1 -1
  198. package/src/__tests__/unified-turn-context-client-os.test.ts +45 -0
  199. package/src/__tests__/usage-cache-backfill-migration.test.ts +5 -0
  200. package/src/__tests__/voice-approval-resolver-relay.test.ts +150 -0
  201. package/src/__tests__/voice-ingress-preflight.test.ts +61 -0
  202. package/src/__tests__/voice-quality.test.ts +2 -2
  203. package/src/__tests__/voice-scoped-grant-consumer.test.ts +1 -7
  204. package/src/__tests__/voice-session-bridge-processing-wait.test.ts +27 -0
  205. package/src/__tests__/voice-session-bridge.test.ts +1 -10
  206. package/src/__tests__/workspace-git-service.test.ts +1 -1
  207. package/src/__tests__/workspace-migration-013-repair-conversation-disk-view.test.ts +1 -0
  208. package/src/__tests__/workspace-migration-118-seed-now-md.test.ts +120 -0
  209. package/src/__tests__/workspace-migration-120-revise-onboarding-threads.test.ts +175 -0
  210. package/src/__tests__/workspace-migration-121-seed-default-user-guardrails.test.ts +118 -0
  211. package/src/__tests__/workspace-migration-122-relocate-default-user-boundary.test.ts +119 -0
  212. package/src/__tests__/workspace-migration-123-swap-quality-profile-to-fable.test.ts +191 -0
  213. package/src/__tests__/workspace-migration-backfill-installation-id.test.ts +235 -241
  214. package/src/acp/__tests__/prepare-agent-env.test.ts +0 -97
  215. package/src/acp/__tests__/session-manager-persistence.test.ts +2 -0
  216. package/src/acp/__tests__/session-manager-resume.test.ts +8 -0
  217. package/src/acp/__tests__/session-manager-usage.test.ts +6 -0
  218. package/src/acp/__tests__/session-manager.test.ts +6 -0
  219. package/src/acp/agent-process.test.ts +116 -0
  220. package/src/acp/agent-process.ts +71 -0
  221. package/src/acp/auto-install.ts +12 -8
  222. package/src/acp/failure-error.test.ts +109 -0
  223. package/src/acp/failure-error.ts +111 -0
  224. package/src/acp/prepare-agent-env.ts +0 -12
  225. package/src/acp/resolve-agent.test.ts +6 -45
  226. package/src/acp/resolve-agent.ts +2 -4
  227. package/src/acp/session-manager.test.ts +312 -0
  228. package/src/acp/session-manager.ts +102 -46
  229. package/src/agent/ax-tree-compaction.test.ts +4 -1
  230. package/src/agent/image-optimize.ts +17 -127
  231. package/src/agent/loop.ts +45 -192
  232. package/src/api/events/background-tool-completed.test.ts +51 -0
  233. package/src/api/events/background-tool-completed.ts +29 -0
  234. package/src/api/events/background-tool-started.test.ts +36 -0
  235. package/src/api/events/background-tool-started.ts +28 -0
  236. package/src/api/events/conversation-error.ts +0 -1
  237. package/src/api/events/open-panel.ts +33 -0
  238. package/src/api/events/subagent-status-changed.ts +4 -1
  239. package/src/api/index.ts +19 -0
  240. package/src/api/responses/conversation-message.ts +34 -0
  241. package/src/approvals/guardian-decision-primitive.ts +74 -24
  242. package/src/approvals/guardian-request-resolvers.ts +450 -122
  243. package/src/apps/app-store.ts +1 -0
  244. package/src/apps/shared-app-links-store.ts +1 -0
  245. package/src/avatar/identity-avatar.ts +3 -7
  246. package/src/background-wake/wake-intent-hooks.test.ts +1 -1
  247. package/src/calls/__tests__/fish-audio-client.test.ts +73 -0
  248. package/src/calls/__tests__/gateway-invite-reader.test.ts +170 -0
  249. package/src/calls/__tests__/relay-setup-router.test.ts +126 -102
  250. package/src/calls/call-controller.ts +134 -48
  251. package/src/calls/call-domain.ts +18 -42
  252. package/src/calls/call-pointer-messages.ts +51 -67
  253. package/src/calls/call-setup-flow-types.ts +76 -0
  254. package/src/calls/call-setup-flow.ts +1743 -0
  255. package/src/calls/call-speech-output.ts +87 -23
  256. package/src/calls/call-store.ts +4 -0
  257. package/src/calls/call-transport.ts +22 -36
  258. package/src/calls/fish-audio-client.ts +3 -0
  259. package/src/calls/gateway-invite-reader.ts +98 -0
  260. package/src/calls/guardian-wait-controller.ts +451 -0
  261. package/src/calls/media-stream-audio-transcode.ts +82 -2
  262. package/src/calls/media-stream-output.ts +142 -36
  263. package/src/calls/media-stream-server.ts +297 -178
  264. package/src/calls/media-stream-stt-session.ts +393 -50
  265. package/src/calls/media-turn-detector.ts +4 -6
  266. package/src/calls/relay-access-wait.ts +3 -4
  267. package/src/calls/relay-setup-router.ts +22 -43
  268. package/src/calls/relay-verification.ts +17 -24
  269. package/src/calls/resolve-call-tts-provider.ts +96 -29
  270. package/src/calls/stt-hints.ts +24 -87
  271. package/src/calls/telephony-credential-preflight.ts +159 -0
  272. package/src/calls/telephony-tts-capability.ts +183 -0
  273. package/src/calls/tts-call-strategy.ts +18 -20
  274. package/src/calls/twilio-provider.ts +3 -2
  275. package/src/calls/twilio-routes.ts +47 -351
  276. package/src/calls/types.ts +5 -3
  277. package/src/calls/voice-ingress-preflight.ts +9 -0
  278. package/src/calls/voice-quality.ts +13 -18
  279. package/src/calls/voice-session-bridge.ts +25 -35
  280. package/src/channels/__tests__/types.test.ts +28 -0
  281. package/src/channels/channel-verification-sessions.ts +7 -2
  282. package/src/channels/config.ts +0 -42
  283. package/src/channels/slack-thread-store.ts +12 -0
  284. package/src/channels/types.ts +23 -0
  285. package/src/cli/commands/__tests__/conversations-slack.test.ts +1 -1
  286. package/src/cli/commands/__tests__/schedules.test.ts +83 -34
  287. package/src/cli/commands/__tests__/status.test.ts +42 -2
  288. package/src/cli/commands/contacts.ts +2 -2
  289. package/src/cli/commands/credentials.ts +17 -0
  290. package/src/cli/commands/monitoring.ts +191 -0
  291. package/src/cli/commands/schedules-worker.ts +175 -0
  292. package/src/cli/commands/schedules.ts +169 -43
  293. package/src/cli/commands/status.ts +12 -1
  294. package/src/cli/commands/tools.ts +5 -1
  295. package/src/cli/lib/__tests__/plugin-catalog-cache.test.ts +1 -0
  296. package/src/cli/lib/__tests__/search-plugins.test.ts +29 -1
  297. package/src/cli/lib/__tests__/toggle-plugin.test.ts +7 -0
  298. package/src/cli/lib/search-plugins.ts +6 -0
  299. package/src/cli/lib/toggle-plugin.ts +21 -2
  300. package/src/cli/program.ts +3 -1
  301. package/src/config/__tests__/deployment-context-defaults.test.ts +23 -0
  302. package/src/config/acp-defaults.test.ts +0 -10
  303. package/src/config/acp-defaults.ts +0 -6
  304. package/src/config/bundled-skills/acp/SKILL.md +13 -45
  305. package/src/config/bundled-skills/acp/TOOLS.json +3 -3
  306. package/src/config/bundled-skills/app-builder/SKILL.md +3 -3
  307. package/src/config/bundled-skills/app-builder/references/RESPONSIVE.md +9 -9
  308. package/src/config/bundled-skills/contacts/tools/contact-merge.ts +1 -1
  309. package/src/config/bundled-skills/contacts/tools/contact-search.ts +1 -1
  310. package/src/config/bundled-skills/phone-calls/SKILL.md +1 -1
  311. package/src/config/bundled-skills/phone-calls/references/CONFIG.md +9 -9
  312. package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +10 -7
  313. package/src/config/bundled-skills/skill-management/TOOLS.json +10 -0
  314. package/src/config/call-site-defaults.ts +0 -2
  315. package/src/config/feature-flag-registry.json +16 -8
  316. package/src/config/loader.ts +11 -0
  317. package/src/config/schema.ts +9 -1
  318. package/src/config/schemas/__tests__/memory-v2.test.ts +2 -2
  319. package/src/config/schemas/__tests__/memory-v3.test.ts +64 -0
  320. package/src/config/schemas/call-site-catalog.ts +0 -12
  321. package/src/config/schemas/calls.ts +8 -0
  322. package/src/config/schemas/elevenlabs.ts +1 -1
  323. package/src/config/schemas/llm.ts +0 -2
  324. package/src/config/schemas/memory-v2.ts +1 -1
  325. package/src/config/schemas/memory-v3.ts +82 -0
  326. package/src/config/schemas/monitoring.ts +61 -0
  327. package/src/config/schemas/schedules.ts +35 -0
  328. package/src/config/seed-inference-profiles.ts +2 -2
  329. package/src/config/skills-plugin-filter.test.ts +96 -0
  330. package/src/config/skills.ts +26 -0
  331. package/src/contacts/__tests__/member-write-relay.test.ts +156 -4
  332. package/src/contacts/canonical-guardian-store.ts +5 -0
  333. package/src/contacts/contact-store.ts +81 -35
  334. package/src/contacts/contacts-write.ts +50 -25
  335. package/src/contacts/member-write-relay.ts +115 -31
  336. package/src/contacts/types.ts +0 -8
  337. package/src/context/compactor.ts +29 -15
  338. package/src/context/outbound-sanitize.ts +202 -0
  339. package/src/daemon/__tests__/abort-null-controller.test.ts +167 -0
  340. package/src/daemon/__tests__/conversation-tool-setup-plugin-scope.test.ts +122 -0
  341. package/src/daemon/__tests__/embedding-reconcile.test.ts +99 -16
  342. package/src/daemon/__tests__/wake-conversation-ops-completion.test.ts +107 -0
  343. package/src/daemon/abort-watchdog.ts +7 -0
  344. package/src/daemon/app-source-watcher.ts +9 -0
  345. package/src/daemon/assistant-attachments.ts +42 -0
  346. package/src/daemon/conversation-agent-loop-handlers.ts +256 -147
  347. package/src/daemon/conversation-agent-loop.ts +61 -68
  348. package/src/daemon/conversation-error.ts +1 -15
  349. package/src/daemon/conversation-history.ts +32 -236
  350. package/src/daemon/conversation-initial-prompt.ts +77 -0
  351. package/src/daemon/conversation-lifecycle.ts +25 -1
  352. package/src/daemon/conversation-messaging.ts +2 -2
  353. package/src/daemon/conversation-plugin-scope.ts +38 -0
  354. package/src/daemon/conversation-process.ts +50 -14
  355. package/src/daemon/conversation-runtime-assembly.ts +36 -6
  356. package/src/daemon/conversation-skill-tools.ts +19 -3
  357. package/src/daemon/conversation-store.ts +3 -3
  358. package/src/daemon/conversation-surfaces.ts +171 -0
  359. package/src/daemon/conversation-tool-setup.test.ts +95 -0
  360. package/src/daemon/conversation-tool-setup.ts +116 -1
  361. package/src/daemon/conversation-turn-finalize.ts +211 -0
  362. package/src/daemon/conversation.ts +92 -1
  363. package/src/daemon/disk-pressure-policy.ts +2 -1
  364. package/src/daemon/event-loop-watchdog.ts +22 -6
  365. package/src/daemon/external-plugins-bootstrap.ts +47 -134
  366. package/src/daemon/handlers/__tests__/config-a2a-accept.test.ts +1 -1
  367. package/src/daemon/handlers/__tests__/config-a2a-complete.test.ts +26 -14
  368. package/src/daemon/handlers/__tests__/config-a2a-invite.test.ts +27 -14
  369. package/src/daemon/handlers/__tests__/config-channels.test.ts +0 -5
  370. package/src/daemon/handlers/config-a2a.ts +7 -14
  371. package/src/daemon/handlers/config-channels.ts +2 -10
  372. package/src/daemon/handlers/conversation-history.ts +3 -1
  373. package/src/daemon/handlers/conversations.ts +0 -52
  374. package/src/daemon/handlers/shared.ts +4 -24
  375. package/src/daemon/handlers/skills.ts +4 -1
  376. package/src/daemon/host-cu-proxy.ts +1 -1
  377. package/src/daemon/lifecycle.ts +59 -472
  378. package/src/daemon/message-protocol.ts +3 -3
  379. package/src/daemon/message-provenance.ts +12 -14
  380. package/src/daemon/message-types/background-tools.ts +28 -0
  381. package/src/daemon/message-types/contacts.ts +2 -10
  382. package/src/daemon/message-types/conversations.ts +10 -0
  383. package/src/daemon/message-types/integrations.ts +2 -0
  384. package/src/daemon/message-types/surfaces.ts +1 -0
  385. package/src/daemon/message-types/sync.ts +1 -0
  386. package/src/daemon/pointer-conversation-trust.ts +23 -9
  387. package/src/daemon/pointer-turn-runner.ts +174 -0
  388. package/src/daemon/providers-setup.ts +16 -0
  389. package/src/daemon/shutdown-handlers.ts +139 -47
  390. package/src/daemon/skill-memory-refresh.ts +2 -2
  391. package/src/daemon/sqlite-corruption-watchdog.test.ts +217 -0
  392. package/src/daemon/sqlite-corruption-watchdog.ts +155 -0
  393. package/src/daemon/tool-setup-types.ts +8 -0
  394. package/src/daemon/trust-context.ts +21 -6
  395. package/src/daemon/turn-latency-tracker.test.ts +93 -0
  396. package/src/daemon/turn-latency-tracker.ts +38 -0
  397. package/src/daemon/wake-conversation-ops.ts +10 -8
  398. package/src/documents/document-comments-store.test.ts +7 -1
  399. package/src/documents/document-comments-store.ts +8 -0
  400. package/src/documents/document-store.ts +15 -0
  401. package/src/export/__tests__/transcript-formatter.test.ts +11 -0
  402. package/src/export/transcript-formatter.ts +49 -67
  403. package/src/home/__tests__/feed-writer.test.ts +247 -1
  404. package/src/home/conversation-starter-checkpoints.ts +1 -0
  405. package/src/home/feed-writer.ts +61 -0
  406. package/src/home/job-handlers/conversation-starters.ts +1 -0
  407. package/src/hooks/hook-loader.ts +12 -0
  408. package/src/hooks/registry.ts +32 -4
  409. package/src/inbound/public-ingress-urls.ts +0 -17
  410. package/src/ipc/__tests__/contacts-info-ipc.test.ts +285 -0
  411. package/src/ipc/assistant-server.ts +28 -7
  412. package/src/ipc/routes/__tests__/contacts-mirror-apply-atomicity.test.ts +62 -0
  413. package/src/ipc/routes/__tests__/contacts-mirror-apply.test.ts +272 -0
  414. package/src/ipc/routes/__tests__/contacts-mirror-ipc-routes.test.ts +322 -0
  415. package/src/ipc/routes/__tests__/invite-ipc-routes.test.ts +60 -4
  416. package/src/ipc/routes/contacts-info-ipc-routes.ts +239 -0
  417. package/src/ipc/routes/contacts-mirror-ipc-routes.ts +202 -0
  418. package/src/ipc/routes/db-proxy.ts +5 -2
  419. package/src/ipc/routes/invite-ipc-routes.ts +53 -39
  420. package/src/jobs/worker.ts +9 -2
  421. package/src/live-voice/__tests__/live-voice-archive.test.ts +10 -1
  422. package/src/live-voice/live-voice-archive.ts +5 -0
  423. package/src/messaging/providers/__tests__/transport-dispatch.test.ts +22 -6
  424. package/src/messaging/providers/channel-transport.ts +6 -0
  425. package/src/messaging/providers/index.ts +3 -0
  426. package/src/messaging/providers/slack/api.test.ts +49 -1
  427. package/src/messaging/providers/slack/api.ts +110 -0
  428. package/src/messaging/providers/slack/send.test.ts +85 -0
  429. package/src/messaging/providers/slack/send.ts +100 -28
  430. package/src/messaging/providers/slack/transport.ts +7 -13
  431. package/src/messaging/providers/whatsapp/send.ts +29 -9
  432. package/src/monitoring/__tests__/control.test.ts +235 -0
  433. package/src/monitoring/__tests__/sample-ring-buffer.test.ts +96 -0
  434. package/src/monitoring/control.ts +105 -0
  435. package/src/monitoring/resource-sampler.ts +258 -0
  436. package/src/monitoring/sample-ring-buffer.ts +108 -0
  437. package/src/monitoring/worker.ts +94 -0
  438. package/src/notifications/README.md +1 -1
  439. package/src/notifications/access-request-copy.ts +94 -23
  440. package/src/notifications/adapters/slack.ts +89 -21
  441. package/src/notifications/approval-card-builder.ts +33 -18
  442. package/src/notifications/approval-card-data.ts +48 -15
  443. package/src/notifications/broadcaster.ts +25 -16
  444. package/src/notifications/decision-engine.ts +131 -32
  445. package/src/notifications/guardian-question-mode.ts +58 -10
  446. package/src/permissions/approval-policy.ts +8 -1
  447. package/src/permissions/checker.ts +2 -0
  448. package/src/permissions/gateway-threshold-reader.ts +7 -6
  449. package/src/permissions/ipc-risk-types.ts +1 -0
  450. package/src/permissions/secret-prompter.ts +11 -3
  451. package/src/permissions/types.ts +2 -2
  452. package/src/persistence/__tests__/conversation-queries-search.test.ts +397 -0
  453. package/src/persistence/__tests__/conversation-search-lexical.test.ts +103 -0
  454. package/src/persistence/__tests__/jobs-worker-memory-disabled.test.ts +95 -0
  455. package/src/persistence/__tests__/slow-query-log.test.ts +266 -0
  456. package/src/persistence/__tests__/slow-sync-log.test.ts +155 -0
  457. package/src/persistence/a2a-invite-store.ts +205 -0
  458. package/src/persistence/attachments-store.ts +94 -10
  459. package/src/persistence/checkpoints.ts +45 -0
  460. package/src/persistence/conversation-crud.ts +453 -260
  461. package/src/persistence/conversation-display-order-migration.ts +8 -2
  462. package/src/persistence/conversation-group-migration.test.ts +8 -0
  463. package/src/persistence/conversation-group-migration.ts +9 -0
  464. package/src/persistence/conversation-queries.ts +244 -125
  465. package/src/persistence/conversation-row-batch-delete.ts +9 -5
  466. package/src/persistence/conversation-search-lexical.ts +49 -0
  467. package/src/persistence/db-async-query.ts +42 -0
  468. package/src/persistence/db-connection.ts +13 -0
  469. package/src/persistence/delivery-channels.ts +0 -82
  470. package/src/persistence/delivery-crud.ts +27 -6
  471. package/src/persistence/embeddings/__tests__/embedding-identity.test.ts +18 -5
  472. package/src/persistence/embeddings/__tests__/messages-lexical-index.test.ts +334 -0
  473. package/src/persistence/embeddings/embedding-identity.ts +17 -5
  474. package/src/persistence/embeddings/embedding-runtime-manager.ts +31 -0
  475. package/src/persistence/embeddings/messages-lexical-index.ts +396 -0
  476. package/src/persistence/embeddings/qdrant-client.ts +81 -5
  477. package/src/persistence/group-crud.ts +13 -1
  478. package/src/persistence/job-handlers/__tests__/message-lexical-backfill.test.ts +506 -0
  479. package/src/persistence/job-handlers/__tests__/message-lexical-enqueue.test.ts +164 -0
  480. package/src/persistence/job-handlers/__tests__/message-lexical.test.ts +259 -0
  481. package/src/persistence/job-handlers/cleanup.ts +57 -9
  482. package/src/persistence/job-handlers/message-lexical-backfill.ts +187 -0
  483. package/src/persistence/job-handlers/message-lexical.ts +251 -0
  484. package/src/persistence/jobs-store.ts +102 -8
  485. package/src/persistence/jobs-worker.ts +68 -28
  486. package/src/persistence/llm-request-log-store.ts +35 -19
  487. package/src/persistence/llm-usage-store.ts +11 -0
  488. package/src/persistence/memory-lifecycle-hooks.test.ts +65 -0
  489. package/src/persistence/memory-lifecycle-hooks.ts +55 -1
  490. package/src/persistence/migrations/028-call-session-mode.ts +1 -1
  491. package/src/persistence/migrations/116-messages-fts.ts +8 -1
  492. package/src/persistence/migrations/311-create-subagents-table.ts +50 -0
  493. package/src/persistence/migrations/312-drop-inbox-conversation-state-table.ts +15 -0
  494. package/src/persistence/migrations/313-drop-messages-fts.ts +17 -0
  495. package/src/persistence/migrations/314-add-conversation-enabled-plugins.ts +25 -0
  496. package/src/persistence/migrations/315-create-a2a-invites.ts +58 -0
  497. package/src/persistence/migrations/316-drop-contact-channels-invite-id.ts +28 -0
  498. package/src/persistence/migrations/317-canonical-guardian-requester-signals.ts +24 -0
  499. package/src/persistence/migrations/318-drop-contact-channel-telemetry.ts +32 -0
  500. package/src/persistence/migrations/__tests__/315-create-a2a-invites.test.ts +161 -0
  501. package/src/persistence/migrations/__tests__/316-drop-contact-channels-invite-id.test.ts +156 -0
  502. package/src/persistence/migrations/__tests__/318-drop-contact-channel-telemetry.test.ts +134 -0
  503. package/src/persistence/migrations/__tests__/migration-prefix-guard.test.ts +99 -0
  504. package/src/persistence/raw-query.ts +50 -11
  505. package/src/persistence/schema/a2a.ts +14 -0
  506. package/src/persistence/schema/contacts.ts +0 -62
  507. package/src/persistence/schema/conversation-groups.ts +12 -0
  508. package/src/persistence/schema/conversations.ts +2 -0
  509. package/src/persistence/schema/documents.ts +65 -0
  510. package/src/persistence/schema/guardian.ts +4 -0
  511. package/src/persistence/schema/index.ts +4 -0
  512. package/src/persistence/schema/memory-injection.ts +62 -0
  513. package/src/persistence/schema/workflows.ts +55 -0
  514. package/src/persistence/slow-query-log.ts +437 -0
  515. package/src/persistence/slow-sync-log.ts +204 -0
  516. package/src/persistence/steps.ts +16 -0
  517. package/src/persistence/subagent-store.ts +125 -0
  518. package/src/persistence/worker-control.ts +45 -238
  519. package/src/plugin-api/event-hub-facade.ts +172 -0
  520. package/src/plugin-api/index.ts +9 -1
  521. package/src/plugin-api/types.ts +40 -9
  522. package/src/plugins/defaults/default-plugin-names.ts +60 -0
  523. package/src/plugins/defaults/index.ts +19 -29
  524. package/src/plugins/defaults/memory/__tests__/conversation-queries.test.ts +46 -67
  525. package/src/plugins/defaults/memory/__tests__/db-async-query.test.ts +36 -1
  526. package/src/plugins/defaults/memory/__tests__/find-most-recent-retrospective-for.test.ts +2 -4
  527. package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-graph-trigger-embed.test.ts +2 -2
  528. package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-schedule.test.ts +9 -0
  529. package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +7 -4
  530. package/src/plugins/defaults/memory/config.ts +11 -0
  531. package/src/plugins/defaults/memory/context-search/agent-runner.ts +1 -1
  532. package/src/plugins/defaults/memory/context-search/sources/conversations.ts +124 -113
  533. package/src/plugins/defaults/memory/embeddings.ts +77 -0
  534. package/src/plugins/defaults/memory/find-most-recent-retrospective-for.ts +66 -0
  535. package/src/plugins/defaults/memory/frontmatter.ts +50 -0
  536. package/src/plugins/defaults/memory/graph/bootstrap.test.ts +36 -10
  537. package/src/plugins/defaults/memory/graph/bootstrap.ts +6 -5
  538. package/src/plugins/defaults/memory/graph/consolidation.ts +3 -5
  539. package/src/plugins/defaults/memory/graph/extraction.ts +3 -6
  540. package/src/plugins/defaults/memory/graph/graph-search.ts +12 -23
  541. package/src/plugins/defaults/memory/graph/narrative.ts +3 -5
  542. package/src/plugins/defaults/memory/graph/pattern-scan.ts +3 -5
  543. package/src/plugins/defaults/memory/graph/retriever.test.ts +1 -6
  544. package/src/plugins/defaults/memory/graph/retriever.ts +5 -10
  545. package/src/plugins/defaults/memory/graph/tools.ts +1 -1
  546. package/src/plugins/defaults/memory/hooks/init.ts +31 -5
  547. package/src/plugins/defaults/memory/indexer.ts +2 -3
  548. package/src/plugins/defaults/memory/injectors.ts +2 -2
  549. package/src/plugins/defaults/memory/job-handler-registration.ts +96 -0
  550. package/src/plugins/defaults/memory/job-handlers/backfill.ts +4 -26
  551. package/src/plugins/defaults/memory/job-handlers/embedding.test.ts +6 -19
  552. package/src/plugins/defaults/memory/job-handlers/embedding.ts +9 -22
  553. package/src/plugins/defaults/memory/job-handlers/index-maintenance.ts +2 -3
  554. package/src/plugins/defaults/memory/job-handlers.ts +13 -12
  555. package/src/plugins/defaults/memory/jobs/embed-concept-page.ts +1 -1
  556. package/src/plugins/defaults/memory/llm-helpers.ts +76 -0
  557. package/src/plugins/defaults/memory/memory-retrospective-job.ts +8 -5
  558. package/src/plugins/defaults/memory/memory-retrospective-startup-cleanup.ts +2 -2
  559. package/src/plugins/defaults/memory/memory-v2-concept-frequency.ts +2 -0
  560. package/src/plugins/defaults/memory/persistence-hooks.ts +46 -1
  561. package/src/plugins/defaults/memory/pkb/pkb-index.ts +1 -5
  562. package/src/plugins/defaults/memory/pkb/pkb-search.ts +2 -2
  563. package/src/plugins/defaults/memory/routes/__tests__/memory-v2-simulate-route.test.ts +4 -6
  564. package/src/plugins/defaults/memory/routes/memory-item-routes.ts +1 -1
  565. package/src/plugins/defaults/memory/search/semantic.ts +2 -2
  566. package/src/plugins/defaults/memory/startup.ts +244 -0
  567. package/src/plugins/defaults/memory/task-memory-cleanup.ts +8 -0
  568. package/src/{daemon → plugins/defaults/memory/v2}/__tests__/memory-v2-startup.test.ts +6 -6
  569. package/src/plugins/defaults/memory/v2/__tests__/migration.test.ts +2 -13
  570. package/src/plugins/defaults/memory/v2/__tests__/router.test.ts +4 -5
  571. package/src/plugins/defaults/memory/v2/__tests__/sweep-job.test.ts +1 -8
  572. package/src/plugins/defaults/memory/v2/activation.ts +2 -4
  573. package/src/plugins/defaults/memory/v2/cli-command-store.ts +2 -4
  574. package/src/plugins/defaults/memory/v2/frontmatter-sweep.ts +1 -1
  575. package/src/{daemon → plugins/defaults/memory/v2}/memory-v2-startup.test.ts +8 -8
  576. package/src/{daemon → plugins/defaults/memory/v2}/memory-v2-startup.ts +20 -22
  577. package/src/plugins/defaults/memory/v2/migration.ts +2 -5
  578. package/src/plugins/defaults/memory/v2/page-store.ts +1 -1
  579. package/src/plugins/defaults/memory/v2/qdrant.ts +2 -3
  580. package/src/plugins/defaults/memory/v2/router.ts +5 -5
  581. package/src/plugins/defaults/memory/v2/sim.ts +2 -4
  582. package/src/plugins/defaults/memory/v2/skill-store.ts +2 -4
  583. package/src/plugins/defaults/memory/v2/sweep-job.ts +6 -6
  584. package/src/plugins/defaults/memory/v3/__tests__/carry-integration.test.ts +11 -9
  585. package/src/plugins/defaults/memory/v3/__tests__/dense.test.ts +107 -2
  586. package/src/plugins/defaults/memory/v3/__tests__/gate-flag.test.ts +69 -0
  587. package/src/plugins/defaults/memory/v3/__tests__/gate.test.ts +181 -0
  588. package/src/plugins/defaults/memory/v3/__tests__/live-integration.test.ts +7 -3
  589. package/src/plugins/defaults/memory/v3/__tests__/orchestrate.test.ts +345 -8
  590. package/src/plugins/defaults/memory/v3/__tests__/pool-select.test.ts +1 -4
  591. package/src/plugins/defaults/memory/v3/__tests__/section-needle.test.ts +64 -0
  592. package/src/plugins/defaults/memory/v3/__tests__/shadow-integration.test.ts +18 -13
  593. package/src/plugins/defaults/memory/v3/__tests__/shadow-plugin.test.ts +62 -1
  594. package/src/plugins/defaults/memory/v3/card.ts +1 -4
  595. package/src/plugins/defaults/memory/v3/dense.ts +60 -25
  596. package/src/plugins/defaults/memory/v3/edge.ts +1 -1
  597. package/src/plugins/defaults/memory/v3/gate-flag.ts +20 -0
  598. package/src/plugins/defaults/memory/v3/gate.ts +158 -0
  599. package/src/plugins/defaults/memory/v3/maintain-job.ts +2 -4
  600. package/src/plugins/defaults/memory/v3/orchestrate.ts +186 -25
  601. package/src/plugins/defaults/memory/v3/pool-select.test.ts +7 -9
  602. package/src/plugins/defaults/memory/v3/pool-select.ts +6 -6
  603. package/src/plugins/defaults/memory/v3/prune.ts +2 -2
  604. package/src/plugins/defaults/memory/v3/section-dense-store.ts +8 -11
  605. package/src/plugins/defaults/memory/v3/section-needle.ts +27 -7
  606. package/src/plugins/defaults/memory/v3/shadow-plugin.ts +10 -0
  607. package/src/plugins/defaults/memory/v3-eval/eval-packets.ts +1 -4
  608. package/src/plugins/defaults/title-generate/hooks/user-prompt-submit.ts +5 -0
  609. package/src/plugins/defaults/turn-context/injectors.ts +1 -0
  610. package/src/plugins/defaults/turn-context/unified-turn-context.ts +12 -0
  611. package/src/plugins/injector-registry.ts +13 -2
  612. package/src/plugins/mtime-cache.ts +36 -47
  613. package/src/plugins/pipeline.ts +15 -1
  614. package/src/plugins/types.ts +14 -23
  615. package/src/prompts/__tests__/system-prompt.test.ts +170 -32
  616. package/src/prompts/persona-resolver.ts +13 -9
  617. package/src/prompts/system-prompt.ts +30 -9
  618. package/src/prompts/templates/BOOTSTRAP.md +16 -119
  619. package/src/prompts/templates/SOUL.md +43 -13
  620. package/src/prompts/templates/system-sections.ts +32 -27
  621. package/src/prompts/templates/users/default.md +19 -0
  622. package/src/providers/__tests__/placeholder-sentinels.test.ts +56 -0
  623. package/src/providers/inference/__tests__/base-url-route-validation.test.ts +96 -1
  624. package/src/providers/model-intents.ts +2 -2
  625. package/src/providers/openai/chat-completions-provider.ts +14 -1
  626. package/src/providers/openai/responses-provider.ts +18 -0
  627. package/src/providers/placeholder-sentinels.ts +18 -8
  628. package/src/providers/retry.ts +1 -0
  629. package/src/providers/speech-to-text/__tests__/provider-catalog.test.ts +0 -64
  630. package/src/providers/speech-to-text/__tests__/resolve.test.ts +92 -79
  631. package/src/providers/speech-to-text/deepgram-realtime.test.ts +98 -0
  632. package/src/providers/speech-to-text/deepgram-realtime.ts +62 -3
  633. package/src/providers/speech-to-text/provider-catalog.ts +0 -89
  634. package/src/providers/speech-to-text/resolve.ts +55 -0
  635. package/src/providers/tool-progress-events.test.ts +50 -0
  636. package/src/providers/tool-progress-events.ts +99 -0
  637. package/src/providers/types.ts +1 -1
  638. package/src/providers/vellum-model-routing.test.ts +51 -0
  639. package/src/providers/vellum-model-routing.ts +84 -0
  640. package/src/runtime/AGENTS.md +5 -4
  641. package/src/runtime/__tests__/agent-wake.test.ts +158 -1
  642. package/src/runtime/__tests__/channel-verification-service.test.ts +2 -2
  643. package/src/runtime/__tests__/trust-verdict-consumer.test.ts +37 -8
  644. package/src/runtime/access-request-helper.ts +154 -3
  645. package/src/runtime/actor-trust-resolver.ts +7 -21
  646. package/src/runtime/agent-wake.ts +41 -1
  647. package/src/runtime/assistant-event.ts +86 -12
  648. package/src/runtime/auth/__tests__/route-policy.test.ts +31 -0
  649. package/src/runtime/channel-approval-types.ts +52 -2
  650. package/src/runtime/channel-approvals.ts +23 -8
  651. package/src/runtime/channel-invite-transport.ts +2 -2
  652. package/src/runtime/channel-invite-transports/voice.ts +1 -1
  653. package/src/runtime/channel-readiness-service.ts +3 -5
  654. package/src/runtime/channel-retry-sweep.ts +18 -24
  655. package/src/runtime/channel-verification-service.ts +9 -11
  656. package/src/runtime/finalize-event-delivery.ts +30 -16
  657. package/src/runtime/guardian-action-service.ts +10 -11
  658. package/src/runtime/guardian-reply-router.ts +122 -21
  659. package/src/runtime/http-server.ts +44 -101
  660. package/src/runtime/introduction-policy.test.ts +214 -0
  661. package/src/runtime/introduction-policy.ts +284 -0
  662. package/src/runtime/invite-service.ts +104 -361
  663. package/src/runtime/local-actor-identity.test.ts +38 -0
  664. package/src/runtime/local-actor-identity.ts +14 -0
  665. package/src/runtime/middleware/__tests__/rate-limiter.test.ts +22 -0
  666. package/src/runtime/middleware/rate-limiter.ts +30 -0
  667. package/src/runtime/middleware/twilio-validation.ts +5 -7
  668. package/src/runtime/migrations/__tests__/gcs-signed-url.test.ts +28 -0
  669. package/src/runtime/migrations/origin-mode.ts +6 -6
  670. package/src/runtime/pre-first-message-gate.ts +1 -0
  671. package/src/runtime/routes/__tests__/channel-verification-revoke.test.ts +6 -35
  672. package/src/runtime/routes/__tests__/consolidation-routes.test.ts +24 -3
  673. package/src/runtime/routes/__tests__/contact-routes.test.ts +80 -15
  674. package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +7 -1
  675. package/src/runtime/routes/__tests__/global-search-routes.test.ts +0 -3
  676. package/src/runtime/routes/__tests__/home-feed-routes.test.ts +142 -1
  677. package/src/runtime/routes/__tests__/invite-relay-routes.test.ts +119 -30
  678. package/src/runtime/routes/__tests__/migration-import-allowed-hosts-env.test.ts +70 -0
  679. package/src/runtime/routes/__tests__/monitoring-routes.test.ts +194 -0
  680. package/src/runtime/routes/__tests__/plugins-routes.test.ts +755 -29
  681. package/src/runtime/routes/__tests__/retrospective-routes.test.ts +4 -0
  682. package/src/runtime/routes/__tests__/schedule-routes-create.test.ts +70 -0
  683. package/src/runtime/routes/__tests__/schedule-worker-routes.test.ts +161 -0
  684. package/src/runtime/routes/__tests__/surface-action-routes.test.ts +1 -1
  685. package/src/runtime/routes/__tests__/surface-content-routes.test.ts +1 -1
  686. package/src/runtime/routes/acp-routes.ts +15 -3
  687. package/src/runtime/routes/app-management-routes.ts +4 -7
  688. package/src/runtime/routes/approval-routes.ts +4 -0
  689. package/src/runtime/routes/attachment-routes.ts +54 -3
  690. package/src/runtime/routes/avatar-routes.ts +0 -4
  691. package/src/runtime/routes/background-tool-routes.ts +34 -5
  692. package/src/runtime/routes/btw-routes.ts +32 -4
  693. package/src/runtime/routes/channel-route-shared.ts +18 -14
  694. package/src/runtime/routes/channel-verification-routes.ts +0 -3
  695. package/src/runtime/routes/contact-routes.ts +298 -117
  696. package/src/runtime/routes/conversation-list-routes.ts +6 -0
  697. package/src/runtime/routes/conversation-management-routes.ts +74 -37
  698. package/src/runtime/routes/conversation-query-routes.ts +5 -2
  699. package/src/runtime/routes/conversation-routes.ts +222 -82
  700. package/src/runtime/routes/conversations-import-routes.ts +8 -1
  701. package/src/runtime/routes/credential-prompt-routes.ts +20 -5
  702. package/src/runtime/routes/debug-routes.ts +1 -0
  703. package/src/runtime/routes/documents-routes.ts +5 -2
  704. package/src/runtime/routes/empty-state-greeting-cache.ts +37 -10
  705. package/src/runtime/routes/global-search-routes.ts +2 -1
  706. package/src/runtime/routes/guardian-approval-interception.ts +51 -0
  707. package/src/runtime/routes/home-feed-routes.ts +60 -1
  708. package/src/runtime/routes/identity-routes.ts +4 -87
  709. package/src/runtime/routes/inbound-message-handler.ts +82 -41
  710. package/src/runtime/routes/inbound-stages/acl-enforcement.test.ts +430 -57
  711. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +302 -572
  712. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +76 -270
  713. package/src/runtime/routes/inbound-stages/background-dispatch.ts +21 -116
  714. package/src/runtime/routes/inbound-stages/edit-intercept.ts +9 -1
  715. package/src/runtime/routes/inbound-stages/escalation-intercept.test.ts +158 -0
  716. package/src/runtime/routes/inbound-stages/escalation-intercept.ts +22 -1
  717. package/src/runtime/routes/index.ts +6 -0
  718. package/src/runtime/routes/inference-provider-connection-routes.ts +22 -16
  719. package/src/runtime/routes/internal-twilio-routes.ts +0 -15
  720. package/src/runtime/routes/messages-lexical-routes.ts +75 -0
  721. package/src/runtime/routes/migration-routes.ts +69 -6
  722. package/src/runtime/routes/monitoring-routes.ts +237 -0
  723. package/src/runtime/routes/plugins-routes.ts +329 -8
  724. package/src/runtime/routes/schedule-routes.ts +49 -8
  725. package/src/runtime/routes/schedule-worker-routes.ts +210 -0
  726. package/src/runtime/routes/secret-routes.ts +1 -1
  727. package/src/runtime/routes/surface-conversation-resolver.ts +1 -0
  728. package/src/runtime/services/__tests__/analyze-conversation.test.ts +54 -9
  729. package/src/runtime/services/__tests__/auto-analysis-enqueue.test.ts +30 -6
  730. package/src/runtime/services/__tests__/conversation-analyze-job.test.ts +43 -8
  731. package/src/runtime/services/__tests__/conversation-serializer.test.ts +20 -0
  732. package/src/runtime/services/analyze-conversation.ts +14 -4
  733. package/src/runtime/services/conversation-serializer.ts +5 -0
  734. package/src/runtime/slack-no-response.ts +47 -0
  735. package/src/runtime/slack-reply-session.test.ts +633 -0
  736. package/src/runtime/slack-reply-session.ts +382 -0
  737. package/src/runtime/slack-task-progress.ts +95 -0
  738. package/src/runtime/sync/resource-sync-events.ts +25 -0
  739. package/src/runtime/tool-grant-request-helper.ts +17 -1
  740. package/src/runtime/trust-class.test.ts +141 -0
  741. package/src/runtime/trust-class.ts +121 -0
  742. package/src/runtime/trust-verdict-consumer.ts +7 -6
  743. package/src/schedule/__tests__/run-script.test.ts +21 -0
  744. package/src/schedule/__tests__/worker-control.test.ts +241 -0
  745. package/src/schedule/run-script.ts +13 -6
  746. package/src/schedule/schedule-usage-store.ts +1 -0
  747. package/src/schedule/scheduler.ts +178 -127
  748. package/src/schedule/worker-control.ts +118 -0
  749. package/src/schedule/worker.ts +131 -0
  750. package/src/skills/__tests__/categories-cache.test.ts +38 -0
  751. package/src/skills/categories-cache.ts +40 -5
  752. package/src/skills/managed-store.ts +41 -6
  753. package/src/skills/validate-input.ts +47 -0
  754. package/src/stt/types.ts +5 -9
  755. package/src/subagent/manager.ts +267 -39
  756. package/src/subagent/types.ts +6 -2
  757. package/src/subagent/validate-allowlists.ts +65 -0
  758. package/src/telemetry/watchdog-direct-emit.test.ts +109 -0
  759. package/src/telemetry/watchdog-direct-emit.ts +89 -0
  760. package/src/tools/acp/list-agents.test.ts +0 -6
  761. package/src/tools/background-tool-registry.ts +61 -0
  762. package/src/tools/document/document-comment-tool.test.ts +4 -0
  763. package/src/tools/host-terminal/host-shell.test.ts +397 -0
  764. package/src/tools/host-terminal/host-shell.ts +203 -14
  765. package/src/tools/skills/find-similar-skills.test.ts +152 -1
  766. package/src/tools/skills/find-similar-skills.ts +30 -4
  767. package/src/tools/skills/load.ts +36 -0
  768. package/src/tools/skills/scaffold-managed.ts +66 -34
  769. package/src/tools/skills/skill-script-runner.ts +17 -0
  770. package/src/tools/skills/skill-tool-factory.ts +5 -1
  771. package/src/tools/terminal/safe-env.ts +3 -0
  772. package/src/tools/terminal/shell.test.ts +177 -0
  773. package/src/tools/terminal/shell.ts +98 -4
  774. package/src/tools/tool-approval-handler.ts +106 -29
  775. package/{node_modules/@vellumai/skill-host-contracts/src → src/tools}/tool-types.ts +16 -17
  776. package/src/tools/types.ts +29 -17
  777. package/src/tools/ui-surface/definitions.ts +3 -1
  778. package/src/tts/__tests__/provider-adapters.test.ts +37 -0
  779. package/src/tts/__tests__/provider-catalog.test.ts +21 -0
  780. package/src/tts/provider-catalog.ts +40 -9
  781. package/src/tts/providers/fish-audio-provider.ts +19 -10
  782. package/src/tts/types.ts +3 -4
  783. package/src/util/__tests__/process-tree.test.ts +10 -2
  784. package/src/util/__tests__/text-spacing.test.ts +53 -0
  785. package/src/util/cgroup-memory.ts +142 -0
  786. package/src/util/image-conversion.ts +281 -0
  787. package/src/util/phone.ts +1 -8
  788. package/src/util/platform.ts +33 -0
  789. package/src/util/process-tree.ts +10 -2
  790. package/src/util/text-spacing.ts +53 -0
  791. package/src/util/worker-process.ts +271 -0
  792. package/src/workflows/journal-store.ts +16 -1
  793. package/src/workflows/library.test.ts +35 -20
  794. package/src/workflows/library.ts +105 -66
  795. package/src/workspace/git-service.ts +1 -0
  796. package/src/workspace/migrations/011-backfill-installation-id.ts +83 -31
  797. package/src/workspace/migrations/041-backfill-google-gmail-settings-scope.ts +41 -22
  798. package/src/workspace/migrations/070-memory-v2-summary-schema-rebuild.ts +1 -1
  799. package/src/workspace/migrations/118-seed-now-md.ts +64 -0
  800. package/src/workspace/migrations/119-strip-persisted-memory-v3-tuning-defaults.ts +169 -0
  801. package/src/workspace/migrations/120-revise-onboarding-threads.ts +47 -0
  802. package/src/workspace/migrations/121-seed-default-user-guardrails.ts +82 -0
  803. package/src/workspace/migrations/122-relocate-default-user-boundary.ts +111 -0
  804. package/src/workspace/migrations/123-swap-quality-profile-to-fable.ts +85 -0
  805. package/src/workspace/migrations/__tests__/119-strip-persisted-memory-v3-tuning-defaults.test.ts +181 -0
  806. package/src/workspace/migrations/registry.ts +12 -0
  807. package/drizzle/0000_dizzy_maggott.sql +0 -301
  808. package/drizzle/meta/0000_snapshot.json +0 -1933
  809. package/drizzle/meta/_journal.json +0 -13
  810. package/node_modules/@vellumai/skill-host-contracts/__tests__/client.test.ts +0 -887
  811. package/node_modules/@vellumai/skill-host-contracts/bun.lock +0 -24
  812. package/node_modules/@vellumai/skill-host-contracts/package.json +0 -18
  813. package/node_modules/@vellumai/skill-host-contracts/src/assistant-event.ts +0 -97
  814. package/node_modules/@vellumai/skill-host-contracts/src/client.ts +0 -1349
  815. package/node_modules/@vellumai/skill-host-contracts/src/index.ts +0 -6
  816. package/node_modules/@vellumai/skill-host-contracts/src/runtime-mode.ts +0 -11
  817. package/node_modules/@vellumai/skill-host-contracts/src/server-message.ts +0 -32
  818. package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +0 -333
  819. package/node_modules/@vellumai/skill-host-contracts/tsconfig.json +0 -20
  820. package/node_modules/@vellumai/skill-host-contracts/tsconfig.test.json +0 -12
  821. package/src/__tests__/invite-redemption-service.test.ts +0 -1180
  822. package/src/__tests__/invite-service-ipc.test.ts +0 -350
  823. package/src/__tests__/job-handler-registry-guard.test.ts +0 -125
  824. package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +0 -203
  825. package/src/__tests__/relay-server.test.ts +0 -6153
  826. package/src/__tests__/telephony-stt-routing.test.ts +0 -329
  827. package/src/__tests__/voice-invite-redemption.test.ts +0 -702
  828. package/src/calls/relay-server.ts +0 -2463
  829. package/src/calls/telephony-stt-routing.ts +0 -145
  830. package/src/contacts/__tests__/contacts-write-revoke-relay.test.ts +0 -128
  831. package/src/daemon/__tests__/daemon-skill-host.test.ts +0 -273
  832. package/src/daemon/daemon-skill-host.ts +0 -262
  833. package/src/daemon/message-types/meet.ts +0 -143
  834. package/src/daemon/shutdown-registry.ts +0 -40
  835. package/src/ipc/__tests__/skill-server-bidirectional.test.ts +0 -253
  836. package/src/ipc/__tests__/skill-server.test.ts +0 -182
  837. package/src/ipc/skill-ipc-types.ts +0 -54
  838. package/src/ipc/skill-routes/__tests__/config.test.ts +0 -146
  839. package/src/ipc/skill-routes/__tests__/events-ipc.test.ts +0 -448
  840. package/src/ipc/skill-routes/__tests__/identity.test.ts +0 -62
  841. package/src/ipc/skill-routes/__tests__/log.test.ts +0 -133
  842. package/src/ipc/skill-routes/__tests__/memory.test.ts +0 -203
  843. package/src/ipc/skill-routes/__tests__/platform.test.ts +0 -111
  844. package/src/ipc/skill-routes/__tests__/providers.test.ts +0 -265
  845. package/src/ipc/skill-routes/__tests__/registries.test.ts +0 -400
  846. package/src/ipc/skill-routes/config.ts +0 -47
  847. package/src/ipc/skill-routes/events.ts +0 -147
  848. package/src/ipc/skill-routes/identity.ts +0 -21
  849. package/src/ipc/skill-routes/index.ts +0 -37
  850. package/src/ipc/skill-routes/log.ts +0 -40
  851. package/src/ipc/skill-routes/memory.ts +0 -92
  852. package/src/ipc/skill-routes/platform.ts +0 -39
  853. package/src/ipc/skill-routes/providers.ts +0 -162
  854. package/src/ipc/skill-routes/registries.ts +0 -338
  855. package/src/ipc/skill-server.ts +0 -831
  856. package/src/ipc/skill-socket-path.ts +0 -20
  857. package/src/jobs/register-job-handlers.ts +0 -74
  858. package/src/persistence/invite-store.ts +0 -481
  859. package/src/plugins/job-handler-registry.ts +0 -94
  860. package/src/providers/cache-control.ts +0 -26
  861. package/src/runtime/__tests__/runtime-mode.test.ts +0 -62
  862. package/src/runtime/invite-redemption-service.ts +0 -828
  863. package/src/runtime/invite-redemption-templates.ts +0 -46
  864. package/src/runtime/runtime-mode.ts +0 -40
  865. package/src/runtime/slack-dm-text-delivery.ts +0 -177
  866. package/src/util/voice-code.ts +0 -31
@@ -134,20 +134,32 @@ export interface ModelProfileInfo {
134
134
  // ─── Shutdown context ────────────────────────────────────────────────────────
135
135
 
136
136
  /**
137
- * Context passed to the `shutdown` hook during daemon teardown. Kept
138
- * intentionally narrower than {@link InitContext} — most teardown
139
- * paths only need to know which assistant version they're shutting
140
- * down against (e.g. for version-conditional cleanup of state files
141
- * written by a previous boot).
137
+ * Why a plugin's `shutdown` hook is firing.
142
138
  *
143
- * Additional fields may be added as concrete plugin needs surface; the
144
- * `assistantVersion` field mirrors the init context's so plugins that
145
- * stash a version stamp at init can compare against the same name on
146
- * tear-down without keeping their own copy.
139
+ * - `shutdown` the daemon is tearing down (process exit).
140
+ * - `uninstall` the plugin's directory was removed at runtime.
141
+ * - `disable` the plugin was disabled at runtime (e.g. a `.disabled`
142
+ * sentinel was added, or a feature flag turned it off).
143
+ */
144
+ export type ShutdownReason = "shutdown" | "uninstall" | "disable";
145
+
146
+ /**
147
+ * Context passed to the `shutdown` hook. Kept intentionally narrower than
148
+ * {@link InitContext} — teardown paths only need to know which assistant
149
+ * version they're shutting down against (e.g. for version-conditional cleanup
150
+ * of state files written by a previous boot) and {@link ShutdownReason why}
151
+ * they're being torn down (so a plugin can, e.g., delete its state on
152
+ * `uninstall` but preserve it across a plain `shutdown`).
153
+ *
154
+ * The `assistantVersion` field mirrors the init context's so plugins that stash
155
+ * a version stamp at init can compare against the same name on tear-down
156
+ * without keeping their own copy.
147
157
  */
148
158
  export interface ShutdownContext {
149
159
  /** Assistant semver for compatibility checks inside the plugin. */
150
160
  assistantVersion: string;
161
+ /** Why the plugin is shutting down. */
162
+ reason: ShutdownReason;
151
163
  }
152
164
 
153
165
  // ─── User-prompt-submit hook context ─────────────────────────────────────────
@@ -182,6 +194,14 @@ export interface UserPromptSubmitContext {
182
194
  * attach turn-scoped metadata to the originating message (e.g. recording an
183
195
  * injected memory block so it survives a conversation reload) key off this
184
196
  * row id rather than the in-memory message arrays, whose entries carry no id.
197
+ *
198
+ * @deprecated This field is always identical to {@link requestId}; use
199
+ * `requestId` instead. Every path that starts an agent loop persists the
200
+ * triggering user message under the turn's request ID before running, so
201
+ * the message row id and the request's correlation ID are the same UUID.
202
+ * This holds for the standard submit, queue-drain, subagent, voice, wake,
203
+ * and conversation-analysis paths alike. This field will be removed in a
204
+ * future API version.
185
205
  */
186
206
  readonly userMessageId: string;
187
207
  /**
@@ -189,6 +209,10 @@ export interface UserPromptSubmitContext {
189
209
  * runtime injection forward it onto the injector turn context so the
190
210
  * assembled blocks are attributed to the originating request; it is fixed
191
211
  * for the turn and cannot be recovered from the message arrays.
212
+ *
213
+ * As of the requestId/userMessageId merge, this value is also the
214
+ * persisted row ID of the user message, so hooks that previously
215
+ * keyed off {@link userMessageId} can use `requestId` directly.
192
216
  */
193
217
  readonly requestId: string;
194
218
  /**
@@ -219,6 +243,13 @@ export interface UserPromptSubmitContext {
219
243
  * it from the message arrays.
220
244
  */
221
245
  readonly prompt: string;
246
+ /**
247
+ * True when the triggering message is a transcript-suppressed machine
248
+ * signal (`metadata.hidden` — e.g. the channel-setup wizard-close marker)
249
+ * rather than something the user typed. Hooks that treat `prompt` as
250
+ * user speech (e.g. title generation) should skip these turns.
251
+ */
252
+ readonly isHiddenPrompt?: boolean;
222
253
  /**
223
254
  * The user's original message list, immutable for the hook. Plugins
224
255
  * may snapshot or compare against this but MUST NOT mutate it.
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Names of the first-party default plugins, as a leaf module.
3
+ *
4
+ * This deliberately imports ONLY each default plugin's `package.json` (pure
5
+ * JSON data, no code) rather than the `./index.js` barrel. The barrel statically
6
+ * pulls in every hook/injector implementation (the memory-v3 engine, caption
7
+ * caches, persistence hooks, …) and reaches back into `daemon/` modules, so
8
+ * importing it from `daemon/conversation-tool-setup.ts` forms a module-init
9
+ * cycle. Sourcing the names from this leaf keeps that consumer cycle-free while
10
+ * staying data-driven (names come from `package.json`, never hand-typed).
11
+ *
12
+ * The set is kept in lock-step with the canonical {@link getAllDefaultPlugins}
13
+ * list by a unit assertion in `daemon/conversation-tool-setup.test.ts`.
14
+ */
15
+
16
+ import channelPkg from "./channel/package.json" with { type: "json" };
17
+ import compactionPkg from "./compaction/package.json" with { type: "json" };
18
+ import documentsPkg from "./documents/package.json" with { type: "json" };
19
+ import emptyResponsePkg from "./empty-response/package.json" with { type: "json" };
20
+ import explorationDriftPkg from "./exploration-drift/package.json" with { type: "json" };
21
+ import historyRepairPkg from "./history-repair/package.json" with { type: "json" };
22
+ import imageFallbackPkg from "./image-fallback/package.json" with { type: "json" };
23
+ import imageRecoveryPkg from "./image-recovery/package.json" with { type: "json" };
24
+ import maxTokensContinuePkg from "./max-tokens-continue/package.json" with { type: "json" };
25
+ import memoryPkg from "./memory/package.json" with { type: "json" };
26
+ import sessionPkg from "./session/package.json" with { type: "json" };
27
+ import surfaceCompletionNudgePkg from "./surface-completion-nudge/package.json" with { type: "json" };
28
+ import taskProgressNudgePkg from "./task-progress-nudge/package.json" with { type: "json" };
29
+ import titleGeneratePkg from "./title-generate/package.json" with { type: "json" };
30
+ import toolErrorPkg from "./tool-error/package.json" with { type: "json" };
31
+ import toolResultTruncatePkg from "./tool-result-truncate/package.json" with { type: "json" };
32
+ import turnContextPkg from "./turn-context/package.json" with { type: "json" };
33
+ import workspacePkg from "./workspace/package.json" with { type: "json" };
34
+
35
+ /**
36
+ * The set of first-party default plugin names — runtime infrastructure
37
+ * (memory, turn-context, workspace, session, history repair, title generation,
38
+ * …), not user-toggleable extensions. Used by per-chat plugin scoping to ensure
39
+ * these are never filtered out (see `getEffectiveEnabledPluginSet`).
40
+ */
41
+ export const DEFAULT_PLUGIN_NAMES: ReadonlySet<string> = new Set([
42
+ memoryPkg.name,
43
+ turnContextPkg.name,
44
+ workspacePkg.name,
45
+ documentsPkg.name,
46
+ channelPkg.name,
47
+ sessionPkg.name,
48
+ imageFallbackPkg.name,
49
+ toolResultTruncatePkg.name,
50
+ emptyResponsePkg.name,
51
+ maxTokensContinuePkg.name,
52
+ toolErrorPkg.name,
53
+ explorationDriftPkg.name,
54
+ taskProgressNudgePkg.name,
55
+ surfaceCompletionNudgePkg.name,
56
+ historyRepairPkg.name,
57
+ imageRecoveryPkg.name,
58
+ compactionPkg.name,
59
+ titleGeneratePkg.name,
60
+ ]);
@@ -33,10 +33,6 @@ import {
33
33
  clearInjectorRegistry,
34
34
  registerPluginInjectors,
35
35
  } from "../injector-registry.js";
36
- import {
37
- clearJobHandlerRegistry,
38
- registerPluginJobHandlers,
39
- } from "../job-handler-registry.js";
40
36
  import { registerPlugin, resetPluginRegistryForTests } from "../registry.js";
41
37
  import { type Plugin, PluginExecutionError } from "../types.js";
42
38
  import { channelInjectors } from "./channel/injectors.js";
@@ -74,7 +70,6 @@ import memoryPostCompact from "./memory/hooks/post-compact.js";
74
70
  import memoryShutdown from "./memory/hooks/shutdown.js";
75
71
  import memoryUserPromptSubmit from "./memory/hooks/user-prompt-submit.js";
76
72
  import { memoryInjectors } from "./memory/injectors.js";
77
- import { memoryJobHandlers } from "./memory/job-handlers.js";
78
73
  import memoryPkg from "./memory/package.json" with { type: "json" };
79
74
  import { memoryPersistenceHooks } from "./memory/persistence-hooks.js";
80
75
  import {
@@ -183,7 +178,6 @@ export const defaultMemoryPlugin: Plugin = {
183
178
  "post-compact": memoryPostCompact,
184
179
  },
185
180
  injectors: [...memoryInjectors, memoryV3Injector, memoryV3SpotlightInjector],
186
- jobHandlers: memoryJobHandlers,
187
181
  };
188
182
 
189
183
  /**
@@ -485,32 +479,13 @@ export function registerDefaultPluginInjectors(): void {
485
479
  }
486
480
  }
487
481
 
488
- /**
489
- * Register every default plugin's background-job handlers into the global
490
- * job-handler registry — the job-handler analog of
491
- * {@link registerDefaultPluginInjectors}. `bootstrapPlugins` calls this before
492
- * the per-plugin init loop so a default plugin's handlers are present
493
- * regardless of its disabled-state. The standalone memory-worker process does
494
- * not run plugin bootstrap, so `registerMemoryJobHandlers`
495
- * (`jobs/register-job-handlers.ts`) calls this directly before forwarding the
496
- * registry union into the worker dispatch table. Idempotent:
497
- * `registerPluginJobHandlers` replaces a plugin's prior set, so the per-plugin
498
- * re-registration in `initializePlugin` is a harmless no-op replace.
499
- */
500
- export function registerDefaultPluginJobHandlers(): void {
501
- for (const plugin of getAllDefaultPlugins()) {
502
- if (plugin.jobHandlers && plugin.jobHandlers.length > 0) {
503
- registerPluginJobHandlers(plugin.manifest.name, plugin.jobHandlers);
504
- }
505
- }
506
- }
507
-
508
482
  /**
509
483
  * Wrap a plugin's persistence hooks so its ACTIVE side-effect hooks no-op while
510
484
  * that plugin is disabled (`assistant plugins disable <name>`), mirroring the
511
485
  * read-time disabled-state filtering the injector/hook/job-handler/tool surfaces
512
486
  * apply. The sentinel is checked per call, so enable/disable takes effect on the
513
487
  * next write without a daemon restart. CLEANUP hooks (`onConversationWiped`,
488
+ * `onConversationDeleted`, `onMessagesDeleted`, `onAllConversationsCleared`,
514
489
  * `onWorkerStartup`) are intentionally NOT gated — they must run even when the
515
490
  * plugin is disabled so state created while it was enabled is not orphaned.
516
491
  */
@@ -527,12 +502,29 @@ export function guardPersistenceHooksByDisabledState(
527
502
  if (isPluginDisabled(pluginName)) return;
528
503
  return hooks.onConversationForked(event);
529
504
  },
505
+ // Gated like the active side effects above: a disabled plugin reports an
506
+ // empty buffer, so the maintenance scheduler treats it as "no buffered
507
+ // work" and skips consolidation — matching how disabled injectors/hooks go
508
+ // inert.
509
+ countMemoryBufferLines() {
510
+ if (isPluginDisabled(pluginName)) return 0;
511
+ return hooks.countMemoryBufferLines();
512
+ },
530
513
  // Cleanup hooks are NOT gated on disabled-state: they must run even while
531
514
  // the plugin is disabled, or jobs/conversations created while it was
532
515
  // enabled would be orphaned.
533
516
  onConversationWiped(conversationId) {
534
517
  return hooks.onConversationWiped(conversationId);
535
518
  },
519
+ onConversationDeleted(conversationId) {
520
+ return hooks.onConversationDeleted(conversationId);
521
+ },
522
+ onMessagesDeleted(messageIds) {
523
+ return hooks.onMessagesDeleted(messageIds);
524
+ },
525
+ onAllConversationsCleared() {
526
+ return hooks.onAllConversationsCleared();
527
+ },
536
528
  onWorkerStartup() {
537
529
  return hooks.onWorkerStartup();
538
530
  },
@@ -542,7 +534,7 @@ export function guardPersistenceHooksByDisabledState(
542
534
  /**
543
535
  * Install the memory feature's persistence-lifecycle handlers into the
544
536
  * persistence seam — the persistence-hooks analog of
545
- * {@link registerDefaultPluginJobHandlers}. `bootstrapPlugins` calls this
537
+ * {@link registerDefaultPluginInjectors}. `bootstrapPlugins` calls this
546
538
  * before the per-plugin init loop so the seam is wired up front; the handlers
547
539
  * are guarded by {@link guardPersistenceHooksByDisabledState} so a disabled
548
540
  * memory plugin drives no persistence side effects and re-enabling it takes
@@ -581,7 +573,5 @@ export function resetPluginRegistryAndRegisterDefaults(): void {
581
573
  registerDefaultPlugins();
582
574
  clearInjectorRegistry();
583
575
  registerDefaultPluginInjectors();
584
- clearJobHandlerRegistry();
585
- registerDefaultPluginJobHandlers();
586
576
  registerDefaultPluginPersistenceHooks();
587
577
  }
@@ -213,6 +213,7 @@ describe("countConversations", () => {
213
213
  createConversation("live-1");
214
214
  const archived = createConversation("archived-1");
215
215
  rawRun(
216
+ "test:archiveConversation",
216
217
  "UPDATE conversations SET archived_at = ? WHERE id = ?",
217
218
  Date.now(),
218
219
  archived.id,
@@ -226,6 +227,7 @@ describe("countConversations", () => {
226
227
  const a1 = createConversation("archived-1");
227
228
  const a2 = createConversation("archived-2");
228
229
  rawRun(
230
+ "test:archiveConversations",
229
231
  "UPDATE conversations SET archived_at = ? WHERE id IN (?, ?)",
230
232
  Date.now(),
231
233
  a1.id,
@@ -239,6 +241,7 @@ describe("countConversations", () => {
239
241
  createConversation("live-1");
240
242
  const archived = createConversation("archived-1");
241
243
  rawRun(
244
+ "test:archiveConversation",
242
245
  "UPDATE conversations SET archived_at = ? WHERE id = ?",
243
246
  Date.now(),
244
247
  archived.id,
@@ -301,6 +304,7 @@ describe("listConversations", () => {
301
304
  // GIVEN a conversation with group_id system:scheduled but conversationType standard
302
305
  const conv = createConversation("schedule-routed");
303
306
  rawRun(
307
+ "test:setGroupScheduled",
304
308
  "UPDATE conversations SET group_id = 'system:scheduled' WHERE id = ?",
305
309
  conv.id,
306
310
  );
@@ -335,6 +339,7 @@ describe("listConversations", () => {
335
339
  // GIVEN a standard conversation routed to system:scheduled
336
340
  const scheduledRouted = createConversation("schedule-routed");
337
341
  rawRun(
342
+ "test:setGroupScheduled",
338
343
  "UPDATE conversations SET group_id = 'system:scheduled' WHERE id = ?",
339
344
  scheduledRouted.id,
340
345
  );
@@ -342,6 +347,7 @@ describe("listConversations", () => {
342
347
  // AND a standard conversation routed to system:background
343
348
  const backgroundRouted = createConversation("background-routed");
344
349
  rawRun(
350
+ "test:setGroupBackground",
345
351
  "UPDATE conversations SET group_id = 'system:background' WHERE id = ?",
346
352
  backgroundRouted.id,
347
353
  );
@@ -375,6 +381,7 @@ describe("listConversations", () => {
375
381
  createConversation("live-1");
376
382
  const archived = createConversation("archived-1");
377
383
  rawRun(
384
+ "test:archiveConversation",
378
385
  "UPDATE conversations SET archived_at = ? WHERE id = ?",
379
386
  Date.now(),
380
387
  archived.id,
@@ -393,6 +400,7 @@ describe("listConversations", () => {
393
400
  createConversation("live-1");
394
401
  const archived = createConversation("archived-1");
395
402
  rawRun(
403
+ "test:archiveConversation",
396
404
  "UPDATE conversations SET archived_at = ? WHERE id = ?",
397
405
  Date.now(),
398
406
  archived.id,
@@ -411,6 +419,7 @@ describe("listConversations", () => {
411
419
  createConversation("live-1");
412
420
  const archived = createConversation("archived-1");
413
421
  rawRun(
422
+ "test:archiveConversation",
414
423
  "UPDATE conversations SET archived_at = ? WHERE id = ?",
415
424
  Date.now(),
416
425
  archived.id,
@@ -434,6 +443,7 @@ describe("listConversations", () => {
434
443
  });
435
444
  const archivedFg = createConversation("archived-fg");
436
445
  rawRun(
446
+ "test:archiveConversations",
437
447
  "UPDATE conversations SET archived_at = ? WHERE id IN (?, ?)",
438
448
  Date.now(),
439
449
  archivedBg.id,
@@ -490,9 +500,24 @@ describe("listConversationsBySource", () => {
490
500
  source: "memory_v2_consolidation",
491
501
  });
492
502
  // Force distinct createdAt regardless of ms-clock granularity.
493
- rawRun("UPDATE conversations SET created_at = ? WHERE id = ?", 1000, a.id);
494
- rawRun("UPDATE conversations SET created_at = ? WHERE id = ?", 3000, b.id);
495
- rawRun("UPDATE conversations SET created_at = ? WHERE id = ?", 2000, c.id);
503
+ rawRun(
504
+ "test:setCreatedAt",
505
+ "UPDATE conversations SET created_at = ? WHERE id = ?",
506
+ 1000,
507
+ a.id,
508
+ );
509
+ rawRun(
510
+ "test:setCreatedAt",
511
+ "UPDATE conversations SET created_at = ? WHERE id = ?",
512
+ 3000,
513
+ b.id,
514
+ );
515
+ rawRun(
516
+ "test:setCreatedAt",
517
+ "UPDATE conversations SET created_at = ? WHERE id = ?",
518
+ 2000,
519
+ c.id,
520
+ );
496
521
 
497
522
  const results = listConversationsBySource("memory_v2_consolidation");
498
523
 
@@ -518,6 +543,7 @@ describe("listConversationsBySource", () => {
518
543
  source: "memory_v2_consolidation",
519
544
  });
520
545
  rawRun(
546
+ "test:archiveConversation",
521
547
  "UPDATE conversations SET archived_at = ? WHERE id = ?",
522
548
  Date.now(),
523
549
  conv.id,
@@ -536,6 +562,7 @@ describe("listConversationsBySource", () => {
536
562
  });
537
563
  createConversation({ title: "live", source: "memory_v2_consolidation" });
538
564
  rawRun(
565
+ "test:archiveConversation",
539
566
  "UPDATE conversations SET archived_at = ? WHERE id = ?",
540
567
  Date.now(),
541
568
  archived.id,
@@ -562,112 +589,61 @@ describe("listConversationsBySource", () => {
562
589
  });
563
590
  });
564
591
 
592
+ // Content-arm (lexical candidate) surfacing behavior is covered in
593
+ // `persistence/__tests__/conversation-queries-search.test.ts`, which mocks the
594
+ // lexical index; this suite covers the title arm's surfacing rules.
565
595
  describe("searchConversations · surfaced conversations", () => {
566
596
  beforeEach(() => {
567
597
  resetTables();
568
598
  });
569
599
 
570
- function insertMessage(
571
- conversationId: string,
572
- content: string,
573
- createdAt = 1000,
574
- ): void {
575
- rawRun(
576
- "INSERT INTO messages (id, conversation_id, role, content, created_at) VALUES (?, ?, ?, ?, ?)",
577
- `msg-${conversationId}-${createdAt}`,
578
- conversationId,
579
- "user",
580
- content,
581
- createdAt,
582
- );
583
- }
584
-
585
600
  function setSurfaced(conversationId: string): void {
586
601
  rawRun(
602
+ "test:setSurfaced",
587
603
  "UPDATE conversations SET surfaced_at = ? WHERE id = ?",
588
604
  Date.now(),
589
605
  conversationId,
590
606
  );
591
607
  }
592
608
 
593
- test("a surfaced background conversation is found by title search", () => {
609
+ test("a surfaced background conversation is found by title search", async () => {
594
610
  const surfaced = createConversation({
595
611
  title: "Quarterly metrics rollup",
596
612
  conversationType: "background",
597
613
  });
598
614
  setSurfaced(surfaced.id);
599
615
 
600
- const results = searchConversations("Quarterly metrics");
616
+ const results = await searchConversations("Quarterly metrics");
601
617
 
602
618
  expect(results.map((r) => r.conversationId)).toEqual([surfaced.id]);
603
619
  });
604
620
 
605
- test("a surfaced background conversation is found by content search", () => {
606
- const surfaced = createConversation({
607
- title: "bg-run",
608
- conversationType: "background",
609
- });
610
- setSurfaced(surfaced.id);
611
- insertMessage(surfaced.id, "the flux capacitor needs recalibration");
612
-
613
- const results = searchConversations("flux capacitor");
614
-
615
- expect(results.map((r) => r.conversationId)).toEqual([surfaced.id]);
616
- expect(results[0]!.matchingMessages).toHaveLength(1);
617
- });
618
-
619
- test("a non-surfaced background conversation stays excluded from search", () => {
620
- const background = createConversation({
621
+ test("a non-surfaced background conversation stays excluded from title search", async () => {
622
+ createConversation({
621
623
  title: "Quarterly metrics rollup",
622
624
  conversationType: "background",
623
625
  });
624
- insertMessage(background.id, "the flux capacitor needs recalibration");
625
626
 
626
- expect(searchConversations("Quarterly metrics")).toEqual([]);
627
- expect(searchConversations("flux capacitor")).toEqual([]);
627
+ expect(await searchConversations("Quarterly metrics")).toEqual([]);
628
628
  });
629
629
 
630
- test("private conversations are never included, even with surfaced_at set", () => {
630
+ test("private conversations are never included, even with surfaced_at set", async () => {
631
631
  const priv = createConversation("Quarterly metrics rollup");
632
632
  setConversationType(priv.id, "private");
633
633
  setSurfaced(priv.id);
634
- insertMessage(priv.id, "the flux capacitor needs recalibration");
635
634
 
636
- expect(searchConversations("Quarterly metrics")).toEqual([]);
637
- expect(searchConversations("flux capacitor")).toEqual([]);
635
+ expect(await searchConversations("Quarterly metrics")).toEqual([]);
638
636
  });
639
637
 
640
- test("surfaced subagent runs stay excluded from search", () => {
638
+ test("surfaced subagent runs stay excluded from title search", async () => {
641
639
  const subagent = createConversation({
642
640
  title: "Quarterly metrics rollup",
643
641
  conversationType: "background",
644
642
  source: "subagent",
645
643
  });
646
644
  setSurfaced(subagent.id);
647
- insertMessage(subagent.id, "the flux capacitor needs recalibration");
648
645
 
649
- expect(searchConversations("Quarterly metrics")).toEqual([]);
650
- expect(searchConversations("flux capacitor")).toEqual([]);
651
- });
652
-
653
- test("LIKE content fallback (non-FTS-tokenizable query) honors surfacing", () => {
654
- // Single-char queries produce no FTS tokens, exercising the LIKE fallback.
655
- const surfaced = createConversation({
656
- title: "bg-run",
657
- conversationType: "background",
658
- });
659
- setSurfaced(surfaced.id);
660
- insertMessage(surfaced.id, "review the C§ draft");
661
-
662
- const hidden = createConversation({
663
- title: "bg-hidden",
664
- conversationType: "background",
665
- });
666
- insertMessage(hidden.id, "another C§ mention", 2000);
667
-
668
- const results = searchConversations("C§");
669
-
670
- expect(results.map((r) => r.conversationId)).toEqual([surfaced.id]);
646
+ expect(await searchConversations("Quarterly metrics")).toEqual([]);
671
647
  });
672
648
  });
673
649
 
@@ -678,6 +654,7 @@ describe("listPinnedConversations · surfaced conversations", () => {
678
654
 
679
655
  function setSurfaced(conversationId: string): void {
680
656
  rawRun(
657
+ "test:setSurfaced",
681
658
  "UPDATE conversations SET surfaced_at = ? WHERE id = ?",
682
659
  Date.now(),
683
660
  conversationId,
@@ -686,6 +663,7 @@ describe("listPinnedConversations · surfaced conversations", () => {
686
663
 
687
664
  function setPinned(conversationId: string): void {
688
665
  rawRun(
666
+ "test:setPinned",
689
667
  "UPDATE conversations SET is_pinned = 1 WHERE id = ?",
690
668
  conversationId,
691
669
  );
@@ -747,6 +725,7 @@ describe("getMessageRoleStatsByConversation", () => {
747
725
  createdAt: number,
748
726
  ): void {
749
727
  rawRun(
728
+ "test:insertMessage",
750
729
  "INSERT INTO messages (id, conversation_id, role, content, created_at) VALUES (?, ?, ?, ?, ?)",
751
730
  `msg-${conversationId}-${role}-${createdAt}`,
752
731
  conversationId,
@@ -16,13 +16,15 @@
16
16
  * 4. Errors from sqlite3 surface as `ok: false` with the stderr
17
17
  * preserved in `error`.
18
18
  */
19
+ import { statSync } from "node:fs";
19
20
  import { beforeEach, describe, expect, test } from "bun:test";
20
21
 
21
22
  const { getSqlite } = await import("../../../../persistence/db-connection.js");
22
23
  const { initializeDb } = await import("../../../../persistence/db-init.js");
23
- const { runAsyncSqlite, _resetFallbackWarning } =
24
+ const { runAsyncSqlite, _resetFallbackWarning, spawnDetachedWalCheckpoint } =
24
25
  await import("../../../../persistence/db-async-query.js");
25
26
  const { findSqlite3 } = await import("../../../../util/sqlite3-runtime.js");
27
+ const { getDbPath } = await import("../../../../util/platform.js");
26
28
 
27
29
  await initializeDb();
28
30
 
@@ -170,3 +172,36 @@ describe("runAsyncSqlite", () => {
170
172
  60_000,
171
173
  );
172
174
  });
175
+
176
+ describe("spawnDetachedWalCheckpoint", () => {
177
+ test.if(sqlite3Available)(
178
+ "folds and truncates the WAL from a detached subprocess",
179
+ async () => {
180
+ const sqlite = getSqlite();
181
+ const walPath = `${getDbPath()}-wal`;
182
+
183
+ // Grow the WAL past zero without checkpointing.
184
+ sqlite.exec("CREATE TABLE IF NOT EXISTS detached_ckpt_probe (x TEXT)");
185
+ sqlite.exec("INSERT INTO detached_ckpt_probe VALUES ('row')");
186
+ expect(statSync(walPath).size).toBeGreaterThan(0);
187
+
188
+ expect(spawnDetachedWalCheckpoint()).toBe(true);
189
+
190
+ // The child is detached with no inherited stdio, so the only
191
+ // observable effect is the WAL file itself — poll for the truncate.
192
+ const deadline = Date.now() + 10_000;
193
+ let walSize = -1;
194
+ while (Date.now() < deadline) {
195
+ walSize = statSync(walPath).size;
196
+ if (walSize === 0) {
197
+ break;
198
+ }
199
+ await Bun.sleep(50);
200
+ }
201
+ expect(walSize).toBe(0);
202
+
203
+ sqlite.exec("DROP TABLE detached_ckpt_probe");
204
+ },
205
+ 30_000,
206
+ );
207
+ });
@@ -9,13 +9,11 @@ mock.module("../../../../util/logger.js", () => ({
9
9
  }),
10
10
  }));
11
11
 
12
- import {
13
- createConversation,
14
- findMostRecentRetrospectiveFor,
15
- } from "../../../../persistence/conversation-crud.js";
12
+ import { createConversation } from "../../../../persistence/conversation-crud.js";
16
13
  import { getDb } from "../../../../persistence/db-connection.js";
17
14
  import { initializeDb } from "../../../../persistence/db-init.js";
18
15
  import { conversations } from "../../../../persistence/schema/index.js";
16
+ import { findMostRecentRetrospectiveFor } from "../find-most-recent-retrospective-for.js";
19
17
  import { MEMORY_RETROSPECTIVE_SOURCE } from "../memory-retrospective-constants.js";
20
18
 
21
19
  await initializeDb();
@@ -67,17 +67,17 @@ const tmpWorkspace = mkdtempSync(
67
67
  const previousWorkspaceEnv = process.env.VELLUM_WORKSPACE_DIR;
68
68
  process.env.VELLUM_WORKSPACE_DIR = tmpWorkspace;
69
69
 
70
- import { registerMemoryJobHandlers } from "../../../../jobs/register-job-handlers.js";
71
70
  import { getMemoryDb } from "../../../../persistence/db-connection.js";
72
71
  import { initializeDb } from "../../../../persistence/db-init.js";
73
72
  import { _resetQdrantBreaker } from "../../../../persistence/embeddings/qdrant-circuit-breaker.js";
74
73
  import { enqueueMemoryJob } from "../../../../persistence/jobs-store.js";
75
74
  import { runMemoryJobsOnce } from "../../../../persistence/jobs-worker.js";
76
75
  import { memoryJobs } from "../../../../persistence/schema/index.js";
76
+ import { registerMemoryPluginJobHandlers } from "../job-handler-registration.js";
77
77
 
78
78
  describe("graph_trigger_embed under memory v2", () => {
79
79
  beforeAll(async () => {
80
- registerMemoryJobHandlers();
80
+ registerMemoryPluginJobHandlers();
81
81
  await initializeDb();
82
82
  });
83
83
 
@@ -57,6 +57,7 @@ afterAll(() => {
57
57
  process.env.VELLUM_WORKSPACE_DIR = previousWorkspaceEnv;
58
58
  }
59
59
  rmSync(tmpWorkspace, { recursive: true, force: true });
60
+ resetMemoryPersistenceHooksForTests();
60
61
  });
61
62
 
62
63
  const { getMemoryDb } =
@@ -70,6 +71,14 @@ const { getMemoryCheckpoint, setMemoryCheckpoint, deleteMemoryCheckpoint } =
70
71
  await import("../../../../persistence/checkpoints.js");
71
72
  const { maybeEnqueueGraphMaintenanceJobs } =
72
73
  await import("../../../../persistence/jobs-worker.js");
74
+ const { registerMemoryPersistenceHooks, resetMemoryPersistenceHooksForTests } =
75
+ await import("../../../../persistence/memory-lifecycle-hooks.js");
76
+ const { memoryPersistenceHooks } = await import("../persistence-hooks.js");
77
+
78
+ // The scheduler reads the memory buffer's line count through the persistence
79
+ // seam; register the real memory implementation so `countMemoryBufferLines`
80
+ // reflects the buffer files these tests write.
81
+ registerMemoryPersistenceHooks(memoryPersistenceHooks);
73
82
 
74
83
  const CONSOLIDATE_CHECKPOINT_KEY = "memory_v2_consolidate_last_run";
75
84
 
@@ -130,6 +130,13 @@ mock.module("../memory-retrospective-state.js", () => ({
130
130
  ],
131
131
  }));
132
132
 
133
+ mock.module("../find-most-recent-retrospective-for.js", () => ({
134
+ findMostRecentRetrospectiveFor: (_id: string) =>
135
+ priorRetroId
136
+ ? { id: priorRetroId, forkParentConversationId: priorRetroOwnerId }
137
+ : null,
138
+ }));
139
+
133
140
  mock.module("../../../../persistence/conversation-crud.js", () => ({
134
141
  getMessagesAfter: (_id: string, _afterId: string | null) => newMessages,
135
142
  getMessages: (id: string) => {
@@ -137,10 +144,6 @@ mock.module("../../../../persistence/conversation-crud.js", () => ({
137
144
  if (id === priorRetroId) return priorRetroMessages;
138
145
  return [];
139
146
  },
140
- findMostRecentRetrospectiveFor: (_id: string) =>
141
- priorRetroId
142
- ? { id: priorRetroId, forkParentConversationId: priorRetroOwnerId }
143
- : null,
144
147
  // The handler calls `getConversation(sourceConversationId)` to read the
145
148
  // source's title for the fork title. `collectPriorRetrospectiveRemembers`
146
149
  // also calls it with the prior retro id to discriminate legacy vs fork
@@ -0,0 +1,11 @@
1
+ import { getConfig } from "../../../config/loader.js";
2
+ import type { MemoryConfig } from "../../../config/types.js";
3
+
4
+ /**
5
+ * The `memory` slice of the live assistant config. Memory code reads its own
6
+ * configuration through this accessor rather than the full `getConfig()`, so its
7
+ * config dependency is a narrow slice of `AssistantConfig`.
8
+ */
9
+ export function getMemoryConfig(): MemoryConfig {
10
+ return getConfig().memory;
11
+ }