@vellumai/assistant 0.10.8 → 0.10.9-dev.202607152225.ec6fdbf

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 (1453) hide show
  1. package/AGENTS.md +4 -0
  2. package/ARCHITECTURE.md +52 -88
  3. package/README.md +14 -35
  4. package/docs/activation-funnel-telemetry.md +20 -18
  5. package/docs/architecture/scheduling.md +0 -86
  6. package/docs/runbook-trusted-contacts.md +19 -19
  7. package/docs/trusted-contact-access.md +70 -69
  8. package/docs/workspace-tools.md +4 -2
  9. package/eslint-rules/__tests__/cli-no-daemon-internals.test.ts +62 -360
  10. package/eslint-rules/cli-no-daemon-internals.js +91 -275
  11. package/eslint.config.mjs +4 -4
  12. package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/package.json +1 -0
  13. package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/__tests__/redacted-credential.test.ts +200 -0
  14. package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/redacted-credential.ts +226 -0
  15. package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/package.json +1 -0
  16. package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/__tests__/redacted-credential.test.ts +200 -0
  17. package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/redacted-credential.ts +226 -0
  18. package/node_modules/@vellumai/gateway-client/src/__tests__/guardian-request-contract.test.ts +575 -0
  19. package/node_modules/@vellumai/gateway-client/src/gateway-ipc-contracts.ts +20 -0
  20. package/node_modules/@vellumai/gateway-client/src/guardian-request-contract.ts +687 -0
  21. package/node_modules/@vellumai/gateway-client/src/index.ts +82 -0
  22. package/node_modules/@vellumai/service-contracts/package.json +1 -0
  23. package/node_modules/@vellumai/service-contracts/src/__tests__/redacted-credential.test.ts +200 -0
  24. package/node_modules/@vellumai/service-contracts/src/redacted-credential.ts +226 -0
  25. package/openapi.yaml +353 -742
  26. package/package.json +2 -2
  27. package/scripts/build-test-fixtures.ts +3 -2
  28. package/scripts/test.ts +2 -7
  29. package/src/__tests__/activation-early-marking.test.ts +1 -8
  30. package/src/__tests__/actor-token-service.test.ts +0 -7
  31. package/src/__tests__/add-message-preassigned-id.test.ts +1 -1
  32. package/src/__tests__/add-message-skip-indexing.test.ts +164 -0
  33. package/src/__tests__/agent-image-optimize.test.ts +104 -1
  34. package/src/__tests__/agent-loop-callsite-precedence.test.ts +5 -15
  35. package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +0 -6
  36. package/src/__tests__/agent-loop-override-profile.test.ts +48 -50
  37. package/src/__tests__/agent-loop-pushes-post-hook-prompt.test.ts +4 -17
  38. package/src/__tests__/agent-loop-set-system-prompt.test.ts +3 -14
  39. package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +0 -4
  40. package/src/__tests__/agent-wake-override-profile.test.ts +40 -71
  41. package/src/__tests__/always-loaded-tools-guard.test.ts +4 -7
  42. package/src/__tests__/annotate-activity-metadata.test.ts +4 -31
  43. package/src/__tests__/annotate-risk-options.test.ts +4 -31
  44. package/src/__tests__/anthropic-provider.test.ts +11 -0
  45. package/src/__tests__/app-asset-bytes.test.ts +72 -0
  46. package/src/__tests__/app-builder-tool-scripts.test.ts +0 -1
  47. package/src/__tests__/app-bundler.test.ts +4 -20
  48. package/src/__tests__/app-conversation-ids-backfill.test.ts +1 -8
  49. package/src/__tests__/app-executors.test.ts +2 -49
  50. package/src/__tests__/app-routes-csp.test.ts +126 -157
  51. package/src/__tests__/approval-cascade.test.ts +0 -82
  52. package/src/__tests__/approval-interception-trust-gates.test.ts +0 -7
  53. package/src/__tests__/approval-primitive.test.ts +1 -9
  54. package/src/__tests__/approval-routes-http.test.ts +5 -63
  55. package/src/__tests__/assistant-event-hub-machine-name.test.ts +1 -19
  56. package/src/__tests__/assistant-events-sse-hardening.test.ts +4 -21
  57. package/src/__tests__/attachment-stored-path-annotation.test.ts +1 -19
  58. package/src/__tests__/attachment-upload-trusted-source.test.ts +0 -13
  59. package/src/__tests__/attachments-store-heic-normalize.test.ts +0 -13
  60. package/src/__tests__/attachments-store.test.ts +5 -19
  61. package/src/__tests__/audit-log-rotation.test.ts +1 -9
  62. package/src/__tests__/auth-fallback-events-store.test.ts +43 -59
  63. package/src/__tests__/available-skills.test.ts +7 -15
  64. package/src/__tests__/avatar-e2e.test.ts +0 -19
  65. package/src/__tests__/avatar-generator.test.ts +0 -9
  66. package/src/__tests__/background-shell-bash.test.ts +0 -20
  67. package/src/__tests__/background-shell-host-bash.test.ts +0 -34
  68. package/src/__tests__/background-workers-disk-pressure.test.ts +1 -43
  69. package/src/__tests__/browser-fill-credential.test.ts +0 -7
  70. package/src/__tests__/browser-manager.test.ts +1 -8
  71. package/src/__tests__/browser-skill-endstate.test.ts +1 -5
  72. package/src/__tests__/btw-routes.test.ts +7 -30
  73. package/src/__tests__/build-persisted-content.test.ts +96 -29
  74. package/src/__tests__/bundle-scanner.test.ts +27 -1
  75. package/src/__tests__/call-controller.test.ts +96 -149
  76. package/src/__tests__/call-conversation-messages.test.ts +2 -9
  77. package/src/__tests__/call-domain.test.ts +21 -56
  78. package/src/__tests__/call-pointer-message-composer.test.ts +0 -8
  79. package/src/__tests__/call-pointer-messages.test.ts +1 -8
  80. package/src/__tests__/call-recovery.test.ts +4 -11
  81. package/src/__tests__/call-routes-http.test.ts +12 -47
  82. package/src/__tests__/call-site-routing-provider.test.ts +5 -16
  83. package/src/__tests__/call-start-guardian-guard.test.ts +0 -10
  84. package/src/__tests__/call-state.test.ts +1 -8
  85. package/src/__tests__/call-store.test.ts +4 -11
  86. package/src/__tests__/cancel-resolves-conversation-key.test.ts +0 -32
  87. package/src/__tests__/catalog-cache.test.ts +0 -8
  88. package/src/__tests__/catalog-files.test.ts +0 -8
  89. package/src/__tests__/catalog-install-normalize.test.ts +0 -7
  90. package/src/__tests__/ces-rpc-credential-backend.test.ts +0 -7
  91. package/src/__tests__/channel-approval-routes.test.ts +23 -34
  92. package/src/__tests__/channel-approvals.test.ts +0 -7
  93. package/src/__tests__/channel-delivery-store.test.ts +6 -17
  94. package/src/__tests__/channel-guardian.test.ts +0 -7
  95. package/src/__tests__/channel-inbound-disk-pressure.test.ts +15 -20
  96. package/src/__tests__/channel-readiness-routes.test.ts +41 -67
  97. package/src/__tests__/channel-readiness-service.test.ts +13 -45
  98. package/src/__tests__/channel-readiness-slack-remote.test.ts +5 -22
  99. package/src/__tests__/channel-reply-delivery.test.ts +18 -5
  100. package/src/__tests__/channel-retry-sweep.test.ts +0 -7
  101. package/src/__tests__/chat-credential-redaction.test.ts +1395 -0
  102. package/src/__tests__/chat-reveal-guard-priming.test.ts +791 -0
  103. package/src/__tests__/checker.test.ts +0 -24
  104. package/src/__tests__/clawhub-files.test.ts +0 -8
  105. package/src/__tests__/clawhub.test.ts +0 -7
  106. package/src/__tests__/clear-all-lexical.test.ts +0 -6
  107. package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +3 -0
  108. package/src/__tests__/client-os-metadata-persistence.test.ts +0 -5
  109. package/src/__tests__/compaction-events.test.ts +26 -99
  110. package/src/__tests__/compaction-ledger-store.test.ts +1 -7
  111. package/src/__tests__/compaction-summary-head-persisted-count.test.ts +0 -27
  112. package/src/__tests__/compaction-trail-store.test.ts +1 -19
  113. package/src/__tests__/compaction.benchmark.test.ts +2 -6
  114. package/src/__tests__/compactor-call-site-logging.test.ts +0 -21
  115. package/src/__tests__/compactor-fixed-boundary.test.ts +0 -21
  116. package/src/__tests__/compactor-image-manifest-trust.test.ts +1 -10
  117. package/src/__tests__/compactor-low-watermark-cut.test.ts +0 -21
  118. package/src/__tests__/compactor-media-strip.test.ts +0 -21
  119. package/src/__tests__/compactor-preserved-tail-count.test.ts +0 -21
  120. package/src/__tests__/compactor-summary-call-truncation.test.ts +0 -21
  121. package/src/__tests__/compactor-web-search-strip.test.ts +0 -21
  122. package/src/__tests__/config-get-vision-flag.test.ts +24 -53
  123. package/src/__tests__/config-loader-backfill.test.ts +9 -25
  124. package/src/__tests__/config-loader-platform-defaults.test.ts +0 -21
  125. package/src/__tests__/config-schema-cmd.test.ts +10 -11
  126. package/src/__tests__/config-schema.test.ts +221 -275
  127. package/src/__tests__/config-set-route.test.ts +32 -62
  128. package/src/__tests__/config-watcher-cleanup-throttle.test.ts +44 -83
  129. package/src/__tests__/config-watcher-skill-reseed.test.ts +0 -16
  130. package/src/__tests__/config-watcher.test.ts +2 -17
  131. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +57 -63
  132. package/src/__tests__/contact-store-interaction-info.test.ts +1 -8
  133. package/src/__tests__/contact-store-user-file.test.ts +1 -8
  134. package/src/__tests__/contacts-tools.test.ts +21 -26
  135. package/src/__tests__/contacts-write.test.ts +1 -8
  136. package/src/__tests__/context-search-memory-v2-source.test.ts +0 -6
  137. package/src/__tests__/context-window-manager-compact-retry.test.ts +0 -27
  138. package/src/__tests__/context-window-manager-overflow-rung.test.ts +0 -21
  139. package/src/__tests__/conversation-abort-tool-results.test.ts +9 -90
  140. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +5 -41
  141. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +16 -54
  142. package/src/__tests__/conversation-agent-loop-overflow.test.ts +14 -79
  143. package/src/__tests__/conversation-agent-loop.test.ts +213 -136
  144. package/src/__tests__/conversation-app-control-instantiation.test.ts +10 -16
  145. package/src/__tests__/conversation-app-control-lifecycle.test.ts +0 -43
  146. package/src/__tests__/conversation-attachments.test.ts +0 -17
  147. package/src/__tests__/conversation-attention-store.test.ts +1 -9
  148. package/src/__tests__/conversation-attention-telegram.test.ts +0 -8
  149. package/src/__tests__/conversation-clear-safety.test.ts +20 -20
  150. package/src/__tests__/conversation-confirmation-signals.test.ts +0 -82
  151. package/src/__tests__/conversation-crud-enabled-plugins.test.ts +1 -7
  152. package/src/__tests__/conversation-crud-inference-profile.test.ts +1 -7
  153. package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +0 -7
  154. package/src/__tests__/conversation-disk-view-integration.test.ts +1 -26
  155. package/src/__tests__/conversation-disk-view.test.ts +1 -26
  156. package/src/__tests__/conversation-enabledplugins-route.test.ts +3 -21
  157. package/src/__tests__/conversation-error.test.ts +21 -7
  158. package/src/__tests__/conversation-fork-crud.test.ts +35 -44
  159. package/src/__tests__/conversation-fork-retrospective.test.ts +9 -24
  160. package/src/__tests__/conversation-fork-route.test.ts +0 -32
  161. package/src/__tests__/conversation-history-web-search.test.ts +20 -17
  162. package/src/__tests__/conversation-inference-profile-list.test.ts +0 -17
  163. package/src/__tests__/conversation-inference-profile-route.test.ts +2 -24
  164. package/src/__tests__/conversation-init.benchmark.test.ts +3 -56
  165. package/src/__tests__/conversation-key-store-disk-view.test.ts +1 -33
  166. package/src/__tests__/conversation-lifecycle.test.ts +63 -103
  167. package/src/__tests__/conversation-list-source.test.ts +0 -18
  168. package/src/__tests__/conversation-load-history-repair.test.ts +39 -91
  169. package/src/__tests__/conversation-load-history-stripped.test.ts +12 -57
  170. package/src/__tests__/conversation-loop-db-lock-resilience.test.ts +10 -20
  171. package/src/__tests__/conversation-message-id-uuidv7.test.ts +1 -18
  172. package/src/__tests__/conversation-pairing.test.ts +0 -7
  173. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +0 -9
  174. package/src/__tests__/conversation-process-callsite.test.ts +15 -97
  175. package/src/__tests__/conversation-provider-retry-repair.test.ts +3 -84
  176. package/src/__tests__/conversation-queue.test.ts +12 -108
  177. package/src/__tests__/conversation-routes-disk-view.test.ts +8 -60
  178. package/src/__tests__/conversation-routes-enabled-plugins.test.ts +5 -63
  179. package/src/__tests__/conversation-routes-guardian-reply.test.ts +13 -22
  180. package/src/__tests__/conversation-routes-hidden-queue.test.ts +5 -64
  181. package/src/__tests__/conversation-routes-slash-commands.test.ts +19 -87
  182. package/src/__tests__/conversation-runtime-assembly.test.ts +34 -37
  183. package/src/__tests__/conversation-seed-composer.test.ts +3 -3
  184. package/src/__tests__/conversation-skill-tools.test.ts +19 -32
  185. package/src/__tests__/conversation-slash-queue.test.ts +3 -90
  186. package/src/__tests__/conversation-slash-unknown.test.ts +0 -87
  187. package/src/__tests__/conversation-speed-override.test.ts +19 -94
  188. package/src/__tests__/conversation-starter-routes.test.ts +0 -7
  189. package/src/__tests__/conversation-store.test.ts +72 -66
  190. package/src/__tests__/conversation-summarize-route.test.ts +0 -11
  191. package/src/__tests__/conversation-summarize-up-to.test.ts +4 -89
  192. package/src/__tests__/conversation-surfaces-action-delivery.test.ts +131 -0
  193. package/src/__tests__/conversation-surfaces-activation-emit.test.ts +36 -36
  194. package/src/__tests__/conversation-surfaces-data-persist.test.ts +4 -2
  195. package/src/__tests__/conversation-title-service.test.ts +0 -7
  196. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +0 -1
  197. package/src/__tests__/conversation-tool-setup-attribution.test.ts +37 -60
  198. package/src/__tests__/conversation-tool-setup-tools-disabled.test.ts +17 -17
  199. package/src/__tests__/conversation-unread-route.test.ts +0 -7
  200. package/src/__tests__/conversation-usage.test.ts +21 -71
  201. package/src/__tests__/conversation-wait-for-idle.test.ts +0 -82
  202. package/src/__tests__/conversation-workspace-cache-state.test.ts +0 -45
  203. package/src/__tests__/conversation-workspace-injection.test.ts +0 -88
  204. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +0 -88
  205. package/src/__tests__/conversations-defer-cli.test.ts +3 -0
  206. package/src/__tests__/conversations-import-system-filter.test.ts +0 -17
  207. package/src/__tests__/credential-broker-browser-fill.test.ts +0 -9
  208. package/src/__tests__/credential-broker-server-use.test.ts +0 -9
  209. package/src/__tests__/credential-health-service.test.ts +14 -31
  210. package/src/__tests__/credential-metadata-store.test.ts +0 -8
  211. package/src/__tests__/credential-prompt-route.test.ts +9 -15
  212. package/src/__tests__/credential-resolve.test.ts +0 -8
  213. package/src/__tests__/credential-routes.test.ts +250 -0
  214. package/src/__tests__/credential-security-invariants.test.ts +4 -8
  215. package/src/__tests__/credential-token-resolver.test.ts +0 -9
  216. package/src/__tests__/cross-provider-web-search.test.ts +12 -18
  217. package/src/__tests__/daemon-assistant-events.test.ts +1 -9
  218. package/src/__tests__/daemon-credential-client.test.ts +0 -7
  219. package/src/__tests__/db-conversation-fork-lineage-migration.test.ts +1 -8
  220. package/src/__tests__/db-conversation-inference-profile-migration.test.ts +1 -7
  221. package/src/__tests__/db-llm-request-log-provider-migration.test.ts +0 -8
  222. package/src/__tests__/db-readiness-http-gate.test.ts +0 -18
  223. package/src/__tests__/db-rename-inference-profile-snake-case-migration.test.ts +1 -7
  224. package/src/__tests__/db-test-helpers.ts +10 -3
  225. package/src/__tests__/delete-managed-skill-tool.test.ts +0 -7
  226. package/src/__tests__/delete-propagation.test.ts +0 -7
  227. package/src/__tests__/deterministic-verification-control-plane.test.ts +0 -7
  228. package/src/__tests__/device-id.test.ts +1 -9
  229. package/src/__tests__/disk-pressure-guard.test.ts +0 -4
  230. package/src/__tests__/disk-pressure-routes.test.ts +0 -4
  231. package/src/__tests__/disk-pressure-tools.test.ts +4 -42
  232. package/src/__tests__/dm-backfill.test.ts +0 -7
  233. package/src/__tests__/dm-persistence.test.ts +0 -5
  234. package/src/__tests__/docker-signing-key-bootstrap.test.ts +1 -8
  235. package/src/__tests__/drain-requeue-on-contention.test.ts +1 -8
  236. package/src/__tests__/dynamic-skill-background-guard.test.ts +0 -43
  237. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +2 -27
  238. package/src/__tests__/edit-propagation.test.ts +1 -8
  239. package/src/__tests__/email-invite-adapter.test.ts +8 -33
  240. package/src/__tests__/embedding-managed-proxy-selection.test.ts +0 -8
  241. package/src/__tests__/emit-event-signal.test.ts +1 -1
  242. package/src/__tests__/emit-signal-routing-intent.test.ts +0 -7
  243. package/src/__tests__/empty-state-greeting-cache.test.ts +9 -9
  244. package/src/__tests__/encrypted-store.test.ts +0 -9
  245. package/src/__tests__/ensure-conversation-exists.test.ts +1 -18
  246. package/src/__tests__/events-client-registration.test.ts +1 -19
  247. package/src/__tests__/events-dev-bypass-actor.test.ts +0 -7
  248. package/src/__tests__/events-tail-route.test.ts +1 -8
  249. package/src/__tests__/file-list-tool.test.ts +22 -15
  250. package/src/__tests__/followup-tools.test.ts +1 -16
  251. package/src/__tests__/gateway-only-enforcement.test.ts +3 -44
  252. package/src/__tests__/get-skill-detail-audit.test.ts +0 -7
  253. package/src/__tests__/google-calendar-watcher.test.ts +175 -0
  254. package/src/__tests__/guardian-action-sweep.test.ts +0 -7
  255. package/src/__tests__/guardian-binding-drift-heal.test.ts +0 -7
  256. package/src/__tests__/guardian-card-withdrawal.test.ts +60 -64
  257. package/src/__tests__/guardian-decision-primitive-canonical.test.ts +172 -135
  258. package/src/__tests__/guardian-dispatch.test.ts +58 -157
  259. package/src/__tests__/guardian-expiry-notifier.test.ts +56 -48
  260. package/src/__tests__/guardian-gateway-sim.ts +626 -0
  261. package/src/__tests__/guardian-outbound-http.test.ts +0 -7
  262. package/src/__tests__/guardian-routing-invariants.test.ts +229 -220
  263. package/src/__tests__/guardian-routing-state.test.ts +2 -9
  264. package/src/__tests__/guardian-verification-voice-binding.test.ts +0 -17
  265. package/src/__tests__/guardian-wait-controller.test.ts +44 -43
  266. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +26 -91
  267. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +18 -103
  268. package/src/__tests__/headless-browser-interactions.test.ts +0 -7
  269. package/src/__tests__/headless-browser-mode.test.ts +0 -9
  270. package/src/__tests__/headless-browser-navigate.test.ts +0 -7
  271. package/src/__tests__/headless-browser-read-tools.test.ts +0 -7
  272. package/src/__tests__/headless-browser-snapshot.test.ts +0 -7
  273. package/src/__tests__/heartbeat-disk-pressure.test.ts +9 -38
  274. package/src/__tests__/heartbeat-service.test.ts +83 -106
  275. package/src/__tests__/helpers/channel-test-adapter.ts +10 -0
  276. package/src/__tests__/helpers/gateway-guardian-requests-store-bridge.ts +155 -0
  277. package/src/__tests__/helpers/set-config.ts +40 -0
  278. package/src/__tests__/host-bash-proxy.test.ts +18 -34
  279. package/src/__tests__/host-browser-proxy.test.ts +15 -20
  280. package/src/__tests__/host-shell-tool.test.ts +2 -34
  281. package/src/__tests__/http-conversation-lineage.test.ts +3 -19
  282. package/src/__tests__/http-user-message-parity.test.ts +3 -95
  283. package/src/__tests__/identity-routes.test.ts +1 -9
  284. package/src/__tests__/image-recovery-hook.test.ts +36 -0
  285. package/src/__tests__/inbound-admitted-introduction-nudge.test.ts +6 -12
  286. package/src/__tests__/inbound-invite-redemption.test.ts +0 -7
  287. package/src/__tests__/inbound-slack-persistence.test.ts +0 -5
  288. package/src/__tests__/inbound-trust-verdict.test.ts +2 -8
  289. package/src/__tests__/inference-no-mode-boot-e2e.test.ts +52 -8
  290. package/src/__tests__/inference-profile-reaper.test.ts +1 -7
  291. package/src/__tests__/inference-profile-session-handler.test.ts +4 -30
  292. package/src/__tests__/inference-profile-session-ipc.test.ts +3 -20
  293. package/src/__tests__/ingress-url-consistency.test.ts +1 -23
  294. package/src/__tests__/injector-background-turn.test.ts +10 -24
  295. package/src/__tests__/injector-chain.test.ts +4 -13
  296. package/src/__tests__/injector-pkb-v2-silenced.test.ts +19 -17
  297. package/src/__tests__/inline-command-runner.test.ts +0 -34
  298. package/src/__tests__/inline-skill-load-permissions.test.ts +1 -30
  299. package/src/__tests__/install-skill-routing.test.ts +7 -6
  300. package/src/__tests__/integration-status.test.ts +25 -17
  301. package/src/__tests__/intent-routing.test.ts +1 -50
  302. package/src/__tests__/internal-telemetry-routes.test.ts +41 -22
  303. package/src/__tests__/interrupted-turn-reconciler.test.ts +1 -8
  304. package/src/__tests__/introduction-card-resolver.test.ts +108 -117
  305. package/src/__tests__/invite-redeemed-ipc.test.ts +0 -7
  306. package/src/__tests__/invite-routes-http.test.ts +12 -23
  307. package/src/__tests__/jobs-store-has-pending-job.test.ts +59 -0
  308. package/src/__tests__/jobs-store-qdrant-breaker.test.ts +1 -14
  309. package/src/__tests__/jobs-store-skill-card-upsert.test.ts +191 -0
  310. package/src/__tests__/jobs-store-upsert-debounced.test.ts +1 -14
  311. package/src/__tests__/lexical-index-dual-write.test.ts +0 -6
  312. package/src/__tests__/list-all-apps.test.ts +200 -0
  313. package/src/__tests__/list-messages-attachments.test.ts +11 -20
  314. package/src/__tests__/list-messages-background-tool-completion.test.ts +6 -18
  315. package/src/__tests__/list-messages-client-message-id.test.ts +4 -16
  316. package/src/__tests__/list-messages-hidden-metadata.test.ts +6 -18
  317. package/src/__tests__/list-messages-page-latest.test.ts +3 -19
  318. package/src/__tests__/list-messages-queued.test.ts +1 -18
  319. package/src/__tests__/list-messages-tool-merge.test.ts +7 -18
  320. package/src/__tests__/llm-context-resolution.test.ts +32 -56
  321. package/src/__tests__/llm-context-route-provider.test.ts +1 -8
  322. package/src/__tests__/llm-request-log-agent-loop-exit-reason.test.ts +1 -19
  323. package/src/__tests__/llm-request-log-call-site.test.ts +1 -19
  324. package/src/__tests__/llm-request-log-clickhouse-routing.test.ts +114 -0
  325. package/src/__tests__/llm-request-log-clickhouse-writer-guards.test.ts +108 -0
  326. package/src/__tests__/llm-request-log-disabled-writes.test.ts +11 -30
  327. package/src/__tests__/llm-request-log-sink-clickhouse.test.ts +205 -0
  328. package/src/__tests__/llm-request-log-source-clickhouse.test.ts +1 -22
  329. package/src/__tests__/llm-request-log-source-factory.test.ts +23 -69
  330. package/src/__tests__/llm-request-log-turn-query.test.ts +1 -19
  331. package/src/__tests__/llm-resolver-override-or-default.test.ts +3 -52
  332. package/src/__tests__/llm-resolver.test.ts +342 -602
  333. package/src/__tests__/llm-schema.test.ts +79 -37
  334. package/src/__tests__/llm-usage-store.test.ts +1 -7
  335. package/src/__tests__/log-export-routes.test.ts +0 -7
  336. package/src/__tests__/log-export-workspace.test.ts +0 -7
  337. package/src/__tests__/managed-profile-guard.test.ts +125 -137
  338. package/src/__tests__/managed-skill-lifecycle.test.ts +6 -50
  339. package/src/__tests__/managed-speech-defaults.test.ts +138 -0
  340. package/src/__tests__/managed-store.test.ts +1 -16
  341. package/src/__tests__/mcp-auth-routes.test.ts +15 -26
  342. package/src/__tests__/mcp-config-secret-boundary.test.ts +49 -91
  343. package/src/__tests__/mcp-health-check.test.ts +14 -20
  344. package/src/__tests__/media-generate-image.test.ts +25 -32
  345. package/src/__tests__/media-stream-output.test.ts +0 -9
  346. package/src/__tests__/media-stream-server-integration.test.ts +19 -27
  347. package/src/__tests__/media-stream-stt-session.test.ts +16 -29
  348. package/src/__tests__/memory-jobs-worker-backoff.test.ts +6 -19
  349. package/src/__tests__/memory-jobs-worker-cleanup-cadence.test.ts +33 -12
  350. package/src/__tests__/memory-jobs-worker-lanes.test.ts +10 -29
  351. package/src/__tests__/memory-recall-log-store.test.ts +1 -19
  352. package/src/__tests__/memory-retrieval-hook.test.ts +0 -3
  353. package/src/__tests__/memory-upsert-concurrency.test.ts +12 -35
  354. package/src/__tests__/memory-v2-static-injector.test.ts +5 -17
  355. package/src/__tests__/messages-after-tiebreaker.test.ts +1 -7
  356. package/src/__tests__/messaging-send-tool.test.ts +67 -7
  357. package/src/__tests__/migration-cross-version-compatibility.test.ts +0 -18
  358. package/src/__tests__/migration-export-http.test.ts +10 -23
  359. package/src/__tests__/migration-export-streaming.test.ts +0 -18
  360. package/src/__tests__/migration-export-to-gcs.test.ts +0 -19
  361. package/src/__tests__/migration-import-commit-http.test.ts +11 -23
  362. package/src/__tests__/migration-import-from-gcs.test.ts +0 -19
  363. package/src/__tests__/migration-import-from-url.test.ts +0 -19
  364. package/src/__tests__/migration-import-preflight-http.test.ts +10 -22
  365. package/src/__tests__/migration-jobs-status.test.ts +8 -23
  366. package/src/__tests__/migration-validate-http.test.ts +2 -19
  367. package/src/__tests__/mtime-cache.test.ts +116 -2
  368. package/src/__tests__/native-web-search.test.ts +0 -21
  369. package/src/__tests__/non-member-access-request.test.ts +102 -93
  370. package/src/__tests__/notification-broadcaster.test.ts +32 -21
  371. package/src/__tests__/notification-candidate-guardian-context.test.ts +36 -34
  372. package/src/__tests__/notification-decision-fallback.test.ts +0 -7
  373. package/src/__tests__/notification-decision-identity.test.ts +0 -7
  374. package/src/__tests__/notification-decision-recipient-context.test.ts +0 -7
  375. package/src/__tests__/notification-deep-link.test.ts +0 -7
  376. package/src/__tests__/notification-guardian-path.test.ts +48 -93
  377. package/src/__tests__/notification-platform-adapter.test.ts +0 -7
  378. package/src/__tests__/notification-routing-intent.test.ts +1 -9
  379. package/src/__tests__/notification-schedule-notify-dedup.test.ts +1 -9
  380. package/src/__tests__/notification-telegram-adapter.test.ts +0 -7
  381. package/src/__tests__/oauth-cli.test.ts +0 -19
  382. package/src/__tests__/oauth-commands-routes.test.ts +28 -43
  383. package/src/__tests__/oauth-connect-orchestrator.test.ts +17 -26
  384. package/src/__tests__/oauth-connect-routes.test.ts +19 -18
  385. package/src/__tests__/oauth-provider-profiles.test.ts +3 -9
  386. package/src/__tests__/oauth-provider-visibility.test.ts +0 -7
  387. package/src/__tests__/oauth-store.test.ts +0 -7
  388. package/src/__tests__/oauth2-gateway-transport.test.ts +41 -43
  389. package/src/__tests__/openai-responses-prompt-cache.test.ts +355 -0
  390. package/src/__tests__/openai-responses-provider.test.ts +98 -9
  391. package/src/__tests__/openrouter-responses-transport.test.ts +170 -0
  392. package/src/__tests__/outbound-slack-persistence.test.ts +13 -46
  393. package/src/__tests__/outlook-email-watcher.test.ts +0 -9
  394. package/src/__tests__/outlook-messaging-provider.test.ts +71 -0
  395. package/src/__tests__/path-policy.test.ts +0 -7
  396. package/src/__tests__/persist-media-references.test.ts +1 -6
  397. package/src/__tests__/persist-unsendable-image-downscale.test.ts +6 -3
  398. package/src/__tests__/persist-unsendable-image.test.ts +39 -7
  399. package/src/__tests__/persistence-secret-redaction.test.ts +7 -28
  400. package/src/__tests__/platform-bash-auto-approve.test.ts +0 -46
  401. package/src/__tests__/platform-callback-registration.test.ts +10 -9
  402. package/src/__tests__/platform-proxy-context.test.ts +0 -8
  403. package/src/__tests__/playbook-execution.test.ts +0 -14
  404. package/src/__tests__/playbook-tools.test.ts +0 -14
  405. package/src/__tests__/plugin-api-model-profiles.test.ts +12 -35
  406. package/src/__tests__/plugin-app-serve-routes.test.ts +315 -0
  407. package/src/__tests__/plugin-import-boundary-guard.test.ts +5 -3
  408. package/src/__tests__/plugin-import-boundary-reverse-guard.test.ts +0 -2
  409. package/src/__tests__/plugin-types.test.ts +0 -7
  410. package/src/__tests__/prechat-onboarding-contract.test.ts +0 -27
  411. package/src/__tests__/pricing.test.ts +45 -0
  412. package/src/__tests__/process-message-background-slack.test.ts +7 -21
  413. package/src/__tests__/process-message-display-content.test.ts +37 -6
  414. package/src/__tests__/processing-flag-persist-failure.test.ts +0 -44
  415. package/src/__tests__/provider-commit-message-generator.test.ts +57 -63
  416. package/src/__tests__/provider-error-scenarios.test.ts +5 -6
  417. package/src/__tests__/provider-platform-proxy-integration.test.ts +21 -57
  418. package/src/__tests__/provider-registry-ollama.test.ts +8 -18
  419. package/src/__tests__/provider-send-message-override-profile.test.ts +28 -39
  420. package/src/__tests__/provider-streaming.benchmark.test.ts +1 -6
  421. package/src/__tests__/provider-usage-tracking.test.ts +13 -35
  422. package/src/__tests__/proxy-approval-callback.test.ts +0 -16
  423. package/src/__tests__/prune-old-conversations-job.test.ts +29 -21
  424. package/src/__tests__/prune-old-tool-invocations-job.test.ts +1 -9
  425. package/src/__tests__/public-ingress-urls.test.ts +1 -24
  426. package/src/__tests__/published-app-updater.test.ts +22 -16
  427. package/src/__tests__/qdrant-collection-migration.test.ts +0 -7
  428. package/src/__tests__/qdrant-manager.test.ts +0 -8
  429. package/src/__tests__/ratelimit.test.ts +1 -8
  430. package/src/__tests__/reaction-persistence.test.ts +18 -24
  431. package/src/__tests__/rebuild-index-graph-nodes.test.ts +0 -14
  432. package/src/__tests__/recording-handler.test.ts +0 -27
  433. package/src/__tests__/request-secret-standalone-channel-gate.test.ts +4 -16
  434. package/src/__tests__/require-fresh-approval.test.ts +0 -45
  435. package/src/__tests__/retry-openrouter-only-normalization.test.ts +24 -36
  436. package/src/__tests__/retry-prompt-cache-key.test.ts +123 -0
  437. package/src/__tests__/retry-thinking-adaptive-only.test.ts +45 -61
  438. package/src/__tests__/retry-thinking-tool-choice.test.ts +60 -80
  439. package/src/__tests__/retry-verbosity-normalization.test.ts +27 -37
  440. package/src/__tests__/reveal-success-registry.test.ts +123 -0
  441. package/src/__tests__/run-conversation-turn-persistence.test.ts +113 -0
  442. package/src/__tests__/{scheduler-worker-standdown.test.ts → run-due-schedules.test.ts} +5 -77
  443. package/src/__tests__/runtime-attachment-metadata.test.ts +5 -18
  444. package/src/__tests__/runtime-events-sse-bilingual.test.ts +1 -19
  445. package/src/__tests__/runtime-events-sse-parity.test.ts +1 -20
  446. package/src/__tests__/runtime-events-sse-reconnect.test.ts +1 -19
  447. package/src/__tests__/runtime-events-sse.test.ts +1 -20
  448. package/src/__tests__/scaffold-managed-skill-tool.test.ts +306 -5
  449. package/src/__tests__/schedule-retry.test.ts +22 -23
  450. package/src/__tests__/schedule-routes-workflow-validation.test.ts +18 -42
  451. package/src/__tests__/schedule-routes.test.ts +2 -150
  452. package/src/__tests__/schedule-store.test.ts +0 -8
  453. package/src/__tests__/schedule-tools.test.ts +1 -16
  454. package/src/__tests__/scheduler-disk-pressure.test.ts +0 -26
  455. package/src/__tests__/scheduler-recurrence.test.ts +43 -76
  456. package/src/__tests__/scheduler-reuse-conversation.test.ts +19 -35
  457. package/src/__tests__/scheduler-wake.test.ts +8 -24
  458. package/src/__tests__/scoped-approval-grants.test.ts +1 -9
  459. package/src/__tests__/scoped-grant-security-matrix.test.ts +1 -9
  460. package/src/__tests__/search-skills-unified.test.ts +0 -6
  461. package/src/__tests__/secret-allowlist.test.ts +1 -8
  462. package/src/__tests__/secret-fixtures.ts +9 -0
  463. package/src/__tests__/secret-ingress-channel.test.ts +4 -32
  464. package/src/__tests__/secret-ingress-cli.test.ts +3 -37
  465. package/src/__tests__/secret-ingress-http.test.ts +15 -78
  466. package/src/__tests__/secret-ingress.test.ts +14 -31
  467. package/src/__tests__/secret-prompt-log-hygiene.test.ts +4 -10
  468. package/src/__tests__/secret-prompter-channel-fallback.test.ts +3 -9
  469. package/src/__tests__/secret-routes-platform-proxy.test.ts +3 -40
  470. package/src/__tests__/secure-keys-managed-failover.test.ts +0 -7
  471. package/src/__tests__/secure-keys.test.ts +0 -9
  472. package/src/__tests__/send-endpoint-busy.test.ts +47 -91
  473. package/src/__tests__/sequence-store.test.ts +0 -9
  474. package/src/__tests__/server-history-render.test.ts +29 -8
  475. package/src/__tests__/set-permission-mode.test.ts +8 -16
  476. package/src/__tests__/settings-routes.test.ts +0 -7
  477. package/src/__tests__/shell-credential-ref.test.ts +0 -18
  478. package/src/__tests__/shell-observability.test.ts +0 -21
  479. package/src/__tests__/shell-tool-proxy-mode.test.ts +0 -34
  480. package/src/__tests__/skill-load-feature-flag.test.ts +0 -27
  481. package/src/__tests__/skill-load-inline-command.test.ts +0 -25
  482. package/src/__tests__/skill-load-inline-includes.test.ts +0 -25
  483. package/src/__tests__/skill-load-plugin-scope.test.ts +0 -24
  484. package/src/__tests__/skill-projection-feature-flag.test.ts +14 -33
  485. package/src/__tests__/skill-projection.benchmark.test.ts +14 -19
  486. package/src/__tests__/skill-script-runner-sandbox.test.ts +1 -39
  487. package/src/__tests__/skills-file-content-endpoint.test.ts +0 -7
  488. package/src/__tests__/skills-files-catalog-fallback.test.ts +0 -14
  489. package/src/__tests__/slack-channel-config.test.ts +24 -79
  490. package/src/__tests__/slack-inbound-verification.test.ts +5 -13
  491. package/src/__tests__/{slack-reaction-canonical-approval.test.ts → slack-reaction-guardian-approval.test.ts} +18 -74
  492. package/src/__tests__/slack-share-routes.test.ts +0 -1
  493. package/src/__tests__/slim-skill-category.test.ts +0 -14
  494. package/src/__tests__/stale-approval-dedup.test.ts +0 -7
  495. package/src/__tests__/subagent-call-site-routing.test.ts +72 -111
  496. package/src/__tests__/subagent-detail.test.ts +1 -1
  497. package/src/__tests__/subagent-fork-prompt-role.test.ts +0 -12
  498. package/src/__tests__/subagent-notify-parent.test.ts +4 -6
  499. package/src/__tests__/subagent-spawn-and-await.test.ts +0 -18
  500. package/src/__tests__/subagent-tool-filtering.test.ts +21 -31
  501. package/src/__tests__/subagent-tool-gate-mode.test.ts +6 -32
  502. package/src/__tests__/subagent-tools.test.ts +92 -67
  503. package/src/__tests__/suggestion-routes.test.ts +28 -42
  504. package/src/__tests__/summarize-boundary.test.ts +2 -1
  505. package/src/__tests__/system-prompt-ask-mode.test.ts +0 -25
  506. package/src/__tests__/system-prompt.test.ts +0 -33
  507. package/src/__tests__/task-memory-cleanup.test.ts +18 -192
  508. package/src/__tests__/telegram-bot-username-resolution.test.ts +24 -48
  509. package/src/__tests__/telegram-config.test.ts +0 -8
  510. package/src/__tests__/telemetry-routes.test.ts +100 -0
  511. package/src/__tests__/telephony-credential-preflight.test.ts +7 -11
  512. package/src/__tests__/telephony-tts-guard.test.ts +38 -21
  513. package/src/__tests__/terminal-tools.test.ts +0 -21
  514. package/src/__tests__/thread-backfill.test.ts +0 -7
  515. package/src/__tests__/title-generate-hook.test.ts +11 -10
  516. package/src/__tests__/token-manager.test.ts +0 -9
  517. package/src/__tests__/tool-approval-handler.test.ts +0 -8
  518. package/src/__tests__/tool-execution-abort-cleanup.test.ts +5 -33
  519. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +3 -23
  520. package/src/__tests__/tool-executor-lifecycle-events.test.ts +0 -48
  521. package/src/__tests__/tool-executor.test.ts +3 -49
  522. package/src/__tests__/tool-grant-request-escalation.test.ts +51 -153
  523. package/src/__tests__/tool-preview-lifecycle.test.ts +2 -29
  524. package/src/__tests__/tool-profiler.test.ts +72 -1
  525. package/src/__tests__/tool-result-metadata-plumbing.test.ts +0 -29
  526. package/src/__tests__/tool-side-effects-slack-dm.test.ts +0 -1
  527. package/src/__tests__/tool-start-timestamp.test.ts +4 -31
  528. package/src/__tests__/tools-get-route.test.ts +2 -1
  529. package/src/__tests__/trust-context-guards.test.ts +19 -7
  530. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +75 -79
  531. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +14 -18
  532. package/src/__tests__/trusted-contact-multichannel.test.ts +0 -7
  533. package/src/__tests__/trusted-contact-verification.test.ts +1 -9
  534. package/src/__tests__/turn-boundary-resolution.test.ts +1 -19
  535. package/src/__tests__/turn-events-store.test.ts +1 -7
  536. package/src/__tests__/turn-outcome-read.test.ts +1 -7
  537. package/src/__tests__/twilio-config.test.ts +11 -28
  538. package/src/__tests__/twilio-provider.test.ts +2 -13
  539. package/src/__tests__/twilio-routes-twiml.test.ts +1 -8
  540. package/src/__tests__/twilio-routes.test.ts +52 -103
  541. package/src/__tests__/twilio-validation.test.ts +5 -22
  542. package/src/__tests__/ui-file-upload-surface.test.ts +6 -9
  543. package/src/__tests__/usage-attribution.test.ts +25 -56
  544. package/src/__tests__/usage-cache-backfill-migration.test.ts +8 -15
  545. package/src/__tests__/usage-routes.test.ts +1 -8
  546. package/src/__tests__/vbundle-pax-and-symlink.test.ts +0 -18
  547. package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +0 -24
  548. package/src/__tests__/vercel-config.test.ts +0 -7
  549. package/src/__tests__/verification-control-plane-policy.test.ts +0 -45
  550. package/src/__tests__/voice-approval-resolver-relay.test.ts +106 -75
  551. package/src/__tests__/voice-config-update.test.ts +114 -21
  552. package/src/__tests__/voice-ingress-preflight.test.ts +16 -15
  553. package/src/__tests__/voice-scoped-grant-consumer.test.ts +0 -30
  554. package/src/__tests__/voice-session-bridge-processing-wait.test.ts +1 -17
  555. package/src/__tests__/voice-session-bridge.test.ts +14 -46
  556. package/src/__tests__/web-search-backend-failure.test.ts +0 -21
  557. package/src/__tests__/whatsapp-invite-adapter.test.ts +11 -30
  558. package/src/__tests__/workspace-git-service.test.ts +801 -2
  559. package/src/__tests__/workspace-migration-009-backfill-conversation-disk-view.test.ts +1 -26
  560. package/src/__tests__/workspace-migration-013-repair-conversation-disk-view.test.ts +1 -26
  561. package/src/__tests__/workspace-migration-028-recover-conversations-from-disk-view.test.ts +1 -26
  562. package/src/a2a/__tests__/e2e-a2a-channel.test.ts +1 -9
  563. package/src/a2a/__tests__/task-store.test.ts +0 -9
  564. package/src/acp/__tests__/session-manager-persistence.test.ts +1 -8
  565. package/src/acp/__tests__/session-manager-resume.test.ts +0 -7
  566. package/src/acp/__tests__/session-manager-startup.test.ts +1 -8
  567. package/src/agent/image-optimize.ts +80 -0
  568. package/src/agent/loop.ts +20 -5
  569. package/src/api/events/open-conversation.test.ts +64 -0
  570. package/src/api/events/open-conversation.ts +33 -0
  571. package/src/api/index.ts +6 -0
  572. package/src/approvals/AGENTS.md +1 -1
  573. package/src/approvals/guardian-card-withdrawal.ts +26 -19
  574. package/src/approvals/guardian-decision-primitive.ts +172 -102
  575. package/src/approvals/guardian-expiry-notifier.ts +20 -19
  576. package/src/approvals/guardian-request-resolvers.ts +305 -275
  577. package/src/apps/app-store.ts +320 -15
  578. package/src/background-wake/background-wake-routes.test.ts +2 -3
  579. package/src/background-wake/next-wake.test.ts +23 -20
  580. package/src/background-wake/wake-intent-hooks.test.ts +0 -10
  581. package/src/bundler/app-bundler.ts +34 -48
  582. package/src/bundler/app-compiler.ts +39 -4
  583. package/src/bundler/bundle-scanner.ts +13 -0
  584. package/src/bundler/manifest.ts +1 -1
  585. package/src/calls/__tests__/call-setup-router.test.ts +84 -88
  586. package/src/calls/__tests__/fish-audio-client.test.ts +6 -11
  587. package/src/calls/__tests__/voice-control-protocol.test.ts +47 -0
  588. package/src/calls/__tests__/voice-session-bridge.test.ts +151 -16
  589. package/src/calls/__tests__/voice-triage-escalate.test.ts +128 -0
  590. package/src/calls/access-request-wait.ts +35 -35
  591. package/src/calls/call-controller.ts +48 -45
  592. package/src/calls/call-setup-flow.ts +2 -2
  593. package/src/calls/call-setup-router.ts +1 -24
  594. package/src/calls/guardian-dispatch.ts +47 -30
  595. package/src/calls/guardian-wait-controller.ts +31 -18
  596. package/src/calls/media-turn-detector.ts +11 -1
  597. package/src/calls/telephony-credential-preflight.ts +19 -1
  598. package/src/calls/telephony-tts-capability.ts +18 -1
  599. package/src/calls/voice-control-protocol.ts +12 -0
  600. package/src/calls/voice-session-bridge.ts +110 -15
  601. package/src/calls/voice-triage-escalate.ts +136 -0
  602. package/src/channels/__tests__/gateway-guardian-requests.test.ts +669 -0
  603. package/src/channels/gateway-guardian-requests.ts +410 -0
  604. package/src/channels/types.ts +10 -5
  605. package/src/cli/AGENTS.md +77 -51
  606. package/src/cli/__tests__/cli-command-help-coverage.test.ts +29 -0
  607. package/src/cli/commands/__tests__/conversations-import.test.ts +23 -24
  608. package/src/cli/commands/__tests__/gateway.test.ts +55 -0
  609. package/src/cli/commands/__tests__/inference-models.test.ts +3 -0
  610. package/src/cli/commands/__tests__/inference-profiles.test.ts +3 -0
  611. package/src/cli/commands/__tests__/inference-providers.test.ts +3 -0
  612. package/src/cli/commands/__tests__/inference-send.test.ts +0 -10
  613. package/src/cli/commands/__tests__/inference-session.test.ts +4 -11
  614. package/src/cli/commands/__tests__/ui.test.ts +2 -2
  615. package/src/cli/commands/apps.help.ts +46 -0
  616. package/src/cli/commands/apps.ts +51 -0
  617. package/src/cli/commands/avatar.help.ts +229 -0
  618. package/src/cli/commands/avatar.ts +58 -250
  619. package/src/cli/commands/backup.help.ts +183 -0
  620. package/src/cli/commands/backup.ts +107 -276
  621. package/src/cli/commands/bash.help.ts +38 -0
  622. package/src/cli/commands/bash.ts +51 -75
  623. package/src/cli/commands/browser.help.ts +193 -0
  624. package/src/cli/commands/browser.ts +234 -347
  625. package/src/cli/commands/cache.help.ts +123 -0
  626. package/src/cli/commands/cache.ts +72 -166
  627. package/src/cli/commands/changelog.help.ts +59 -0
  628. package/src/cli/commands/changelog.ts +29 -61
  629. package/src/cli/commands/channel-verification-sessions.help.ts +178 -0
  630. package/src/cli/commands/channel-verification-sessions.ts +71 -226
  631. package/src/cli/commands/channels/index.help.ts +67 -0
  632. package/src/cli/commands/channels/index.ts +55 -105
  633. package/src/cli/commands/clients.help.ts +72 -0
  634. package/src/cli/commands/clients.ts +100 -153
  635. package/src/cli/commands/completions.help.ts +33 -0
  636. package/src/cli/commands/completions.ts +43 -66
  637. package/src/cli/commands/config.help.ts +126 -0
  638. package/src/cli/commands/config.ts +59 -174
  639. package/src/cli/commands/contacts.help.ts +327 -0
  640. package/src/cli/commands/contacts.ts +318 -603
  641. package/src/cli/commands/conversations-defer.ts +141 -202
  642. package/src/cli/commands/conversations-import.ts +80 -113
  643. package/src/cli/commands/conversations.help.ts +364 -0
  644. package/src/cli/commands/conversations.ts +143 -328
  645. package/src/cli/commands/credentials.help.ts +290 -0
  646. package/src/cli/commands/credentials.ts +271 -487
  647. package/src/cli/commands/db/index.help.ts +27 -0
  648. package/src/cli/commands/db/index.ts +7 -3
  649. package/src/cli/commands/db/refresh.ts +131 -0
  650. package/src/cli/commands/db/repair-step-conversation-backfill.ts +19 -9
  651. package/src/cli/commands/db/repair.ts +41 -43
  652. package/src/cli/commands/db/status.ts +79 -83
  653. package/src/cli/commands/domain.help.ts +34 -0
  654. package/src/cli/commands/domain.ts +10 -15
  655. package/src/cli/commands/email.help.ts +176 -0
  656. package/src/cli/commands/email.ts +323 -412
  657. package/src/cli/commands/gateway.help.ts +115 -0
  658. package/src/cli/commands/gateway.ts +105 -123
  659. package/src/cli/commands/image-generation.help.ts +72 -0
  660. package/src/cli/commands/image-generation.ts +13 -62
  661. package/src/cli/commands/inference-callsites.ts +34 -49
  662. package/src/cli/commands/inference-models.ts +6 -21
  663. package/src/cli/commands/inference-profiles.ts +95 -156
  664. package/src/cli/commands/inference-providers-default.ts +27 -42
  665. package/src/cli/commands/inference-providers.ts +25 -87
  666. package/src/cli/commands/inference-session.ts +189 -249
  667. package/src/cli/commands/inference.help.ts +485 -0
  668. package/src/cli/commands/inference.ts +104 -165
  669. package/src/cli/commands/keys.help.ts +46 -0
  670. package/src/cli/commands/keys.ts +37 -71
  671. package/src/cli/commands/mcp.help.ts +167 -0
  672. package/src/cli/commands/mcp.ts +123 -267
  673. package/src/cli/commands/memory/__tests__/memory-items.test.ts +4 -0
  674. package/src/cli/commands/memory/__tests__/memory-v2.test.ts +4 -0
  675. package/src/cli/commands/memory/__tests__/memory-v3.test.ts +4 -0
  676. package/src/cli/commands/memory/__tests__/worker.test.ts +12 -5
  677. package/src/cli/commands/memory/index.help.ts +814 -0
  678. package/src/cli/commands/memory/index.ts +5 -27
  679. package/src/cli/commands/memory/items.ts +257 -404
  680. package/src/cli/commands/memory/memory-retrospective.ts +31 -71
  681. package/src/cli/commands/memory/memory-v2-compare-render.ts +2 -2
  682. package/src/cli/commands/memory/memory-v2.ts +435 -646
  683. package/src/cli/commands/memory/memory-v3.ts +158 -283
  684. package/src/cli/commands/memory/nodes.ts +154 -249
  685. package/src/cli/commands/memory/worker.ts +83 -128
  686. package/src/cli/commands/monitoring.help.ts +57 -0
  687. package/src/cli/commands/monitoring.ts +17 -41
  688. package/src/cli/commands/notifications.help.ts +293 -0
  689. package/src/cli/commands/notifications.ts +420 -657
  690. package/src/cli/commands/oauth/apps.ts +182 -315
  691. package/src/cli/commands/oauth/connect.ts +4 -35
  692. package/src/cli/commands/oauth/disconnect.ts +44 -71
  693. package/src/cli/commands/oauth/index.help.ts +855 -0
  694. package/src/cli/commands/oauth/index.ts +5 -31
  695. package/src/cli/commands/oauth/mode.ts +5 -28
  696. package/src/cli/commands/oauth/ping.ts +44 -66
  697. package/src/cli/commands/oauth/providers.ts +413 -772
  698. package/src/cli/commands/oauth/request.ts +6 -35
  699. package/src/cli/commands/oauth/shared.ts +1 -1
  700. package/src/cli/commands/oauth/status.test.ts +6 -6
  701. package/src/cli/commands/oauth/status.ts +45 -62
  702. package/src/cli/commands/oauth/token.ts +32 -71
  703. package/src/cli/commands/pending.help.ts +26 -0
  704. package/src/cli/commands/pending.ts +77 -78
  705. package/src/cli/commands/platform/__tests__/connect.test.ts +3 -1
  706. package/src/cli/commands/platform/__tests__/disconnect.test.ts +4 -4
  707. package/src/cli/commands/platform/__tests__/status.test.ts +0 -90
  708. package/src/cli/commands/platform/connect.ts +10 -21
  709. package/src/cli/commands/platform/disconnect.ts +11 -26
  710. package/src/cli/commands/platform/index.help.ts +187 -0
  711. package/src/cli/commands/platform/index.ts +22 -169
  712. package/src/cli/commands/plugins.help.ts +247 -0
  713. package/src/cli/commands/plugins.ts +356 -437
  714. package/src/cli/commands/ps.help.ts +26 -0
  715. package/src/cli/commands/ps.ts +5 -17
  716. package/src/cli/commands/routes.help.ts +72 -0
  717. package/src/cli/commands/routes.ts +78 -125
  718. package/src/cli/commands/schedules-worker.ts +70 -138
  719. package/src/cli/commands/schedules.help.ts +514 -0
  720. package/src/cli/commands/schedules.ts +494 -871
  721. package/src/cli/commands/sequence.help.ts +183 -0
  722. package/src/cli/commands/sequence.ts +181 -343
  723. package/src/cli/commands/skills.help.ts +159 -0
  724. package/src/cli/commands/skills.ts +230 -368
  725. package/src/cli/commands/status.help.ts +32 -0
  726. package/src/cli/commands/status.ts +38 -3
  727. package/src/cli/commands/stt.help.ts +52 -0
  728. package/src/cli/commands/stt.ts +9 -47
  729. package/src/cli/commands/telemetry.help.ts +14 -0
  730. package/src/cli/commands/telemetry.ts +19 -17
  731. package/src/cli/commands/tools-run.ts +30 -45
  732. package/src/cli/commands/tools.help.ts +81 -0
  733. package/src/cli/commands/tools.ts +43 -83
  734. package/src/cli/commands/trust.help.ts +43 -0
  735. package/src/cli/commands/trust.ts +82 -109
  736. package/src/cli/commands/tts.help.ts +88 -0
  737. package/src/cli/commands/tts.ts +116 -188
  738. package/src/cli/commands/ui.help.ts +213 -0
  739. package/src/cli/commands/ui.ts +363 -380
  740. package/src/cli/commands/usage.help.ts +147 -0
  741. package/src/cli/commands/usage.ts +87 -206
  742. package/src/cli/commands/watchers.help.ts +211 -0
  743. package/src/cli/commands/watchers.ts +261 -417
  744. package/src/cli/commands/webhooks.help.ts +95 -0
  745. package/src/cli/commands/webhooks.ts +44 -115
  746. package/src/cli/index.help.ts +91 -0
  747. package/src/cli/lib/__tests__/global-json-option.test.ts +97 -0
  748. package/src/cli/lib/__tests__/install-from-github.test.ts +144 -4
  749. package/src/cli/lib/__tests__/plugin-catalog-cache.test.ts +96 -132
  750. package/src/cli/lib/__tests__/plugin-catalog-local.test.ts +65 -0
  751. package/src/cli/lib/__tests__/plugin-catalog-platform.test.ts +167 -0
  752. package/src/cli/lib/__tests__/plugin-catalog-resolve.test.ts +197 -0
  753. package/src/cli/lib/__tests__/plugin-details.test.ts +349 -240
  754. package/src/cli/lib/__tests__/plugin-fingerprint.test.ts +31 -0
  755. package/src/cli/lib/__tests__/plugin-icon-file.test.ts +50 -1
  756. package/src/cli/lib/__tests__/plugin-marketplace.test.ts +94 -0
  757. package/src/cli/lib/__tests__/plugins-install-offline.test.ts +147 -0
  758. package/src/cli/lib/__tests__/search-plugins.test.ts +193 -309
  759. package/src/cli/lib/bundled-marketplace.json +439 -0
  760. package/src/cli/lib/cli-command-help.ts +83 -10
  761. package/src/cli/lib/global-json-option.ts +41 -0
  762. package/src/cli/lib/install-from-github.ts +69 -2
  763. package/src/cli/lib/plugin-catalog-cache.ts +22 -50
  764. package/src/cli/lib/plugin-catalog-local.ts +71 -0
  765. package/src/cli/lib/plugin-catalog-platform.ts +117 -0
  766. package/src/cli/lib/plugin-catalog-resolve.ts +72 -0
  767. package/src/cli/lib/plugin-details.ts +100 -34
  768. package/src/cli/lib/plugin-fingerprint.ts +18 -7
  769. package/src/cli/lib/plugin-icon-file.ts +38 -26
  770. package/src/cli/lib/plugin-marketplace.ts +15 -2
  771. package/src/cli/lib/publish-plugin.ts +3 -3
  772. package/src/cli/lib/search-plugins.ts +48 -111
  773. package/src/cli/program.ts +7 -0
  774. package/src/cli.ts +22 -13
  775. package/src/config/__tests__/default-profile-catalog.test.ts +8 -12
  776. package/src/config/__tests__/default-provider.test.ts +0 -21
  777. package/src/config/__tests__/deployment-context-defaults.test.ts +0 -21
  778. package/src/config/__tests__/feature-flag-registry-bundled.test.ts +2 -2
  779. package/src/config/__tests__/loader-callsite-strip-fallback.test.ts +0 -21
  780. package/src/config/__tests__/loader-last-known-good.test.ts +0 -21
  781. package/src/config/__tests__/loader-sparse-array-cleanup.test.ts +0 -21
  782. package/src/config/__tests__/platform-rehydration.test.ts +125 -0
  783. package/src/config/__tests__/profile-materialization.test.ts +1 -88
  784. package/src/config/__tests__/seed-default-provider.test.ts +0 -21
  785. package/src/config/__tests__/sync-gated-profiles.test.ts +0 -21
  786. package/src/config/bundled-skills/app-builder/SKILL.md +24 -1
  787. package/src/config/bundled-skills/app-builder/references/CUSTOM_ROUTES.md +30 -0
  788. package/src/config/bundled-skills/contacts/SKILL.md +1 -1
  789. package/src/config/bundled-skills/contacts/tools/contact-merge.ts +4 -2
  790. package/src/config/bundled-skills/messaging/TOOLS.json +2 -2
  791. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +28 -20
  792. package/src/config/bundled-skills/phone-calls/references/CONFIG.md +7 -7
  793. package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +3 -3
  794. package/src/config/bundled-skills/schedule/SKILL.md +0 -1
  795. package/src/config/bundled-skills/schedule/TOOLS.json +2 -2
  796. package/src/config/bundled-skills/settings/TOOLS.json +5 -3
  797. package/src/config/bundled-skills/settings/tools/voice-config-update.ts +84 -10
  798. package/src/config/bundled-skills/transcribe/tools/transcribe-media.test.ts +0 -7
  799. package/src/config/call-site-defaults.ts +3 -3
  800. package/src/config/feature-flag-registry.json +15 -63
  801. package/src/config/llm-resolver.ts +88 -475
  802. package/src/config/managed-speech-defaults.ts +115 -0
  803. package/src/config/platform-rehydration.ts +76 -0
  804. package/src/config/profile-materialization.ts +11 -11
  805. package/src/config/schema.ts +93 -129
  806. package/src/config/schemas/__tests__/live-voice.test.ts +24 -6
  807. package/src/config/schemas/__tests__/stt.test.ts +37 -0
  808. package/src/config/schemas/live-voice.ts +10 -4
  809. package/src/config/schemas/llm.ts +51 -15
  810. package/src/config/schemas/memory-lifecycle.ts +1 -13
  811. package/src/config/schemas/memory-retrospective.ts +8 -0
  812. package/src/config/schemas/memory.ts +0 -4
  813. package/src/config/schemas/stt.ts +33 -6
  814. package/src/config/schemas/tts.ts +53 -6
  815. package/src/config/schemas/workspace-git.ts +8 -0
  816. package/src/contacts/contact-store.ts +3 -58
  817. package/src/contacts/types.ts +1 -1
  818. package/src/conversations/__tests__/message-consolidation.test.ts +6 -5
  819. package/src/conversations/message-consolidation.ts +34 -112
  820. package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +64 -7
  821. package/src/daemon/__tests__/conversation-tool-setup-plugin-scope.test.ts +3 -7
  822. package/src/daemon/__tests__/conversation-tool-setup.test.ts +8 -6
  823. package/src/daemon/__tests__/embedding-reconcile.test.ts +0 -11
  824. package/src/daemon/__tests__/inference-profile-notification.test.ts +5 -11
  825. package/src/daemon/__tests__/inflight-message-content.test.ts +219 -0
  826. package/src/daemon/__tests__/native-web-search-metadata.test.ts +5 -27
  827. package/src/daemon/__tests__/route-conversation-post.test.ts +158 -0
  828. package/src/daemon/__tests__/wake-conversation-ops-completion.test.ts +0 -6
  829. package/src/daemon/__tests__/web-search-status-text.test.ts +0 -29
  830. package/src/daemon/app-source-watcher.ts +17 -23
  831. package/src/daemon/chat-credential-redaction.ts +1365 -0
  832. package/src/daemon/conversation-agent-loop-handlers.ts +742 -77
  833. package/src/daemon/conversation-agent-loop.ts +10 -17
  834. package/src/daemon/conversation-error.ts +53 -16
  835. package/src/daemon/conversation-history.ts +6 -12
  836. package/src/daemon/conversation-messaging.ts +13 -1
  837. package/src/daemon/conversation-process.ts +16 -11
  838. package/src/daemon/conversation-runtime-assembly.ts +148 -52
  839. package/src/daemon/conversation-surfaces.ts +217 -100
  840. package/src/daemon/conversation-tool-setup.ts +59 -112
  841. package/src/daemon/conversation-turn-finalize.ts +18 -0
  842. package/src/daemon/conversation.ts +35 -66
  843. package/src/daemon/event-loop-watchdog.test.ts +1 -6
  844. package/src/daemon/external-plugins-bootstrap.ts +20 -74
  845. package/src/daemon/handlers/__tests__/config-a2a-accept.test.ts +0 -7
  846. package/src/daemon/handlers/__tests__/config-a2a-complete.test.ts +1 -8
  847. package/src/daemon/handlers/__tests__/config-a2a-invite.test.ts +1 -8
  848. package/src/daemon/handlers/__tests__/config-a2a-redeem.test.ts +1 -8
  849. package/src/daemon/handlers/__tests__/config-a2a.test.ts +1 -8
  850. package/src/daemon/handlers/conversation-history.ts +6 -4
  851. package/src/daemon/handlers/conversations.ts +19 -9
  852. package/src/daemon/handlers/shared.ts +24 -1
  853. package/src/daemon/inflight-message-content.ts +228 -0
  854. package/src/daemon/lifecycle.ts +21 -31
  855. package/src/daemon/message-protocol.ts +2 -7
  856. package/src/daemon/message-provenance.ts +17 -8
  857. package/src/daemon/message-types/conversations.ts +6 -17
  858. package/src/daemon/message-types/host-ui-snapshot.ts +44 -0
  859. package/src/daemon/message-types/inbox.ts +3 -46
  860. package/src/daemon/orphan-reaper.test.ts +1 -6
  861. package/src/daemon/process-message.ts +9 -0
  862. package/src/daemon/providers-setup.ts +5 -75
  863. package/src/daemon/route-conversation-post.ts +158 -0
  864. package/src/daemon/shutdown-handlers.ts +11 -17
  865. package/src/daemon/sqlite-corruption-watchdog.test.ts +0 -6
  866. package/src/documents/document-comments-store.test.ts +1 -7
  867. package/src/export/__tests__/transcript-formatter.test.ts +8 -8
  868. package/src/export/formatter.ts +8 -17
  869. package/src/export/transcript-formatter.ts +4 -1
  870. package/src/heartbeat/__tests__/heartbeat-run-store.test.ts +0 -9
  871. package/src/heartbeat/__tests__/heartbeat-service.test.ts +29 -57
  872. package/src/home/__tests__/home-content-refresh.test.ts +0 -7
  873. package/src/home/__tests__/suggested-prompts.test.ts +0 -11
  874. package/src/ipc/__tests__/contacts-info-ipc.test.ts +12 -10
  875. package/src/ipc/__tests__/email-ipc.test.ts +90 -0
  876. package/src/ipc/assistant-server.ts +10 -22
  877. package/src/ipc/routes/__tests__/guardian-label-ipc-routes.test.ts +74 -0
  878. package/src/ipc/routes/__tests__/invite-ipc-routes.test.ts +0 -7
  879. package/src/ipc/routes/guardian-label-ipc-routes.ts +42 -0
  880. package/src/live-voice/__tests__/live-voice-archive.test.ts +1 -8
  881. package/src/live-voice/__tests__/live-voice-credential-preflight.test.ts +89 -49
  882. package/src/live-voice/__tests__/live-voice-integration.test.ts +116 -2
  883. package/src/live-voice/__tests__/live-voice-resume-registry.test.ts +58 -0
  884. package/src/live-voice/__tests__/live-voice-resume-turn.test.ts +280 -0
  885. package/src/live-voice/__tests__/live-voice-triage-escalate.test.ts +337 -0
  886. package/src/live-voice/__tests__/live-voice-tts.test.ts +0 -4
  887. package/src/live-voice/__tests__/live-voice-vad.test.ts +432 -12
  888. package/src/live-voice/__tests__/protocol.test.ts +122 -0
  889. package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +0 -41
  890. package/src/live-voice/live-voice-credential-preflight.ts +27 -3
  891. package/src/live-voice/live-voice-resume-registry.ts +54 -0
  892. package/src/live-voice/live-voice-session.ts +602 -61
  893. package/src/live-voice/protocol.ts +143 -1
  894. package/src/mcp/__tests__/mcp-auth-orchestrator.test.ts +3 -7
  895. package/src/messaging/provider-types.ts +9 -0
  896. package/src/messaging/providers/a2a/__tests__/deliver.test.ts +0 -9
  897. package/src/messaging/providers/outlook/adapter.ts +17 -2
  898. package/src/messaging/providers/outlook/client.ts +11 -2
  899. package/src/messaging/providers/outlook/types.ts +9 -0
  900. package/src/messaging/providers/slack/__tests__/download.test.ts +1 -8
  901. package/src/messaging/providers/slack/binding-metadata.test.ts +23 -21
  902. package/src/messaging/providers/slack/send.test.ts +0 -7
  903. package/src/messaging/providers/slack/withdraw.test.ts +0 -6
  904. package/src/messaging/providers/telegram-bot/send.test.ts +0 -7
  905. package/src/monitoring/__tests__/plugin-source-watch.test.ts +40 -1
  906. package/src/monitoring/plugin-source-watch.ts +56 -62
  907. package/src/monitoring/recovery/__tests__/inflight-content.test.ts +166 -0
  908. package/src/monitoring/recovery/inflight-content.ts +260 -0
  909. package/src/monitoring/recovery/run-recovery.ts +72 -0
  910. package/src/monitoring/worker.ts +68 -7
  911. package/src/notifications/AGENTS.md +1 -1
  912. package/src/notifications/README.md +4 -4
  913. package/src/notifications/__tests__/broadcaster.test.ts +4 -17
  914. package/src/notifications/__tests__/connected-channels.test.ts +11 -8
  915. package/src/notifications/__tests__/decision-engine.test.ts +0 -7
  916. package/src/notifications/__tests__/destination-resolver.test.ts +18 -12
  917. package/src/notifications/__tests__/deterministic-checks.test.ts +1 -9
  918. package/src/notifications/adapters/macos.ts +3 -5
  919. package/src/notifications/adapters/platform.ts +1 -1
  920. package/src/notifications/broadcaster.ts +13 -4
  921. package/src/notifications/conversation-candidates.ts +21 -28
  922. package/src/notifications/copy-composer.ts +0 -6
  923. package/src/notifications/decision-engine.ts +1 -1
  924. package/src/notifications/{canonical-delivery-recorder.ts → guardian-delivery-recorder.ts} +47 -33
  925. package/src/notifications/home-feed-side-effect.ts +0 -2
  926. package/src/notifications/signal.ts +0 -4
  927. package/src/oauth/byo-connection.test.ts +0 -9
  928. package/src/oauth/connection-resolver.test.ts +18 -46
  929. package/src/oauth/seed-providers.ts +6 -0
  930. package/src/onboarding/__tests__/onboarding-events-store.test.ts +122 -44
  931. package/src/onboarding/onboarding-events-store.ts +67 -115
  932. package/src/onboarding/onboarding-research-events-store.test.ts +222 -0
  933. package/src/onboarding/onboarding-research-events-store.ts +92 -0
  934. package/src/permissions/checker.test.ts +10 -24
  935. package/src/permissions/confirmation-guardian-request.test.ts +94 -0
  936. package/src/permissions/{confirmation-canonical-request.ts → confirmation-guardian-request.ts} +44 -29
  937. package/src/permissions/gateway-threshold-reader.test.ts +0 -8
  938. package/src/permissions/prompter.ts +6 -4
  939. package/src/permissions/question-prompter.test.ts +7 -14
  940. package/src/persistence/__tests__/bulk-write-gate.test.ts +1 -7
  941. package/src/persistence/__tests__/conversation-queries-search.test.ts +0 -7
  942. package/src/persistence/__tests__/main-db-readonly-probe.ts +80 -0
  943. package/src/persistence/__tests__/main-db-readonly.test.ts +35 -0
  944. package/src/persistence/__tests__/message-content-file.test.ts +161 -52
  945. package/src/persistence/__tests__/raw-query-telemetry.test.ts +74 -0
  946. package/src/persistence/conversation-crud.ts +175 -45
  947. package/src/persistence/conversation-disk-view.ts +32 -15
  948. package/src/persistence/conversation-group-migration.test.ts +1 -8
  949. package/src/persistence/conversation-title-service.ts +59 -22
  950. package/src/persistence/db-connection.ts +46 -1
  951. package/src/persistence/db-singleton.ts +7 -1
  952. package/src/persistence/embeddings/__tests__/messages-lexical-index.test.ts +3 -7
  953. package/src/persistence/embeddings/messages-lexical-index.ts +11 -0
  954. package/src/persistence/job-handlers/__tests__/message-lexical-backfill.test.ts +0 -7
  955. package/src/persistence/job-handlers/__tests__/message-lexical-enqueue.test.ts +0 -6
  956. package/src/persistence/job-handlers/__tests__/message-lexical.test.ts +0 -7
  957. package/src/persistence/job-handlers/cleanup.ts +30 -16
  958. package/src/persistence/job-handlers/message-lexical-backfill.ts +8 -5
  959. package/src/persistence/job-handlers/message-lexical.ts +2 -2
  960. package/src/persistence/jobs-store.ts +123 -17
  961. package/src/persistence/lifecycle-events-store.test.ts +84 -0
  962. package/src/persistence/lifecycle-events-store.ts +27 -52
  963. package/src/persistence/llm-request-log-sink-clickhouse.ts +325 -0
  964. package/src/persistence/llm-request-log-store.ts +185 -106
  965. package/src/persistence/llm-request-log-writer-types.ts +80 -0
  966. package/src/persistence/llm-usage-store.ts +5 -2
  967. package/src/persistence/message-content-file.ts +182 -71
  968. package/src/persistence/message-content.ts +18 -10
  969. package/src/persistence/migrations/305-drop-contact-acl-columns.ts +3 -2
  970. package/src/persistence/migrations/325-create-config-setting-events.ts +40 -0
  971. package/src/persistence/migrations/326-move-injection-events-to-memory-db.ts +104 -0
  972. package/src/persistence/migrations/327-create-flush-checkpoints.ts +86 -0
  973. package/src/persistence/migrations/328-drop-memory-v3-learned-edge-tables.ts +16 -0
  974. package/src/persistence/migrations/329-move-onboarding-events-to-telemetry-db.test.ts +179 -0
  975. package/src/persistence/migrations/329-move-onboarding-events-to-telemetry-db.ts +119 -0
  976. package/src/persistence/migrations/330-move-auth-fallback-events-to-telemetry-db.test.ts +197 -0
  977. package/src/persistence/migrations/330-move-auth-fallback-events-to-telemetry-db.ts +108 -0
  978. package/src/persistence/migrations/331-move-lifecycle-events-to-telemetry-db.test.ts +159 -0
  979. package/src/persistence/migrations/331-move-lifecycle-events-to-telemetry-db.ts +97 -0
  980. package/src/persistence/migrations/332-move-skill-loaded-events-to-telemetry-db.test.ts +219 -0
  981. package/src/persistence/migrations/332-move-skill-loaded-events-to-telemetry-db.ts +128 -0
  982. package/src/persistence/migrations/333-create-telemetry-events-table.test.ts +66 -0
  983. package/src/persistence/migrations/333-create-telemetry-events-table.ts +43 -0
  984. package/src/persistence/migrations/334-backfill-telemetry-events-outbox.test.ts +584 -0
  985. package/src/persistence/migrations/334-backfill-telemetry-events-outbox.ts +386 -0
  986. package/src/persistence/migrations/335-collapse-memory-embed-backlog.test.ts +181 -0
  987. package/src/persistence/migrations/335-collapse-memory-embed-backlog.ts +177 -0
  988. package/src/persistence/migrations/__tests__/327-create-flush-checkpoints.test.ts +124 -0
  989. package/src/persistence/raw-query.ts +27 -1
  990. package/src/persistence/schema/calls.ts +0 -23
  991. package/src/persistence/schema/conversation-starters.ts +31 -0
  992. package/src/persistence/schema/conversations.ts +3 -3
  993. package/src/persistence/schema/guardian.ts +0 -150
  994. package/src/persistence/schema/index.ts +1 -0
  995. package/src/persistence/schema/infrastructure.ts +25 -72
  996. package/src/persistence/schema/memory-core.ts +0 -25
  997. package/src/persistence/schema/memory-injection.ts +3 -1
  998. package/src/persistence/schema/tasks.ts +1 -60
  999. package/src/persistence/steps.ts +22 -0
  1000. package/src/platform/client.test.ts +110 -0
  1001. package/src/platform/client.ts +24 -4
  1002. package/src/platform/consent-cache.test.ts +5 -18
  1003. package/src/platform/consent-cache.ts +8 -6
  1004. package/src/platform/managed-speech.test.ts +218 -0
  1005. package/src/platform/managed-speech.ts +204 -0
  1006. package/src/plugin-api/conversation-turn.ts +250 -0
  1007. package/src/plugin-api/index.ts +21 -0
  1008. package/src/plugin-api/model-profiles.test.ts +29 -28
  1009. package/src/plugin-api/vision-support.test.ts +25 -38
  1010. package/src/plugin-api/vision-support.ts +26 -17
  1011. package/src/plugins/AGENTS.md +8 -0
  1012. package/src/plugins/__tests__/source-fingerprint.test.ts +41 -0
  1013. package/src/plugins/collect-source-versions.ts +77 -0
  1014. package/src/plugins/defaults/image-recovery/detect.ts +32 -10
  1015. package/src/plugins/defaults/image-recovery/hooks/post-model-call.ts +20 -18
  1016. package/src/plugins/defaults/image-recovery/recover.ts +86 -59
  1017. package/src/plugins/defaults/memory/__tests__/activation-session-store.test.ts +1 -8
  1018. package/src/plugins/defaults/memory/__tests__/clear-stale-processing-flags.test.ts +1 -8
  1019. package/src/plugins/defaults/memory/__tests__/conversation-queries.test.ts +1 -8
  1020. package/src/plugins/defaults/memory/__tests__/conversation-row-batch-delete.test.ts +7 -18
  1021. package/src/plugins/defaults/memory/__tests__/db-memory-attach.test.ts +22 -18
  1022. package/src/plugins/defaults/memory/__tests__/embedding-cache.test.ts +0 -6
  1023. package/src/plugins/defaults/memory/__tests__/find-most-recent-retrospective-for.test.ts +1 -8
  1024. package/src/plugins/defaults/memory/__tests__/fork-message-copy.test.ts +7 -18
  1025. package/src/plugins/defaults/memory/__tests__/jobs-store-enqueue-gate.test.ts +29 -39
  1026. package/src/plugins/defaults/memory/__tests__/jobs-worker-memory-disabled.test.ts +11 -26
  1027. package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-graph-trigger-embed.test.ts +3 -22
  1028. package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-schedule.test.ts +215 -1
  1029. package/src/plugins/defaults/memory/__tests__/memory-retrospective-enqueue.test.ts +0 -7
  1030. package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +114 -16
  1031. package/src/plugins/defaults/memory/__tests__/memory-retrospective-prompt.test.ts +180 -0
  1032. package/src/plugins/defaults/memory/__tests__/memory-retrospective-skill-card.test.ts +153 -519
  1033. package/src/plugins/defaults/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +0 -7
  1034. package/src/plugins/defaults/memory/__tests__/memory-retrospective-state.test.ts +6 -17
  1035. package/src/plugins/defaults/memory/__tests__/memory-retrospective-trigger-check.test.ts +0 -7
  1036. package/src/plugins/defaults/memory/__tests__/memory-v2-activation-log-store.test.ts +1 -19
  1037. package/src/plugins/defaults/memory/__tests__/memory-v2-concept-frequency.test.ts +0 -18
  1038. package/src/plugins/defaults/memory/__tests__/shutdown-hook.test.ts +8 -7
  1039. package/src/plugins/defaults/memory/__tests__/table-relocation.test.ts +49 -0
  1040. package/src/{persistence → plugins/defaults/memory}/__tests__/worker-control.test.ts +8 -10
  1041. package/src/plugins/defaults/memory/graph/capability-seed.ts +4 -6
  1042. package/src/plugins/defaults/memory/graph/extraction.ts +5 -1
  1043. package/src/plugins/defaults/memory/graph/graph-search.test.ts +2 -8
  1044. package/src/plugins/defaults/memory/graph/tool-handlers.test.ts +0 -6
  1045. package/src/plugins/defaults/memory/graph/tool-handlers.ts +2 -2
  1046. package/src/plugins/defaults/memory/graph/tools.ts +47 -13
  1047. package/src/plugins/defaults/memory/graph-topology/__tests__/build-memory-graph.test.ts +81 -2
  1048. package/src/plugins/defaults/memory/graph-topology/build-memory-graph.ts +67 -32
  1049. package/src/plugins/defaults/memory/hooks/shutdown.ts +8 -11
  1050. package/src/plugins/defaults/memory/indexer.ts +2 -1
  1051. package/src/plugins/defaults/memory/job-handlers/backfill.ts +8 -5
  1052. package/src/plugins/defaults/memory/job-handlers/embedding.test.ts +0 -7
  1053. package/src/plugins/defaults/memory/job-handlers/embedding.ts +2 -2
  1054. package/src/plugins/defaults/memory/job-handlers/index-maintenance.ts +7 -2
  1055. package/src/plugins/defaults/memory/jobs/__tests__/embed-concept-page.test.ts +73 -8
  1056. package/src/plugins/defaults/memory/jobs/embed-concept-page.ts +5 -3
  1057. package/src/plugins/defaults/memory/jobs/embed-pkb-file.test.ts +0 -13
  1058. package/src/plugins/defaults/memory/jobs-worker.ts +139 -107
  1059. package/src/plugins/defaults/memory/memory-db.ts +27 -0
  1060. package/src/plugins/defaults/memory/memory-retrospective-constants.ts +4 -4
  1061. package/src/plugins/defaults/memory/memory-retrospective-job.ts +56 -180
  1062. package/src/plugins/defaults/memory/memory-retrospective-prompt.ts +216 -0
  1063. package/src/plugins/defaults/memory/memory-retrospective-skill-card.ts +122 -202
  1064. package/src/plugins/defaults/memory/message-media.ts +2 -2
  1065. package/src/plugins/defaults/memory/paths.ts +3 -2
  1066. package/src/plugins/defaults/memory/pkb/pkb-index.test.ts +0 -12
  1067. package/src/plugins/defaults/memory/pkb/pkb-reconcile.test.ts +0 -9
  1068. package/src/plugins/defaults/memory/pkb/pkb-search.test.ts +0 -6
  1069. package/src/plugins/defaults/memory/routes/__tests__/memory-v2-simulate-route.test.ts +15 -92
  1070. package/src/plugins/defaults/memory/routes/__tests__/memory-worker-routes.test.ts +201 -0
  1071. package/src/plugins/defaults/memory/routes/memory-item-routes.test.ts +7 -21
  1072. package/src/plugins/defaults/memory/routes/memory-v2-routes.ts +3 -8
  1073. package/src/plugins/defaults/memory/routes/memory-worker-routes.ts +162 -0
  1074. package/src/plugins/defaults/memory/startup.ts +6 -7
  1075. package/src/plugins/defaults/memory/task-memory-cleanup.ts +11 -22
  1076. package/src/plugins/defaults/memory/tools.test.ts +40 -8
  1077. package/src/plugins/defaults/memory/tools.ts +12 -2
  1078. package/src/plugins/defaults/memory/v2/__tests__/activation.test.ts +0 -19
  1079. package/src/plugins/defaults/memory/v2/__tests__/backfill-jobs.test.ts +63 -40
  1080. package/src/plugins/defaults/memory/v2/__tests__/cli-command-store.test.ts +61 -130
  1081. package/src/plugins/defaults/memory/v2/__tests__/consolidation-job.test.ts +406 -10
  1082. package/src/plugins/defaults/memory/v2/__tests__/harness-compare.test.ts +1 -10
  1083. package/src/plugins/defaults/memory/v2/__tests__/harness-oracle.test.ts +1 -10
  1084. package/src/plugins/defaults/memory/v2/__tests__/harness-replay-input.test.ts +1 -10
  1085. package/src/plugins/defaults/memory/v2/__tests__/injection-events.test.ts +61 -69
  1086. package/src/plugins/defaults/memory/v2/__tests__/injection.test.ts +0 -19
  1087. package/src/plugins/defaults/memory/v2/__tests__/migration.test.ts +11 -10
  1088. package/src/plugins/defaults/memory/v2/__tests__/page-index.test.ts +0 -5
  1089. package/src/plugins/defaults/memory/v2/__tests__/qdrant.test.ts +6 -22
  1090. package/src/plugins/defaults/memory/v2/__tests__/reranker.test.ts +3 -5
  1091. package/src/plugins/defaults/memory/v2/__tests__/router.test.ts +7 -20
  1092. package/src/plugins/defaults/memory/v2/__tests__/sim.test.ts +0 -24
  1093. package/src/plugins/defaults/memory/v2/__tests__/skill-content.test.ts +17 -11
  1094. package/src/plugins/defaults/memory/v2/__tests__/skill-store.test.ts +0 -16
  1095. package/src/plugins/defaults/memory/v2/__tests__/static-context.test.ts +0 -10
  1096. package/src/plugins/defaults/memory/v2/__tests__/sweep-job.test.ts +0 -6
  1097. package/src/plugins/defaults/memory/v2/backfill-jobs.ts +5 -2
  1098. package/src/plugins/defaults/memory/v2/cli-command-content.ts +43 -12
  1099. package/src/plugins/defaults/memory/v2/cli-command-store.ts +34 -50
  1100. package/src/plugins/defaults/memory/v2/consolidation-job.ts +216 -10
  1101. package/src/plugins/defaults/memory/v2/harness/router-retriever.ts +1 -8
  1102. package/src/plugins/defaults/memory/v2/injection-events.ts +16 -14
  1103. package/src/plugins/defaults/memory/v2/injection.ts +1 -2
  1104. package/src/plugins/defaults/memory/v2/memory-v2-startup.test.ts +0 -5
  1105. package/src/plugins/defaults/memory/v2/migration.ts +55 -24
  1106. package/src/plugins/defaults/memory/v2/prompts/consolidation.ts +4 -0
  1107. package/src/plugins/defaults/memory/v2/router.ts +4 -14
  1108. package/src/plugins/defaults/memory/v2/sweep-job.ts +1 -0
  1109. package/src/plugins/defaults/memory/v3/__tests__/carry-integration.test.ts +10 -22
  1110. package/src/plugins/defaults/memory/v3/__tests__/dense.test.ts +0 -5
  1111. package/src/plugins/defaults/memory/v3/__tests__/injection.test.ts +18 -20
  1112. package/src/plugins/defaults/memory/v3/__tests__/section-dense-store.test.ts +0 -5
  1113. package/src/plugins/defaults/memory/v3/__tests__/selection-log-store.test.ts +5 -9
  1114. package/src/plugins/defaults/memory/v3/__tests__/shadow-plugin.test.ts +51 -31
  1115. package/src/plugins/defaults/memory/v3/prune.test.ts +3 -11
  1116. package/src/{persistence → plugins/defaults/memory}/worker-control.ts +12 -21
  1117. package/src/plugins/defaults/memory/worker.ts +19 -2
  1118. package/src/plugins/mtime-cache.ts +166 -70
  1119. package/src/plugins/plugin-tree-walk.ts +41 -4
  1120. package/src/plugins/source-fingerprint.ts +9 -3
  1121. package/src/plugins/surface-import.ts +28 -0
  1122. package/src/plugins/types.ts +9 -23
  1123. package/src/prompts/__tests__/system-prompt.test.ts +0 -28
  1124. package/src/prompts/__tests__/task-progress-hint-section.test.ts +0 -28
  1125. package/src/providers/__tests__/connection-model-compat.test.ts +6 -19
  1126. package/src/providers/__tests__/count-tokens-forwarding.test.ts +1 -21
  1127. package/src/providers/__tests__/dispatch-connection-routing.test.ts +9 -26
  1128. package/src/providers/__tests__/registry-native-web-search.test.ts +4 -10
  1129. package/src/providers/__tests__/retry-callsite.test.ts +240 -235
  1130. package/src/providers/__tests__/satellite-connection-routing.test.ts +11 -36
  1131. package/src/providers/__tests__/vellum-mismatch-routing.test.ts +0 -5
  1132. package/src/providers/anthropic/client.ts +9 -3
  1133. package/src/providers/call-site-routing.ts +7 -3
  1134. package/src/providers/connection-resolution.ts +9 -11
  1135. package/src/providers/content-block-schema.ts +149 -0
  1136. package/src/providers/inference/__tests__/base-url-route-validation.test.ts +7 -11
  1137. package/src/providers/inference/__tests__/codex-token-refresh.test.ts +1 -15
  1138. package/src/providers/inference/auth.ts +23 -0
  1139. package/src/providers/inference/backfill.ts +25 -9
  1140. package/src/providers/model-catalog.ts +213 -5
  1141. package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +54 -0
  1142. package/src/providers/openai/chat-completions-provider.ts +13 -2
  1143. package/src/providers/openai/responses-provider.ts +232 -5
  1144. package/src/providers/openrouter/client.ts +53 -0
  1145. package/src/providers/retry.ts +25 -2
  1146. package/src/providers/speech-to-text/__tests__/provider-catalog.test.ts +13 -0
  1147. package/src/providers/speech-to-text/__tests__/resolve.test.ts +211 -74
  1148. package/src/providers/speech-to-text/__tests__/vellum-managed-realtime.test.ts +408 -0
  1149. package/src/providers/speech-to-text/__tests__/vellum-managed.test.ts +121 -0
  1150. package/src/providers/speech-to-text/__tests__/vellum-speech-relay-connection.test.ts +126 -0
  1151. package/src/providers/speech-to-text/deepgram-realtime.ts +167 -37
  1152. package/src/providers/speech-to-text/incremental-batch-stream.ts +413 -0
  1153. package/src/providers/speech-to-text/openai-whisper-stream.ts +16 -363
  1154. package/src/providers/speech-to-text/provider-catalog.ts +26 -1
  1155. package/src/providers/speech-to-text/resolve.ts +74 -13
  1156. package/src/providers/speech-to-text/vellum-managed-realtime.ts +309 -0
  1157. package/src/providers/speech-to-text/vellum-managed.ts +71 -0
  1158. package/src/providers/speech-to-text/vellum-speech-relay-connection.ts +174 -0
  1159. package/src/providers/types.ts +23 -4
  1160. package/src/providers/vellum-model-routing.test.ts +26 -0
  1161. package/src/providers/vellum-model-routing.ts +30 -0
  1162. package/src/runtime/AGENTS.md +1 -1
  1163. package/src/runtime/__tests__/actor-trust-resolver.test.ts +2 -8
  1164. package/src/runtime/__tests__/agent-wake.test.ts +100 -27
  1165. package/src/runtime/__tests__/background-job-runner.test.ts +22 -0
  1166. package/src/runtime/__tests__/guardian-vellum-migration.test.ts +0 -5
  1167. package/src/runtime/__tests__/member-verdict-cache.test.ts +2 -9
  1168. package/src/runtime/__tests__/trust-verdict-consumer.test.ts +22 -5
  1169. package/src/runtime/access-request-helper.ts +84 -60
  1170. package/src/runtime/actor-trust-resolver.ts +2 -2
  1171. package/src/runtime/agent-wake.ts +75 -26
  1172. package/src/runtime/assistant-event-hub.ts +1 -0
  1173. package/src/runtime/auth/__tests__/middleware.test.ts +1 -10
  1174. package/src/runtime/auth/__tests__/route-policy.test.ts +0 -7
  1175. package/src/runtime/auth/__tests__/token-service.test.ts +1 -8
  1176. package/src/runtime/auth/same-actor.ts +2 -1
  1177. package/src/runtime/background-job-runner.ts +22 -0
  1178. package/src/runtime/channel-approval-types.ts +1 -1
  1179. package/src/runtime/channel-reply-delivery.ts +38 -19
  1180. package/src/runtime/confirmation-request-guardian-bridge.ts +45 -39
  1181. package/src/runtime/for-chat-mint-registry.ts +118 -0
  1182. package/src/runtime/guardian-action-service.ts +32 -27
  1183. package/src/runtime/guardian-decision-types.ts +2 -2
  1184. package/src/runtime/guardian-reply-router.ts +80 -98
  1185. package/src/runtime/http-server.ts +61 -41
  1186. package/src/runtime/introduction-policy.ts +2 -2
  1187. package/src/runtime/local-actor-identity.ts +19 -7
  1188. package/src/runtime/pending-interactions.ts +1 -0
  1189. package/src/runtime/reveal-nonce.ts +49 -0
  1190. package/src/runtime/reveal-success-registry.ts +306 -0
  1191. package/src/runtime/routes/__tests__/acp-routes.test.ts +0 -7
  1192. package/src/runtime/routes/__tests__/backup-routes.test.ts +195 -125
  1193. package/src/runtime/routes/__tests__/channel-verification-routes.test.ts +4 -1
  1194. package/src/runtime/routes/__tests__/client-routes.test.ts +0 -7
  1195. package/src/runtime/routes/__tests__/connection-routes-vs-cli-parity.test.ts +1 -19
  1196. package/src/runtime/routes/__tests__/consolidation-routes.test.ts +1 -8
  1197. package/src/runtime/routes/__tests__/contact-routes-merge-relay.test.ts +186 -0
  1198. package/src/runtime/routes/__tests__/contact-routes-update-channel-relay.test.ts +2 -3
  1199. package/src/runtime/routes/__tests__/content-source-routes.test.ts +0 -7
  1200. package/src/runtime/routes/__tests__/conversation-compaction-routes.test.ts +5 -27
  1201. package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +0 -7
  1202. package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +12 -30
  1203. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +59 -56
  1204. package/src/runtime/routes/__tests__/conversation-surface-routes.test.ts +0 -7
  1205. package/src/runtime/routes/__tests__/default-provider-routes.test.ts +53 -73
  1206. package/src/runtime/routes/__tests__/gateway-status-routes.test.ts +84 -0
  1207. package/src/runtime/routes/__tests__/inference-callsites-routes.test.ts +2 -10
  1208. package/src/runtime/routes/__tests__/inference-profiles-routes.test.ts +58 -90
  1209. package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +161 -93
  1210. package/src/runtime/routes/__tests__/llm-call-sites-routes.test.ts +6 -1
  1211. package/src/runtime/routes/__tests__/monitoring-routes.test.ts +0 -8
  1212. package/src/runtime/routes/__tests__/plugins-routes.test.ts +218 -64
  1213. package/src/runtime/routes/__tests__/question-routes.test.ts +2 -4
  1214. package/src/runtime/routes/__tests__/retrospective-routes.test.ts +1 -8
  1215. package/src/runtime/routes/__tests__/sanity-routes.test.ts +0 -7
  1216. package/src/runtime/routes/__tests__/schedule-routes-create.test.ts +2 -1
  1217. package/src/runtime/routes/__tests__/schedule-worker-routes.test.ts +16 -56
  1218. package/src/runtime/routes/__tests__/stt-routes.test.ts +0 -9
  1219. package/src/runtime/routes/__tests__/suggest-trust-rule-routes.test.ts +0 -7
  1220. package/src/runtime/routes/__tests__/surface-action-routes.test.ts +5 -0
  1221. package/src/runtime/routes/__tests__/surface-content-routes.test.ts +354 -1
  1222. package/src/runtime/routes/__tests__/tts-routes.test.ts +0 -11
  1223. package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +163 -10
  1224. package/src/runtime/routes/__tests__/user-routes-cli.test.ts +154 -0
  1225. package/src/runtime/routes/__tests__/wake-conversation-routes.test.ts +0 -7
  1226. package/src/runtime/routes/acp-routes.ts +21 -9
  1227. package/src/runtime/routes/app-management-routes.ts +231 -60
  1228. package/src/runtime/routes/app-routes.ts +130 -83
  1229. package/src/runtime/routes/auth-routes.ts +3 -1
  1230. package/src/runtime/routes/background-wake-routes.ts +0 -1
  1231. package/src/runtime/routes/cache-routes.ts +3 -3
  1232. package/src/runtime/routes/call-routes.ts +5 -1
  1233. package/src/runtime/routes/channel-verification-routes.ts +2 -1
  1234. package/src/runtime/routes/contact-prompt-routes.ts +11 -5
  1235. package/src/runtime/routes/contact-routes.ts +34 -42
  1236. package/src/runtime/routes/conversation-attention-routes.ts +1 -1
  1237. package/src/runtime/routes/conversation-cli-routes.ts +1 -1
  1238. package/src/runtime/routes/conversation-query-routes.ts +4 -4
  1239. package/src/runtime/routes/conversation-routes.ts +111 -72
  1240. package/src/runtime/routes/credential-routes.ts +116 -3
  1241. package/src/runtime/routes/email-routes.ts +17 -1
  1242. package/src/runtime/routes/events-routes.ts +1 -0
  1243. package/src/runtime/routes/gateway-status-routes.ts +69 -0
  1244. package/src/runtime/routes/guardian-action-routes.ts +18 -16
  1245. package/src/runtime/routes/guardian-approval-interception.ts +6 -4
  1246. package/src/runtime/routes/guardian-approval-prompt.ts +7 -5
  1247. package/src/runtime/routes/guardian-expiry-sweep.ts +130 -0
  1248. package/src/runtime/routes/inbound-message-handler.ts +9 -33
  1249. package/src/runtime/routes/inbound-stages/acl-enforcement.test.ts +0 -5
  1250. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +9 -9
  1251. package/src/runtime/routes/inbound-stages/admission-policy.test.ts +24 -6
  1252. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +0 -7
  1253. package/src/runtime/routes/inbound-stages/bootstrap-intercept.test.ts +0 -5
  1254. package/src/runtime/routes/inbound-stages/bootstrap-intercept.ts +6 -3
  1255. package/src/runtime/routes/inbound-stages/edit-intercept.ts +5 -1
  1256. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.test.ts +0 -9
  1257. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +4 -1
  1258. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.test.ts +3 -12
  1259. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +16 -14
  1260. package/src/runtime/routes/inbound-stages/reaction-intercept.test.ts +8 -2
  1261. package/src/runtime/routes/inbound-stages/reaction-intercept.ts +15 -7
  1262. package/src/runtime/routes/inbound-stages/transcribe-audio.test.ts +0 -9
  1263. package/src/runtime/routes/index.ts +5 -5
  1264. package/src/runtime/routes/inference-provider-connection-routes.ts +73 -24
  1265. package/src/runtime/routes/inference-send-routes.ts +1 -1
  1266. package/src/runtime/routes/internal-telemetry-routes.ts +11 -2
  1267. package/src/runtime/routes/oauth-connect-routes.ts +27 -7
  1268. package/src/runtime/routes/platform-routes.ts +4 -14
  1269. package/src/runtime/routes/playground/__tests__/force-compact.test.ts +0 -4
  1270. package/src/runtime/routes/playground/__tests__/guard.test.ts +0 -4
  1271. package/src/runtime/routes/playground/__tests__/inject-failures.test.ts +0 -14
  1272. package/src/runtime/routes/playground/__tests__/reset-circuit.test.ts +0 -21
  1273. package/src/runtime/routes/playground/__tests__/seed-conversation.test.ts +0 -4
  1274. package/src/runtime/routes/playground/__tests__/seeded-conversations.test.ts +16 -18
  1275. package/src/runtime/routes/playground/__tests__/state.test.ts +0 -14
  1276. package/src/runtime/routes/playground/seed-conversation.ts +5 -4
  1277. package/src/runtime/routes/playground/seeded-conversations.ts +3 -2
  1278. package/src/runtime/routes/plugins-routes.ts +163 -25
  1279. package/src/runtime/routes/profiler-routes.ts +2 -5
  1280. package/src/runtime/routes/publish-routes.ts +15 -18
  1281. package/src/runtime/routes/question-routes.ts +8 -4
  1282. package/src/runtime/routes/schedule-routes.ts +20 -78
  1283. package/src/runtime/routes/schedule-worker-routes.ts +16 -84
  1284. package/src/runtime/routes/secret-routes.ts +14 -0
  1285. package/src/runtime/routes/settings-routes.ts +21 -25
  1286. package/src/runtime/routes/subagents-routes.ts +17 -18
  1287. package/src/runtime/routes/surface-action-routes.ts +18 -39
  1288. package/src/runtime/routes/surface-content-routes.ts +59 -1
  1289. package/src/runtime/routes/surface-conversation-resolver.ts +148 -4
  1290. package/src/runtime/routes/telemetry-routes.ts +74 -1
  1291. package/src/runtime/routes/tts-routes.ts +9 -5
  1292. package/src/runtime/routes/ui-snapshot-routes.test.ts +219 -0
  1293. package/src/runtime/routes/ui-snapshot-routes.ts +313 -0
  1294. package/src/runtime/routes/user-route-dispatcher.ts +52 -53
  1295. package/src/runtime/routes/user-route-resolution.ts +141 -0
  1296. package/src/runtime/routes/user-routes-cli.ts +56 -35
  1297. package/src/runtime/routes/user-routes.ts +9 -2
  1298. package/src/runtime/routes/vellum-actor-trust.ts +67 -0
  1299. package/src/runtime/services/__tests__/auto-analysis-guard.test.ts +1 -8
  1300. package/src/runtime/tool-grant-request-helper.ts +34 -30
  1301. package/src/runtime/trust-verdict-consumer.ts +4 -6
  1302. package/src/schedule/__tests__/worker-control.test.ts +3 -3
  1303. package/src/schedule/schedule-store.ts +0 -41
  1304. package/src/schedule/scheduler.ts +38 -257
  1305. package/src/schedule/worker-control.ts +11 -21
  1306. package/src/schedule/worker.ts +18 -5
  1307. package/src/security/__tests__/oauth2-device-code.test.ts +12 -60
  1308. package/src/security/__tests__/provider-key-env-fallback.test.ts +0 -10
  1309. package/src/security/auth-fallback-events-store.ts +34 -72
  1310. package/src/security/secret-scanner.ts +26 -1
  1311. package/src/sequence/engine.ts +15 -6
  1312. package/src/services/published-app-updater.ts +6 -11
  1313. package/src/stt/__tests__/daemon-batch-transcriber.test.ts +24 -4
  1314. package/src/stt/daemon-batch-transcriber.ts +33 -2
  1315. package/src/stt/stt-stream-session.ts +17 -11
  1316. package/src/stt/types.ts +2 -1
  1317. package/src/subagent/manager.ts +4 -3
  1318. package/src/telemetry/AGENTS.md +44 -0
  1319. package/src/telemetry/__tests__/config-setting-events-store.test.ts +63 -0
  1320. package/src/telemetry/__tests__/config-setting-snapshot.test.ts +107 -0
  1321. package/src/telemetry/__tests__/flush-checkpoints.test.ts +56 -0
  1322. package/src/telemetry/__tests__/outbox-test-harness.ts +83 -0
  1323. package/src/telemetry/__tests__/telemetry-event-fixtures.ts +258 -0
  1324. package/src/telemetry/__tests__/watchdog-events-store.test.ts +32 -122
  1325. package/src/telemetry/config-setting-events-store.ts +40 -0
  1326. package/src/telemetry/config-setting-snapshot.ts +135 -0
  1327. package/src/telemetry/flush-checkpoints.ts +70 -0
  1328. package/src/telemetry/skill-loaded-events-store.test.ts +54 -113
  1329. package/src/telemetry/skill-loaded-events-store.ts +21 -77
  1330. package/src/telemetry/telemetry-event-sources.test.ts +211 -0
  1331. package/src/telemetry/telemetry-event-sources.ts +582 -0
  1332. package/src/telemetry/telemetry-events-outbox.test.ts +330 -0
  1333. package/src/telemetry/telemetry-events-outbox.ts +204 -0
  1334. package/src/telemetry/telemetry-main-db.ts +48 -0
  1335. package/src/telemetry/telemetry-wire-source.json +4 -0
  1336. package/src/telemetry/telemetry-wire-validation.test.ts +157 -0
  1337. package/src/telemetry/telemetry-wire-validation.ts +125 -0
  1338. package/src/telemetry/telemetry-wire.generated.ts +433 -0
  1339. package/src/telemetry/tool-executed-events-store.test.ts +0 -8
  1340. package/src/telemetry/tool-executed-events-store.ts +2 -2
  1341. package/src/telemetry/turn-trace-store.test.ts +86 -7
  1342. package/src/telemetry/turn-trace-store.ts +29 -1
  1343. package/src/telemetry/types.test.ts +38 -0
  1344. package/src/telemetry/types.ts +302 -87
  1345. package/src/telemetry/usage-telemetry-reporter.test.ts +921 -364
  1346. package/src/telemetry/usage-telemetry-reporter.ts +235 -722
  1347. package/src/telemetry/watchdog-direct-emit.test.ts +0 -5
  1348. package/src/telemetry/watchdog-direct-emit.ts +7 -1
  1349. package/src/telemetry/watchdog-events-store.ts +11 -70
  1350. package/src/tools/acp/spawn.test.ts +0 -7
  1351. package/src/tools/apps/definitions.ts +1 -7
  1352. package/src/tools/apps/executors.ts +11 -36
  1353. package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +11 -24
  1354. package/src/tools/browser/__tests__/browser-status.test.ts +47 -33
  1355. package/src/tools/browser/cdp-client/__tests__/cdp-inspect-client.test.ts +1 -11
  1356. package/src/tools/browser/cdp-client/__tests__/factory.test.ts +75 -58
  1357. package/src/tools/browser/cdp-client/__tests__/local-cdp-client.test.ts +0 -10
  1358. package/src/tools/browser/network-recorder.test.ts +0 -11
  1359. package/src/tools/document/document-comment-tool.test.ts +1 -7
  1360. package/src/tools/host-terminal/host-shell.test.ts +0 -32
  1361. package/src/tools/host-terminal/host-shell.ts +6 -2
  1362. package/src/tools/network/__tests__/web-fetch-firecrawl.test.ts +13 -15
  1363. package/src/tools/network/__tests__/web-search-metadata.test.ts +15 -18
  1364. package/src/tools/network/__tests__/web-search.test.ts +39 -50
  1365. package/src/tools/registry.ts +148 -196
  1366. package/src/tools/skills/find-similar-skills.test.ts +0 -7
  1367. package/src/tools/skills/sandbox-runner.ts +5 -2
  1368. package/src/tools/skills/scaffold-managed.ts +105 -12
  1369. package/src/tools/subagent/read.ts +6 -4
  1370. package/src/tools/subagent/spawn.ts +20 -29
  1371. package/src/tools/terminal/safe-env.ts +7 -2
  1372. package/src/tools/terminal/shell.test.ts +4 -8
  1373. package/src/tools/terminal/shell.ts +5 -2
  1374. package/src/tools/tool-approval-handler.ts +39 -23
  1375. package/src/tools/tool-input-summary.ts +2 -1
  1376. package/src/tools/tool-manifest.ts +20 -6
  1377. package/src/tools/tool-profiler.ts +37 -6
  1378. package/src/tools/ui-surface/definitions.ts +1 -7
  1379. package/src/tools/workflows/run-workflow.test.ts +8 -22
  1380. package/src/tts/__tests__/provider-adapters.test.ts +28 -22
  1381. package/src/tts/__tests__/provider-resolution.test.ts +26 -0
  1382. package/src/tts/__tests__/synthesis-stream.test.ts +6 -6
  1383. package/src/tts/__tests__/vellum-provider.test.ts +251 -0
  1384. package/src/tts/provider-catalog.ts +6 -0
  1385. package/src/tts/providers/__tests__/vellum-tts-socket.test.ts +266 -0
  1386. package/src/tts/providers/vellum-provider.ts +220 -0
  1387. package/src/tts/providers/vellum-tts-socket.ts +377 -0
  1388. package/src/tts/synthesize-text.ts +15 -5
  1389. package/src/tts/tts-config-resolver.ts +2 -7
  1390. package/src/tts/types.ts +1 -0
  1391. package/src/usage/attribution.ts +20 -114
  1392. package/src/util/abort-reasons.ts +1 -3
  1393. package/src/util/image-conversion.ts +23 -5
  1394. package/src/util/logger.ts +8 -3
  1395. package/src/{config/bundled-skills/messaging/tools/gmail-mime-helpers.ts → util/mime-type.ts} +4 -1
  1396. package/src/util/platform.ts +0 -60
  1397. package/src/util/pricing.ts +10 -1
  1398. package/src/util/telemetry-db-path.ts +9 -7
  1399. package/src/watcher/__tests__/telemetry.test.ts +41 -11
  1400. package/src/watcher/providers/google-calendar.ts +81 -49
  1401. package/src/watcher/telemetry.ts +22 -5
  1402. package/src/workflows/engine-integration.test.ts +0 -6
  1403. package/src/workflows/engine.test.ts +1 -9
  1404. package/src/workflows/journal-store.test.ts +1 -9
  1405. package/src/workflows/leaf-runner.test.ts +17 -50
  1406. package/src/workflows/library.test.ts +1 -9
  1407. package/src/workflows/run-manager.test.ts +1 -9
  1408. package/src/workspace/git-service.ts +932 -37
  1409. package/src/workspace/provider-commit-message-generator.ts +6 -4
  1410. package/__tests__/permissions/gateway-threshold-reader.test.ts +0 -450
  1411. package/src/__tests__/canonical-guardian-store.test.ts +0 -928
  1412. package/src/__tests__/guardian-principal-id-roundtrip.test.ts +0 -140
  1413. package/src/__tests__/plugin-route-contribution.test.ts +0 -245
  1414. package/src/__tests__/skill-runtime-path.test.ts +0 -63
  1415. package/src/__tests__/task-compiler.test.ts +0 -317
  1416. package/src/__tests__/task-management-tools.test.ts +0 -1128
  1417. package/src/__tests__/task-scheduler.test.ts +0 -786
  1418. package/src/config/schemas/schedules.ts +0 -35
  1419. package/src/contacts/canonical-guardian-store.ts +0 -902
  1420. package/src/daemon/message-types/work-items.ts +0 -243
  1421. package/src/runtime/routes/__tests__/memory-worker-routes.test.ts +0 -306
  1422. package/src/runtime/routes/__tests__/task-routes.test.ts +0 -644
  1423. package/src/runtime/routes/assets/vellum-design-system.css +0 -1959
  1424. package/src/runtime/routes/canonical-guardian-expiry-sweep.ts +0 -129
  1425. package/src/runtime/routes/inbound-stages/escalation-intercept.test.ts +0 -158
  1426. package/src/runtime/routes/inbound-stages/escalation-intercept.ts +0 -187
  1427. package/src/runtime/routes/memory-worker-routes.ts +0 -227
  1428. package/src/runtime/routes/task-routes.ts +0 -380
  1429. package/src/runtime/routes/work-items-routes.test.ts +0 -75
  1430. package/src/runtime/routes/work-items-routes.ts +0 -881
  1431. package/src/runtime/skill-route-registry.ts +0 -131
  1432. package/src/tasks/SPEC.md +0 -132
  1433. package/src/tasks/task-compiler.ts +0 -194
  1434. package/src/tasks/task-runner.ts +0 -119
  1435. package/src/tasks/task-scheduler.ts +0 -22
  1436. package/src/tasks/task-store.ts +0 -153
  1437. package/src/tasks/tool-sanitizer.ts +0 -38
  1438. package/src/tools/apps/registry.ts +0 -16
  1439. package/src/tools/system/register.ts +0 -9
  1440. package/src/tools/tasks/task-delete.ts +0 -121
  1441. package/src/tools/tasks/task-list.ts +0 -56
  1442. package/src/tools/tasks/task-run.ts +0 -122
  1443. package/src/tools/tasks/task-save.ts +0 -64
  1444. package/src/tools/tasks/work-item-enqueue.ts +0 -300
  1445. package/src/tools/tasks/work-item-list.ts +0 -65
  1446. package/src/tools/tasks/work-item-remove.ts +0 -94
  1447. package/src/tools/tasks/work-item-run.ts +0 -99
  1448. package/src/tools/tasks/work-item-update.ts +0 -166
  1449. package/src/tools/ui-surface/registry.ts +0 -14
  1450. package/src/work-items/resolve-required-tools.test.ts +0 -37
  1451. package/src/work-items/resolve-required-tools.ts +0 -26
  1452. package/src/work-items/work-item-runner.ts +0 -187
  1453. package/src/work-items/work-item-store.ts +0 -416
@@ -6,11 +6,27 @@ import {
6
6
  type TurnDetectorConfig,
7
7
  } from "../calls/media-turn-detector.js";
8
8
  import { sanitizeForTts } from "../calls/tts-text-sanitizer.js";
9
+ import {
10
+ couldBeControlMarker,
11
+ ESCALATE_MARKER,
12
+ stripInternalSpeechMarkers,
13
+ } from "../calls/voice-control-protocol.js";
9
14
  import type {
10
15
  VoiceTurnHandle,
11
16
  VoiceTurnOptions,
12
17
  } from "../calls/voice-session-bridge.js";
18
+ import {
19
+ ESCALATION_CONTINUATION_CONTENT,
20
+ ESCALATION_PROFILE,
21
+ FALLBACK_ESCALATION_BRIDGE,
22
+ FRONT_DOOR_PROFILE,
23
+ isVoiceTriageEscalateEnabled,
24
+ needsFallbackBridge,
25
+ type VoiceRoutingLeg,
26
+ } from "../calls/voice-triage-escalate.js";
27
+ import { isAssistantFeatureFlagEnabled } from "../config/assistant-feature-flags.js";
13
28
  import { getConfig } from "../config/loader.js";
29
+ import type { TrustContext } from "../daemon/trust-context-types.js";
14
30
  import { ensureConversationExists } from "../persistence/conversation-crud.js";
15
31
  import {
16
32
  listProviderIds,
@@ -38,6 +54,12 @@ import {
38
54
  type LiveVoiceMetricsEvent,
39
55
  type LiveVoiceTurnSeedMarks,
40
56
  } from "./live-voice-metrics.js";
57
+ import {
58
+ registerVoiceResumeHandler,
59
+ unregisterVoiceResumeHandler,
60
+ type VoiceResumeHandler,
61
+ type VoiceResumeOptions,
62
+ } from "./live-voice-resume-registry.js";
41
63
  import {
42
64
  type LiveVoiceSession as LiveVoiceSessionContract,
43
65
  type LiveVoiceSessionCloseReason,
@@ -51,6 +73,7 @@ import type {
51
73
  } from "./live-voice-tts.js";
52
74
  import {
53
75
  type LiveVoiceClientFrame,
76
+ type LiveVoiceClientUpdateConfigFrame,
54
77
  LiveVoiceProtocolErrorCode,
55
78
  type LiveVoiceServerFramePayload,
56
79
  } from "./protocol.js";
@@ -77,10 +100,12 @@ const SERVER_VAD_PRE_ROLL_MAX_CHUNKS = 25;
77
100
  // provider keeps its own, longer, finalize fallback).
78
101
  const FINALIZE_GRACE_MS = 1_000;
79
102
  // Consecutive speech (ms) required before speech during assistant playback
80
- // flushes it (speech_started) and cancels the turn, so a cough or noise blip
81
- // cannot kill a reply mid-sentence. Mirrors the liveVoice.vad.bargeInMinSpeechMs
82
- // schema default; 0 disables the guard for instant barge-in.
83
- const DEFAULT_BARGE_IN_MIN_SPEECH_MS = 60;
103
+ // flushes it (speech_started) and cancels the turn, so a cough, a filler word,
104
+ // or the assistant's own TTS bleeding through imperfect browser echo
105
+ // cancellation cannot kill a reply mid-sentence. Mirrors the
106
+ // liveVoice.vad.bargeInMinSpeechMs schema default; 0 disables the guard for
107
+ // instant barge-in.
108
+ const DEFAULT_BARGE_IN_MIN_SPEECH_MS = 250;
84
109
  // At most this many TTS segment jobs are open (provider stream started,
85
110
  // frames not yet fully emitted) per turn: the emitting job plus one
86
111
  // prefetching job. The prefetch buffers its chunks in memory until promoted;
@@ -244,10 +269,20 @@ interface ActiveAssistantTurn {
244
269
  handle: VoiceTurnHandle | null;
245
270
  assistantCompleted: boolean;
246
271
  ttsDone: boolean;
247
- // A tts_audio frame actually went out to the client — the barge-in gate:
248
- // speech only cancels a turn that has audibly started speaking.
272
+ // A tts_audio frame actually went out to the client — latches on the first
273
+ // forwarded chunk so the firstTtsAudio metric is marked exactly once per turn.
249
274
  ttsAudioStarted: boolean;
250
275
  finalized: boolean;
276
+ // When this turn started from a barge-in, the interrupted request's
277
+ // transcript. Appended to the turn's control prompt (both legs) so the model
278
+ // merges it with this turn's utterance instead of treating that utterance as
279
+ // a fresh follow-up. Null for an ordinary (non-barge-in) turn.
280
+ interruptedRequest: string | null;
281
+ // Triage-and-escalate (Voice Mode): the front-door leg emitted [ESCALATE]
282
+ // and the strong "escalated" leg has taken over this same turn. Guards the
283
+ // front-door leg's trailing completion from finalizing the turn, and makes
284
+ // the hand-off idempotent.
285
+ escalationHandedOff: boolean;
251
286
  ttsBuffer: string;
252
287
  // A non-empty speakable segment reached the TTS queue — gates the eager
253
288
  // first-segment flush that trades clause quality for speech onset.
@@ -264,6 +299,21 @@ interface ActiveAssistantTurn {
264
299
  assistantAudioSampleRate?: number;
265
300
  }
266
301
 
302
+ // Base control prompt for every live-voice turn. When a turn starts from a
303
+ // barge-in, the interruption merge note is appended to it (see
304
+ // buildInterruptionMergeNote) so the model reconciles the interrupted request
305
+ // with the new utterance.
306
+ const LIVE_VOICE_CONTROL_PROMPT =
307
+ "You are speaking in a local live voice session. Keep replies brief and conversational.";
308
+
309
+ // System-level guidance appended to a barge-in turn's control prompt so the
310
+ // model treats the new utterance as a continuation of the request it was cut
311
+ // off answering, rather than a fresh follow-up. Reaches the model only; it is
312
+ // not a user message and never renders as a transcript bubble.
313
+ function buildInterruptionMergeNote(interruptedRequest: string): string {
314
+ return `The user interrupted your previous, unfinished reply. Their earlier request was: "${interruptedRequest}". Treat their current message as a continuation of that request and address both together, or stay silent if they only want you to stop.`;
315
+ }
316
+
267
317
  export class LiveVoiceSession implements LiveVoiceSessionContract {
268
318
  private readonly context: LiveVoiceSessionFactoryContext;
269
319
  private readonly resolveTranscriber: LiveVoiceStreamingTranscriberResolver;
@@ -285,7 +335,9 @@ export class LiveVoiceSession implements LiveVoiceSessionContract {
285
335
  // Energy gate for server-VAD speech classification; undefined defers to
286
336
  // DEFAULT_SPEECH_ENERGY_THRESHOLD.
287
337
  private readonly speechEnergyThreshold: number | undefined;
288
- private readonly bargeInMinSpeechMs: number;
338
+ // Mutable so a mid-session `update_config` frame can retune "interrupt
339
+ // sensitivity" live (see applyConfigUpdate).
340
+ private bargeInMinSpeechMs: number;
289
341
  // Sustained-speech barge-in guard, armed at speech onset while the
290
342
  // assistant turn is audibly speaking: consecutive speech-chunk duration
291
343
  // accumulates until it reaches bargeInMinSpeechMs, then the deferred
@@ -305,6 +357,11 @@ export class LiveVoiceSession implements LiveVoiceSessionContract {
305
357
  // the chunk's PCM duration; zeroed whenever the client flushes playback
306
358
  // (speech_started, turn_cancelled, interrupt, close).
307
359
  private assistantPlaybackTailUntilMs = 0;
360
+ // Set when barge-in cancels an in-flight turn: the interrupted request's
361
+ // transcript, carried into the next turn so the model merges the two.
362
+ // Consumed (and cleared) when that turn launches; cleared if the barge-in
363
+ // utterance is discarded, so it can never attach to a later, unrelated turn.
364
+ private pendingInterruptedRequest: string | null = null;
308
365
  private readonly maxPendingAudioBytes: number;
309
366
  // Set on VAD speech onset; consumed when the first speech chunk is routed
310
367
  // to an utterance so the metric lands on the right turn.
@@ -341,6 +398,15 @@ export class LiveVoiceSession implements LiveVoiceSessionContract {
341
398
  /** The cycle whose grace timer is armed (only the newest release has one). */
342
399
  private finalizeGraceCycle: UtteranceCycle | null = null;
343
400
  private readonly finalizeGraceMs: number;
401
+ // Registered in the registry so the HTTP surface-action path can resume a
402
+ // yielded interactive surface as a SPOKEN turn on this session (JARVIS-1287).
403
+ private readonly voiceResumeHandler: VoiceResumeHandler;
404
+ // A resume requested while an assistant turn was still in flight; dispatched
405
+ // once the active turn settles (see flushPendingResume).
406
+ private pendingResume: {
407
+ content: string;
408
+ opts?: VoiceResumeOptions;
409
+ } | null = null;
344
410
 
345
411
  constructor(
346
412
  context: LiveVoiceSessionFactoryContext,
@@ -358,6 +424,10 @@ export class LiveVoiceSession implements LiveVoiceSessionContract {
358
424
  this.createTurnId = options.createTurnId ?? randomUUID;
359
425
  this.conversationId =
360
426
  context.startFrame.conversationId ?? context.sessionId;
427
+ this.voiceResumeHandler = {
428
+ resumeWithText: (content, opts) => this.resumeWithText(content, opts),
429
+ };
430
+ registerVoiceResumeHandler(this.conversationId, this.voiceResumeHandler);
361
431
  this.metricsClock = options.metricsClock ?? Date.now;
362
432
  this.metrics = new LiveVoiceMetricsCollector({
363
433
  sessionId: context.sessionId,
@@ -365,12 +435,23 @@ export class LiveVoiceSession implements LiveVoiceSessionContract {
365
435
  ...(options.metricsClock ? { clock: options.metricsClock } : {}),
366
436
  });
367
437
  this.speechEnergyThreshold = options.speechEnergyThreshold;
438
+ // Precedence for the two sensitivity knobs: per-session start-frame
439
+ // override (the client's user setting) > daemon `liveVoice.vad` config
440
+ // (seeded into `options` by the factory) > in-code default.
368
441
  this.bargeInMinSpeechMs =
369
- options.bargeInMinSpeechMs ?? DEFAULT_BARGE_IN_MIN_SPEECH_MS;
442
+ context.startFrame.bargeInMinSpeechMs ??
443
+ options.bargeInMinSpeechMs ??
444
+ DEFAULT_BARGE_IN_MIN_SPEECH_MS;
370
445
  this.finalizeGraceMs = options.finalizeGraceMs ?? FINALIZE_GRACE_MS;
446
+ const turnDetectorConfig: TurnDetectorConfig = {
447
+ ...(options.turnDetectorConfig ?? {}),
448
+ ...(context.startFrame.silenceThresholdMs !== undefined
449
+ ? { silenceThresholdMs: context.startFrame.silenceThresholdMs }
450
+ : {}),
451
+ };
371
452
  this.turnDetector =
372
453
  context.startFrame.turnDetection === "server_vad"
373
- ? new MediaTurnDetector(options.turnDetectorConfig ?? {}, {
454
+ ? new MediaTurnDetector(turnDetectorConfig, {
374
455
  onTurnStart: () => this.handleVadSpeechStart(),
375
456
  onTurnEnd: (reason) => this.handleVadUtteranceEnd(reason),
376
457
  })
@@ -440,6 +521,25 @@ export class LiveVoiceSession implements LiveVoiceSessionContract {
440
521
  return;
441
522
  case "start":
442
523
  return;
524
+ case "update_config":
525
+ this.applyConfigUpdate(frame);
526
+ return;
527
+ }
528
+ }
529
+
530
+ /**
531
+ * Apply a mid-session `update_config` frame: retune the live turn detector's
532
+ * pause ("pause before reply") and/or the barge-in guard ("interrupt
533
+ * sensitivity") without reconnecting. Each field is optional and independent;
534
+ * changes take effect from the next utterance. A no-op on manual (non-
535
+ * server_vad) sessions, which have no turn detector.
536
+ */
537
+ private applyConfigUpdate(frame: LiveVoiceClientUpdateConfigFrame): void {
538
+ if (frame.silenceThresholdMs !== undefined) {
539
+ this.turnDetector?.setSilenceThresholdMs(frame.silenceThresholdMs);
540
+ }
541
+ if (frame.bargeInMinSpeechMs !== undefined) {
542
+ this.bargeInMinSpeechMs = frame.bargeInMinSpeechMs;
443
543
  }
444
544
  }
445
545
 
@@ -454,6 +554,7 @@ export class LiveVoiceSession implements LiveVoiceSessionContract {
454
554
 
455
555
  const shouldEmitSessionEndMetrics = this.state !== "failed";
456
556
  this.state = "closed";
557
+ unregisterVoiceResumeHandler(this.conversationId, this.voiceResumeHandler);
457
558
  this.turnDetector?.dispose();
458
559
  this.stopSessionTranscriber();
459
560
  await this.cancelAssistantTurn("session_closed");
@@ -622,6 +723,10 @@ export class LiveVoiceSession implements LiveVoiceSessionContract {
622
723
  return;
623
724
  }
624
725
 
726
+ // A resume deferred behind the finished turn takes the freed slot before a
727
+ // fresh utterance is armed (no-op when there's nothing pending).
728
+ this.flushPendingResume();
729
+
625
730
  const current = this.currentUtterance;
626
731
  if (current && !current.completed) {
627
732
  // server_vad armed the next utterance during the finished turn; it may
@@ -846,12 +951,14 @@ export class LiveVoiceSession implements LiveVoiceSessionContract {
846
951
  }
847
952
 
848
953
  // VAD speech onset. Contract: speech_started tells the client to flush
849
- // tail playback immediately; barge-in then cancels the active turn only
850
- // once its first tts_audio chunk was forwarded — speech during a pre-TTS
851
- // "thinking" turn never kills the unspoken reply. While a turn is audibly
852
- // speaking, both are deferred behind the sustained-speech guard so a
853
- // cough or noise blip cannot kill the reply; onset while listening keeps
854
- // the instant speech_started (turn-taking latency is untouched).
954
+ // tail playback immediately; barge-in then cancels any in-flight,
955
+ // non-finalized turn — including a pre-TTS "thinking" turn whose reply is
956
+ // still being generated, so a user can cut in before the assistant starts
957
+ // talking (JARVIS-1266). Speaking over a thinking or audibly speaking turn
958
+ // is deferred behind the same sustained-speech guard, so a cough or noise
959
+ // blip cannot kill an unspoken reply or clip a spoken one; sustained speech
960
+ // aborts the turn. Onset while listening keeps the instant speech_started
961
+ // (turn-taking latency is untouched).
855
962
  private handleVadSpeechStart(): void {
856
963
  if (this.isClosed || this.state === "failed") {
857
964
  return;
@@ -860,25 +967,27 @@ export class LiveVoiceSession implements LiveVoiceSessionContract {
860
967
  this.vadSpeechStartPending = true;
861
968
 
862
969
  const turn = this.activeAssistantTurn;
863
- const speakingTurn =
864
- turn && !turn.finalized && turn.ttsAudioStarted ? turn : null;
970
+ // Any in-flight, non-finalized turn is interruptible, whether it is still
971
+ // "thinking" (pre-TTS) or audibly speaking, so a user can cut in before the
972
+ // assistant starts talking.
973
+ const bargeableTurn = turn && !turn.finalized ? turn : null;
865
974
  // The client can still be draining audible playback after tts_done
866
975
  // (the turn is already cleared server-side) — that tail deserves the
867
976
  // same guard, or a noise blip clips the reply's last words.
868
977
  const drainingPlayback = Date.now() < this.assistantPlaybackTailUntilMs;
869
978
 
870
- if ((speakingTurn || drainingPlayback) && this.bargeInMinSpeechMs > 0) {
979
+ if ((bargeableTurn || drainingPlayback) && this.bargeInMinSpeechMs > 0) {
871
980
  // Onset audio keeps flowing into the cycle/pre-roll while the guard
872
981
  // accumulates (trackBargeInGuard), so no speech is lost either way.
873
- this.pendingBargeIn = { turn: speakingTurn, speechMs: 0 };
982
+ this.pendingBargeIn = { turn: bargeableTurn, speechMs: 0 };
874
983
  return;
875
984
  }
876
985
 
877
986
  this.pendingBargeIn = null;
878
987
  this.assistantPlaybackTailUntilMs = 0;
879
988
  void this.sendFrame({ type: "speech_started" });
880
- if (speakingTurn) {
881
- this.bargeIn(speakingTurn);
989
+ if (bargeableTurn) {
990
+ this.bargeIn(bargeableTurn);
882
991
  }
883
992
  }
884
993
 
@@ -917,6 +1026,13 @@ export class LiveVoiceSession implements LiveVoiceSessionContract {
917
1026
  // do not collide with it in the collector. turn_cancelled flushes
918
1027
  // client playback, so the drain estimate resets with it.
919
1028
  this.assistantPlaybackTailUntilMs = 0;
1029
+ // Carry the interrupted request into the next turn so it merges with the
1030
+ // barge-in utterance rather than being answered as a fresh follow-up.
1031
+ const interruptedRequest = turn.utterance.finalTranscriptSegments
1032
+ .join(" ")
1033
+ .trim();
1034
+ this.pendingInterruptedRequest =
1035
+ interruptedRequest.length > 0 ? interruptedRequest : null;
920
1036
  turn.abortController.abort();
921
1037
  this.metrics.markBargeIn(turn.turnId);
922
1038
  void (async () => {
@@ -1363,6 +1479,10 @@ export class LiveVoiceSession implements LiveVoiceSessionContract {
1363
1479
  this.assistantPlaybackTailUntilMs = 0;
1364
1480
  this.takeVadPreRoll();
1365
1481
  this.vadPendingTurnEnd = null;
1482
+ // A client interrupt is a hard reset: any barge-in merge context waiting for
1483
+ // the next turn is now stale (the interrupted utterance may be discarded
1484
+ // without ever reaching finalizePendingUtterance).
1485
+ this.pendingInterruptedRequest = null;
1366
1486
  const utterance = this.currentUtterance;
1367
1487
  this.stopSessionTranscriber();
1368
1488
  if (utterance) {
@@ -1435,12 +1555,34 @@ export class LiveVoiceSession implements LiveVoiceSessionContract {
1435
1555
  return;
1436
1556
  }
1437
1557
 
1558
+ // Consume any pending barge-in merge context for this turn (one barge-in
1559
+ // feeds exactly the next launched turn).
1560
+ const interruptedRequest = this.pendingInterruptedRequest;
1561
+ this.pendingInterruptedRequest = null;
1562
+ await this.launchAssistantTurn(utterance, content, { interruptedRequest });
1563
+ }
1564
+
1565
+ // Build the ActiveAssistantTurn for a released utterance and drive its model
1566
+ // leg. Shared by the STT path (startAssistantTurnIfReady) and the spoken
1567
+ // surface-resume path (startResumeTurn) so both run identical turn machinery.
1568
+ private async launchAssistantTurn(
1569
+ utterance: UtteranceCycle,
1570
+ content: string,
1571
+ opts?: {
1572
+ // Only set on the surface-resume path; the STT path leaves it undefined
1573
+ // so no active-surface context is injected into an ordinary spoken turn.
1574
+ activeSurfaceId?: string;
1575
+ // Set on a barge-in follow-up turn: the interrupted request's transcript,
1576
+ // appended to the turn's control prompt so the model merges the two.
1577
+ interruptedRequest?: string | null;
1578
+ },
1579
+ ): Promise<void> {
1438
1580
  utterance.assistantTurnStarted = true;
1439
1581
  const token = Symbol("live-voice-assistant-turn");
1440
1582
  const turnId = this.ensureTurnId(utterance);
1441
1583
  this.startMetricsTurnIfNeeded(utterance, turnId);
1442
1584
  const abortController = new AbortController();
1443
- this.activeAssistantTurn = {
1585
+ const activeTurn: ActiveAssistantTurn = {
1444
1586
  token,
1445
1587
  turnId,
1446
1588
  utterance,
@@ -1450,6 +1592,8 @@ export class LiveVoiceSession implements LiveVoiceSessionContract {
1450
1592
  ttsDone: false,
1451
1593
  ttsAudioStarted: false,
1452
1594
  finalized: false,
1595
+ interruptedRequest: opts?.interruptedRequest ?? null,
1596
+ escalationHandedOff: false,
1453
1597
  ttsBuffer: "",
1454
1598
  ttsSegmentEnqueued: false,
1455
1599
  ttsJobs: [],
@@ -1458,12 +1602,234 @@ export class LiveVoiceSession implements LiveVoiceSessionContract {
1458
1602
  assistantAudioChunks: [],
1459
1603
  assistantAudioMimeType: "audio/pcm",
1460
1604
  };
1605
+ this.activeAssistantTurn = activeTurn;
1461
1606
 
1462
1607
  await this.sendFrame({ type: "thinking", turnId });
1463
1608
  if (!this.isActiveAssistantTurn(token)) {
1464
1609
  return;
1465
1610
  }
1466
1611
 
1612
+ // Triage-and-escalate (Voice Mode): active only when BOTH the voice-mode
1613
+ // surface flag and the voice-triage-escalate routing flag are on. A
1614
+ // live-voice session already implies voice-mode client-side; the explicit
1615
+ // check keeps the "gated behind both flags" contract true server-side.
1616
+ const cfg = getConfig();
1617
+ const escalateEnabled =
1618
+ isAssistantFeatureFlagEnabled("voice-mode", cfg) &&
1619
+ isVoiceTriageEscalateEnabled(cfg);
1620
+
1621
+ // Front-door leg: with routing on, a fast profile fronts the turn and may
1622
+ // hand off to the strong profile on [ESCALATE]; with it off, a single leg
1623
+ // runs on the call-site default — byte-for-byte the prior behavior.
1624
+ await this.startAssistantLeg(
1625
+ activeTurn,
1626
+ escalateEnabled
1627
+ ? {
1628
+ content,
1629
+ overrideProfile: FRONT_DOOR_PROFILE,
1630
+ routingLeg: "front-door",
1631
+ frontDoor: true,
1632
+ ...(opts?.activeSurfaceId !== undefined
1633
+ ? { activeSurfaceId: opts.activeSurfaceId }
1634
+ : {}),
1635
+ }
1636
+ : {
1637
+ content,
1638
+ ...(opts?.activeSurfaceId !== undefined
1639
+ ? { activeSurfaceId: opts.activeSurfaceId }
1640
+ : {}),
1641
+ },
1642
+ );
1643
+ }
1644
+
1645
+ /**
1646
+ * Resume a yielded interactive surface as a SPOKEN turn. The HTTP surface-
1647
+ * action path calls this (via the resume registry) once the user completes a
1648
+ * surface the voice turn raised, so the follow-up reply is synthesized to
1649
+ * audio through this session's TTS pipeline instead of running silently
1650
+ * through the text pipeline (JARVIS-1287).
1651
+ *
1652
+ * If a turn is still in flight the resume is deferred (pendingResume) and
1653
+ * dispatched once that turn settles — never rejected with CONVERSATION_BUSY.
1654
+ */
1655
+ resumeWithText(content: string, opts?: VoiceResumeOptions): void {
1656
+ const trimmed = content.trim();
1657
+ if (
1658
+ this.isClosed ||
1659
+ this.state === "failed" ||
1660
+ !this.startVoiceTurn ||
1661
+ trimmed.length === 0
1662
+ ) {
1663
+ return;
1664
+ }
1665
+ if (this.activeAssistantTurn) {
1666
+ this.pendingResume = { content: trimmed, opts };
1667
+ return;
1668
+ }
1669
+ void this.startResumeTurn(trimmed, opts).catch((err) => {
1670
+ log.error(
1671
+ { err, conversationId: this.conversationId },
1672
+ "live-voice resume turn failed",
1673
+ );
1674
+ });
1675
+ }
1676
+
1677
+ private async startResumeTurn(
1678
+ content: string,
1679
+ opts?: VoiceResumeOptions,
1680
+ ): Promise<void> {
1681
+ if (this.isClosed || this.state === "failed" || !this.startVoiceTurn) {
1682
+ return;
1683
+ }
1684
+ if (this.activeAssistantTurn) {
1685
+ this.pendingResume = { content, opts };
1686
+ return;
1687
+ }
1688
+ // A synthetic utterance carrying only the resume text: it is not
1689
+ // this.currentUtterance (which holds the server-VAD armed next utterance),
1690
+ // so the armed transcriber is untouched. finalizeAssistantTurn works on
1691
+ // turn.utterance and tolerates the empty audio buffers.
1692
+ const utterance: UtteranceCycle = {
1693
+ phase: "transcriber_closed",
1694
+ released: true,
1695
+ assistantTurnStarted: false,
1696
+ completed: false,
1697
+ finalizeRequested: false,
1698
+ transcriber: null,
1699
+ pendingAudioChunks: [],
1700
+ pendingAudioBytes: 0,
1701
+ finalTranscriptSegments: [content],
1702
+ turnId: null,
1703
+ userMessageId: null,
1704
+ userAudioChunks: [],
1705
+ metricsTurnStarted: false,
1706
+ metricsTurnFinished: false,
1707
+ stashedMetricsMarks: {
1708
+ firstAudioAtMs: null,
1709
+ firstPartialAtMs: null,
1710
+ speechStartAtMs: null,
1711
+ utteranceEndAtMs: null,
1712
+ finalTranscriptAtMs: null,
1713
+ },
1714
+ };
1715
+ await this.launchAssistantTurn(utterance, content, {
1716
+ activeSurfaceId: opts?.activeSurfaceId,
1717
+ });
1718
+ }
1719
+
1720
+ // Dispatch a resume deferred behind an in-flight turn, once that turn has
1721
+ // settled. Null out pendingResume before dispatch so a re-entrant settle
1722
+ // cannot double-fire the same resume.
1723
+ private flushPendingResume(): void {
1724
+ const deferred = this.pendingResume;
1725
+ this.pendingResume = null;
1726
+ if (
1727
+ deferred &&
1728
+ !this.activeAssistantTurn &&
1729
+ !this.isClosed &&
1730
+ this.state !== "failed"
1731
+ ) {
1732
+ void this.startResumeTurn(deferred.content, deferred.opts).catch(
1733
+ (err) => {
1734
+ log.error(
1735
+ { err, conversationId: this.conversationId },
1736
+ "live-voice deferred resume turn failed",
1737
+ );
1738
+ },
1739
+ );
1740
+ } else if (deferred) {
1741
+ // Could not dispatch now (turn still active / session gone); keep it for
1742
+ // the next settle point rather than dropping it.
1743
+ this.pendingResume = deferred;
1744
+ }
1745
+ }
1746
+
1747
+ /**
1748
+ * Drive one model leg of an assistant turn through the session bridge,
1749
+ * streaming its deltas to the live-voice client and TTS. Returns once the
1750
+ * leg's turn handle is acquired (or the start fails) — turn completion stays
1751
+ * callback-driven via message_complete, exactly as the single-leg path did.
1752
+ *
1753
+ * A turn runs one leg normally. Under triage-and-escalate the front-door leg
1754
+ * (`frontDoor: true`) may emit [ESCALATE]; the marker and everything after it
1755
+ * are held back from the live-voice transcript and TTS here at the source,
1756
+ * and `escalateTurn` starts a second "escalated" leg that shares this same
1757
+ * ActiveAssistantTurn. (The shared conversation-hub broadcast and persisted
1758
+ * assistant message still carry the raw marker — see issue #37850.)
1759
+ */
1760
+ private async startAssistantLeg(
1761
+ activeTurn: ActiveAssistantTurn,
1762
+ leg: {
1763
+ content: string;
1764
+ overrideProfile?: string;
1765
+ routingLeg?: VoiceRoutingLeg;
1766
+ frontDoor?: boolean;
1767
+ // Present only on the primary surface-resume leg — never on the escalated
1768
+ // continuation leg, so the active-surface context stays turn-scoped.
1769
+ activeSurfaceId?: string;
1770
+ },
1771
+ ): Promise<void> {
1772
+ if (!this.startVoiceTurn) {
1773
+ return;
1774
+ }
1775
+ const { token, utterance, turnId } = activeTurn;
1776
+
1777
+ // Front-door marker gate. `rawText` accumulates this leg's full stream (for
1778
+ // marker detection and the fallback-bridge decision); `frontDoorEmitted`
1779
+ // tracks how much of it has been forwarded, so a trailing partial marker
1780
+ // held back on one delta is released once a later delta disproves it.
1781
+ let rawText = "";
1782
+ let frontDoorEmitted = 0;
1783
+
1784
+ const emitFrontDoor = (chunk: string): void => {
1785
+ if (chunk.length === 0) {
1786
+ return;
1787
+ }
1788
+ this.markFirstAssistantDelta(utterance, turnId);
1789
+ // Same send-time abort gate as the default-leg delta path: a front-door
1790
+ // delta queued behind a backed-up outbound frame must not be written
1791
+ // once barge-in aborts the turn. Escalation aborts the front-door handle,
1792
+ // not this turn's controller, so legitimate front-door text still sends.
1793
+ void this.sendFrame(
1794
+ { type: "assistant_text_delta", text: chunk },
1795
+ () => !activeTurn.abortController.signal.aborted && !this.isClosed,
1796
+ );
1797
+ this.bufferAssistantTextForTts(token, chunk);
1798
+ };
1799
+
1800
+ // Forward the marker-free, non-partial-marker prefix that has not been
1801
+ // emitted yet. Returns true once the complete [ESCALATE] marker arrives.
1802
+ const flushFrontDoor = (): boolean => {
1803
+ const markerIdx = rawText.indexOf(ESCALATE_MARKER, frontDoorEmitted);
1804
+ if (markerIdx !== -1) {
1805
+ emitFrontDoor(
1806
+ stripInternalSpeechMarkers(
1807
+ rawText.slice(frontDoorEmitted, markerIdx),
1808
+ ),
1809
+ );
1810
+ // Suppress the marker and anything the model streams after it.
1811
+ frontDoorEmitted = rawText.length;
1812
+ return true;
1813
+ }
1814
+ let safeEnd = rawText.length;
1815
+ const lastOpen = rawText.lastIndexOf("[");
1816
+ if (lastOpen >= frontDoorEmitted) {
1817
+ const tail = rawText.slice(lastOpen);
1818
+ // Hold back a trailing "[…" that could still become a control marker;
1819
+ // a real partial that never completes is simply never spoken.
1820
+ if (!tail.includes("]") && couldBeControlMarker(tail)) {
1821
+ safeEnd = lastOpen;
1822
+ }
1823
+ }
1824
+ if (safeEnd > frontDoorEmitted) {
1825
+ emitFrontDoor(
1826
+ stripInternalSpeechMarkers(rawText.slice(frontDoorEmitted, safeEnd)),
1827
+ );
1828
+ frontDoorEmitted = safeEnd;
1829
+ }
1830
+ return false;
1831
+ };
1832
+
1467
1833
  try {
1468
1834
  const handle = await this.startVoiceTurn({
1469
1835
  conversationId: this.conversationId,
@@ -1472,67 +1838,106 @@ export class LiveVoiceSession implements LiveVoiceSessionContract {
1472
1838
  assistantMessageChannel: "vellum",
1473
1839
  userMessageInterface: "macos",
1474
1840
  assistantMessageInterface: "macos",
1475
- voiceControlPrompt:
1476
- "You are speaking in a local live voice session. Keep replies brief and conversational.",
1841
+ voiceControlPrompt: activeTurn.interruptedRequest
1842
+ ? `${LIVE_VOICE_CONTROL_PROMPT}\n\n${buildInterruptionMergeNote(
1843
+ activeTurn.interruptedRequest,
1844
+ )}`
1845
+ : LIVE_VOICE_CONTROL_PROMPT,
1477
1846
  approvalMode: "local-live-voice",
1478
- content,
1847
+ content: leg.content,
1479
1848
  isInbound: true,
1480
- signal: abortController.signal,
1849
+ signal: activeTurn.abortController.signal,
1850
+ ...(leg.overrideProfile != null
1851
+ ? { overrideProfile: leg.overrideProfile }
1852
+ : {}),
1853
+ ...(leg.routingLeg != null ? { routingLeg: leg.routingLeg } : {}),
1854
+ ...(leg.activeSurfaceId != null
1855
+ ? { activeSurfaceId: leg.activeSurfaceId }
1856
+ : {}),
1481
1857
  callbacks: {
1482
1858
  assistant_text_delta: (msg) => {
1483
1859
  if (!this.isForwardingAssistantText(token)) {
1484
1860
  return;
1485
1861
  }
1862
+ if (leg.frontDoor) {
1863
+ rawText += msg.text;
1864
+ if (activeTurn.escalationHandedOff) {
1865
+ return;
1866
+ }
1867
+ if (flushFrontDoor()) {
1868
+ this.escalateTurn(activeTurn, rawText);
1869
+ }
1870
+ return;
1871
+ }
1486
1872
  this.markFirstAssistantDelta(utterance, turnId);
1487
- void this.sendFrame({
1488
- type: "assistant_text_delta",
1489
- text: msg.text,
1490
- });
1873
+ void this.sendFrame(
1874
+ {
1875
+ type: "assistant_text_delta",
1876
+ text: msg.text,
1877
+ },
1878
+ // Re-check at send time (mirrors the tts_audio path): a delta
1879
+ // already queued behind a backed-up outbound frame must not be
1880
+ // written once barge-in has aborted the turn, or the cancelled
1881
+ // reply's text leaks ahead of turn_cancelled. Key off this turn's
1882
+ // own abort signal — a normal message_complete finalizes and
1883
+ // clears activeAssistantTurn while trailing deltas may still be
1884
+ // draining, so an activeAssistantTurn-based guard would drop them.
1885
+ () =>
1886
+ !activeTurn.abortController.signal.aborted && !this.isClosed,
1887
+ );
1491
1888
  this.bufferAssistantTextForTts(token, msg.text);
1492
1889
  },
1493
1890
  message_complete: (msg) => {
1494
- const activeTurn = this.activeAssistantTurn;
1891
+ const current = this.activeAssistantTurn;
1495
1892
  if (
1496
- activeTurn?.token !== token ||
1497
- activeTurn.assistantCompleted ||
1893
+ current?.token !== token ||
1894
+ current.assistantCompleted ||
1498
1895
  // A barged-in turn finalizes through cancelAssistantTurn.
1499
- activeTurn.abortController.signal.aborted ||
1896
+ current.abortController.signal.aborted ||
1500
1897
  this.isClosed
1501
1898
  ) {
1502
1899
  return;
1503
1900
  }
1504
- activeTurn.assistantCompleted = true;
1901
+ // A front-door leg that handed off is finished; the escalated leg
1902
+ // drives completion. The front-door leg's own trailing completion
1903
+ // (including the generation_cancelled from its abort) is a no-op.
1904
+ if (leg.frontDoor && current.escalationHandedOff) {
1905
+ return;
1906
+ }
1907
+ current.assistantCompleted = true;
1505
1908
  if (msg.type === "generation_cancelled") {
1506
1909
  void this.finalizeAssistantTurn(
1507
- activeTurn,
1910
+ current,
1508
1911
  "cancelled",
1509
1912
  "generation_cancelled",
1510
1913
  );
1511
1914
  return;
1512
1915
  }
1513
- activeTurn.assistantMessageId = msg.messageId ?? null;
1916
+ current.assistantMessageId = msg.messageId ?? null;
1514
1917
  this.completeTtsForTurn(token);
1515
1918
  },
1516
1919
  persisted_user_message_id: (messageId) => {
1517
- const activeTurn = this.activeAssistantTurn;
1518
- if (activeTurn?.token !== token) {
1920
+ const current = this.activeAssistantTurn;
1921
+ // Only the first leg's user row is the real caller utterance; the
1922
+ // escalated leg persists a hidden synthetic continuation prompt.
1923
+ if (current?.token !== token || leg.routingLeg === "escalated") {
1519
1924
  return;
1520
1925
  }
1521
- activeTurn.utterance.userMessageId = messageId;
1926
+ current.utterance.userMessageId = messageId;
1522
1927
  },
1523
1928
  persisted_assistant_message_id: (messageId) => {
1524
- const activeTurn = this.activeAssistantTurn;
1525
- if (activeTurn?.token !== token) {
1929
+ const current = this.activeAssistantTurn;
1930
+ if (current?.token !== token) {
1526
1931
  return;
1527
1932
  }
1528
- activeTurn.assistantMessageId = messageId;
1933
+ current.assistantMessageId = messageId;
1529
1934
  },
1530
1935
  },
1531
1936
  onError: (message) => {
1532
- const activeTurn = this.activeAssistantTurn;
1937
+ const current = this.activeAssistantTurn;
1533
1938
  if (
1534
1939
  !this.isActiveAssistantTurn(token) ||
1535
- activeTurn?.assistantCompleted
1940
+ current?.assistantCompleted
1536
1941
  ) {
1537
1942
  return;
1538
1943
  }
@@ -1551,17 +1956,23 @@ export class LiveVoiceSession implements LiveVoiceSessionContract {
1551
1956
  },
1552
1957
  });
1553
1958
 
1554
- const activeTurn = this.activeAssistantTurn;
1555
- if (activeTurn?.token !== token) {
1959
+ const current = this.activeAssistantTurn;
1960
+ if (current?.token !== token) {
1556
1961
  handle.abort();
1557
1962
  return;
1558
1963
  }
1559
- if (activeTurn.finalized) {
1964
+ if (current.finalized) {
1560
1965
  this.activeAssistantTurn = null;
1561
1966
  return;
1562
1967
  }
1968
+ // The front-door leg may have handed off before its handle resolved;
1969
+ // abort it rather than exposing it as the turn's live handle.
1970
+ if (leg.frontDoor && current.escalationHandedOff) {
1971
+ handle.abort();
1972
+ return;
1973
+ }
1563
1974
 
1564
- activeTurn.handle = handle;
1975
+ current.handle = handle;
1565
1976
  } catch (err) {
1566
1977
  if (!this.isActiveAssistantTurn(token)) {
1567
1978
  return;
@@ -1580,6 +1991,47 @@ export class LiveVoiceSession implements LiveVoiceSessionContract {
1580
1991
  }
1581
1992
  }
1582
1993
 
1994
+ /**
1995
+ * Hand the turn from the front-door leg to the strong "escalated" leg after
1996
+ * [ESCALATE]. Speaks a holding phrase (the front-door leg's own pre-marker
1997
+ * text, or a canned fallback when that was too short) and force-flushes it so
1998
+ * it plays during the strong-model call, then starts the escalated leg on the
1999
+ * same ActiveAssistantTurn. Idempotent.
2000
+ */
2001
+ private escalateTurn(
2002
+ activeTurn: ActiveAssistantTurn,
2003
+ frontDoorText: string,
2004
+ ): void {
2005
+ if (activeTurn.escalationHandedOff || activeTurn.finalized) {
2006
+ return;
2007
+ }
2008
+ activeTurn.escalationHandedOff = true;
2009
+ // Abort the front-door leg so a model that keeps generating past the marker
2010
+ // adds no latency before the escalated leg starts.
2011
+ activeTurn.handle?.abort();
2012
+ activeTurn.handle = null;
2013
+
2014
+ // Speak a bridge so the strong-model call has no dead air. Fall back to a
2015
+ // canned phrase only when the front-door leg spoke too little before the
2016
+ // marker (measured pre-marker, so suppressed post-marker text can't count).
2017
+ if (needsFallbackBridge(frontDoorText)) {
2018
+ this.bufferAssistantTextForTts(
2019
+ activeTurn.token,
2020
+ `${FALLBACK_ESCALATION_BRIDGE} `,
2021
+ );
2022
+ }
2023
+ // Force-flush now: on the TTS path an unpunctuated bridge would otherwise
2024
+ // sit buffered until a sentence boundary and leave the caller in silence
2025
+ // during the escalated model's call.
2026
+ this.flushTtsBuffer(activeTurn.token, true);
2027
+
2028
+ void this.startAssistantLeg(activeTurn, {
2029
+ content: ESCALATION_CONTINUATION_CONTENT,
2030
+ overrideProfile: ESCALATION_PROFILE,
2031
+ routingLeg: "escalated",
2032
+ });
2033
+ }
2034
+
1583
2035
  private async cancelAssistantTurn(reason: string): Promise<void> {
1584
2036
  const turn = this.activeAssistantTurn;
1585
2037
  this.activeAssistantTurn = null;
@@ -1605,7 +2057,14 @@ export class LiveVoiceSession implements LiveVoiceSessionContract {
1605
2057
  private isActiveAssistantTurn(token: symbol): boolean {
1606
2058
  const activeTurn = this.activeAssistantTurn;
1607
2059
  return (
1608
- activeTurn?.token === token && !activeTurn.finalized && !this.isClosed
2060
+ activeTurn?.token === token &&
2061
+ !activeTurn.finalized &&
2062
+ // Barge-in aborts synchronously but finalizes through an async
2063
+ // cancelAssistantTurn chain; the abort makes the turn dead at once so a
2064
+ // rejected startVoiceTurn or a trailing onError in that window does not
2065
+ // treat it as live (and emit a stray error frame or double-finalize).
2066
+ !activeTurn.abortController.signal.aborted &&
2067
+ !this.isClosed
1609
2068
  );
1610
2069
  }
1611
2070
 
@@ -1615,6 +2074,10 @@ export class LiveVoiceSession implements LiveVoiceSessionContract {
1615
2074
  activeTurn?.token === token &&
1616
2075
  !activeTurn.assistantCompleted &&
1617
2076
  !activeTurn.finalized &&
2077
+ // Fence a late first assistant_text_delta once barge-in aborts a pre-TTS
2078
+ // turn, before its async teardown finalizes — mirrors isForwardingTts so
2079
+ // no cancelled-turn text leaks after turn_cancelled.
2080
+ !activeTurn.abortController.signal.aborted &&
1618
2081
  !this.isClosed
1619
2082
  );
1620
2083
  }
@@ -1688,6 +2151,14 @@ export class LiveVoiceSession implements LiveVoiceSessionContract {
1688
2151
  }
1689
2152
  }
1690
2153
 
2154
+ // Now that the active turn is actually cleared, dispatch a resume that
2155
+ // arrived mid-turn. `finalizeAssistantTurn` runs its own flush too, but
2156
+ // this path finalizes with `clearActive: false`, so at that point the
2157
+ // slot was still taken and the flush re-stashed. `scheduleRearmAfterTurn`
2158
+ // below no-ops in manual (no-`turnDetector`) sessions, so without this
2159
+ // flush the deferred resume would never start there (JARVIS-1287).
2160
+ this.flushPendingResume();
2161
+
1691
2162
  // Re-arm only after the terminal tts_done frame so a slow or failing
1692
2163
  // next transcriber cannot block or precede turn completion. A
1693
2164
  // cancelled turn re-arms through cancelAssistantTurn instead.
@@ -1879,9 +2350,13 @@ export class LiveVoiceSession implements LiveVoiceSessionContract {
1879
2350
  if (activeTurn?.token !== token) {
1880
2351
  return;
1881
2352
  }
1882
- activeTurn.assistantAudioChunks.push(
1883
- Buffer.from(chunk.dataBase64, "base64"),
1884
- );
2353
+ // Only retain the assistant TTS audio when it will be archived (see
2354
+ // collectUserAudio); the mime/sample-rate are cheap and left unconditional.
2355
+ if (this.archiveAudio) {
2356
+ activeTurn.assistantAudioChunks.push(
2357
+ Buffer.from(chunk.dataBase64, "base64"),
2358
+ );
2359
+ }
1885
2360
  activeTurn.assistantAudioMimeType = chunk.contentType;
1886
2361
  activeTurn.assistantAudioSampleRate = chunk.sampleRate;
1887
2362
  job.frames = job.frames.then(async () => {
@@ -1894,10 +2369,10 @@ export class LiveVoiceSession implements LiveVoiceSessionContract {
1894
2369
  },
1895
2370
  () => this.isForwardingTts(token),
1896
2371
  );
1897
- // Arm the barge-in gate only once a tts_audio frame was actually
1898
- // written — a backed-up outbound queue must not let speech cancel a
1899
- // still-unspoken reply. Token match keeps a stale turn's late send
1900
- // from arming a newer turn.
2372
+ // Skip a frame that wasn't actually written — a backed-up outbound
2373
+ // queue hasn't reached the client, so it must not extend the
2374
+ // playback-tail estimate or latch first-audio state. Token match keeps
2375
+ // a stale turn's late send from latching a newer turn.
1901
2376
  if (!sent) {
1902
2377
  return;
1903
2378
  }
@@ -1921,7 +2396,12 @@ export class LiveVoiceSession implements LiveVoiceSessionContract {
1921
2396
  }
1922
2397
 
1923
2398
  private collectUserAudio(utterance: UtteranceCycle, chunk: Buffer): void {
1924
- utterance.userAudioChunks.push(Buffer.from(chunk));
2399
+ // Only retain the raw audio when it will actually be archived — otherwise
2400
+ // buffering a whole turn's PCM is dead memory. The first-audio metric is
2401
+ // independent of archiving, so it stays unconditional.
2402
+ if (this.archiveAudio) {
2403
+ utterance.userAudioChunks.push(Buffer.from(chunk));
2404
+ }
1925
2405
  this.markUtteranceMetric(utterance, "firstAudioAtMs", (turnId) =>
1926
2406
  this.metrics.markFirstAudio(turnId),
1927
2407
  );
@@ -2036,6 +2516,13 @@ export class LiveVoiceSession implements LiveVoiceSessionContract {
2036
2516
  utterance: UtteranceCycle,
2037
2517
  reason: string,
2038
2518
  ): Promise<void> {
2519
+ // An utterance that finalizes here never became a turn (empty transcript,
2520
+ // client interrupt, transcriber close, error), so it ends the window a
2521
+ // barge-in's merge context was waiting to attach to. Drop that context so
2522
+ // it can't leak into a later, unrelated turn. The barged turn itself
2523
+ // finalizes through finalizeAssistantTurn, not here, so this never clears a
2524
+ // request that the barge-in follow-up turn is still about to consume.
2525
+ this.pendingInterruptedRequest = null;
2039
2526
  utterance.completed = true;
2040
2527
  const turnId = utterance.turnId;
2041
2528
  if (!turnId) {
@@ -2089,6 +2576,11 @@ export class LiveVoiceSession implements LiveVoiceSessionContract {
2089
2576
  if (options.rearm ?? true) {
2090
2577
  this.scheduleRearmAfterTurn();
2091
2578
  }
2579
+
2580
+ // A surface-resume that arrived mid-turn waits here: the just-cleared
2581
+ // active turn frees the slot, so dispatch it now. rearmAfterTurn also
2582
+ // flushes (covers the manual path where scheduleRearmAfterTurn no-ops).
2583
+ this.flushPendingResume();
2092
2584
  }
2093
2585
 
2094
2586
  private async archiveBufferedAudio(input: {
@@ -2316,7 +2808,8 @@ export function createLiveVoiceSession(
2316
2808
  // unchanged. Optional-chained
2317
2809
  // because hand-built test configs may predate the liveVoice namespace;
2318
2810
  // absent config falls through to the in-code defaults.
2319
- const vadConfig = getConfig().liveVoice?.vad;
2811
+ const liveVoiceConfig = getConfig().liveVoice;
2812
+ const vadConfig = liveVoiceConfig?.vad;
2320
2813
  return new LiveVoiceSession(context, {
2321
2814
  ...options,
2322
2815
  turnDetectorConfig:
@@ -2340,9 +2833,16 @@ export function createLiveVoiceSession(
2340
2833
  options.streamTtsAudio === undefined
2341
2834
  ? defaultStreamLiveVoiceTtsAudio
2342
2835
  : options.streamTtsAudio,
2836
+ // Off by default (see the `liveVoice.archiveAudio` schema): voice turns
2837
+ // persist only their transcribed text, so the recorded audio never lands
2838
+ // as an attachment on the conversation messages. Enable via config for
2839
+ // playback/debugging. An explicit option (incl. `null`) always wins — the
2840
+ // test seam and any future caller override.
2343
2841
  archiveAudio:
2344
2842
  options.archiveAudio === undefined
2345
- ? defaultArchiveLiveVoiceAudio
2843
+ ? liveVoiceConfig?.archiveAudio
2844
+ ? defaultArchiveLiveVoiceAudio
2845
+ : null
2346
2846
  : options.archiveAudio,
2347
2847
  emitMetrics: options.emitMetrics ?? true,
2348
2848
  });
@@ -2383,8 +2883,49 @@ async function defaultStartVoiceTurn(
2383
2883
  options.conversationId,
2384
2884
  );
2385
2885
  }
2886
+ // Stamp the turn with the guardian's trust context — the same resolution the
2887
+ // text-send route runs for a local vellum principal. A local live-voice
2888
+ // session only exists for the guardian's own authenticated client (the
2889
+ // gateway pins the `/v1/live-voice` upgrade to the bound guardian), but the
2890
+ // live-voice ingress bypasses the send-message route, so without this stamp
2891
+ // the turn resolved to the fail-closed `unknown` trust class and every
2892
+ // sensitive tool was denied. Resolution stays fail-closed: a gateway miss /
2893
+ // missing binding leaves the context unset (`unknown`), never a blind grant.
2894
+ const trustContext = await resolveLocalLiveVoiceTrustContext(
2895
+ options.conversationId,
2896
+ );
2386
2897
  const { startVoiceTurn } = await import("../calls/voice-session-bridge.js");
2387
- return startVoiceTurn(options);
2898
+ return startVoiceTurn({
2899
+ ...options,
2900
+ ...(trustContext ? { trustContext } : {}),
2901
+ });
2902
+ }
2903
+
2904
+ /**
2905
+ * Resolve the local guardian's {@link TrustContext} for a live-voice turn, or
2906
+ * `undefined` when it cannot be established (no vellum guardian binding, or
2907
+ * the gateway is unreachable) — the turn then runs under the fail-closed
2908
+ * `unknown` capability set, exactly as an unstamped turn does.
2909
+ */
2910
+ async function resolveLocalLiveVoiceTrustContext(
2911
+ conversationId: string,
2912
+ ): Promise<TrustContext | undefined> {
2913
+ const { findLocalGuardianPrincipalId } =
2914
+ await import("../runtime/local-actor-identity.js");
2915
+ const { resolveLocalPrincipalTrustContext } =
2916
+ await import("../runtime/local-principal-trust.js");
2917
+ const guardianPrincipalId = await findLocalGuardianPrincipalId();
2918
+ if (!guardianPrincipalId) {
2919
+ return undefined;
2920
+ }
2921
+ const trustContext = await resolveLocalPrincipalTrustContext({
2922
+ actorPrincipalId: guardianPrincipalId,
2923
+ sourceChannel: "vellum",
2924
+ conversationExternalId: conversationId,
2925
+ });
2926
+ // Only stamp a positive guardian resolution; the resolver's own
2927
+ // fail-closed `unknown` carries no more information than no stamp.
2928
+ return trustContext.trustClass === "guardian" ? trustContext : undefined;
2388
2929
  }
2389
2930
 
2390
2931
  async function defaultStreamLiveVoiceTtsAudio(