@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
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Register the background-job handlers into the worker's dispatch table.
3
+ *
4
+ * The memory plugin owns registration end-to-end: its `init` hook (daemon) and
5
+ * the standalone worker process — the two callers that actually start the
6
+ * worker — register here rather than routing handlers through a generic plugin
7
+ * job-handler registry. Keeping registration inside the plugin means the startup
8
+ * path never has to reach back through the `plugins/defaults` barrel, which would
9
+ * otherwise close an import cycle.
10
+ *
11
+ * This registers the memory plugin's own handlers plus the host's non-plugin
12
+ * domain handlers (persistence cleanup, message-content lexical indexing,
13
+ * conversations, media, home, runtime). Those domain handlers — and their daemon
14
+ * imports below — live here temporarily; they will move to a memory-agnostic
15
+ * background schedule worker in a future rework, at which point they leave the
16
+ * memory plugin.
17
+ *
18
+ * Idempotent: registering a type twice overwrites with the same handler, so
19
+ * repeated calls (e.g. the daemon init hook and the standalone worker process)
20
+ * are safe.
21
+ */
22
+
23
+ import { buildConversationSummaryJob } from "../../../conversations/job-handlers/summarization.js";
24
+ import { generateConversationStartersJob } from "../../../home/job-handlers/conversation-starters.js";
25
+ import { mediaProcessingJob } from "../../../media/job-handlers/media-processing.js";
26
+ import {
27
+ pruneOldConversationsJob,
28
+ pruneOldLlmRequestLogsJob,
29
+ pruneOldToolInvocationsJob,
30
+ pruneOldTraceEventsJob,
31
+ } from "../../../persistence/job-handlers/cleanup.js";
32
+ import {
33
+ deleteMessageLexicalJob,
34
+ indexMessageLexicalJob,
35
+ purgeConversationLexicalJob,
36
+ } from "../../../persistence/job-handlers/message-lexical.js";
37
+ import { backfillLexicalIndexJob } from "../../../persistence/job-handlers/message-lexical-backfill.js";
38
+ import { registerJobHandler } from "../../../persistence/jobs-worker.js";
39
+ import { conversationAnalyzeJob } from "../../../runtime/services/conversation-analyze-job.js";
40
+ import { memoryJobHandlers } from "./job-handlers.js";
41
+
42
+ export function registerMemoryPluginJobHandlers(): void {
43
+ // The memory plugin's own handlers.
44
+ for (const { type, handler } of memoryJobHandlers) {
45
+ registerJobHandler(type, handler);
46
+ }
47
+
48
+ // Non-plugin domain handlers for domains that are not plugins (persistence
49
+ // cleanup, message-content lexical indexing, conversations, media, home,
50
+ // runtime). These are host-owned and merely share the background job queue;
51
+ // they will move to a memory-agnostic background schedule worker soon. Each is
52
+ // registered behind an arrow that reads the imported binding at dispatch time
53
+ // rather than capturing it eagerly, so a per-test `mock.module` of the
54
+ // underlying handler is honored.
55
+ registerJobHandler("prune_old_conversations", (job, config) =>
56
+ pruneOldConversationsJob(job, config),
57
+ );
58
+ registerJobHandler("index_message_lexical", (job, config) =>
59
+ indexMessageLexicalJob(job, config),
60
+ );
61
+ registerJobHandler("purge_conversation_lexical", (job, config) =>
62
+ purgeConversationLexicalJob(job, config),
63
+ );
64
+ registerJobHandler("delete_message_lexical", (job, config) =>
65
+ deleteMessageLexicalJob(job, config),
66
+ );
67
+ registerJobHandler("backfill_lexical_index", (job, config) =>
68
+ backfillLexicalIndexJob(job, config),
69
+ );
70
+ registerJobHandler("prune_old_llm_request_logs", (job, config) =>
71
+ pruneOldLlmRequestLogsJob(job, config),
72
+ );
73
+ registerJobHandler("prune_old_trace_events", (job, config) =>
74
+ pruneOldTraceEventsJob(job, config),
75
+ );
76
+ registerJobHandler("prune_old_tool_invocations", (job, config) =>
77
+ pruneOldToolInvocationsJob(job, config),
78
+ );
79
+ registerJobHandler("build_conversation_summary", async (job, config) => {
80
+ // Stale rows enqueued before v2 was enabled must not consume the
81
+ // `conversationSummarization` LLM budget — v2 readers do not consume
82
+ // `memorySummaries`, mirroring the `graph_extract` gate in the memory
83
+ // plugin's job handlers.
84
+ if (config.memory.v2.enabled) {
85
+ return;
86
+ }
87
+ await buildConversationSummaryJob(job, config);
88
+ });
89
+ registerJobHandler("media_processing", (job) => mediaProcessingJob(job));
90
+ registerJobHandler("conversation_analyze", (job, config) =>
91
+ conversationAnalyzeJob(job, config),
92
+ );
93
+ registerJobHandler("generate_conversation_starters", (job) =>
94
+ generateConversationStartersJob(job),
95
+ );
96
+ }
@@ -6,38 +6,18 @@ import {
6
6
  resetMessageCursorCheckpoint,
7
7
  writeMessageCursorCheckpoint,
8
8
  } from "../../../../persistence/checkpoints.js";
9
- import { messageMetadataSchema } from "../../../../persistence/conversation-crud.js";
9
+ import { parseMessageMetadata } from "../../../../persistence/conversation-crud.js";
10
10
  import { getDb } from "../../../../persistence/db-connection.js";
11
11
  import {
12
12
  enqueueMemoryJob,
13
13
  type MemoryJob,
14
14
  } from "../../../../persistence/jobs-store.js";
15
15
  import { messages } from "../../../../persistence/schema/index.js";
16
- import type { TrustClass } from "../../../../runtime/actor-trust-resolver.js";
17
16
  import { indexMessageNow } from "../indexer.js";
18
17
 
19
18
  const BACKFILL_CHECKPOINT_KEY = "memory:backfill:last_created_at";
20
19
  const BACKFILL_CHECKPOINT_ID_KEY = "memory:backfill:last_message_id";
21
20
 
22
- function parseMessageMetadata(rawMetadata: string | null): {
23
- provenanceTrustClass: TrustClass | undefined;
24
- automated: boolean | undefined;
25
- } {
26
- if (!rawMetadata)
27
- return { provenanceTrustClass: undefined, automated: undefined };
28
- try {
29
- const parsed = messageMetadataSchema.safeParse(JSON.parse(rawMetadata));
30
- if (!parsed.success)
31
- return { provenanceTrustClass: undefined, automated: undefined };
32
- return {
33
- provenanceTrustClass: parsed.data.provenanceTrustClass,
34
- automated: parsed.data.automated,
35
- };
36
- } catch {
37
- return { provenanceTrustClass: undefined, automated: undefined };
38
- }
39
- }
40
-
41
21
  export async function backfillJob(
42
22
  job: MemoryJob,
43
23
  config: AssistantConfig,
@@ -73,9 +53,7 @@ export async function backfillJob(
73
53
 
74
54
  if (batch.length > 0) {
75
55
  for (const message of batch) {
76
- const { provenanceTrustClass, automated } = parseMessageMetadata(
77
- message.metadata ?? null,
78
- );
56
+ const meta = parseMessageMetadata(message.metadata ?? null);
79
57
  await indexMessageNow(
80
58
  {
81
59
  messageId: message.id,
@@ -84,8 +62,8 @@ export async function backfillJob(
84
62
  content: message.content,
85
63
  createdAt: message.createdAt,
86
64
  scopeId: "default",
87
- provenanceTrustClass,
88
- automated,
65
+ provenanceTrustClass: meta?.provenanceTrustClass,
66
+ automated: meta?.automated,
89
67
  },
90
68
  config.memory,
91
69
  );
@@ -41,25 +41,12 @@ mock.module("../../../../persistence/job-utils.js", () => ({
41
41
  }));
42
42
 
43
43
  import { resetDbForTesting } from "../../../../__tests__/db-test-helpers.js";
44
- import { DEFAULT_CONFIG } from "../../../../config/defaults.js";
45
- import type { AssistantConfig } from "../../../../config/types.js";
46
44
  import { getDb } from "../../../../persistence/db-connection.js";
47
45
  import { initializeDb } from "../../../../persistence/db-init.js";
48
46
  import type { MemoryJob } from "../../../../persistence/jobs-store.js";
49
47
  import { mediaAssets } from "../../../../persistence/schema/index.js";
50
48
  import { embedMediaJob } from "./embedding.js";
51
49
 
52
- const TEST_CONFIG: AssistantConfig = {
53
- ...DEFAULT_CONFIG,
54
- memory: {
55
- ...DEFAULT_CONFIG.memory,
56
- extraction: {
57
- ...DEFAULT_CONFIG.memory.extraction,
58
- useLLM: false,
59
- },
60
- },
61
- };
62
-
63
50
  describe("embedMediaJob", () => {
64
51
  // initializeDb runs the full migration chain (hundreds of steps); under
65
52
  // parallel CI load it can exceed bun's default 5s hook timeout, so allow more.
@@ -90,12 +77,12 @@ describe("embedMediaJob", () => {
90
77
  }
91
78
 
92
79
  test("skips when assetId is missing", async () => {
93
- await embedMediaJob(makeJob({}), TEST_CONFIG);
80
+ await embedMediaJob(makeJob({}));
94
81
  expect(embedAndUpsertCalls).toHaveLength(0);
95
82
  });
96
83
 
97
84
  test("skips when asset is not found", async () => {
98
- await embedMediaJob(makeJob({ assetId: "nonexistent" }), TEST_CONFIG);
85
+ await embedMediaJob(makeJob({ assetId: "nonexistent" }));
99
86
  expect(embedAndUpsertCalls).toHaveLength(0);
100
87
  });
101
88
 
@@ -122,7 +109,7 @@ describe("embedMediaJob", () => {
122
109
  })
123
110
  .run();
124
111
 
125
- await embedMediaJob(makeJob({ assetId: "asset-registered" }), TEST_CONFIG);
112
+ await embedMediaJob(makeJob({ assetId: "asset-registered" }));
126
113
  expect(embedAndUpsertCalls).toHaveLength(0);
127
114
  });
128
115
 
@@ -149,7 +136,7 @@ describe("embedMediaJob", () => {
149
136
  })
150
137
  .run();
151
138
 
152
- await embedMediaJob(makeJob({ assetId: "asset-image" }), TEST_CONFIG);
139
+ await embedMediaJob(makeJob({ assetId: "asset-image" }));
153
140
 
154
141
  expect(embedAndUpsertCalls).toHaveLength(1);
155
142
  const call = embedAndUpsertCalls[0];
@@ -191,7 +178,7 @@ describe("embedMediaJob", () => {
191
178
  })
192
179
  .run();
193
180
 
194
- await embedMediaJob(makeJob({ assetId: "asset-audio" }), TEST_CONFIG);
181
+ await embedMediaJob(makeJob({ assetId: "asset-audio" }));
195
182
 
196
183
  expect(embedAndUpsertCalls).toHaveLength(1);
197
184
  const call = embedAndUpsertCalls[0];
@@ -224,7 +211,7 @@ describe("embedMediaJob", () => {
224
211
  })
225
212
  .run();
226
213
 
227
- await embedMediaJob(makeJob({ assetId: "asset-video" }), TEST_CONFIG);
214
+ await embedMediaJob(makeJob({ assetId: "asset-video" }));
228
215
 
229
216
  expect(embedAndUpsertCalls).toHaveLength(1);
230
217
  const call = embedAndUpsertCalls[0];
@@ -2,10 +2,9 @@ import { readFile } from "node:fs/promises";
2
2
 
3
3
  import { eq } from "drizzle-orm";
4
4
 
5
- import type { AssistantConfig } from "../../../../config/types.js";
6
5
  import { getDb } from "../../../../persistence/db-connection.js";
7
6
  import type { EmbeddingInput } from "../../../../persistence/embeddings/embedding-types.js";
8
- import { asString, embedAndUpsert } from "../../../../persistence/job-utils.js";
7
+ import { asString } from "../../../../persistence/job-utils.js";
9
8
  import type { MemoryJob } from "../../../../persistence/jobs-store.js";
10
9
  import { extractMediaBlocks } from "../../../../persistence/message-content.js";
11
10
  import {
@@ -14,11 +13,9 @@ import {
14
13
  memorySummaries,
15
14
  messages,
16
15
  } from "../../../../persistence/schema/index.js";
16
+ import { embedAndUpsert } from "../embeddings.js";
17
17
 
18
- export async function embedSegmentJob(
19
- job: MemoryJob,
20
- config: AssistantConfig,
21
- ): Promise<void> {
18
+ export async function embedSegmentJob(job: MemoryJob): Promise<void> {
22
19
  const segmentId = asString(job.payload.segmentId);
23
20
  if (!segmentId) return;
24
21
  const db = getDb();
@@ -28,7 +25,7 @@ export async function embedSegmentJob(
28
25
  .where(eq(memorySegments.id, segmentId))
29
26
  .get();
30
27
  if (!segment) return;
31
- await embedAndUpsert(config, "segment", segment.id, segment.text, {
28
+ await embedAndUpsert("segment", segment.id, segment.text, {
32
29
  conversation_id: segment.conversationId,
33
30
  message_id: segment.messageId,
34
31
  created_at: segment.createdAt,
@@ -36,10 +33,7 @@ export async function embedSegmentJob(
36
33
  });
37
34
  }
38
35
 
39
- export async function embedSummaryJob(
40
- job: MemoryJob,
41
- config: AssistantConfig,
42
- ): Promise<void> {
36
+ export async function embedSummaryJob(job: MemoryJob): Promise<void> {
43
37
  const summaryId = asString(job.payload.summaryId);
44
38
  if (!summaryId) return;
45
39
  const db = getDb();
@@ -50,7 +44,6 @@ export async function embedSummaryJob(
50
44
  .get();
51
45
  if (!summary) return;
52
46
  await embedAndUpsert(
53
- config,
54
47
  "summary",
55
48
  summary.id,
56
49
  `[${summary.scope}] ${summary.summary}`,
@@ -63,10 +56,7 @@ export async function embedSummaryJob(
63
56
  );
64
57
  }
65
58
 
66
- export async function embedMediaJob(
67
- job: MemoryJob,
68
- config: AssistantConfig,
69
- ): Promise<void> {
59
+ export async function embedMediaJob(job: MemoryJob): Promise<void> {
70
60
  const assetId = asString(job.payload.assetId);
71
61
  if (!assetId) return;
72
62
 
@@ -88,7 +78,7 @@ export async function embedMediaJob(
88
78
  mimeType: asset.mimeType,
89
79
  };
90
80
 
91
- await embedAndUpsert(config, "media", asset.id, input, {
81
+ await embedAndUpsert("media", asset.id, input, {
92
82
  created_at: asset.createdAt,
93
83
  kind: asset.mediaType,
94
84
  subject: asset.title,
@@ -96,10 +86,7 @@ export async function embedMediaJob(
96
86
  });
97
87
  }
98
88
 
99
- export async function embedAttachmentJob(
100
- job: MemoryJob,
101
- config: AssistantConfig,
102
- ): Promise<void> {
89
+ export async function embedAttachmentJob(job: MemoryJob): Promise<void> {
103
90
  const messageId = asString(job.payload.messageId);
104
91
  const blockIndex = job.payload.blockIndex as number;
105
92
  if (!messageId || typeof blockIndex !== "number") return;
@@ -124,7 +111,7 @@ export async function embedAttachmentJob(
124
111
 
125
112
  // Use messageId + blockIndex as targetId for uniqueness
126
113
  const targetId = `${messageId}:${blockIndex}`;
127
- await embedAndUpsert(config, "media", targetId, input, {
114
+ await embedAndUpsert("media", targetId, input, {
128
115
  created_at: message.createdAt,
129
116
  message_id: messageId,
130
117
  conversation_id: message.conversationId,
@@ -1,8 +1,6 @@
1
1
  import { eq, isNotNull, like, ne } from "drizzle-orm";
2
2
 
3
- import { getConfig } from "../../../../config/loader.js";
4
3
  import { getDb } from "../../../../persistence/db-connection.js";
5
- import { selectedBackendSupportsMultimodal } from "../../../../persistence/embeddings/embedding-backend.js";
6
4
  import { withQdrantBreaker } from "../../../../persistence/embeddings/qdrant-circuit-breaker.js";
7
5
  import { getQdrantClient } from "../../../../persistence/embeddings/qdrant-client.js";
8
6
  import {
@@ -24,6 +22,7 @@ import {
24
22
  messages,
25
23
  } from "../../../../persistence/schema/index.js";
26
24
  import { getLogger } from "../../../../util/logger.js";
25
+ import { selectedBackendSupportsMultimodal } from "../embeddings.js";
27
26
 
28
27
  const log = getLogger("memory-jobs-worker");
29
28
 
@@ -50,7 +49,7 @@ export async function rebuildIndexJob(): Promise<void> {
50
49
  // Re-enqueue multimodal embedding jobs only when the resolved embedding
51
50
  // backend supports multimodal inputs. Without this gate, embed_media and
52
51
  // embed_attachment jobs would all fail for text-only backends.
53
- if (await selectedBackendSupportsMultimodal(getConfig())) {
52
+ if (await selectedBackendSupportsMultimodal()) {
54
53
  const assets = db
55
54
  .select({ id: mediaAssets.id })
56
55
  .from(mediaAssets)
@@ -3,10 +3,9 @@
3
3
  *
4
4
  * Each entry pairs a job-queue `type` with the handler that processes it,
5
5
  * sourcing the implementation from the memory feature (`src/memory/*`) and the
6
- * v3 engine (`./v3/`). `defaultMemoryPlugin` exposes this array via its
7
- * `jobHandlers` field; bootstrap registers it into the global job-handler
8
- * registry, and the general job worker (`jobs/register-job-handlers.ts`)
9
- * forwards it into the worker dispatch table.
6
+ * v3 engine (`./v3/`). The memory plugin registers this array directly into the
7
+ * worker dispatch table from its `init` hook see `job-handler-registration.ts`
8
+ * (and the standalone worker process, which self-registers it).
10
9
  *
11
10
  * Each handler is wrapped in an arrow that reads the imported binding at
12
11
  * dispatch time rather than capturing it eagerly, so a per-test `mock.module` of
@@ -110,17 +109,17 @@ async function graphNarrativeRefineJob(
110
109
  }
111
110
 
112
111
  /**
113
- * The memory feature's per-job-type handlers, contributed to the general job
114
- * worker via the `default-memory` plugin's `jobHandlers` field.
112
+ * The memory feature's per-job-type handlers, registered directly into the
113
+ * worker dispatch table by the memory plugin's `init` hook.
115
114
  */
116
115
  export const memoryJobHandlers: readonly JobHandlerEntry[] = [
117
116
  {
118
117
  type: "embed_segment",
119
- handler: (job, config) => embedSegmentJob(job, config),
118
+ handler: (job) => embedSegmentJob(job),
120
119
  },
121
120
  {
122
121
  type: "embed_summary",
123
- handler: (job, config) => embedSummaryJob(job, config),
122
+ handler: (job) => embedSummaryJob(job),
124
123
  },
125
124
  { type: "backfill", handler: (job, config) => backfillJob(job, config) },
126
125
  { type: "rebuild_index", handler: () => rebuildIndexJob() },
@@ -128,14 +127,14 @@ export const memoryJobHandlers: readonly JobHandlerEntry[] = [
128
127
  type: "delete_qdrant_vectors",
129
128
  handler: (job) => deleteQdrantVectorsJob(job),
130
129
  },
131
- { type: "embed_media", handler: (job, config) => embedMediaJob(job, config) },
130
+ { type: "embed_media", handler: (job) => embedMediaJob(job) },
132
131
  {
133
132
  type: "embed_attachment",
134
- handler: (job, config) => embedAttachmentJob(job, config),
133
+ handler: (job) => embedAttachmentJob(job),
135
134
  },
136
135
  {
137
136
  type: "embed_graph_node",
138
- handler: (job, config) => embedGraphNodeJob(job, config),
137
+ handler: (job) => embedGraphNodeJob(job),
139
138
  },
140
139
  {
141
140
  type: "embed_pkb_file",
@@ -150,7 +149,9 @@ export const memoryJobHandlers: readonly JobHandlerEntry[] = [
150
149
  handler: async (job, config) => {
151
150
  // Stale rows enqueued before v2 was enabled (or by any unguarded v1
152
151
  // path) must not consume embedding/extraction budget when v2 is on.
153
- if (config.memory.v2.enabled) return;
152
+ if (config.memory.v2.enabled) {
153
+ return;
154
+ }
154
155
  await graphExtractJob(job, config);
155
156
  },
156
157
  },
@@ -23,7 +23,6 @@ import { and, eq } from "drizzle-orm";
23
23
  import type { AssistantConfig } from "../../../../config/types.js";
24
24
  import { getDb } from "../../../../persistence/db-connection.js";
25
25
  import {
26
- embedWithBackend,
27
26
  generateSparseEmbedding,
28
27
  getMemoryBackendStatus,
29
28
  } from "../../../../persistence/embeddings/embedding-backend.js";
@@ -43,6 +42,7 @@ import { BackendUnavailableError } from "../../../../util/errors.js";
43
42
  import { getLogger } from "../../../../util/logger.js";
44
43
  import { getWorkspaceDir } from "../../../../util/platform.js";
45
44
  import { applyCorrectionIfCalibrated } from "../anisotropy.js";
45
+ import { embedWithBackend } from "../embeddings.js";
46
46
  import { readPage } from "../v2/page-store.js";
47
47
  import {
48
48
  deleteConceptPageEmbedding,
@@ -0,0 +1,76 @@
1
+ import type {
2
+ ContentBlock,
3
+ Message,
4
+ ProviderResponse,
5
+ ToolUseContent,
6
+ } from "@vellumai/plugin-api";
7
+
8
+ /**
9
+ * Small pure helpers over the LLM request/response types the memory plugin
10
+ * runs its own inference with (via `getConfiguredProvider`). They live inside
11
+ * the plugin — rather than importing the host's `providers/*` — so memory
12
+ * depends only on its own files plus `@vellumai/plugin-api`, the boundary the
13
+ * plugin model enforces. Every type they touch is exported from the contract.
14
+ */
15
+
16
+ /**
17
+ * Extract the first text block's text from a ProviderResponse.
18
+ * Returns empty string if no text block is found.
19
+ */
20
+ export function extractText(response: ProviderResponse): string {
21
+ const block = response.content.find(
22
+ (b): b is Extract<ContentBlock, { type: "text" }> => b.type === "text",
23
+ );
24
+ return block?.text?.trim() ?? "";
25
+ }
26
+
27
+ /**
28
+ * Find the first tool_use block in a ProviderResponse.
29
+ */
30
+ export function extractToolUse(
31
+ response: ProviderResponse,
32
+ ): ToolUseContent | undefined {
33
+ return response.content.find(
34
+ (b): b is ToolUseContent => b.type === "tool_use",
35
+ );
36
+ }
37
+
38
+ /**
39
+ * Build a single user message in the provider Message format.
40
+ */
41
+ export function userMessage(text: string): Message {
42
+ return { role: "user", content: [{ type: "text", text }] };
43
+ }
44
+
45
+ /**
46
+ * Build a text content block carrying an ephemeral `cache_control` breakpoint
47
+ * with a 1h TTL, marking a byte-stable prefix the provider KV cache should
48
+ * persist across calls. The internal `TextContent` type omits the field (only
49
+ * the Anthropic provider transforms it onto the wire, preserved through
50
+ * `toAnthropicBlockSafe`), so we reach through a `Record` cast to keep the core
51
+ * types provider-agnostic. The 1h TTL matches the provider's auto-applied
52
+ * breakpoints; Haiku models have the `ttl` stripped provider-side.
53
+ */
54
+ export function cachedTextBlock(text: string): ContentBlock {
55
+ const block: ContentBlock = { type: "text", text };
56
+ (block as unknown as Record<string, unknown>).cache_control = {
57
+ type: "ephemeral",
58
+ ttl: "1h",
59
+ };
60
+ return block;
61
+ }
62
+
63
+ /**
64
+ * Function-calling schema handed to the provider as an LLM tool (the shape the
65
+ * model sees: name, description, input JSON schema). Structurally matches the
66
+ * host provider wire-spec (`providers/types` → `tools/tool-types` `ToolDefinition`)
67
+ * so instances stay assignable to `Provider.sendMessage({ tools })`. Kept local
68
+ * rather than imported from `@vellumai/plugin-api`: the contract's same-named
69
+ * `ToolDefinition` is the richer, all-optional author-facing tool type, which
70
+ * doesn't match the all-required wire-spec at the `: ToolDefinition` sites here.
71
+ */
72
+ export interface ToolDefinition {
73
+ name: string;
74
+ description: string;
75
+ input_schema: object;
76
+ }
@@ -57,7 +57,6 @@ import {
57
57
  type ConversationRow,
58
58
  deleteConversation,
59
59
  deleteConversationGently,
60
- findMostRecentRetrospectiveFor,
61
60
  forkConversationForRetrospective,
62
61
  getConversation,
63
62
  getMessagesAfter,
@@ -73,6 +72,7 @@ import { resolveUserSlug } from "../../../prompts/persona-resolver.js";
73
72
  import type { SystemPromptPersonaOverride } from "../../../prompts/system-prompt.js";
74
73
  import { wakeAgentForOpportunity } from "../../../runtime/agent-wake.js";
75
74
  import { getLogger } from "../../../util/logger.js";
75
+ import { findMostRecentRetrospectiveFor } from "./find-most-recent-retrospective-for.js";
76
76
  import {
77
77
  MEMORY_RETROSPECTIVE_FORK_SOURCE,
78
78
  MEMORY_RETROSPECTIVE_GROUP_ID,
@@ -454,9 +454,10 @@ interface SourceParityPins {
454
454
  * stored on the conversation row — the slugs are omitted so the wake keeps
455
455
  * today's persona derivation for them.
456
456
  *
457
- * `hasNoClient` — pinned on BOTH the persona override (the prompt's
458
- * `05-access-preference` section renders different text under the flag) and
459
- * the tool-context pin, using the live-turn derivation: interactive
457
+ * `hasNoClient` — pinned on BOTH the persona override (kept for prompt-build
458
+ * parity; no system-prompt section branches on the flag, so this pin does not
459
+ * affect prompt output) and the tool-context pin (the live consumer, gating
460
+ * tool availability), using the live-turn derivation: interactive
460
461
  * interfaces run `updateClient(_, false)` (`hasNoClient = false`), while
461
462
  * channel-routed and chrome-extension turns stay clientless (`true`) — the
462
463
  * exact `isInteractiveInterface` predicate `conversation-routes.ts` /
@@ -951,7 +952,9 @@ When you do capture a procedure:
951
952
 
952
953
  2. Capture procedure-scoped knowledge alongside the body. Failure modes, gotchas, and cached values you observed in the trace (error signatures and how you recovered, preconditions, IDs/paths/endpoints that held steady) belong in companion files passed via \`scaffold_managed_skill\`'s \`files\` input (for example \`references/failure-modes.md\`), and the SKILL.md body should reference them so a future load surfaces them.
953
954
 
954
- 3. Set \`category\` to the single closest-fitting value from this published set (a value outside it gets no Skills-UI bucket, so always pick from the list, never invent one): browsing, calendar, commerce, content, development, email, health, integrations, messaging, productivity, system, voice.
955
+ 3. Set \`activation_hints\` to the concrete situations that should trigger this skill later phrased as the intent you observed in the trace ("user asks to …", "needs to …", "when the goal is …"), NOT the mechanical steps. These become the skill's "Use when" retrieval signal, so a future turn with a matching intent surfaces the skill even when its name doesn't match the request. Give 1–4 short, distinct triggers. Optionally set \`avoid_when\` for situations where the skill should NOT be used.
956
+
957
+ 4. Set \`category\` to the single closest-fitting value from this published set (a value outside it gets no Skills-UI bucket, so always pick from the list, never invent one): browsing, calendar, commerce, content, development, email, health, integrations, messaging, productivity, system, voice.
955
958
 
956
959
  Ordinary facts still go through \`remember\` (unlinked) exactly as above — skills are for executed, reusable procedures, not for facts.
957
960
  `;
@@ -51,7 +51,6 @@ import {
51
51
  sql,
52
52
  } from "drizzle-orm";
53
53
 
54
- import { getConfig } from "../../../config/loader.js";
55
54
  import { deleteConversation } from "../../../persistence/conversation-crud.js";
56
55
  import { getDb, getMemoryDb } from "../../../persistence/db-connection.js";
57
56
  import {
@@ -59,6 +58,7 @@ import {
59
58
  memoryJobs,
60
59
  } from "../../../persistence/schema/index.js";
61
60
  import { getLogger } from "../../../util/logger.js";
61
+ import { getMemoryConfig } from "./config.js";
62
62
  import { MEMORY_RETROSPECTIVE_SOURCES } from "./memory-retrospective-constants.js";
63
63
  import { loadRetrospectiveRunMessages } from "./memory-retrospective-fork-boundary.js";
64
64
 
@@ -94,7 +94,7 @@ export function sweepOrphanMemoryRetrospectiveConversations(
94
94
  // retained superseded run from a crash orphan. Tradeoff: under this opt-in,
95
95
  // genuine crash orphans persist too. That's acceptable — the operator asked
96
96
  // for full run history, and an orphan is just one more retained conversation.
97
- if (getConfig().memory?.retrospective?.keepSupersededRuns === true) {
97
+ if (getMemoryConfig()?.retrospective?.keepSupersededRuns === true) {
98
98
  return { swept: 0 };
99
99
  }
100
100
 
@@ -71,6 +71,7 @@ export async function getConceptFrequencySummary(
71
71
  const onDiskSlugsPromise = listPages(workspaceDir);
72
72
 
73
73
  const aggRows = rawAll<AggRow>(
74
+ "conceptFreq:summary:agg",
74
75
  `SELECT
75
76
  json_extract(c.value, '$.slug') AS slug,
76
77
  json_extract(c.value, '$.status') AS status,
@@ -87,6 +88,7 @@ export async function getConceptFrequencySummary(
87
88
  );
88
89
 
89
90
  const logCountRow = rawGet<CountRow>(
91
+ "conceptFreq:summary:count",
90
92
  `SELECT COUNT(*) AS count
91
93
  FROM memory_v2_activation_logs
92
94
  WHERE (? IS NULL OR conversation_id = ?)