@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
@@ -1,8 +1,24 @@
1
1
  /**
2
2
  * Usage telemetry reporter.
3
3
  *
4
- * Periodically flushes LLM usage events and turn events (user messages) from
5
- * the local SQLite database and POSTs them to the platform telemetry endpoint.
4
+ * Periodically flushes unreported telemetry events (LLM usage, turns,
5
+ * lifecycle, ...) from the local SQLite databases and POSTs them to the
6
+ * platform telemetry endpoint. Each event type is a
7
+ * {@link TelemetryEventSource}; the reporter is a generic engine over the
8
+ * source list it is constructed with, acknowledging each source after a
9
+ * successful upload in one of two modes: watermark-mode sources advance a
10
+ * compound `(createdAt, id)` cursor in the telemetry DB's
11
+ * `flush_checkpoints` table, and ack-mode sources (those defining `ack`)
12
+ * delete their shipped rows instead.
13
+ *
14
+ * Flushing is split across two processes, each running its own reporter
15
+ * instance over a disjoint source partition: the daemon flushes turn events
16
+ * (their completeness barrier and consented traces read live in-memory
17
+ * conversation state), and the resource monitor process flushes everything
18
+ * else off the daemon's event loop — see `monitoring/worker.ts`. The
19
+ * per-source watermark cursors live in the telemetry DB, which both
20
+ * processes open read-write; each instance only touches its own sources'
21
+ * cursors, so the split shares no flush state.
6
22
  *
7
23
  * Authenticated-only: events are sent via the managed proxy context
8
24
  * (Api-Key header). When no platform credentials are available, or when
@@ -10,39 +26,27 @@
10
26
  * flush is skipped and retried next cycle.
11
27
  */
12
28
 
13
- import { isAssistantFeatureFlagEnabled } from "../config/assistant-feature-flags.js";
14
29
  import { getPlatformOrganizationId, getPlatformUserId } from "../config/env.js";
15
- import { getConfig } from "../config/loader.js";
16
- import { queryUnreportedOnboardingEvents } from "../onboarding/onboarding-events-store.js";
17
- import {
18
- getMemoryCheckpoint,
19
- setMemoryCheckpoint,
20
- } from "../persistence/checkpoints.js";
21
- import { queryUnreportedLifecycleEvents } from "../persistence/lifecycle-events-store.js";
22
- import { queryUnreportedUsageEvents } from "../persistence/llm-usage-store.js";
23
30
  import { VellumPlatformClient } from "../platform/client.js";
24
- import {
25
- getCachedShareAnalytics,
26
- getCachedShareDiagnostics,
27
- getCachedShareDiagnosticsVersion,
28
- } from "../platform/consent-cache.js";
31
+ import { getCachedShareAnalytics } from "../platform/consent-cache.js";
29
32
  import { arePlatformFeaturesEnabled } from "../platform/feature-gate.js";
30
- import { queryUnreportedAuthFallbackEvents } from "../security/auth-fallback-events-store.js";
31
- import type { UsageAttributionProfileSource } from "../usage/types.js";
32
33
  import { getDeviceId } from "../util/device-id.js";
33
34
  import { getLogger } from "../util/logger.js";
34
35
  import { APP_VERSION } from "../version.js";
35
36
  import {
36
- type ActivationStepName,
37
- buildActivationDaemonEventId,
38
- } from "./activation-funnel.js";
39
- import { queryUnreportedSkillLoadedEvents } from "./skill-loaded-events-store.js";
40
- import { queryUnreportedToolExecutedEvents } from "./tool-executed-events-store.js";
41
- import { isDiagnosticsConsentVersionEligible } from "./trace-collection-policy.js";
42
- import { queryUnreportedTurnEvents } from "./turn-events-store.js";
43
- import { assembleBoundedTurnTrace, isTurnSettled } from "./turn-trace-store.js";
44
- import type { TelemetryEvent, TurnTelemetryClientInfo } from "./types.js";
45
- import { queryUnreportedWatchdogEvents } from "./watchdog-events-store.js";
37
+ type FlushCheckpointStore,
38
+ telemetryDbFlushCheckpointStore,
39
+ } from "./flush-checkpoints.js";
40
+ import {
41
+ DAEMON_TELEMETRY_EVENT_SOURCES,
42
+ MONITOR_TELEMETRY_EVENT_SOURCES,
43
+ type TelemetryEventSource,
44
+ type TelemetryEventSourceBatch,
45
+ TOOL_EXECUTED_SOURCE_ID,
46
+ watermarkKeysForSource,
47
+ } from "./telemetry-event-sources.js";
48
+ import { useReadOnlyMainDbForTelemetry } from "./telemetry-main-db.js";
49
+ import { validateWireEvents } from "./telemetry-wire-validation.js";
46
50
 
47
51
  const log = getLogger("usage-telemetry");
48
52
 
@@ -50,59 +54,11 @@ const log = getLogger("usage-telemetry");
50
54
  // Constants
51
55
  // ---------------------------------------------------------------------------
52
56
 
53
- const CHECKPOINT_KEY_WATERMARK = "telemetry:usage:last_reported_at";
54
- const CHECKPOINT_KEY_WATERMARK_ID = "telemetry:usage:last_reported_id";
55
- const CHECKPOINT_KEY_TURN_WATERMARK = "telemetry:turns:last_reported_at";
56
- const CHECKPOINT_KEY_TURN_WATERMARK_ID = "telemetry:turns:last_reported_id";
57
- const CHECKPOINT_KEY_LIFECYCLE_WATERMARK =
58
- "telemetry:lifecycle:last_reported_at";
59
- const CHECKPOINT_KEY_LIFECYCLE_WATERMARK_ID =
60
- "telemetry:lifecycle:last_reported_id";
61
- const CHECKPOINT_KEY_ONBOARDING_WATERMARK =
62
- "telemetry:onboarding:last_reported_at";
63
- const CHECKPOINT_KEY_ONBOARDING_WATERMARK_ID =
64
- "telemetry:onboarding:last_reported_id";
65
- const CHECKPOINT_KEY_AUTH_FALLBACK_WATERMARK =
66
- "telemetry:auth_fallback:last_reported_at";
67
- const CHECKPOINT_KEY_AUTH_FALLBACK_WATERMARK_ID =
68
- "telemetry:auth_fallback:last_reported_id";
69
- const CHECKPOINT_KEY_TOOL_EXECUTED_WATERMARK =
70
- "telemetry:tool_executed:last_reported_at";
71
- const CHECKPOINT_KEY_TOOL_EXECUTED_WATERMARK_ID =
72
- "telemetry:tool_executed:last_reported_id";
73
- const CHECKPOINT_KEY_SKILL_LOADED_WATERMARK =
74
- "telemetry:skill_loaded:last_reported_at";
75
- const CHECKPOINT_KEY_SKILL_LOADED_WATERMARK_ID =
76
- "telemetry:skill_loaded:last_reported_id";
77
- const CHECKPOINT_KEY_WATCHDOG_WATERMARK = "telemetry:watchdog:last_reported_at";
78
- const CHECKPOINT_KEY_WATCHDOG_WATERMARK_ID =
79
- "telemetry:watchdog:last_reported_id";
80
57
  // Written into the `*_id` watermark checkpoints by the opt-out flush branch.
81
58
  // Sorts lexicographically above every real row ID (all event stores generate
82
59
  // lowercase v4 UUIDs), so the compound cursor's same-millisecond arm
83
60
  // (`createdAt == watermark AND id > afterId`) can never match an opt-out row.
84
61
  const OPT_OUT_WATERMARK_ID_SENTINEL = "ffffffff-ffff-ffff-ffff-ffffffffffff";
85
- // (timestamp, id) checkpoint-key pairs for every event type's compound
86
- // cursor — keep in sync when adding an event type.
87
- const WATERMARK_KEY_PAIRS: ReadonlyArray<readonly [string, string]> = [
88
- [CHECKPOINT_KEY_WATERMARK, CHECKPOINT_KEY_WATERMARK_ID],
89
- [CHECKPOINT_KEY_TURN_WATERMARK, CHECKPOINT_KEY_TURN_WATERMARK_ID],
90
- [CHECKPOINT_KEY_LIFECYCLE_WATERMARK, CHECKPOINT_KEY_LIFECYCLE_WATERMARK_ID],
91
- [CHECKPOINT_KEY_ONBOARDING_WATERMARK, CHECKPOINT_KEY_ONBOARDING_WATERMARK_ID],
92
- [
93
- CHECKPOINT_KEY_AUTH_FALLBACK_WATERMARK,
94
- CHECKPOINT_KEY_AUTH_FALLBACK_WATERMARK_ID,
95
- ],
96
- [
97
- CHECKPOINT_KEY_TOOL_EXECUTED_WATERMARK,
98
- CHECKPOINT_KEY_TOOL_EXECUTED_WATERMARK_ID,
99
- ],
100
- [
101
- CHECKPOINT_KEY_SKILL_LOADED_WATERMARK,
102
- CHECKPOINT_KEY_SKILL_LOADED_WATERMARK_ID,
103
- ],
104
- [CHECKPOINT_KEY_WATCHDOG_WATERMARK, CHECKPOINT_KEY_WATCHDOG_WATERMARK_ID],
105
- ];
106
62
  const REPORT_INTERVAL_MS = 5 * 60 * 1000;
107
63
  const INITIAL_FLUSH_DELAY_MS = 30_000; // Delay first flush to let CES handshake complete
108
64
  const BATCH_SIZE = 500;
@@ -119,29 +75,64 @@ export function getUsageTelemetryReporter(): UsageTelemetryReporter | null {
119
75
  return _instance;
120
76
  }
121
77
 
78
+ function startReporterWithSources(
79
+ sources: readonly TelemetryEventSource[],
80
+ label: string,
81
+ ): void {
82
+ if (process.env.VELLUM_DEV === "1") {
83
+ return;
84
+ }
85
+ if (_instance) {
86
+ return;
87
+ }
88
+ _instance = new UsageTelemetryReporter(sources);
89
+ _instance.start();
90
+ log.info(`${label} telemetry reporter started`);
91
+ }
92
+
122
93
  /**
123
- * Construct and start the singleton usage telemetry reporter. No-op in dev mode
124
- * (VELLUM_DEV=1) and idempotent if already started.
94
+ * Construct and start the daemon's singleton telemetry reporter, flushing
95
+ * the daemon-owned sources (turn events). No-op in dev mode (VELLUM_DEV=1)
96
+ * and idempotent if already started.
125
97
  *
126
98
  * Started even when share_analytics consent is opted out: flush() re-checks
127
- * consent each cycle and, when opted out, sends nothing but advances all
128
- * watermarks (including the final flush in stop()). New opted-out
129
- * tool_invocations rows are already unreportable by construction — the audit
130
- * listener persists NULL telemetry columns for them, which the tool_executed
131
- * projection filters out — so the opted-out flushes are defense in depth there
132
- * (covering rows recorded under builds that predate that write-time gate) and
133
- * remain the primary guard for the always-on tables without a write-time gate
134
- * (llm_usage, turn events). Not gated on DB readiness: getDb() can still work
135
- * when initializeDb() failed mid-migration, in which case the audit listener
136
- * keeps writing rows the opt-out branch must keep covered. The reporter is
137
- * degraded-mode safe — its constructor and flush() treat DB errors as non-fatal.
99
+ * consent each cycle and, when opted out, sends nothing but advances its
100
+ * sources' watermarks (including the final flush in stop()). Not gated on DB
101
+ * readiness: getDb() can still work when initializeDb() failed mid-migration,
102
+ * in which case message writes keep producing rows the opt-out branch must
103
+ * keep covered. The reporter is degraded-mode safe — flush() treats DB errors
104
+ * as non-fatal.
105
+ *
106
+ * Also initializes the tool_executed absent-watermark epoch even though that
107
+ * source is flushed by the monitor process: the "no flush has ever advanced
108
+ * it" guard needs the before-any-tool-runs ordering only daemon startup can
109
+ * provide (the monitor boots concurrently with the daemon serving turns).
138
110
  */
139
111
  export function startUsageTelemetryReporter(): void {
140
- if (process.env.VELLUM_DEV === "1") return;
141
- if (_instance) return;
142
- _instance = new UsageTelemetryReporter();
143
- _instance.start();
144
- log.info("Usage telemetry reporter started");
112
+ if (process.env.VELLUM_DEV === "1") {
113
+ return;
114
+ }
115
+ initToolExecutedWatermarkIfAbsent(telemetryDbFlushCheckpointStore);
116
+ startReporterWithSources(DAEMON_TELEMETRY_EVENT_SOURCES, "Daemon");
117
+ }
118
+
119
+ /**
120
+ * Construct and start the resource monitor process's singleton telemetry
121
+ * reporter, flushing every non-turn source off the daemon's event loop.
122
+ * No-op in dev mode (VELLUM_DEV=1) and idempotent if already started.
123
+ *
124
+ * Switches this process's telemetry main-DB reads to the dedicated
125
+ * read-only connection first: the monitor observes the daemon's main DB
126
+ * (WAL permits cross-process readers) and must never write to it or create
127
+ * it. The caller (monitoring/worker.ts) is responsible for the consent
128
+ * refresh loop the share_analytics gate reads.
129
+ */
130
+ export function startMonitorUsageTelemetryReporter(): void {
131
+ if (process.env.VELLUM_DEV === "1") {
132
+ return;
133
+ }
134
+ useReadOnlyMainDbForTelemetry();
135
+ startReporterWithSources(MONITOR_TELEMETRY_EVENT_SOURCES, "Monitor");
145
136
  }
146
137
 
147
138
  /**
@@ -149,7 +140,9 @@ export function startUsageTelemetryReporter(): void {
149
140
  * and clear it. No-op when the reporter was never started (e.g. dev mode).
150
141
  */
151
142
  export async function stopUsageTelemetryReporter(): Promise<void> {
152
- if (!_instance) return;
143
+ if (!_instance) {
144
+ return;
145
+ }
153
146
  try {
154
147
  await _instance.stop();
155
148
  } finally {
@@ -157,34 +150,39 @@ export async function stopUsageTelemetryReporter(): Promise<void> {
157
150
  }
158
151
  }
159
152
 
160
- // ---------------------------------------------------------------------------
161
- // Helpers
162
- // ---------------------------------------------------------------------------
163
-
164
153
  /**
165
- * Parse a stored `watchdog_events.detail` JSON text column into the object the
166
- * platform expects. Returns null for a null column or an unparseable/corrupted
167
- * blob (mirroring the turn `client` metadata parse: a bad blob emits null
168
- * rather than failing the batch). A non-object (e.g. a bare number or string)
169
- * also resolves to null, since the platform serializer treats `detail` as a
170
- * JSON object bag.
154
+ * Initialize the tool_executed flush watermark to "now" when absent.
155
+ *
156
+ * `tool_invocations` is an always-on audit table that predates the reporter
157
+ * shipping its rows: an absent watermark means no flush (opted in or out) has
158
+ * ever advanced it, so rows recorded before this build — including any
159
+ * opted-out period under older builds that gated the reporter on the
160
+ * usage-data opt-out — would otherwise ship retroactively. Runs at daemon
161
+ * startup, before any tool can run, so no legitimate row falls behind the
162
+ * epoch; the checkpoint persists immediately so a crash can't leave it absent
163
+ * and re-initialize later. An EXISTING watermark is never touched: opted-out
164
+ * sessions keep it advancing via the opt-out flush branch, and overwriting it
165
+ * would drop a legitimate unshipped backlog. The other sources need no init:
166
+ * their recording is either consent-gated at write time (opt-out rows never
167
+ * exist) or covered by the same watermark discipline from first boot.
168
+ *
169
+ * Best-effort: DB init failures are tolerated at daemon startup (degraded
170
+ * mode), so this never throws — matching flush(), which treats DB errors as
171
+ * non-fatal.
171
172
  */
172
- function parseWatchdogDetail(
173
- raw: string | null,
174
- ): Record<string, unknown> | null {
175
- if (!raw) return null;
173
+ export function initToolExecutedWatermarkIfAbsent(
174
+ checkpoints: FlushCheckpointStore,
175
+ ): void {
176
176
  try {
177
- const parsed = JSON.parse(raw) as unknown;
178
- if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
179
- return parsed as Record<string, unknown>;
177
+ const key = watermarkKeysForSource(TOOL_EXECUTED_SOURCE_ID).at;
178
+ if (checkpoints.get(key) == null) {
179
+ checkpoints.set(key, String(Date.now()));
180
180
  }
181
- return null;
182
- } catch {
181
+ } catch (err) {
183
182
  log.warn(
184
- { rawDetail: raw.slice(0, 200) },
185
- "Telemetry watchdog: failed to parse detail; emitting null",
183
+ { err },
184
+ "tool_executed watermark init failed — non-fatal; a later run with a working DB re-runs the absent-checkpoint init",
186
185
  );
187
- return null;
188
186
  }
189
187
  }
190
188
 
@@ -196,39 +194,23 @@ export class UsageTelemetryReporter {
196
194
  private initialFlushTimer: ReturnType<typeof setTimeout> | null = null;
197
195
  private timer: ReturnType<typeof setInterval> | null = null;
198
196
  private activeFlush: Promise<void> | null = null;
199
-
200
- constructor() {
201
- // `tool_invocations` is an always-on audit table that predates this
202
- // reporter shipping its rows: an absent watermark means no flush (opted
203
- // in or out) has ever advanced it, so rows recorded before this build —
204
- // including any opted-out period under older builds that gated the
205
- // reporter on the usage-data opt-out — would otherwise ship retroactively.
206
- // Initialize an absent watermark to "now" at construction. Construction
207
- // happens during daemon startup before any tool runs, so no legitimate
208
- // row falls behind the watermark — initializing at first FLUSH instead
209
- // would drop tools used during the 30s+ flush delay. The checkpoint is
210
- // persisted immediately so a crash before the first flush can't leave it
211
- // absent and re-initialize later. An EXISTING watermark is never touched:
212
- // opted-out sessions keep it advancing via the opt-out flush branch, and
213
- // overwriting it here would drop a legitimate unshipped backlog.
214
- // `skill_loaded` needs no init: recording is gated on share_analytics
215
- // consent, so opt-out rows never exist and its standard 0 default is safe.
216
- //
217
- // Best-effort: DB init failures are tolerated at daemon startup (degraded
218
- // mode), so this must never throw out of the constructor — matching
219
- // flush(), which treats DB errors as non-fatal.
220
- try {
221
- if (getMemoryCheckpoint(CHECKPOINT_KEY_TOOL_EXECUTED_WATERMARK) == null) {
222
- setMemoryCheckpoint(
223
- CHECKPOINT_KEY_TOOL_EXECUTED_WATERMARK,
224
- String(Date.now()),
225
- );
226
- }
227
- } catch (err) {
228
- log.warn(
229
- { err },
230
- "tool_executed watermark init failed at construction — non-fatal; a later construction with a working DB re-runs the absent-checkpoint init",
231
- );
197
+ private readonly sources: readonly TelemetryEventSource[];
198
+ private readonly checkpoints: FlushCheckpointStore;
199
+
200
+ constructor(
201
+ sources: readonly TelemetryEventSource[],
202
+ checkpoints: FlushCheckpointStore = telemetryDbFlushCheckpointStore,
203
+ ) {
204
+ this.sources = sources;
205
+ this.checkpoints = checkpoints;
206
+ // Backstop for the tool_executed absent-watermark epoch (see
207
+ // initToolExecutedWatermarkIfAbsent) — the authoritative init runs at
208
+ // daemon startup, which alone guarantees the before-any-tool-runs
209
+ // ordering; constructing an instance that flushes the source re-runs the
210
+ // guarded init in case that never happened (e.g. a standalone monitor
211
+ // started out of band).
212
+ if (this.sources.some((s) => s.id === TOOL_EXECUTED_SOURCE_ID)) {
213
+ initToolExecutedWatermarkIfAbsent(this.checkpoints);
232
214
  }
233
215
  }
234
216
 
@@ -267,7 +249,9 @@ export class UsageTelemetryReporter {
267
249
  }
268
250
 
269
251
  async flush(): Promise<void> {
270
- if (this.activeFlush) return; // overlap guard
252
+ if (this.activeFlush) {
253
+ return; // overlap guard
254
+ }
271
255
  this.activeFlush = this._doFlush();
272
256
  try {
273
257
  await this.activeFlush;
@@ -278,7 +262,9 @@ export class UsageTelemetryReporter {
278
262
 
279
263
  private async _doFlush(batchCount = 0): Promise<void> {
280
264
  try {
281
- if (batchCount >= MAX_CONSECUTIVE_BATCHES) return;
265
+ if (batchCount >= MAX_CONSECUTIVE_BATCHES) {
266
+ return;
267
+ }
282
268
 
283
269
  // Skip when platform features are disabled (VELLUM_DISABLE_PLATFORM in
284
270
  // local mode; the flag is ignored when IS_PLATFORM is set, matching
@@ -289,6 +275,17 @@ export class UsageTelemetryReporter {
289
275
  return;
290
276
  }
291
277
 
278
+ // Skip when the flush-checkpoint store (telemetry DB) is unreachable.
279
+ // An unreadable watermark must not be mistaken for cursor 0 — that
280
+ // would requery and re-ship history from the beginning. Nothing is
281
+ // advanced or sent; the cycle retries once the store is back.
282
+ if (!this.checkpoints.isAvailable()) {
283
+ log.warn(
284
+ "Telemetry flush: flush-checkpoint store unavailable — skipping, will retry next cycle",
285
+ );
286
+ return;
287
+ }
288
+
292
289
  // Respect opt-out: if the platform owner has not granted
293
290
  // `share_analytics` consent, skip the flush and advance watermarks so
294
291
  // events recorded during the opt-out window are never sent
@@ -306,205 +303,76 @@ export class UsageTelemetryReporter {
306
303
  // opted-out tool_invocations rows persist NULL telemetry columns and
307
304
  // are unreportable by construction regardless of watermark timing.
308
305
  if (!getCachedShareAnalytics()) {
309
- // Advance the timestamp watermarks and pin the ID watermarks to a
310
- // sentinel that sorts above any real UUID. The sentinel (rather than
311
- // "") keeps the compound-cursor branch active — a falsy ID would
306
+ // Ack-mode sources drop their pending rows outright. Watermark-mode
307
+ // sources advance the timestamp watermarks and pin the ID watermarks
308
+ // to a sentinel that sorts above any real UUID. The sentinel (rather
309
+ // than "") keeps the compound-cursor branch active — a falsy ID would
312
310
  // downgrade the query to a timestamp-only `gt(createdAt, watermark)`
313
311
  // — while making its same-millisecond arm unsatisfiable, so a row
314
312
  // written in the same millisecond as this flush's Date.now() can
315
313
  // never ship after a later opt-in. The next opted-in flush that
316
314
  // ships events overwrites the sentinel with a real row ID.
317
315
  const now = String(Date.now());
318
- for (const [timestampKey, idKey] of WATERMARK_KEY_PAIRS) {
319
- setMemoryCheckpoint(timestampKey, now);
320
- setMemoryCheckpoint(idKey, OPT_OUT_WATERMARK_ID_SENTINEL);
316
+ for (const source of this.sources) {
317
+ if (source.ack) {
318
+ source.ack.discardPending();
319
+ continue;
320
+ }
321
+ const keys = watermarkKeysForSource(source.id);
322
+ this.checkpoints.set(keys.at, now);
323
+ this.checkpoints.set(keys.id, OPT_OUT_WATERMARK_ID_SENTINEL);
321
324
  }
322
325
  return;
323
326
  }
324
327
 
325
- // Read usage watermark (compound cursor: createdAt + id)
326
- const watermark = Number(
327
- getMemoryCheckpoint(CHECKPOINT_KEY_WATERMARK) ?? "0",
328
- );
329
- const watermarkId =
330
- getMemoryCheckpoint(CHECKPOINT_KEY_WATERMARK_ID) ?? undefined;
331
-
332
- // Read turn watermark (compound cursor: createdAt + id)
333
- const turnWatermark = Number(
334
- getMemoryCheckpoint(CHECKPOINT_KEY_TURN_WATERMARK) ?? "0",
335
- );
336
- const turnWatermarkId =
337
- getMemoryCheckpoint(CHECKPOINT_KEY_TURN_WATERMARK_ID) ?? undefined;
338
-
339
- // Read lifecycle watermark (compound cursor: createdAt + id)
340
- const lifecycleWatermark = Number(
341
- getMemoryCheckpoint(CHECKPOINT_KEY_LIFECYCLE_WATERMARK) ?? "0",
342
- );
343
- const lifecycleWatermarkId =
344
- getMemoryCheckpoint(CHECKPOINT_KEY_LIFECYCLE_WATERMARK_ID) ?? undefined;
345
-
346
- // Read onboarding watermark (compound cursor: createdAt + id)
347
- const onboardingWatermark = Number(
348
- getMemoryCheckpoint(CHECKPOINT_KEY_ONBOARDING_WATERMARK) ?? "0",
349
- );
350
- const onboardingWatermarkId =
351
- getMemoryCheckpoint(CHECKPOINT_KEY_ONBOARDING_WATERMARK_ID) ??
352
- undefined;
353
-
354
- // Read auth-fallback watermark (compound cursor: createdAt + id)
355
- const authFallbackWatermark = Number(
356
- getMemoryCheckpoint(CHECKPOINT_KEY_AUTH_FALLBACK_WATERMARK) ?? "0",
357
- );
358
- const authFallbackWatermarkId =
359
- getMemoryCheckpoint(CHECKPOINT_KEY_AUTH_FALLBACK_WATERMARK_ID) ??
360
- undefined;
361
-
362
- // Read tool-executed watermark (compound cursor: createdAt + id).
363
- // An absent checkpoint was initialized to construction time (see the
364
- // constructor), guarding opt-out windows; the 0 fallback here is a
365
- // defensive default matching the other event types. Legacy rows are
366
- // excluded at the query level (see queryUnreportedToolExecutedEvents).
367
- const toolExecutedWatermark = Number(
368
- getMemoryCheckpoint(CHECKPOINT_KEY_TOOL_EXECUTED_WATERMARK) ?? "0",
369
- );
370
- const toolExecutedWatermarkId =
371
- getMemoryCheckpoint(CHECKPOINT_KEY_TOOL_EXECUTED_WATERMARK_ID) ??
372
- undefined;
373
-
374
- // Read skill-loaded watermark (compound cursor: createdAt + id).
375
- // Writes are gated on share_analytics consent, so opted-out rows
376
- // cannot exist and the standard 0 default is safe.
377
- const skillLoadedWatermark = Number(
378
- getMemoryCheckpoint(CHECKPOINT_KEY_SKILL_LOADED_WATERMARK) ?? "0",
379
- );
380
- const skillLoadedWatermarkId =
381
- getMemoryCheckpoint(CHECKPOINT_KEY_SKILL_LOADED_WATERMARK_ID) ??
382
- undefined;
383
-
384
- // Read watchdog watermark (compound cursor: createdAt + id).
385
- // Writes are gated on share_analytics consent, so opted-out rows
386
- // cannot exist and the standard 0 default is safe.
387
- const watchdogWatermark = Number(
388
- getMemoryCheckpoint(CHECKPOINT_KEY_WATCHDOG_WATERMARK) ?? "0",
389
- );
390
- const watchdogWatermarkId =
391
- getMemoryCheckpoint(CHECKPOINT_KEY_WATCHDOG_WATERMARK_ID) ?? undefined;
392
-
393
- // Query unreported events
394
- const events = queryUnreportedUsageEvents(
395
- watermark,
396
- watermarkId,
397
- BATCH_SIZE,
398
- );
399
- const turnEvents = queryUnreportedTurnEvents(
400
- turnWatermark,
401
- turnWatermarkId,
402
- BATCH_SIZE,
403
- );
404
- const lifecycleEvents = queryUnreportedLifecycleEvents(
405
- lifecycleWatermark,
406
- lifecycleWatermarkId,
407
- BATCH_SIZE,
408
- );
409
- const onboardingEvents = queryUnreportedOnboardingEvents(
410
- onboardingWatermark,
411
- onboardingWatermarkId,
412
- BATCH_SIZE,
413
- );
414
- const authFallbackEvents = queryUnreportedAuthFallbackEvents(
415
- authFallbackWatermark,
416
- authFallbackWatermarkId,
417
- BATCH_SIZE,
418
- );
419
- const toolExecutedEvents = queryUnreportedToolExecutedEvents(
420
- toolExecutedWatermark,
421
- toolExecutedWatermarkId,
422
- BATCH_SIZE,
423
- );
424
- const skillLoadedEvents = queryUnreportedSkillLoadedEvents(
425
- skillLoadedWatermark,
426
- skillLoadedWatermarkId,
427
- BATCH_SIZE,
428
- );
429
- const watchdogEvents = queryUnreportedWatchdogEvents(
430
- watchdogWatermark,
431
- watchdogWatermarkId,
432
- BATCH_SIZE,
433
- );
328
+ // Read each source's watermark (compound cursor: createdAt + id) and
329
+ // collect its reportable batch. Absent checkpoints default to cursor 0
330
+ // — safe for the consent-gated tables (opted-out rows never exist) and
331
+ // for tool_executed, whose absent watermark was initialized at
332
+ // construction (see the constructor).
333
+ const batches: Array<{
334
+ source: TelemetryEventSource;
335
+ batch: TelemetryEventSourceBatch;
336
+ }> = this.sources.map((source) => {
337
+ const keys = watermarkKeysForSource(source.id);
338
+ const afterCreatedAt = Number(this.checkpoints.get(keys.at) ?? "0");
339
+ const afterId = this.checkpoints.get(keys.id) ?? undefined;
340
+ return {
341
+ source,
342
+ batch: source.collect(afterCreatedAt, afterId, BATCH_SIZE),
343
+ };
344
+ });
434
345
 
435
- // Turn completeness barrier (every turn event).
436
- //
437
- // A turn event must only be sent once that turn is COMPLETE, for two
438
- // reasons sharing the same failure mode (the watermark advances on ship,
439
- // so anything captured early is frozen forever):
440
- // - the consented `trace` would capture a partial mid-reply
441
- // transcript, and
442
- // - the `outcome` stamp (`messages.metadata.turnOutcome`, written by
443
- // the agent loop / drainBatch while the conversation is still
444
- // processing) would be missed, permanently mislabeling a
445
- // failed/cancelled/batched turn as normally-replied.
446
- // So we report only the leading run of complete turns and STOP at the
447
- // first incomplete (in-flight) one: the turn watermark is a single
448
- // monotonic `(createdAt, id)` cursor, so a later complete turn cannot be
449
- // reported past an earlier deferred one without skipping it. The
450
- // deferred turn (and everything after it) is picked up on a later flush
451
- // once its response settles.
452
- //
453
- // Trace eligibility is composed daemon-side to mirror the platform's
454
- // authoritative owner-based ingest gate, so traces for ineligible owners
455
- // never leave the device. Three parts, fail-closed (all must be true):
456
- // 1. the `trace-collection` LaunchDarkly flag (delivered via the
457
- // assistant-tagged flag sync, already evaluated server-side for this
458
- // assistant's owner),
459
- // 2. the owner's cached `share_diagnostics` consent, and
460
- // 3. the owner's cached `share_diagnostics_accepted_version` being at or
461
- // past the disclosing version — the platform applies the identical
462
- // check, so an old consent never yields a trace here or there.
463
- const traceEligible =
464
- isAssistantFeatureFlagEnabled("trace-collection", getConfig()) &&
465
- getCachedShareDiagnostics() &&
466
- isDiagnosticsConsentVersionEligible(getCachedShareDiagnosticsVersion());
467
- let reportableTurnEvents = turnEvents;
468
- if (turnEvents.length > 0) {
469
- let barrier = turnEvents.length;
470
- for (let i = 0; i < turnEvents.length; i++) {
471
- const t = turnEvents[i];
472
- if (
473
- !isTurnSettled({
474
- conversationId: t.conversationId,
475
- userMessageId: t.id,
476
- userMessageCreatedAt: t.createdAt,
477
- })
478
- ) {
479
- barrier = i;
480
- break;
481
- }
482
- }
483
- if (barrier < turnEvents.length) {
484
- reportableTurnEvents = turnEvents.slice(0, barrier);
485
- log.debug(
346
+ // Ack-mode batches must carry a row id per event: without them nothing
347
+ // can be acknowledged post-2xx, so shipping would re-send the same rows
348
+ // on every flush. Exclude such a batch from the POST instead.
349
+ for (const entry of batches) {
350
+ const { source, batch } = entry;
351
+ if (
352
+ source.ack &&
353
+ batch.events.length > 0 &&
354
+ (batch.rowIds ?? []).length !== batch.events.length
355
+ ) {
356
+ log.warn(
486
357
  {
487
- deferredTurnId: turnEvents[barrier].id,
488
- deferredConversationId: turnEvents[barrier].conversationId,
489
- reportedTurns: barrier,
490
- deferredTurns: turnEvents.length - barrier,
358
+ sourceId: source.id,
359
+ eventCount: batch.events.length,
360
+ rowIdCount: batch.rowIds?.length ?? 0,
491
361
  },
492
- "Deferring in-progress turn(s) from telemetry until complete",
362
+ "Telemetry flush: ack-mode batch missing/mismatched rowIds — excluding from POST",
493
363
  );
364
+ entry.batch = {
365
+ events: [],
366
+ rowIds: [],
367
+ lastCursor: null,
368
+ fullBatch: false,
369
+ };
494
370
  }
495
371
  }
496
372
 
497
- if (
498
- events.length === 0 &&
499
- reportableTurnEvents.length === 0 &&
500
- lifecycleEvents.length === 0 &&
501
- onboardingEvents.length === 0 &&
502
- authFallbackEvents.length === 0 &&
503
- toolExecutedEvents.length === 0 &&
504
- skillLoadedEvents.length === 0 &&
505
- watchdogEvents.length === 0
506
- )
373
+ if (batches.every(({ batch }) => batch.events.length === 0)) {
507
374
  return;
375
+ }
508
376
 
509
377
  // Resolve auth context. We send authenticated-only: if no platform
510
378
  // credentials are available yet, skip without advancing watermarks so the
@@ -512,290 +380,35 @@ export class UsageTelemetryReporter {
512
380
  const client = await VellumPlatformClient.create();
513
381
  if (!client) {
514
382
  log.debug(
515
- { pendingEventCount: events.length + turnEvents.length },
383
+ {
384
+ pendingEventCount: batches.reduce(
385
+ (total, { batch }) => total + batch.events.length,
386
+ 0,
387
+ ),
388
+ },
516
389
  "Telemetry flush: no platform credentials — skipping, will retry next cycle",
517
390
  );
518
391
  return;
519
392
  }
520
393
  log.debug(
521
394
  {
522
- usageCount: events.length,
523
- turnCount: reportableTurnEvents.length,
524
- lifecycleCount: lifecycleEvents.length,
525
- onboardingCount: onboardingEvents.length,
526
- authFallbackCount: authFallbackEvents.length,
527
- toolExecutedCount: toolExecutedEvents.length,
528
- skillLoadedCount: skillLoadedEvents.length,
529
- watchdogCount: watchdogEvents.length,
395
+ counts: Object.fromEntries(
396
+ batches.map(({ source, batch }) => [
397
+ source.id,
398
+ batch.events.length,
399
+ ]),
400
+ ),
530
401
  },
531
402
  "Telemetry flush: resolved auth context",
532
403
  );
533
404
 
534
- // Build payload
535
- const typedEvents: TelemetryEvent[] = [
536
- ...events.map(
537
- (e): TelemetryEvent => ({
538
- type: "llm_usage",
539
- daemon_event_id: e.id,
540
- // Conversation-level metadata for analytics joins. All three
541
- // are nullable on the wire: `conversation_id` is null for
542
- // LLM calls not tied to a conversation (memory consolidation,
543
- // background work), and the other two cascade from that.
544
- conversation_id: e.conversationId,
545
- conversation_type: e.conversationType,
546
- turn_index: e.turnIndex,
547
- provider: e.provider,
548
- model: e.model,
549
- input_tokens: e.inputTokens,
550
- output_tokens: e.outputTokens,
551
- cache_creation_input_tokens: e.cacheCreationInputTokens ?? null,
552
- cache_read_input_tokens: e.cacheReadInputTokens ?? null,
553
- llm_call_count: e.llmCallCount,
554
- raw_usage: e.rawUsage,
555
- actor: e.actor,
556
- llm_call_site: e.callSite,
557
- inference_profile: e.inferenceProfile,
558
- inference_profile_source: e.inferenceProfileSource,
559
- cost: e.estimatedCostUsd ?? null,
560
- recorded_at: e.createdAt,
561
- // Record-time version when present; otherwise the running
562
- // binary's `APP_VERSION` (a legacy row from before
563
- // migration 267 ran). We deliberately don't emit explicit
564
- // `null` — under the platform contract a present-but-null
565
- // per-event value would override the envelope, and we'd
566
- // rather have a concrete version than no version.
567
- assistant_version: e.assistantVersion ?? APP_VERSION,
568
- }),
569
- ),
570
- ...reportableTurnEvents.map((e): TelemetryEvent => {
571
- // Per-turn trace collection gate. `traceEligible` (computed above)
572
- // requires the `trace-collection` flag AND the owner's cached
573
- // `share_diagnostics` consent AND an eligible accepted consent
574
- // version. Fail-closed: when any is off the trace is omitted and the
575
- // trace-free turn row flushes as before. The
576
- // `share_analytics` gate above already passed, so this is an
577
- // additional, independent gate specific to trace PII. Every turn
578
- // reaching here is settled (the completeness barrier dropped any
579
- // in-flight turns), so the trace is never a partial mid-turn snapshot.
580
- const trace = traceEligible
581
- ? assembleBoundedTurnTrace({
582
- conversationId: e.conversationId,
583
- userMessageId: e.id,
584
- userMessageCreatedAt: e.createdAt,
585
- })
586
- : null;
587
- // `messages.metadata.client` is a nested JSON object extracted
588
- // via `json_extract`; sqlite returns it as a text representation.
589
- // Parse defensively — a corrupted blob in the JSON column should
590
- // not block the whole batch flush.
591
- let client: TurnTelemetryClientInfo | null = null;
592
- if (e.clientMetadata) {
593
- try {
594
- const parsed = JSON.parse(e.clientMetadata) as unknown;
595
- if (
596
- parsed &&
597
- typeof parsed === "object" &&
598
- !Array.isArray(parsed)
599
- ) {
600
- client = parsed as TurnTelemetryClientInfo;
601
- }
602
- } catch {
603
- // Malformed client JSON — emit null rather than fail the
604
- // batch. Logged once below for visibility.
605
- log.warn(
606
- { turnId: e.id, conversationId: e.conversationId },
607
- "Telemetry turn: failed to parse messages.metadata.client; emitting null",
608
- );
609
- }
610
- }
611
- // Narrow the raw metadata projection to the wire union — only
612
- // `stampTurnOutcome` writes the key, but the JSON column is
613
- // uncontrolled, so an unexpected value is dropped rather than
614
- // shipped.
615
- const outcome =
616
- e.outcome === "batched" ||
617
- e.outcome === "failed" ||
618
- e.outcome === "cancelled"
619
- ? e.outcome
620
- : null;
621
- return {
622
- type: "turn",
623
- daemon_event_id: e.id,
624
- recorded_at: e.createdAt,
625
- conversation_id: e.conversationId,
626
- conversation_type: e.conversationType,
627
- turn_index: e.turnIndex,
628
- interface_id: e.interfaceId,
629
- channel_id: e.channelId,
630
- client,
631
- // Outcome stamps are omit-when-absent: a normally-replied turn's
632
- // wire shape is byte-identical to a pre-outcome turn event.
633
- ...(outcome ? { outcome } : {}),
634
- ...(outcome === "batched" && e.batchedInto
635
- ? { batched_into: e.batchedInto }
636
- : {}),
637
- ...(outcome === "failed" && e.failureCode
638
- ? { failure_code: e.failureCode }
639
- : {}),
640
- // Only attach `trace` when consent is on AND a bounded trace was
641
- // assembled. Omitting the key entirely when there's no trace keeps
642
- // the wire shape byte-identical to pre-trace turn events for the
643
- // common (no-consent) path.
644
- ...(trace ? { trace } : {}),
645
- // Turn events derive from `messages` + `conversations`
646
- // rather than a dedicated table. Adding `assistant_version`
647
- // to `messages` is a separate (larger) migration; until
648
- // then we stamp the running binary's `APP_VERSION` so the
649
- // wire value is concrete (matches what the envelope would
650
- // have provided, but per-event so it survives the platform
651
- // contract that treats present per-event values as winning
652
- // over the envelope). Same upload-time attribution risk
653
- // for turn events as before this PR — lifecycle, onboarding
654
- // and turn events all still rely on the envelope; only
655
- // llm_usage is record-time accurate in this PR.
656
- assistant_version: APP_VERSION,
657
- };
658
- }),
659
- ...lifecycleEvents.map(
660
- (e): TelemetryEvent => ({
661
- type: "lifecycle",
662
- daemon_event_id: e.id,
663
- event_name: e.eventName,
664
- recorded_at: e.createdAt,
665
- // Lifecycle events fall back to the envelope `assistant_version`
666
- // — same upload-time attribution risk as before this PR. Adding
667
- // the record-time column to `lifecycle_events` (#18112) is a
668
- // separate follow-up that mirrors what this PR does for
669
- // `llm_usage_events`.
670
- assistant_version: APP_VERSION,
671
- }),
672
- ),
673
- ...onboardingEvents.map(
674
- (e): TelemetryEvent => ({
675
- type: "onboarding",
676
- // Wire-only override for activation rows: a deterministic id keyed
677
- // on funnel_version/session/step lets dbt collapse a moment that
678
- // fires more than once. Key on the ROW's stored `funnelVersion`
679
- // (not the binary's current constant) so rows recorded under an
680
- // older version — flushed offline or after an upgrade — keep a
681
- // stable id and still collapse with already-ingested rows. The
682
- // SQLite watermark cursor still uses `e.id`/`e.createdAt`, so this
683
- // override is checkpoint-safe.
684
- daemon_event_id:
685
- e.sessionId && e.stepName && e.funnelVersion
686
- ? buildActivationDaemonEventId(
687
- e.sessionId,
688
- e.stepName as ActivationStepName,
689
- e.funnelVersion,
690
- )
691
- : e.id,
692
- recorded_at: e.createdAt,
693
- screen: e.screen,
694
- ...(e.toolsJson ? { tools: JSON.parse(e.toolsJson) } : {}),
695
- ...(e.tasksJson ? { tasks: JSON.parse(e.tasksJson) } : {}),
696
- ...(e.tone ? { tone: e.tone } : {}),
697
- ...(e.googleConnected != null
698
- ? { google_connected: e.googleConnected }
699
- : {}),
700
- ...(e.googleScopesJson
701
- ? { google_scopes: JSON.parse(e.googleScopesJson) }
702
- : {}),
703
- ...(e.abVariant ? { ab_variant: e.abVariant } : {}),
704
- // Activation funnel fields — only present on activation rows.
705
- ...(e.sessionId ? { session_id: e.sessionId } : {}),
706
- ...(e.stepName ? { step_name: e.stepName } : {}),
707
- ...(e.stepIndex != null ? { step_index: e.stepIndex } : {}),
708
- ...(e.completedAt ? { completed_at: e.completedAt } : {}),
709
- ...(e.funnelVersion ? { funnel_version: e.funnelVersion } : {}),
710
- // Onboarding events fall back to the envelope `assistant_version`,
711
- // so events recorded under an older build are attributed to the
712
- // version running at upload time. Adding a record-time column to
713
- // `onboarding_events` (mirroring `llm_usage_events`) is a known
714
- // follow-up.
715
- assistant_version: APP_VERSION,
716
- }),
717
- ),
718
- ...authFallbackEvents.map(
719
- (e): TelemetryEvent => ({
720
- type: "auth_fallback",
721
- daemon_event_id: e.id,
722
- recorded_at: e.createdAt,
723
- guard: e.guard,
724
- path: e.path,
725
- failure_kind: e.failureKind,
726
- count: e.count,
727
- window_start: e.windowStart,
728
- window_end: e.windowEnd,
729
- // Aggregated counts forwarded by the gateway carry no record-time
730
- // binary version; stamp the running binary's `APP_VERSION` so the
731
- // wire value is concrete rather than an explicit null that would
732
- // override the envelope under the platform's per-event-wins
733
- // contract.
734
- assistant_version: APP_VERSION,
735
- }),
736
- ),
737
- ...toolExecutedEvents.map(
738
- (e): TelemetryEvent => ({
739
- type: "tool_executed",
740
- daemon_event_id: e.id,
741
- recorded_at: e.createdAt,
742
- tool_name: e.toolName,
743
- // The store filters out permission-denied rows, so the only
744
- // non-success decision that reaches here is "error".
745
- status: e.decision === "error" ? "errored" : "fulfilled",
746
- duration_ms: e.durationMs,
747
- arg_bytes: e.argBytes,
748
- result_bytes: e.resultBytes,
749
- conversation_id: e.conversationId,
750
- provider: e.provider,
751
- model: e.model,
752
- inference_profile: e.inferenceProfile,
753
- inference_profile_source:
754
- e.inferenceProfileSource as UsageAttributionProfileSource | null,
755
- // `tool_invocations` has no record-time version column — stamp
756
- // the running binary's `APP_VERSION` so the wire value is
757
- // concrete rather than an explicit null that would override the
758
- // envelope under the platform's per-event-wins contract.
759
- assistant_version: APP_VERSION,
760
- }),
761
- ),
762
- ...skillLoadedEvents.map(
763
- (e): TelemetryEvent => ({
764
- type: "skill_loaded",
765
- daemon_event_id: e.id,
766
- recorded_at: e.createdAt,
767
- skill_name: e.skillName,
768
- skill_updated_at: e.skillUpdatedAt,
769
- conversation_id: e.conversationId,
770
- provider: e.provider,
771
- model: e.model,
772
- inference_profile: e.inferenceProfile,
773
- inference_profile_source:
774
- e.inferenceProfileSource as UsageAttributionProfileSource | null,
775
- // `skill_loaded_events` has no record-time version column — same
776
- // upload-time APP_VERSION stamping as the other non-llm_usage
777
- // event types.
778
- assistant_version: APP_VERSION,
779
- }),
780
- ),
781
- ...watchdogEvents.map(
782
- (e): TelemetryEvent => ({
783
- type: "watchdog",
784
- daemon_event_id: e.id,
785
- recorded_at: e.createdAt,
786
- check_name: e.checkName,
787
- value: e.value,
788
- // `detail` is stored as JSON text; parse defensively so a
789
- // corrupted blob never fails the batch flush. A parse failure
790
- // emits null rather than dropping the event.
791
- detail: parseWatchdogDetail(e.detail),
792
- // `watchdog_events` has no record-time version column — same
793
- // upload-time APP_VERSION stamping as the other non-llm_usage
794
- // event types.
795
- assistant_version: APP_VERSION,
796
- }),
797
- ),
798
- ];
405
+ // Build payload — sources in construction order, each source's events
406
+ // in cursor order.
407
+ const typedEvents = batches.flatMap(({ batch }) => batch.events);
408
+
409
+ // Pre-flush wire validation — observability only: warns about events
410
+ // the server would silently drop; the batch is POSTed unchanged.
411
+ validateWireEvents(typedEvents, log);
799
412
 
800
413
  const organizationId = getPlatformOrganizationId() || undefined;
801
414
  const userId = getPlatformUserId() || undefined;
@@ -828,123 +441,23 @@ export class UsageTelemetryReporter {
828
441
  }
829
442
  await resp.text(); // consume body to release connection
830
443
 
831
- // Advance usage watermark (compound cursor)
832
- if (events.length > 0) {
833
- const lastEvent = events[events.length - 1];
834
- setMemoryCheckpoint(
835
- CHECKPOINT_KEY_WATERMARK,
836
- String(lastEvent.createdAt),
837
- );
838
- setMemoryCheckpoint(CHECKPOINT_KEY_WATERMARK_ID, lastEvent.id);
839
- }
840
-
841
- // Advance turn watermark (compound cursor) — only to the last REPORTED
842
- // turn. Deferred (in-flight) turns sit beyond this cursor and are
843
- // re-evaluated on a later flush, so the watermark never skips them.
844
- if (reportableTurnEvents.length > 0) {
845
- const lastTurn = reportableTurnEvents[reportableTurnEvents.length - 1];
846
- setMemoryCheckpoint(
847
- CHECKPOINT_KEY_TURN_WATERMARK,
848
- String(lastTurn.createdAt),
849
- );
850
- setMemoryCheckpoint(CHECKPOINT_KEY_TURN_WATERMARK_ID, lastTurn.id);
851
- }
852
-
853
- // Advance lifecycle watermark (compound cursor)
854
- if (lifecycleEvents.length > 0) {
855
- const lastLifecycle = lifecycleEvents[lifecycleEvents.length - 1];
856
- setMemoryCheckpoint(
857
- CHECKPOINT_KEY_LIFECYCLE_WATERMARK,
858
- String(lastLifecycle.createdAt),
859
- );
860
- setMemoryCheckpoint(
861
- CHECKPOINT_KEY_LIFECYCLE_WATERMARK_ID,
862
- lastLifecycle.id,
863
- );
864
- }
865
-
866
- // Advance onboarding watermark (compound cursor)
867
- if (onboardingEvents.length > 0) {
868
- const lastOnboarding = onboardingEvents[onboardingEvents.length - 1];
869
- setMemoryCheckpoint(
870
- CHECKPOINT_KEY_ONBOARDING_WATERMARK,
871
- String(lastOnboarding.createdAt),
872
- );
873
- setMemoryCheckpoint(
874
- CHECKPOINT_KEY_ONBOARDING_WATERMARK_ID,
875
- lastOnboarding.id,
876
- );
877
- }
878
-
879
- // Advance auth-fallback watermark (compound cursor)
880
- if (authFallbackEvents.length > 0) {
881
- const lastAuthFallback =
882
- authFallbackEvents[authFallbackEvents.length - 1];
883
- setMemoryCheckpoint(
884
- CHECKPOINT_KEY_AUTH_FALLBACK_WATERMARK,
885
- String(lastAuthFallback.createdAt),
886
- );
887
- setMemoryCheckpoint(
888
- CHECKPOINT_KEY_AUTH_FALLBACK_WATERMARK_ID,
889
- lastAuthFallback.id,
890
- );
891
- }
892
-
893
- // Advance tool-executed watermark (compound cursor)
894
- if (toolExecutedEvents.length > 0) {
895
- const lastToolExecuted =
896
- toolExecutedEvents[toolExecutedEvents.length - 1];
897
- setMemoryCheckpoint(
898
- CHECKPOINT_KEY_TOOL_EXECUTED_WATERMARK,
899
- String(lastToolExecuted.createdAt),
900
- );
901
- setMemoryCheckpoint(
902
- CHECKPOINT_KEY_TOOL_EXECUTED_WATERMARK_ID,
903
- lastToolExecuted.id,
904
- );
905
- }
906
-
907
- // Advance skill-loaded watermark (compound cursor)
908
- if (skillLoadedEvents.length > 0) {
909
- const lastSkillLoaded = skillLoadedEvents[skillLoadedEvents.length - 1];
910
- setMemoryCheckpoint(
911
- CHECKPOINT_KEY_SKILL_LOADED_WATERMARK,
912
- String(lastSkillLoaded.createdAt),
913
- );
914
- setMemoryCheckpoint(
915
- CHECKPOINT_KEY_SKILL_LOADED_WATERMARK_ID,
916
- lastSkillLoaded.id,
917
- );
918
- }
919
-
920
- // Advance watchdog watermark (compound cursor)
921
- if (watchdogEvents.length > 0) {
922
- const lastWatchdog = watchdogEvents[watchdogEvents.length - 1];
923
- setMemoryCheckpoint(
924
- CHECKPOINT_KEY_WATCHDOG_WATERMARK,
925
- String(lastWatchdog.createdAt),
926
- );
927
- setMemoryCheckpoint(
928
- CHECKPOINT_KEY_WATCHDOG_WATERMARK_ID,
929
- lastWatchdog.id,
930
- );
444
+ // Acknowledge each source's shipped rows: ack-mode sources delete them
445
+ // (never touching flush_checkpoints), watermark-mode sources advance
446
+ // their compound cursor to the last reported row.
447
+ for (const { source, batch } of batches) {
448
+ if (source.ack) {
449
+ if (batch.events.length > 0) {
450
+ source.ack.acknowledge(batch.rowIds ?? []);
451
+ }
452
+ } else if (batch.lastCursor) {
453
+ const keys = watermarkKeysForSource(source.id);
454
+ this.checkpoints.set(keys.at, String(batch.lastCursor.createdAt));
455
+ this.checkpoints.set(keys.id, batch.lastCursor.id);
456
+ }
931
457
  }
932
458
 
933
- // If we got a full batch of any type, there may be more — recurse.
934
- // Turns use the REPORTED count: when the completeness barrier truncates
935
- // the batch, the deferred turns must wait for a later flush (by which
936
- // point they've settled) rather than being re-queried and re-deferred in
937
- // a tight recursion.
938
- if (
939
- events.length === BATCH_SIZE ||
940
- reportableTurnEvents.length === BATCH_SIZE ||
941
- lifecycleEvents.length === BATCH_SIZE ||
942
- onboardingEvents.length === BATCH_SIZE ||
943
- authFallbackEvents.length === BATCH_SIZE ||
944
- toolExecutedEvents.length === BATCH_SIZE ||
945
- skillLoadedEvents.length === BATCH_SIZE ||
946
- watchdogEvents.length === BATCH_SIZE
947
- ) {
459
+ // If any source produced a full batch, there may be more — recurse.
460
+ if (batches.some(({ batch }) => batch.fullBatch)) {
948
461
  await this._doFlush(batchCount + 1);
949
462
  }
950
463
  } catch (err) {