@vellumai/assistant 0.10.5 → 0.10.6-dev.202607062043.72bc40b

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 (672) hide show
  1. package/ARCHITECTURE.md +65 -64
  2. package/Dockerfile +1 -0
  3. package/README.md +7 -10
  4. package/__tests__/permissions/gateway-threshold-reader.test.ts +1 -1
  5. package/docs/stt-provider-onboarding.md +4 -5
  6. package/docs/trusted-contact-access.md +7 -7
  7. package/eslint-rules/cli-no-daemon-internals.js +3 -0
  8. package/node_modules/@vellumai/gateway-client/src/__tests__/contact-read-contracts.test.ts +36 -0
  9. package/node_modules/@vellumai/gateway-client/src/__tests__/invite-contract.test.ts +233 -0
  10. package/node_modules/@vellumai/gateway-client/src/__tests__/trust-verdict-contract.test.ts +22 -0
  11. package/node_modules/@vellumai/gateway-client/src/__tests__/verification-session-contract.test.ts +299 -0
  12. package/node_modules/@vellumai/gateway-client/src/channel-permission-contract.ts +156 -0
  13. package/node_modules/@vellumai/gateway-client/src/gateway-ipc-contracts.ts +20 -8
  14. package/node_modules/@vellumai/gateway-client/src/index.ts +112 -0
  15. package/node_modules/@vellumai/gateway-client/src/invite-contract.ts +216 -0
  16. package/node_modules/@vellumai/gateway-client/src/outbound-contract.ts +10 -0
  17. package/node_modules/@vellumai/gateway-client/src/trust-verdict-contract.ts +14 -0
  18. package/node_modules/@vellumai/gateway-client/src/verification-session-contract.ts +398 -0
  19. package/node_modules/@vellumai/service-contracts/src/__tests__/ingress.test.ts +0 -8
  20. package/node_modules/@vellumai/service-contracts/src/twilio-ingress.ts +3 -14
  21. package/openapi.yaml +378 -266
  22. package/package.json +1 -1
  23. package/src/__tests__/access-request-seed-content-blocks.test.ts +60 -4
  24. package/src/__tests__/acp-session.test.ts +4 -1
  25. package/src/__tests__/actor-trust-resolver-address-fallback.test.ts +1 -7
  26. package/src/__tests__/add-message-preassigned-id.test.ts +56 -0
  27. package/src/__tests__/anthropic-provider.test.ts +60 -19
  28. package/src/__tests__/app-conversation-ids-backfill.test.ts +3 -0
  29. package/src/__tests__/app-dir-path-guard.test.ts +2 -3
  30. package/src/__tests__/app-source-watcher.test.ts +11 -0
  31. package/src/__tests__/assistant-event-hub.test.ts +65 -0
  32. package/src/__tests__/assistant-id-boundary-guard.test.ts +0 -1
  33. package/src/__tests__/assistant-stream-state.test.ts +18 -0
  34. package/src/__tests__/attachment-stored-path-annotation.test.ts +151 -0
  35. package/src/__tests__/attachments-store.test.ts +40 -1
  36. package/src/__tests__/attachments.test.ts +53 -0
  37. package/src/__tests__/background-workers-disk-pressure.test.ts +2 -28
  38. package/src/__tests__/btw-routes.test.ts +57 -3
  39. package/src/__tests__/call-controller.test.ts +260 -79
  40. package/src/__tests__/call-domain.test.ts +48 -1
  41. package/src/__tests__/call-pointer-no-hardcoded-copy.guard.test.ts +2 -6
  42. package/src/__tests__/call-routes-http.test.ts +15 -14
  43. package/src/__tests__/call-setup-flow-invite.test.ts +568 -0
  44. package/src/__tests__/call-setup-flow-midcall-trust.test.ts +231 -0
  45. package/src/__tests__/call-setup-flow-name-capture.test.ts +754 -0
  46. package/src/__tests__/call-setup-flow-verification.test.ts +924 -0
  47. package/src/__tests__/call-setup-flow.test.ts +311 -0
  48. package/src/__tests__/call-start-guardian-guard.test.ts +29 -3
  49. package/src/__tests__/channel-approval-routes.test.ts +0 -1
  50. package/src/__tests__/channel-guardian.test.ts +293 -629
  51. package/src/__tests__/channel-readiness-service.test.ts +0 -6
  52. package/src/__tests__/channel-readiness-slack-remote.test.ts +0 -4
  53. package/src/__tests__/channel-reply-delivery.test.ts +214 -5
  54. package/src/__tests__/channel-setup-panel-ack.test.ts +184 -0
  55. package/src/__tests__/clear-all-lexical.test.ts +13 -49
  56. package/src/__tests__/client-os-metadata-persistence.test.ts +166 -0
  57. package/src/__tests__/config-loader-backfill.test.ts +16 -36
  58. package/src/__tests__/config-schema.test.ts +25 -118
  59. package/src/__tests__/contact-store-interaction-info.test.ts +27 -70
  60. package/src/__tests__/contacts-relay-reads.test.ts +188 -23
  61. package/src/__tests__/contacts-tools.test.ts +42 -1
  62. package/src/__tests__/contacts-write.test.ts +181 -0
  63. package/src/__tests__/context-search-conversations-source.test.ts +4 -0
  64. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +0 -4
  65. package/src/__tests__/conversation-agent-loop-overflow.test.ts +0 -4
  66. package/src/__tests__/conversation-agent-loop.test.ts +0 -4
  67. package/src/__tests__/conversation-analysis-routes.test.ts +1 -1
  68. package/src/__tests__/conversation-attention-telegram.test.ts +0 -1
  69. package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +2 -61
  70. package/src/__tests__/conversation-disk-view.test.ts +1 -0
  71. package/src/__tests__/conversation-error.test.ts +26 -0
  72. package/src/__tests__/conversation-fork-crud.test.ts +3 -3
  73. package/src/__tests__/conversation-fork-retrospective.test.ts +0 -2
  74. package/src/__tests__/conversation-key-store-disk-view.test.ts +80 -0
  75. package/src/__tests__/conversation-queue.test.ts +108 -0
  76. package/src/__tests__/conversation-routes-enabled-plugins.test.ts +7 -3
  77. package/src/__tests__/conversation-routes-guardian-reply.test.ts +1 -0
  78. package/src/__tests__/conversation-routes-hidden-queue.test.ts +1 -0
  79. package/src/__tests__/conversation-routes-slash-commands.test.ts +1 -0
  80. package/src/__tests__/conversation-runtime-assembly.test.ts +59 -16
  81. package/src/__tests__/conversation-slash-queue.test.ts +0 -4
  82. package/src/__tests__/conversation-slash-unknown.test.ts +0 -4
  83. package/src/__tests__/credential-prompt-route.test.ts +69 -0
  84. package/src/__tests__/credential-security-invariants.test.ts +1 -0
  85. package/src/__tests__/default-plugin-names-guard.test.ts +28 -0
  86. package/src/__tests__/deterministic-verification-control-plane.test.ts +36 -64
  87. package/src/__tests__/disk-pressure-tools.test.ts +6 -0
  88. package/src/__tests__/empty-response-hook.test.ts +2 -0
  89. package/src/__tests__/empty-state-greeting-cache.test.ts +9 -0
  90. package/src/__tests__/exploration-drift-hook.test.ts +1 -0
  91. package/src/__tests__/file-edit-tool.test.ts +4 -3
  92. package/src/__tests__/file-read-tool.test.ts +4 -3
  93. package/src/__tests__/file-write-tool.test.ts +4 -3
  94. package/src/__tests__/gateway-only-enforcement.test.ts +15 -110
  95. package/src/__tests__/gateway-only-guard.test.ts +0 -1
  96. package/src/__tests__/guardian-expiry-notifier.test.ts +1 -0
  97. package/src/__tests__/guardian-outbound-http.test.ts +32 -18
  98. package/src/__tests__/guardian-routing-invariants.test.ts +18 -0
  99. package/src/__tests__/guardian-verification-voice-binding.test.ts +1 -1
  100. package/src/__tests__/guardian-wait-controller.test.ts +628 -0
  101. package/src/__tests__/helpers/create-guardian-binding.ts +1 -1
  102. package/src/__tests__/helpers/gateway-verification-sessions-stub.ts +171 -0
  103. package/src/__tests__/helpers/seed-contact-channel.ts +0 -2
  104. package/src/__tests__/helpers/verification-sessions-ipc-sim.ts +653 -0
  105. package/src/__tests__/history-repair-hook.test.ts +3 -0
  106. package/src/__tests__/hook-broadcast.test.ts +188 -0
  107. package/src/__tests__/http-conversation-lineage.test.ts +6 -1
  108. package/src/__tests__/http-user-message-parity.test.ts +1 -0
  109. package/src/__tests__/image-recovery-hook.test.ts +2 -0
  110. package/src/__tests__/image-source-path-reinject.test.ts +155 -14
  111. package/src/__tests__/inactive-tool-error-messages.test.ts +109 -0
  112. package/src/__tests__/inbound-invite-redemption.test.ts +72 -341
  113. package/src/__tests__/injector-chain.test.ts +4 -0
  114. package/src/__tests__/introduction-card-resolver.test.ts +363 -0
  115. package/src/__tests__/invite-redeemed-ipc.test.ts +97 -0
  116. package/src/__tests__/invite-routes-http.test.ts +246 -420
  117. package/src/__tests__/job-handler-registration-guard.test.ts +88 -0
  118. package/src/__tests__/lexical-index-dual-write.test.ts +105 -87
  119. package/src/__tests__/list-messages-attachments.test.ts +1 -0
  120. package/src/__tests__/managed-profile-guard.test.ts +569 -78
  121. package/src/__tests__/max-tokens-continue-hook.test.ts +1 -0
  122. package/src/__tests__/mcp-config-secret-boundary.test.ts +1 -0
  123. package/src/__tests__/media-stream-audio-transcode.test.ts +113 -0
  124. package/src/__tests__/media-stream-output.test.ts +350 -19
  125. package/src/__tests__/media-stream-server-integration.test.ts +947 -173
  126. package/src/__tests__/media-stream-stt-session.test.ts +498 -1
  127. package/src/__tests__/memory-jobs-worker-backoff.test.ts +1 -1
  128. package/src/__tests__/memory-jobs-worker-lanes.test.ts +3 -3
  129. package/src/__tests__/memory-retrieval-hook.test.ts +1 -0
  130. package/src/__tests__/memory-worker-tool-registry-guard.test.ts +59 -0
  131. package/src/__tests__/mtime-cache.test.ts +268 -84
  132. package/src/__tests__/notification-decision-fallback.test.ts +10 -8
  133. package/src/__tests__/notification-decision-strategy.test.ts +57 -8
  134. package/src/__tests__/persistence-layering-guard.test.ts +23 -9
  135. package/src/__tests__/phone.test.ts +1 -15
  136. package/src/__tests__/plugin-bootstrap.test.ts +6 -191
  137. package/src/__tests__/plugin-config-data-migration.test.ts +2 -4
  138. package/src/__tests__/plugin-disabled-state.test.ts +0 -97
  139. package/src/__tests__/plugin-effective-enabled-set.test.ts +50 -68
  140. package/src/__tests__/plugin-import-boundary-guard.test.ts +14 -3
  141. package/src/__tests__/plugin-pipeline.test.ts +98 -2
  142. package/src/__tests__/plugin-tool-contribution.test.ts +1 -1
  143. package/src/__tests__/plugin-types.test.ts +0 -1
  144. package/src/__tests__/public-ingress-urls.test.ts +0 -48
  145. package/src/__tests__/qdrant-collection-migration.test.ts +104 -0
  146. package/src/__tests__/reaction-intercept-member-verdict-warm.test.ts +0 -1
  147. package/src/__tests__/reaction-persistence.test.ts +2 -4
  148. package/src/__tests__/registry.test.ts +9 -10
  149. package/src/__tests__/schedule-routes.test.ts +6 -0
  150. package/src/__tests__/secret-ingress-http.test.ts +1 -0
  151. package/src/__tests__/secret-routes-platform-proxy.test.ts +5 -2
  152. package/src/__tests__/shared-dep-links.test.ts +123 -0
  153. package/src/__tests__/skill-load-feature-flag.test.ts +2 -4
  154. package/src/__tests__/skill-load-inline-command.test.ts +2 -4
  155. package/src/__tests__/skill-load-inline-includes.test.ts +2 -4
  156. package/src/__tests__/skill-load-plugin-scope.test.ts +2 -4
  157. package/src/__tests__/skill-load-tool.test.ts +3 -6
  158. package/src/__tests__/slack-inbound-verification.test.ts +22 -3
  159. package/src/__tests__/slack-reaction-canonical-approval.test.ts +51 -1
  160. package/src/__tests__/surface-completion-nudge-hook.test.ts +2 -0
  161. package/src/__tests__/task-progress-nudge-hook.test.ts +1 -0
  162. package/src/__tests__/telephony-credential-preflight.test.ts +312 -0
  163. package/src/__tests__/telephony-tts-guard.test.ts +531 -0
  164. package/src/__tests__/title-generate-hook.test.ts +2 -0
  165. package/src/__tests__/tool-approval-handler.test.ts +87 -1
  166. package/src/__tests__/tool-approval-seed-content-blocks.test.ts +45 -20
  167. package/src/__tests__/tool-error-hook.test.ts +1 -0
  168. package/src/__tests__/tool-execution-abort-cleanup.test.ts +9 -33
  169. package/src/__tests__/tool-executor.test.ts +77 -4
  170. package/src/__tests__/tool-grant-request-escalation.test.ts +48 -2
  171. package/src/__tests__/tool-name-aliases.test.ts +111 -0
  172. package/src/__tests__/tool-result-truncate-hook.test.ts +1 -0
  173. package/src/__tests__/tool-side-effects-slack-dm.test.ts +79 -22
  174. package/src/__tests__/trust-context-guards.test.ts +1 -1
  175. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +11 -0
  176. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +21 -3
  177. package/src/__tests__/trusted-contact-multichannel.test.ts +23 -8
  178. package/src/__tests__/trusted-contact-verification.test.ts +7 -9
  179. package/src/__tests__/twilio-provider.test.ts +17 -17
  180. package/src/__tests__/twilio-routes-twiml.test.ts +6 -543
  181. package/src/__tests__/twilio-routes.test.ts +258 -388
  182. package/src/__tests__/twilio-validation.test.ts +1 -1
  183. package/src/__tests__/usage-cache-backfill-migration.test.ts +5 -0
  184. package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +2 -4
  185. package/src/__tests__/voice-approval-resolver-relay.test.ts +150 -0
  186. package/src/__tests__/voice-ingress-preflight.test.ts +61 -0
  187. package/src/__tests__/workspace-git-service.test.ts +1 -1
  188. package/src/__tests__/workspace-migration-013-repair-conversation-disk-view.test.ts +1 -0
  189. package/src/__tests__/workspace-migration-124-correct-default-user-boundary-comments.test.ts +172 -0
  190. package/src/__tests__/workspace-migration-125-repoint-managed-connections-to-vellum.test.ts +140 -0
  191. package/src/acp/__tests__/session-manager-persistence.test.ts +2 -0
  192. package/src/acp/__tests__/session-manager-resume.test.ts +8 -0
  193. package/src/acp/__tests__/session-manager-usage.test.ts +6 -0
  194. package/src/acp/__tests__/session-manager.test.ts +6 -0
  195. package/src/acp/agent-process.test.ts +116 -0
  196. package/src/acp/agent-process.ts +71 -0
  197. package/src/acp/failure-error.test.ts +109 -0
  198. package/src/acp/failure-error.ts +111 -0
  199. package/src/acp/session-manager.test.ts +312 -0
  200. package/src/acp/session-manager.ts +102 -46
  201. package/src/agent/attachments.ts +55 -13
  202. package/src/agent/loop.ts +38 -71
  203. package/src/api/events/hook-event.ts +53 -0
  204. package/src/api/events/open-panel.ts +7 -0
  205. package/src/api/index.ts +8 -0
  206. package/src/approvals/guardian-decision-primitive.ts +74 -24
  207. package/src/approvals/guardian-request-resolvers.ts +433 -125
  208. package/src/apps/app-store.ts +3 -2
  209. package/src/apps/shared-app-links-store.ts +1 -0
  210. package/src/background-wake/wake-intent-hooks.test.ts +7 -0
  211. package/src/calls/__tests__/{relay-setup-router.test.ts → call-setup-router.test.ts} +158 -107
  212. package/src/calls/__tests__/fish-audio-client.test.ts +73 -0
  213. package/src/calls/__tests__/gateway-invite-reader.test.ts +170 -0
  214. package/src/calls/{relay-access-wait.ts → access-request-wait.ts} +4 -5
  215. package/src/calls/call-controller.ts +97 -50
  216. package/src/calls/call-domain.ts +18 -42
  217. package/src/calls/call-pointer-messages.ts +18 -0
  218. package/src/calls/call-setup-flow-types.ts +76 -0
  219. package/src/calls/call-setup-flow.ts +1742 -0
  220. package/src/calls/{relay-setup-router.ts → call-setup-router.ts} +27 -46
  221. package/src/calls/call-speech-output.ts +87 -24
  222. package/src/calls/call-store.ts +4 -0
  223. package/src/calls/call-transport.ts +22 -36
  224. package/src/calls/{relay-verification.ts → call-verification.ts} +22 -67
  225. package/src/calls/fish-audio-client.ts +3 -0
  226. package/src/calls/gateway-invite-reader.ts +98 -0
  227. package/src/calls/guardian-wait-controller.ts +451 -0
  228. package/src/calls/media-stream-audio-transcode.ts +82 -2
  229. package/src/calls/media-stream-output.ts +142 -36
  230. package/src/calls/media-stream-server.ts +304 -185
  231. package/src/calls/media-stream-stt-session.ts +393 -50
  232. package/src/calls/media-turn-detector.ts +4 -6
  233. package/src/calls/resolve-call-tts-provider.ts +99 -34
  234. package/src/calls/telephony-credential-preflight.ts +159 -0
  235. package/src/calls/telephony-tts-capability.ts +186 -0
  236. package/src/calls/tts-call-strategy.ts +10 -106
  237. package/src/calls/twilio-provider.ts +3 -2
  238. package/src/calls/twilio-routes.ts +47 -351
  239. package/src/calls/types.ts +5 -3
  240. package/src/calls/voice-ingress-preflight.ts +9 -0
  241. package/src/calls/voice-session-bridge.ts +4 -4
  242. package/src/channels/__tests__/gateway-verification-sessions.test.ts +521 -0
  243. package/src/channels/config.ts +0 -42
  244. package/src/channels/gateway-verification-sessions.ts +309 -0
  245. package/src/cli/commands/contacts.ts +2 -2
  246. package/src/cli/commands/conversations.ts +0 -65
  247. package/src/cli/commands/credentials.ts +17 -0
  248. package/src/cli/commands/keys.ts +86 -83
  249. package/src/cli/commands/memory/__tests__/memory-items.test.ts +445 -0
  250. package/src/cli/commands/memory/index.ts +10 -1
  251. package/src/cli/commands/memory/items.ts +490 -0
  252. package/src/cli/commands/monitoring.ts +111 -25
  253. package/src/cli/commands/platform/__tests__/credits.test.ts +111 -0
  254. package/src/cli/commands/platform/index.ts +86 -4
  255. package/src/cli/lib/__tests__/confirm-prompt.test.ts +9 -9
  256. package/src/cli/lib/diff-plugin.ts +7 -3
  257. package/src/cli/lib/inspect-plugin.ts +28 -10
  258. package/src/cli/lib/install-from-github.ts +69 -24
  259. package/src/cli/lib/ipc-params.ts +3 -3
  260. package/src/cli/lib/list-installed-plugins.ts +11 -5
  261. package/src/cli/lib/merge-plugin-tree.ts +15 -9
  262. package/src/cli/lib/plugin-fingerprint.ts +32 -69
  263. package/src/cli/lib/publish-plugin.ts +1 -1
  264. package/src/cli/lib/unknown-command.ts +3 -1
  265. package/src/cli/lib/upgrade-plugin.ts +2 -5
  266. package/src/config/__tests__/sync-gated-profiles.test.ts +2 -2
  267. package/src/config/bundled-skills/app-builder/SKILL.md +3 -3
  268. package/src/config/bundled-skills/app-builder/TOOLS.json +0 -20
  269. package/src/config/bundled-skills/app-builder/tools/app-create.ts +0 -4
  270. package/src/config/bundled-skills/app-builder/tools/app-delete.ts +1 -5
  271. package/src/config/bundled-skills/app-builder/tools/app-generate-icon.ts +0 -4
  272. package/src/config/bundled-skills/app-builder/tools/app-refresh.ts +0 -4
  273. package/src/config/bundled-skills/app-builder/tools/app-update.ts +0 -4
  274. package/src/config/bundled-skills/contacts/tools/contact-merge.ts +1 -1
  275. package/src/config/bundled-skills/contacts/tools/contact-search.ts +1 -1
  276. package/src/config/bundled-skills/phone-calls/SKILL.md +1 -1
  277. package/src/config/bundled-skills/phone-calls/references/CONFIG.md +9 -9
  278. package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +10 -7
  279. package/src/config/bundled-skills/settings/tools/voice-config-update.ts +1 -1
  280. package/src/config/feature-flag-registry.json +2 -2
  281. package/src/config/loader.ts +0 -2
  282. package/src/config/schemas/__tests__/memory-v3.test.ts +12 -0
  283. package/src/config/schemas/calls.ts +8 -6
  284. package/src/config/schemas/elevenlabs.ts +1 -1
  285. package/src/config/schemas/llm.ts +9 -9
  286. package/src/config/schemas/memory-v3.ts +10 -4
  287. package/src/config/schemas/monitoring.ts +25 -10
  288. package/src/config/schemas/tts.ts +5 -15
  289. package/src/config/seed-inference-profiles.ts +35 -23
  290. package/src/contacts/__tests__/member-write-relay.test.ts +101 -5
  291. package/src/contacts/canonical-guardian-store.ts +5 -0
  292. package/src/contacts/contact-store.ts +81 -35
  293. package/src/contacts/contacts-write.ts +50 -25
  294. package/src/contacts/member-write-relay.ts +74 -31
  295. package/src/contacts/types.ts +0 -8
  296. package/src/credential-execution/ces-runtime.ts +116 -1
  297. package/src/credential-execution/executable-discovery.ts +63 -4
  298. package/src/credential-execution/process-manager.test.ts +130 -3
  299. package/src/credential-execution/process-manager.ts +60 -13
  300. package/src/daemon/app-source-watcher.ts +8 -0
  301. package/src/daemon/conversation-agent-loop.ts +44 -25
  302. package/src/daemon/conversation-error.ts +43 -0
  303. package/src/daemon/conversation-lifecycle.ts +37 -15
  304. package/src/daemon/conversation-messaging.ts +82 -30
  305. package/src/daemon/conversation-plugin-scope.ts +38 -0
  306. package/src/daemon/conversation-process.ts +96 -28
  307. package/src/daemon/conversation-runtime-assembly.ts +25 -40
  308. package/src/daemon/conversation-surfaces.ts +162 -8
  309. package/src/daemon/conversation-tool-setup.test.ts +51 -1
  310. package/src/daemon/conversation-tool-setup.ts +63 -21
  311. package/src/daemon/conversation.ts +44 -13
  312. package/src/daemon/event-loop-watchdog.ts +60 -4
  313. package/src/daemon/external-plugins-bootstrap.ts +10 -66
  314. package/src/daemon/handlers/__tests__/config-a2a-accept.test.ts +1 -1
  315. package/src/daemon/handlers/__tests__/config-a2a-complete.test.ts +26 -14
  316. package/src/daemon/handlers/__tests__/config-a2a-invite.test.ts +27 -14
  317. package/src/daemon/handlers/__tests__/config-channels.test.ts +19 -13
  318. package/src/daemon/handlers/config-a2a.ts +7 -14
  319. package/src/daemon/handlers/config-channels.ts +44 -44
  320. package/src/daemon/handlers/shared.ts +1 -1
  321. package/src/daemon/lifecycle.ts +5 -26
  322. package/src/daemon/message-protocol.ts +2 -0
  323. package/src/daemon/message-types/contacts.ts +2 -10
  324. package/src/daemon/providers-setup.ts +2 -2
  325. package/src/daemon/shutdown-handlers.ts +0 -5
  326. package/src/daemon/sqlite-corruption-watchdog.test.ts +217 -0
  327. package/src/daemon/sqlite-corruption-watchdog.ts +155 -0
  328. package/src/daemon/tool-side-effects.ts +41 -12
  329. package/src/daemon/trust-context.ts +7 -0
  330. package/src/documents/document-comments-store.test.ts +7 -1
  331. package/src/documents/document-comments-store.ts +8 -0
  332. package/src/documents/document-store.ts +15 -0
  333. package/src/heartbeat/__tests__/heartbeat-service.test.ts +6 -0
  334. package/src/home/conversation-starter-checkpoints.ts +1 -0
  335. package/src/home/job-handlers/conversation-starters.ts +1 -0
  336. package/src/hooks/__tests__/hook-live-reload.test.ts +167 -0
  337. package/src/hooks/hook-broadcast.ts +60 -0
  338. package/src/hooks/hook-loader.ts +88 -117
  339. package/src/hooks/hook-logger.ts +28 -0
  340. package/src/hooks/registry.ts +58 -20
  341. package/src/hooks/types.ts +642 -0
  342. package/src/inbound/public-ingress-urls.ts +0 -17
  343. package/src/ipc/__tests__/contacts-info-ipc.test.ts +285 -0
  344. package/src/ipc/assistant-server.ts +28 -7
  345. package/src/ipc/routes/__tests__/contacts-mirror-apply-atomicity.test.ts +62 -0
  346. package/src/ipc/routes/__tests__/contacts-mirror-apply.test.ts +272 -0
  347. package/src/ipc/routes/__tests__/contacts-mirror-ipc-routes.test.ts +322 -0
  348. package/src/ipc/routes/__tests__/invite-ipc-routes.test.ts +60 -4
  349. package/src/ipc/routes/contacts-info-ipc-routes.ts +239 -0
  350. package/src/ipc/routes/contacts-mirror-ipc-routes.ts +202 -0
  351. package/src/ipc/routes/db-proxy.ts +6 -2
  352. package/src/ipc/routes/invite-ipc-routes.ts +53 -39
  353. package/src/live-voice/__tests__/live-voice-archive.test.ts +10 -1
  354. package/src/live-voice/__tests__/live-voice-tts.test.ts +10 -10
  355. package/src/live-voice/live-voice-archive.ts +5 -0
  356. package/src/live-voice/live-voice-tts.ts +1 -1
  357. package/src/messaging/providers/slack/api.test.ts +96 -1
  358. package/src/messaging/providers/slack/api.ts +38 -17
  359. package/src/messaging/providers/slack/send.ts +3 -0
  360. package/src/messaging/providers/whatsapp/send.ts +29 -9
  361. package/src/monitoring/__tests__/active-conversations.test.ts +87 -0
  362. package/src/monitoring/__tests__/control.test.ts +11 -5
  363. package/src/monitoring/__tests__/daemon-heartbeat.test.ts +50 -0
  364. package/src/monitoring/__tests__/page-cache.test.ts +82 -0
  365. package/src/monitoring/__tests__/plugin-source-watch.test.ts +214 -0
  366. package/src/monitoring/__tests__/process-memory.test.ts +67 -0
  367. package/src/monitoring/__tests__/resource-sampler.test.ts +111 -0
  368. package/src/monitoring/__tests__/slabinfo.test.ts +42 -0
  369. package/src/monitoring/__tests__/stall-capture.test.ts +130 -0
  370. package/src/monitoring/active-conversations.ts +97 -0
  371. package/src/monitoring/control.ts +5 -8
  372. package/src/monitoring/daemon-heartbeat.ts +81 -0
  373. package/src/monitoring/page-cache.ts +152 -0
  374. package/src/monitoring/plugin-source-watch.ts +246 -0
  375. package/src/monitoring/process-memory.ts +115 -0
  376. package/src/monitoring/prune-snapshots.ts +33 -0
  377. package/src/monitoring/resource-sampler.ts +170 -91
  378. package/src/monitoring/slabinfo.ts +73 -0
  379. package/src/monitoring/stall-capture.ts +191 -0
  380. package/src/monitoring/worker.ts +17 -4
  381. package/src/notifications/access-request-copy.ts +94 -23
  382. package/src/notifications/adapters/slack.ts +45 -8
  383. package/src/notifications/approval-card-builder.ts +33 -18
  384. package/src/notifications/approval-card-data.ts +48 -15
  385. package/src/notifications/broadcaster.ts +4 -1
  386. package/src/notifications/decision-engine.ts +10 -1
  387. package/src/permissions/approval-policy.ts +8 -1
  388. package/src/permissions/checker.test.ts +98 -1
  389. package/src/permissions/checker.ts +76 -16
  390. package/src/permissions/gateway-threshold-reader.ts +7 -6
  391. package/src/permissions/ipc-risk-types.ts +10 -0
  392. package/src/permissions/secret-prompter.ts +11 -3
  393. package/src/persistence/__tests__/conversation-queries-search.test.ts +4 -0
  394. package/src/persistence/__tests__/slow-query-log.test.ts +77 -1
  395. package/src/persistence/a2a-invite-store.ts +205 -0
  396. package/src/persistence/attachments-store.ts +26 -3
  397. package/src/persistence/conversation-crud.ts +137 -110
  398. package/src/persistence/conversation-display-order-migration.ts +8 -2
  399. package/src/persistence/conversation-group-migration.test.ts +8 -0
  400. package/src/persistence/conversation-group-migration.ts +9 -0
  401. package/src/persistence/conversation-key-store.ts +5 -0
  402. package/src/persistence/conversation-queries.ts +4 -0
  403. package/src/persistence/embeddings/__tests__/messages-lexical-index.test.ts +54 -4
  404. package/src/persistence/embeddings/embedding-local.ts +2 -0
  405. package/src/persistence/embeddings/messages-lexical-index.ts +50 -1
  406. package/src/persistence/embeddings/qdrant-client.ts +52 -1
  407. package/src/persistence/group-crud.ts +13 -1
  408. package/src/persistence/job-handlers/cleanup.ts +27 -5
  409. package/src/persistence/job-handlers/message-lexical.ts +3 -6
  410. package/src/persistence/jobs-store.ts +10 -2
  411. package/src/persistence/llm-usage-store.ts +11 -0
  412. package/src/persistence/migrations/028-call-session-mode.ts +1 -1
  413. package/src/persistence/migrations/315-create-a2a-invites.ts +58 -0
  414. package/src/persistence/migrations/316-drop-contact-channels-invite-id.ts +28 -0
  415. package/src/persistence/migrations/317-canonical-guardian-requester-signals.ts +24 -0
  416. package/src/persistence/migrations/318-drop-contact-channel-telemetry.ts +32 -0
  417. package/src/persistence/migrations/319-remove-legacy-managed-connections.ts +47 -0
  418. package/src/persistence/migrations/__tests__/315-create-a2a-invites.test.ts +161 -0
  419. package/src/persistence/migrations/__tests__/316-drop-contact-channels-invite-id.test.ts +156 -0
  420. package/src/persistence/migrations/__tests__/318-drop-contact-channel-telemetry.test.ts +134 -0
  421. package/src/persistence/migrations/__tests__/319-remove-legacy-managed-connections.test.ts +88 -0
  422. package/src/persistence/raw-query.ts +49 -13
  423. package/src/persistence/schema/a2a.ts +14 -0
  424. package/src/persistence/schema/calls.ts +0 -49
  425. package/src/persistence/schema/contacts.ts +0 -34
  426. package/src/persistence/schema/guardian.ts +4 -0
  427. package/src/persistence/slow-query-log.ts +195 -19
  428. package/src/persistence/steps.ts +10 -0
  429. package/src/persistence/subagent-store.ts +5 -2
  430. package/src/persistence/worker-control.ts +1 -1
  431. package/src/plugin-api/constants.ts +2 -0
  432. package/src/plugin-api/index.ts +6 -1
  433. package/src/plugin-api/types.ts +25 -518
  434. package/src/plugins/__tests__/source-fingerprint.test.ts +151 -0
  435. package/src/plugins/defaults/index.ts +7 -109
  436. package/src/plugins/defaults/main.ts +52 -0
  437. package/src/plugins/defaults/memory/__tests__/conversation-queries.test.ts +34 -3
  438. package/src/plugins/defaults/memory/__tests__/filing-jobs.test.ts +123 -0
  439. package/src/{persistence → plugins/defaults/memory}/__tests__/jobs-worker-memory-disabled.test.ts +8 -8
  440. package/src/plugins/defaults/memory/__tests__/jobs-worker-pkb-schedule.test.ts +273 -0
  441. package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-graph-trigger-embed.test.ts +3 -3
  442. package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-schedule.test.ts +1 -12
  443. package/src/plugins/defaults/memory/__tests__/shutdown-hook.test.ts +26 -0
  444. package/src/plugins/defaults/memory/context-search/sources/conversations.ts +1 -0
  445. package/src/plugins/defaults/memory/filing-jobs.ts +133 -0
  446. package/src/plugins/defaults/memory/graph/bootstrap.test.ts +36 -10
  447. package/src/plugins/defaults/memory/graph/bootstrap.ts +3 -0
  448. package/src/plugins/defaults/memory/graph/scoring.ts +2 -2
  449. package/src/plugins/defaults/memory/hooks/conversation-deleted.ts +34 -0
  450. package/src/plugins/defaults/memory/hooks/init.ts +28 -13
  451. package/src/plugins/defaults/memory/hooks/shutdown.ts +11 -4
  452. package/src/plugins/defaults/memory/job-handler-registration.ts +96 -0
  453. package/src/plugins/defaults/memory/job-handlers.ts +14 -6
  454. package/src/{persistence → plugins/defaults/memory}/jobs-worker.ts +120 -20
  455. package/src/plugins/defaults/memory/memory-v2-concept-frequency.ts +2 -0
  456. package/src/plugins/defaults/memory/persistence-hooks.ts +49 -65
  457. package/src/plugins/defaults/memory/pkb-schedule.ts +31 -0
  458. package/src/plugins/defaults/memory/rerank-local.ts +2 -0
  459. package/src/plugins/defaults/memory/startup.ts +16 -11
  460. package/src/plugins/defaults/memory/task-memory-cleanup.ts +30 -85
  461. package/src/plugins/defaults/memory/v2/__tests__/qdrant.test.ts +115 -4
  462. package/src/plugins/defaults/memory/v2/qdrant.ts +59 -2
  463. package/src/plugins/defaults/memory/v3/__tests__/gate-flag.test.ts +17 -4
  464. package/src/plugins/defaults/memory/v3/__tests__/orchestrate.test.ts +114 -2
  465. package/src/plugins/defaults/memory/v3/__tests__/shadow-plugin.test.ts +25 -6
  466. package/src/plugins/defaults/memory/v3/gate-flag.ts +9 -4
  467. package/src/plugins/defaults/memory/v3/gate.ts +3 -3
  468. package/src/plugins/defaults/memory/v3/orchestrate.ts +32 -0
  469. package/src/plugins/defaults/memory/v3/shadow-plugin.ts +7 -5
  470. package/src/{jobs → plugins/defaults/memory}/worker.ts +31 -7
  471. package/src/plugins/ensure-shared-dep-links.ts +150 -0
  472. package/src/plugins/injector-registry.ts +6 -12
  473. package/src/plugins/mtime-cache.ts +366 -36
  474. package/src/plugins/pipeline.ts +65 -23
  475. package/src/plugins/plugin-tree-walk.ts +107 -0
  476. package/src/plugins/source-fingerprint.ts +108 -0
  477. package/src/plugins/source-versions.ts +108 -0
  478. package/src/plugins/surface-import.ts +27 -6
  479. package/src/plugins/types.ts +20 -24
  480. package/src/plugins/user-loader.ts +15 -0
  481. package/src/prompts/templates/users/default.md +5 -5
  482. package/src/providers/__tests__/inference.test.ts +42 -31
  483. package/src/providers/__tests__/vellum-connection-routing.test.ts +124 -0
  484. package/src/providers/__tests__/vellum-mismatch-routing.test.ts +134 -0
  485. package/src/providers/connection-resolution.ts +35 -2
  486. package/src/providers/inference/__tests__/base-url-route-validation.test.ts +96 -1
  487. package/src/providers/inference/__tests__/connections-label.test.ts +9 -28
  488. package/src/providers/inference/adapter-factory.ts +8 -1
  489. package/src/providers/inference/auth.ts +12 -4
  490. package/src/providers/inference/backfill.ts +7 -5
  491. package/src/providers/inference/connections.ts +54 -30
  492. package/src/providers/provider-availability.ts +11 -4
  493. package/src/providers/registry.ts +21 -7
  494. package/src/providers/speech-to-text/__tests__/provider-catalog.test.ts +0 -64
  495. package/src/providers/speech-to-text/__tests__/resolve.test.ts +92 -79
  496. package/src/providers/speech-to-text/deepgram-realtime.test.ts +98 -0
  497. package/src/providers/speech-to-text/deepgram-realtime.ts +62 -3
  498. package/src/providers/speech-to-text/provider-catalog.ts +0 -89
  499. package/src/providers/speech-to-text/resolve.ts +55 -0
  500. package/src/providers/vellum-model-routing.test.ts +51 -0
  501. package/src/providers/vellum-model-routing.ts +108 -0
  502. package/src/runtime/AGENTS.md +4 -4
  503. package/src/runtime/__tests__/trust-verdict-consumer.test.ts +37 -8
  504. package/src/runtime/access-request-helper.ts +15 -1
  505. package/src/runtime/assistant-stream-state.ts +80 -25
  506. package/src/runtime/auth/__tests__/route-policy.test.ts +31 -0
  507. package/src/runtime/channel-approval-types.ts +52 -2
  508. package/src/runtime/channel-approvals.ts +23 -8
  509. package/src/runtime/channel-invite-transport.ts +2 -2
  510. package/src/runtime/channel-invite-transports/voice.ts +1 -1
  511. package/src/runtime/channel-readiness-service.ts +3 -5
  512. package/src/runtime/channel-reply-delivery.ts +83 -24
  513. package/src/runtime/channel-retry-sweep.ts +4 -0
  514. package/src/runtime/channel-verification-service.ts +34 -487
  515. package/src/runtime/guardian-action-service.ts +10 -11
  516. package/src/runtime/guardian-reply-router.ts +122 -21
  517. package/src/runtime/http-server.ts +32 -97
  518. package/src/runtime/introduction-policy.test.ts +214 -0
  519. package/src/runtime/introduction-policy.ts +284 -0
  520. package/src/runtime/invite-service.ts +104 -361
  521. package/src/runtime/middleware/twilio-validation.ts +5 -7
  522. package/src/runtime/{slack-no-response.ts → no-response.ts} +26 -6
  523. package/src/runtime/pre-first-message-gate.ts +1 -0
  524. package/src/runtime/routes/__tests__/channel-verification-revoke.test.ts +20 -43
  525. package/src/runtime/routes/__tests__/consolidation-routes.test.ts +24 -3
  526. package/src/runtime/routes/__tests__/contact-routes.test.ts +80 -15
  527. package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +7 -1
  528. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +180 -54
  529. package/src/runtime/routes/__tests__/global-search-routes.test.ts +0 -3
  530. package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +61 -24
  531. package/src/runtime/routes/__tests__/invite-relay-routes.test.ts +119 -30
  532. package/src/runtime/routes/__tests__/monitoring-routes.test.ts +100 -35
  533. package/src/runtime/routes/__tests__/retrospective-routes.test.ts +4 -0
  534. package/src/runtime/routes/__tests__/surface-action-routes.test.ts +1 -1
  535. package/src/runtime/routes/__tests__/surface-content-routes.test.ts +1 -1
  536. package/src/runtime/routes/acp-routes.ts +15 -3
  537. package/src/runtime/routes/app-management-routes.ts +0 -92
  538. package/src/runtime/routes/approval-routes.ts +4 -0
  539. package/src/runtime/routes/btw-routes.ts +32 -4
  540. package/src/runtime/routes/channel-route-shared.ts +18 -14
  541. package/src/runtime/routes/channel-verification-routes.ts +10 -9
  542. package/src/runtime/routes/consolidation-routes.ts +4 -2
  543. package/src/runtime/routes/contact-routes.ts +298 -117
  544. package/src/runtime/routes/conversation-management-routes.ts +1 -70
  545. package/src/runtime/routes/conversation-query-routes.ts +240 -56
  546. package/src/runtime/routes/conversation-routes.ts +26 -5
  547. package/src/runtime/routes/credential-prompt-routes.ts +20 -5
  548. package/src/runtime/routes/debug-routes.ts +1 -0
  549. package/src/runtime/routes/documents-routes.ts +5 -2
  550. package/src/runtime/routes/empty-state-greeting-cache.ts +37 -10
  551. package/src/runtime/routes/filing-routes.ts +50 -27
  552. package/src/runtime/routes/global-search-routes.ts +1 -0
  553. package/src/runtime/routes/inbound-message-handler.ts +9 -7
  554. package/src/runtime/routes/inbound-stages/acl-enforcement.test.ts +419 -82
  555. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +147 -610
  556. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +6 -1
  557. package/src/runtime/routes/inbound-stages/background-dispatch.ts +1 -1
  558. package/src/runtime/routes/inbound-stages/bootstrap-intercept.test.ts +266 -0
  559. package/src/runtime/routes/inbound-stages/bootstrap-intercept.ts +129 -23
  560. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.test.ts +93 -44
  561. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +72 -28
  562. package/src/runtime/routes/index.ts +0 -2
  563. package/src/runtime/routes/inference-provider-connection-routes.ts +26 -19
  564. package/src/runtime/routes/internal-twilio-routes.ts +0 -15
  565. package/src/runtime/routes/monitoring-routes.ts +79 -42
  566. package/src/runtime/routes/platform-routes.ts +82 -1
  567. package/src/runtime/routes/secret-routes.ts +14 -9
  568. package/src/runtime/routes/surface-conversation-resolver.ts +1 -0
  569. package/src/runtime/services/__tests__/analyze-conversation.test.ts +54 -9
  570. package/src/runtime/services/analyze-conversation.ts +14 -4
  571. package/src/runtime/slack-reply-session.test.ts +208 -15
  572. package/src/runtime/slack-reply-session.ts +65 -12
  573. package/src/runtime/slack-task-progress.test.ts +127 -0
  574. package/src/runtime/slack-task-progress.ts +47 -12
  575. package/src/runtime/trust-verdict-consumer.ts +7 -6
  576. package/src/runtime/verification-outbound-actions.ts +80 -54
  577. package/src/schedule/schedule-usage-store.ts +1 -0
  578. package/src/security/secure-keys.ts +15 -11
  579. package/src/stt/types.ts +5 -9
  580. package/src/telemetry/types.ts +10 -8
  581. package/src/telemetry/watchdog-direct-emit.test.ts +109 -0
  582. package/src/telemetry/watchdog-direct-emit.ts +89 -0
  583. package/src/tools/calls/call-start.ts +2 -2
  584. package/src/tools/document/document-comment-tool.test.ts +4 -0
  585. package/src/tools/executor.ts +59 -3
  586. package/src/tools/filesystem/edit.ts +0 -3
  587. package/src/tools/filesystem/fuzzy-match.ts +1 -1
  588. package/src/tools/filesystem/list.ts +0 -3
  589. package/src/tools/filesystem/read.ts +0 -3
  590. package/src/tools/filesystem/search.ts +0 -3
  591. package/src/tools/filesystem/write.ts +0 -3
  592. package/src/tools/network/__tests__/web-fetch-firecrawl.test.ts +21 -24
  593. package/src/tools/network/__tests__/web-search-metadata.test.ts +8 -19
  594. package/src/tools/network/__tests__/web-search.test.ts +34 -29
  595. package/src/tools/network/web-fetch.ts +9 -5
  596. package/src/tools/network/web-search.ts +0 -3
  597. package/src/tools/registry.ts +15 -27
  598. package/src/tools/skills/execute.ts +0 -3
  599. package/src/tools/skills/load.ts +0 -2
  600. package/src/tools/subagent/notify-parent.ts +0 -3
  601. package/src/tools/system/request-permission.ts +0 -3
  602. package/src/tools/terminal/safe-env.ts +2 -0
  603. package/src/tools/terminal/shell.ts +0 -3
  604. package/src/tools/tool-approval-handler.ts +171 -39
  605. package/src/tools/tool-manifest.ts +5 -41
  606. package/src/tools/tool-name-aliases.ts +141 -2
  607. package/src/tools/types.ts +7 -0
  608. package/src/tools/ui-surface/definitions.ts +1 -1
  609. package/src/tts/__tests__/provider-adapters.test.ts +53 -68
  610. package/src/tts/__tests__/provider-catalog-consistency.test.ts +8 -5
  611. package/src/tts/__tests__/provider-catalog.test.ts +21 -0
  612. package/src/tts/__tests__/provider-resolution.test.ts +83 -0
  613. package/src/tts/provider-catalog.ts +103 -232
  614. package/src/tts/provider-definition.ts +156 -0
  615. package/src/tts/providers/deepgram-provider.ts +41 -0
  616. package/src/tts/providers/elevenlabs-provider.ts +41 -0
  617. package/src/tts/providers/fish-audio-provider.ts +61 -10
  618. package/src/tts/providers/xai-provider.ts +41 -0
  619. package/src/tts/synthesize-text.ts +1 -1
  620. package/src/tts/types.ts +35 -16
  621. package/src/util/__tests__/cgroup-cpu.test.ts +31 -0
  622. package/src/util/__tests__/cgroup-memory.test.ts +104 -0
  623. package/src/util/__tests__/worker-memory.test.ts +64 -0
  624. package/src/util/cgroup-cpu.ts +47 -0
  625. package/src/util/cgroup-memory.ts +128 -7
  626. package/src/util/counter-diff.ts +21 -0
  627. package/src/util/phone.ts +1 -8
  628. package/src/util/process-tree.ts +3 -3
  629. package/src/util/worker-memory.ts +77 -0
  630. package/src/util/worker-process.ts +5 -1
  631. package/src/workflows/journal-store.ts +16 -1
  632. package/src/workspace/git-service.ts +6 -0
  633. package/src/workspace/migrations/124-correct-default-user-boundary-comments.ts +98 -0
  634. package/src/workspace/migrations/125-repoint-managed-connections-to-vellum.ts +99 -0
  635. package/src/workspace/migrations/registry.ts +4 -0
  636. package/src/__tests__/app-git-history.test.ts +0 -180
  637. package/src/__tests__/app-git-service.test.ts +0 -140
  638. package/src/__tests__/conversation-wipe.test.ts +0 -159
  639. package/src/__tests__/elevenlabs-client.test.ts +0 -297
  640. package/src/__tests__/filing-service.test.ts +0 -584
  641. package/src/__tests__/invite-redemption-service.test.ts +0 -1180
  642. package/src/__tests__/invite-service-ipc.test.ts +0 -350
  643. package/src/__tests__/job-handler-registry-guard.test.ts +0 -131
  644. package/src/__tests__/relay-server.test.ts +0 -6149
  645. package/src/__tests__/stt-hints.test.ts +0 -476
  646. package/src/__tests__/telephony-stt-routing.test.ts +0 -329
  647. package/src/__tests__/voice-invite-redemption.test.ts +0 -702
  648. package/src/__tests__/voice-quality.test.ts +0 -626
  649. package/src/apps/app-git-service.ts +0 -366
  650. package/src/calls/elevenlabs-client.ts +0 -116
  651. package/src/calls/relay-server.ts +0 -2465
  652. package/src/calls/stt-hints.ts +0 -186
  653. package/src/calls/telephony-stt-routing.ts +0 -145
  654. package/src/calls/voice-quality.ts +0 -124
  655. package/src/channels/channel-verification-sessions.ts +0 -562
  656. package/src/contacts/__tests__/contacts-write-revoke-relay.test.ts +0 -128
  657. package/src/contacts/guardian-rate-limits.ts +0 -191
  658. package/src/jobs/register-job-handlers.ts +0 -101
  659. package/src/persistence/invite-store.ts +0 -481
  660. package/src/persistence/memory-lifecycle-hooks.test.ts +0 -146
  661. package/src/persistence/memory-lifecycle-hooks.ts +0 -174
  662. package/src/plugins/defaults/default-plugin-names.ts +0 -60
  663. package/src/plugins/defaults/memory/filing-service.ts +0 -430
  664. package/src/plugins/job-handler-registry.ts +0 -94
  665. package/src/runtime/invite-redemption-service.ts +0 -828
  666. package/src/runtime/invite-redemption-templates.ts +0 -46
  667. package/src/runtime/routes/wipe-conversation-routes.ts +0 -97
  668. package/src/tts/__tests__/provider-registry.test.ts +0 -90
  669. package/src/tts/provider-registry.ts +0 -73
  670. package/src/tts/providers/index.ts +0 -44
  671. package/src/tts/providers/register-builtins.ts +0 -130
  672. package/src/util/voice-code.ts +0 -31
@@ -438,7 +438,12 @@ describe("processChannelMessageInBackground — slack thread mapping", () => {
438
438
  await flush();
439
439
 
440
440
  expect(slackStreamOps()).toEqual([
441
- { action: "start", threadTs, markdownText: "Streamed DM reply." },
441
+ {
442
+ action: "start",
443
+ threadTs,
444
+ markdownText: "Streamed DM reply.",
445
+ taskDisplayMode: "plan",
446
+ },
442
447
  { action: "stop", streamTs },
443
448
  ]);
444
449
  expect(
@@ -46,7 +46,7 @@ import type {
46
46
  MessageProcessor,
47
47
  SlackInboundMessageMetadata,
48
48
  } from "../../http-types.js";
49
- import { hasDeliverableAssistantText } from "../../slack-no-response.js";
49
+ import { hasDeliverableAssistantText } from "../../no-response.js";
50
50
  import { createSlackReplySession } from "../../slack-reply-session.js";
51
51
  import type { TaskProgressData } from "../../slack-task-progress.js";
52
52
  import {
@@ -0,0 +1,266 @@
1
+ /**
2
+ * Unit tests for the bootstrap deep-link intercept stage against the
3
+ * gateway-backed session client.
4
+ *
5
+ * Covers: the happy-path /start gv_<token> handoff (resolve → bind →
6
+ * fresh identity-bound session → delivery tracking; the mint revokes the
7
+ * bootstrap session gateway-side), fall-through for unresolvable tokens,
8
+ * ACL-threaded session reuse (no second gateway lookup), the
9
+ * gateway-unreachable posture (handled "unavailable" response — never
10
+ * fall-through to normal processing), retryability (any failure before the
11
+ * mint leaves the original session pending_bootstrap), and the atomic claim:
12
+ * a concurrent handoff that already consumed the token conflicts instead of
13
+ * minting a second code.
14
+ */
15
+ import { beforeEach, describe, expect, mock, test } from "bun:test";
16
+
17
+ import { createGatewayVerificationSessionsStub } from "../../../__tests__/helpers/gateway-verification-sessions-stub.js";
18
+
19
+ mock.module("../../../util/logger.js", () => ({
20
+ getLogger: () =>
21
+ new Proxy({} as Record<string, unknown>, { get: () => () => {} }),
22
+ }));
23
+
24
+ // Gateway-backed session client (async IPC); throw toggles simulate an
25
+ // unreachable gateway per lifecycle call.
26
+ const gatewaySessions = createGatewayVerificationSessionsStub({
27
+ mintResult: () => ({
28
+ sessionId: "new-session-1",
29
+ secret: "654321",
30
+ challengeHash: "hash-1",
31
+ expiresAt: Date.now() + 600_000,
32
+ ttlSeconds: 600,
33
+ }),
34
+ });
35
+ mock.module(
36
+ "../../../channels/gateway-verification-sessions.js",
37
+ () => gatewaySessions.module,
38
+ );
39
+
40
+ const telegramReplies: Array<{ chatId: string; text: string }> = [];
41
+ mock.module("../../../messaging/providers/telegram-bot/send.js", () => ({
42
+ sendTelegramReply: async (chatId: string, text: string) => {
43
+ telegramReplies.push({ chatId, text });
44
+ },
45
+ }));
46
+
47
+ mock.module("../../verification-outbound-actions.js", () => ({
48
+ RESEND_COOLDOWN_MS: 60_000,
49
+ }));
50
+
51
+ import type { VerificationSessionWire } from "../../../channels/gateway-verification-sessions.js";
52
+ import type { BootstrapInterceptParams } from "./bootstrap-intercept.js";
53
+ import { handleBootstrapIntercept } from "./bootstrap-intercept.js";
54
+
55
+ function makeParams(
56
+ overrides: Partial<BootstrapInterceptParams> = {},
57
+ ): BootstrapInterceptParams {
58
+ return {
59
+ isDuplicate: false,
60
+ commandIntent: { type: "start", payload: "gv_token123" },
61
+ rawSenderId: "user-42",
62
+ canonicalAssistantId: "self",
63
+ sourceChannel: "telegram",
64
+ conversationExternalId: "chat-123",
65
+ eventId: "event-1",
66
+ ...overrides,
67
+ };
68
+ }
69
+
70
+ beforeEach(() => {
71
+ gatewaySessions.reset();
72
+ gatewaySessions.state.bootstrapSession = {
73
+ id: "bootstrap-session-1",
74
+ channel: "telegram",
75
+ status: "pending_bootstrap",
76
+ };
77
+ telegramReplies.length = 0;
78
+ });
79
+
80
+ describe("handleBootstrapIntercept", () => {
81
+ test("valid token binds identity, rotates the session, and returns bootstrap_bound", async () => {
82
+ const result = await handleBootstrapIntercept(makeParams());
83
+
84
+ expect(result).toEqual({
85
+ accepted: true,
86
+ duplicate: false,
87
+ eventId: "event-1",
88
+ verificationOutcome: "bootstrap_bound",
89
+ });
90
+
91
+ // Raw token (gv_ prefix stripped); hashing is gateway-side.
92
+ expect(gatewaySessions.calls.resolveBootstrapToken).toEqual([
93
+ ["telegram", "token123"],
94
+ ]);
95
+ expect(gatewaySessions.calls.bindSessionIdentity).toEqual([
96
+ ["bootstrap-session-1", "user-42", "chat-123"],
97
+ ]);
98
+ // The mint revokes the bootstrap session gateway-side; no separate
99
+ // status transition — that would make a mint failure unretryable.
100
+ expect(gatewaySessions.calls.updateSessionStatus).toHaveLength(0);
101
+ expect(gatewaySessions.calls.create).toEqual([
102
+ {
103
+ channel: "telegram",
104
+ expectedExternalUserId: "user-42",
105
+ expectedChatId: "chat-123",
106
+ identityBindingStatus: "bound",
107
+ destinationAddress: "chat-123",
108
+ // Atomic gateway-side claim of the bootstrap session.
109
+ requireSourceSessionPending: "bootstrap-session-1",
110
+ },
111
+ ]);
112
+ expect(gatewaySessions.calls.updateSessionDelivery).toHaveLength(1);
113
+ expect(gatewaySessions.calls.updateSessionDelivery[0][0]).toBe(
114
+ "new-session-1",
115
+ );
116
+ });
117
+
118
+ test("unresolvable token falls through to normal /start handling", async () => {
119
+ gatewaySessions.state.bootstrapSession = null;
120
+
121
+ const result = await handleBootstrapIntercept(makeParams());
122
+
123
+ expect(result).toBeNull();
124
+ expect(gatewaySessions.calls.bindSessionIdentity).toHaveLength(0);
125
+ expect(gatewaySessions.calls.create).toHaveLength(0);
126
+ });
127
+
128
+ test("non-pending_bootstrap session falls through", async () => {
129
+ gatewaySessions.state.bootstrapSession = {
130
+ id: "bootstrap-session-1",
131
+ channel: "telegram",
132
+ status: "consumed",
133
+ };
134
+
135
+ const result = await handleBootstrapIntercept(makeParams());
136
+
137
+ expect(result).toBeNull();
138
+ expect(gatewaySessions.calls.bindSessionIdentity).toHaveLength(0);
139
+ });
140
+
141
+ test("non-bootstrap commands fall through untouched", async () => {
142
+ expect(
143
+ await handleBootstrapIntercept(
144
+ makeParams({ commandIntent: { type: "start", payload: "iv_other" } }),
145
+ ),
146
+ ).toBeNull();
147
+ expect(
148
+ await handleBootstrapIntercept(makeParams({ isDuplicate: true })),
149
+ ).toBeNull();
150
+ expect(
151
+ await handleBootstrapIntercept(makeParams({ rawSenderId: undefined })),
152
+ ).toBeNull();
153
+ expect(gatewaySessions.calls.resolveBootstrapToken).toHaveLength(0);
154
+ });
155
+
156
+ test("gateway unreachable on token resolution returns a handled unavailable response — no fall-through", async () => {
157
+ gatewaySessions.unreachable.resolveBootstrapToken = true;
158
+
159
+ const result = await handleBootstrapIntercept(makeParams());
160
+
161
+ expect(result).toEqual({
162
+ accepted: true,
163
+ duplicate: false,
164
+ eventId: "event-1",
165
+ verificationOutcome: "bootstrap_unavailable",
166
+ });
167
+ expect(gatewaySessions.calls.bindSessionIdentity).toHaveLength(0);
168
+ expect(gatewaySessions.calls.create).toHaveLength(0);
169
+ expect(telegramReplies).toHaveLength(1);
170
+ expect(telegramReplies[0].text).toContain("tap the link again");
171
+ });
172
+
173
+ test("gateway unreachable on identity bind leaves the session pending_bootstrap and responds unavailable", async () => {
174
+ gatewaySessions.unreachable.bindSessionIdentity = true;
175
+
176
+ const result = await handleBootstrapIntercept(makeParams());
177
+
178
+ expect(result).toMatchObject({
179
+ verificationOutcome: "bootstrap_unavailable",
180
+ });
181
+ // Nothing moved the session out of pending_bootstrap — re-tap retries.
182
+ expect(gatewaySessions.calls.updateSessionStatus).toHaveLength(0);
183
+ expect(gatewaySessions.calls.create).toHaveLength(0);
184
+ expect(telegramReplies).toHaveLength(1);
185
+ });
186
+
187
+ test("gateway unreachable on session creation leaves the session pending_bootstrap and responds unavailable", async () => {
188
+ gatewaySessions.unreachable.createOutboundSessionConditional = true;
189
+
190
+ const result = await handleBootstrapIntercept(makeParams());
191
+
192
+ expect(result).toMatchObject({
193
+ verificationOutcome: "bootstrap_unavailable",
194
+ });
195
+ // Bind ran but binding never changes status, so the token is still
196
+ // resolvable and the deep link remains retryable.
197
+ expect(gatewaySessions.calls.bindSessionIdentity).toHaveLength(1);
198
+ expect(gatewaySessions.calls.updateSessionStatus).toHaveLength(0);
199
+ expect(gatewaySessions.calls.updateSessionDelivery).toHaveLength(0);
200
+ expect(telegramReplies).toHaveLength(1);
201
+ });
202
+
203
+ test("ACL-threaded session skips the second gateway lookup and completes the handoff", async () => {
204
+ const result = await handleBootstrapIntercept(
205
+ makeParams({
206
+ validatedBootstrapSession: {
207
+ id: "bootstrap-session-1",
208
+ channel: "telegram",
209
+ status: "pending_bootstrap",
210
+ } as unknown as VerificationSessionWire,
211
+ }),
212
+ );
213
+
214
+ expect(result).toMatchObject({ verificationOutcome: "bootstrap_bound" });
215
+ expect(gatewaySessions.calls.resolveBootstrapToken).toHaveLength(0);
216
+ expect(gatewaySessions.calls.bindSessionIdentity).toEqual([
217
+ ["bootstrap-session-1", "user-42", "chat-123"],
218
+ ]);
219
+ });
220
+
221
+ test("ACL-threaded session with a failing handoff still returns the handled unavailable response", async () => {
222
+ gatewaySessions.unreachable.bindSessionIdentity = true;
223
+
224
+ const result = await handleBootstrapIntercept(
225
+ makeParams({
226
+ validatedBootstrapSession: {
227
+ id: "bootstrap-session-1",
228
+ channel: "telegram",
229
+ status: "pending_bootstrap",
230
+ } as unknown as VerificationSessionWire,
231
+ }),
232
+ );
233
+
234
+ expect(result).toMatchObject({
235
+ verificationOutcome: "bootstrap_unavailable",
236
+ });
237
+ expect(gatewaySessions.calls.resolveBootstrapToken).toHaveLength(0);
238
+ expect(telegramReplies).toHaveLength(1);
239
+ });
240
+
241
+ test("losing the concurrent claim race returns a handled response without a second code", async () => {
242
+ gatewaySessions.state.conflictReason = "source_session_not_pending";
243
+
244
+ const result = await handleBootstrapIntercept(makeParams());
245
+
246
+ // The winner already sent its code; the loser must not mint, reply, or
247
+ // touch delivery tracking — and must not fall through.
248
+ expect(result).toEqual({
249
+ accepted: true,
250
+ duplicate: false,
251
+ eventId: "event-1",
252
+ verificationOutcome: "bootstrap_already_claimed",
253
+ });
254
+ expect(gatewaySessions.calls.create).toHaveLength(1);
255
+ expect(gatewaySessions.calls.updateSessionDelivery).toHaveLength(0);
256
+ expect(telegramReplies).toHaveLength(0);
257
+ });
258
+
259
+ test("delivery-tracking failure after the code is sent does not unwind the bootstrap", async () => {
260
+ gatewaySessions.unreachable.updateSessionDelivery = true;
261
+
262
+ const result = await handleBootstrapIntercept(makeParams());
263
+
264
+ expect(result).toMatchObject({ verificationOutcome: "bootstrap_bound" });
265
+ });
266
+ });
@@ -11,16 +11,19 @@
11
11
  * Extracted from inbound-message-handler.ts to keep the top-level handler
12
12
  * focused on orchestration.
13
13
  */
14
- import type { ChannelId } from "../../../channels/types.js";
15
- import { sendTelegramReply } from "../../../messaging/providers/telegram-bot/send.js";
16
- import { getLogger } from "../../../util/logger.js";
14
+ import type {
15
+ CreateOutboundSessionResult,
16
+ VerificationSessionWire,
17
+ } from "../../../channels/gateway-verification-sessions.js";
17
18
  import {
18
19
  bindSessionIdentity,
19
- createOutboundSession,
20
+ createOutboundSessionConditional,
20
21
  resolveBootstrapToken,
21
22
  updateSessionDelivery,
22
- updateSessionStatus,
23
- } from "../../channel-verification-service.js";
23
+ } from "../../../channels/gateway-verification-sessions.js";
24
+ import type { ChannelId } from "../../../channels/types.js";
25
+ import { sendTelegramReply } from "../../../messaging/providers/telegram-bot/send.js";
26
+ import { getLogger } from "../../../util/logger.js";
24
27
  import { RESEND_COOLDOWN_MS } from "../../verification-outbound-actions.js";
25
28
  import {
26
29
  composeVerificationTelegram,
@@ -41,6 +44,40 @@ export interface BootstrapInterceptParams {
41
44
  sourceChannel: ChannelId;
42
45
  conversationExternalId: string;
43
46
  eventId: string;
47
+ /**
48
+ * Session already resolved by ACL enforcement for this token. When set,
49
+ * the admission floor was skipped on its strength; this stage reuses it
50
+ * instead of re-resolving via the gateway.
51
+ */
52
+ validatedBootstrapSession?: VerificationSessionWire;
53
+ }
54
+
55
+ const BOOTSTRAP_UNAVAILABLE_REPLY =
56
+ "I couldn't process your verification link just now. Please tap the link again in a moment.";
57
+
58
+ /**
59
+ * Deterministic handled response for gateway failures mid-bootstrap. ACL may
60
+ * have skipped the admission floor for this token, so a gv_ command must
61
+ * never fall through to normal processing on a transient gateway failure.
62
+ */
63
+ async function respondBootstrapUnavailable(
64
+ conversationExternalId: string,
65
+ eventId: string,
66
+ ): Promise<Record<string, unknown>> {
67
+ try {
68
+ await sendTelegramReply(conversationExternalId, BOOTSTRAP_UNAVAILABLE_REPLY);
69
+ } catch (err) {
70
+ log.error(
71
+ { err, chatId: conversationExternalId },
72
+ "Failed to deliver bootstrap unavailable reply",
73
+ );
74
+ }
75
+ return {
76
+ accepted: true,
77
+ duplicate: false,
78
+ eventId,
79
+ verificationOutcome: "bootstrap_unavailable",
80
+ };
44
81
  }
45
82
 
46
83
  /**
@@ -60,6 +97,7 @@ export async function handleBootstrapIntercept(
60
97
  sourceChannel,
61
98
  conversationExternalId,
62
99
  eventId,
100
+ validatedBootstrapSession,
63
101
  } = params;
64
102
 
65
103
  if (
@@ -72,29 +110,85 @@ export async function handleBootstrapIntercept(
72
110
  return null;
73
111
  }
74
112
 
113
+ // Sessions live in the gateway. When ACL already validated this token it
114
+ // threads the session through — no second lookup. Otherwise resolve here;
115
+ // a gateway failure must never fall through to normal processing (the
116
+ // floor may have been skipped), so degrade to a handled "try again" reply.
75
117
  const bootstrapToken = (commandIntent.payload as string).slice(3);
76
- const bootstrapSession = resolveBootstrapToken(sourceChannel, bootstrapToken);
118
+ let bootstrapSession: VerificationSessionWire | null;
119
+ if (validatedBootstrapSession) {
120
+ bootstrapSession = validatedBootstrapSession;
121
+ } else {
122
+ try {
123
+ bootstrapSession = await resolveBootstrapToken(
124
+ sourceChannel,
125
+ bootstrapToken,
126
+ );
127
+ } catch (err) {
128
+ log.warn(
129
+ { err, sourceChannel },
130
+ "Bootstrap intercept: token resolution failed (gateway unreachable)",
131
+ );
132
+ return respondBootstrapUnavailable(conversationExternalId, eventId);
133
+ }
134
+ }
77
135
 
78
136
  if (!bootstrapSession || bootstrapSession.status !== "pending_bootstrap") {
79
- // Not found or expired — fall through to normal /start handling
137
+ // Not found or expired — fall through to normal /start handling. Only
138
+ // reachable when ACL did not validate the token (a threaded session is
139
+ // always pending_bootstrap), so the admission floor already ran.
80
140
  return null;
81
141
  }
82
142
 
83
- // Bind the pending_bootstrap session to the sender's identity
84
- bindSessionIdentity(bootstrapSession.id, rawSenderId, conversationExternalId);
143
+ let minted: Awaited<ReturnType<typeof createOutboundSessionConditional>>;
144
+ try {
145
+ // Bind the pending_bootstrap session to the sender's identity. Binding
146
+ // leaves status untouched, so a failure anywhere before the mint keeps
147
+ // the token resolvable and the deep link retryable.
148
+ await bindSessionIdentity(
149
+ bootstrapSession.id,
150
+ rawSenderId,
151
+ conversationExternalId,
152
+ );
85
153
 
86
- // Transition bootstrap session to awaiting_response
87
- updateSessionStatus(bootstrapSession.id, "awaiting_response");
154
+ // Mint the identity-bound replacement with a fresh secret. The gateway
155
+ // revokes the bootstrap session in the same call, so a successful mint
156
+ // is what consumes the token — no separate status transition needed.
157
+ // requireSourceSessionPending makes the claim atomic gateway-side: if a
158
+ // concurrent /start for the same deep link already minted (revoking the
159
+ // bootstrap session), this call conflicts instead of revoking the
160
+ // winner's freshly sent code.
161
+ minted = await createOutboundSessionConditional({
162
+ channel: sourceChannel,
163
+ expectedExternalUserId: rawSenderId,
164
+ expectedChatId: conversationExternalId,
165
+ identityBindingStatus: "bound",
166
+ destinationAddress: conversationExternalId,
167
+ requireSourceSessionPending: bootstrapSession.id,
168
+ });
169
+ } catch (err) {
170
+ log.warn(
171
+ { err, sourceChannel, sessionId: bootstrapSession.id },
172
+ "Bootstrap intercept: session handoff failed (gateway unreachable)",
173
+ );
174
+ return respondBootstrapUnavailable(conversationExternalId, eventId);
175
+ }
88
176
 
89
- // Create a new identity-bound outbound session with a fresh secret.
90
- // The old bootstrap session is auto-revoked by createOutboundSession.
91
- const newSession = createOutboundSession({
92
- channel: sourceChannel,
93
- expectedExternalUserId: rawSenderId,
94
- expectedChatId: conversationExternalId,
95
- identityBindingStatus: "bound",
96
- destinationAddress: conversationExternalId,
97
- });
177
+ if ("conflict" in minted) {
178
+ // A concurrent /start already claimed this token and sent its code —
179
+ // handled response, no new mint, no reply (the winner's code stands).
180
+ log.info(
181
+ { sourceChannel, sessionId: bootstrapSession.id, reason: minted.reason },
182
+ "Bootstrap intercept: token already claimed by a concurrent handoff",
183
+ );
184
+ return {
185
+ accepted: true,
186
+ duplicate: false,
187
+ eventId,
188
+ verificationOutcome: "bootstrap_already_claimed",
189
+ };
190
+ }
191
+ const newSession: CreateOutboundSessionResult = minted;
98
192
 
99
193
  // Compose and send the verification prompt via Telegram
100
194
  const telegramBody = composeVerificationTelegram(
@@ -114,9 +208,21 @@ export async function handleBootstrapIntercept(
114
208
  canonicalAssistantId,
115
209
  );
116
210
 
117
- // Update delivery tracking
211
+ // Update delivery tracking (best-effort — the code is already on its way)
118
212
  const now = Date.now();
119
- updateSessionDelivery(newSession.sessionId, now, 1, now + RESEND_COOLDOWN_MS);
213
+ try {
214
+ await updateSessionDelivery(
215
+ newSession.sessionId,
216
+ now,
217
+ 1,
218
+ now + RESEND_COOLDOWN_MS,
219
+ );
220
+ } catch (err) {
221
+ log.error(
222
+ { err, sessionId: newSession.sessionId },
223
+ "Bootstrap intercept: failed to update session delivery tracking",
224
+ );
225
+ }
120
226
 
121
227
  return ({
122
228
  accepted: true,