@vellumai/assistant 0.6.3 → 0.6.4

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 (667) hide show
  1. package/ARCHITECTURE.md +273 -10
  2. package/Dockerfile +2 -3
  3. package/bun.lock +5 -13
  4. package/docs/backup-troubleshooting.md +52 -0
  5. package/docs/browser-use-architecture-phase2.md +174 -0
  6. package/docs/stt-provider-onboarding.md +120 -0
  7. package/knip.json +12 -2
  8. package/node_modules/@vellumai/ces-contracts/bun.lock +8 -6
  9. package/node_modules/@vellumai/ces-contracts/package.json +3 -3
  10. package/openapi.yaml +982 -72
  11. package/package.json +4 -6
  12. package/scripts/generate-openapi.ts +0 -1
  13. package/scripts/test.sh +73 -18
  14. package/src/__tests__/agent-image-optimize.test.ts +28 -0
  15. package/src/__tests__/agent-loop.test.ts +123 -0
  16. package/src/__tests__/anthropic-provider.test.ts +263 -10
  17. package/src/__tests__/auto-analysis-end-to-end.test.ts +550 -0
  18. package/src/__tests__/auto-analysis-prompt.test.ts +50 -0
  19. package/src/__tests__/browser-fill-credential.test.ts +11 -0
  20. package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +2 -2
  21. package/src/__tests__/browser-skill-endstate.test.ts +31 -7
  22. package/src/__tests__/btw-routes.test.ts +7 -0
  23. package/src/__tests__/call-controller.test.ts +581 -20
  24. package/src/__tests__/catalog-files.test.ts +138 -0
  25. package/src/__tests__/channel-invite-transport.test.ts +2 -2
  26. package/src/__tests__/channel-readiness-routes.test.ts +16 -20
  27. package/src/__tests__/channel-readiness-service.test.ts +12 -7
  28. package/src/__tests__/checker.test.ts +157 -10
  29. package/src/__tests__/clawhub-files.test.ts +347 -0
  30. package/src/__tests__/commit-message-enrichment-service.test.ts +36 -19
  31. package/src/__tests__/config-analysis.test.ts +100 -0
  32. package/src/__tests__/config-schema.test.ts +1013 -66
  33. package/src/__tests__/config-watcher-cleanup-throttle.test.ts +339 -0
  34. package/src/__tests__/config-watcher.test.ts +43 -8
  35. package/src/__tests__/contact-store-user-file.test.ts +512 -0
  36. package/src/__tests__/contacts-write.test.ts +197 -0
  37. package/src/__tests__/context-window-manager.test.ts +88 -0
  38. package/src/__tests__/conversation-abort-tool-results.test.ts +2 -0
  39. package/src/__tests__/conversation-agent-loop-overflow.test.ts +1 -0
  40. package/src/__tests__/conversation-agent-loop.test.ts +98 -2
  41. package/src/__tests__/conversation-confirmation-signals.test.ts +135 -0
  42. package/src/__tests__/conversation-error.test.ts +70 -0
  43. package/src/__tests__/conversation-history-web-search.test.ts +11 -4
  44. package/src/__tests__/conversation-init.benchmark.test.ts +6 -1
  45. package/src/__tests__/conversation-launcher-skill-regression.test.ts +51 -0
  46. package/src/__tests__/conversation-list-source.test.ts +145 -0
  47. package/src/__tests__/conversation-pre-run-repair.test.ts +2 -0
  48. package/src/__tests__/conversation-provider-retry-repair.test.ts +2 -0
  49. package/src/__tests__/conversation-queue.test.ts +901 -60
  50. package/src/__tests__/conversation-routes-disk-view.test.ts +270 -0
  51. package/src/__tests__/conversation-runtime-assembly.test.ts +55 -0
  52. package/src/__tests__/conversation-skill-tools.test.ts +7 -4
  53. package/src/__tests__/conversation-slash-commands.test.ts +33 -0
  54. package/src/__tests__/conversation-slash-queue.test.ts +89 -18
  55. package/src/__tests__/conversation-slash-unknown.test.ts +2 -0
  56. package/src/__tests__/conversation-tool-setup-batch-authorized.test.ts +226 -0
  57. package/src/__tests__/conversation-workspace-injection.test.ts +2 -0
  58. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +2 -0
  59. package/src/__tests__/credential-health-service.test.ts +352 -0
  60. package/src/__tests__/credential-security-invariants.test.ts +5 -3
  61. package/src/__tests__/credential-vault-unit.test.ts +379 -3
  62. package/src/__tests__/credentials-cli.test.ts +40 -16
  63. package/src/__tests__/cross-provider-web-search.test.ts +146 -35
  64. package/src/__tests__/deterministic-verification-control-plane.test.ts +10 -1
  65. package/src/__tests__/device-id.test.ts +112 -0
  66. package/src/__tests__/docker-signing-key-bootstrap.test.ts +167 -4
  67. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +1 -3
  68. package/src/__tests__/email-html-renderer.test.ts +71 -0
  69. package/src/__tests__/email-invite-adapter.test.ts +36 -32
  70. package/src/__tests__/emit-event-signal.test.ts +71 -0
  71. package/src/__tests__/extension-id-sync-guard.test.ts +75 -8
  72. package/src/__tests__/fixtures/mock-chrome-extension.ts +11 -0
  73. package/src/__tests__/gateway-only-enforcement.test.ts +206 -1
  74. package/src/__tests__/gateway-only-guard.test.ts +0 -1
  75. package/src/__tests__/gemini-provider.test.ts +64 -0
  76. package/src/__tests__/get-skill-detail-audit.test.ts +325 -0
  77. package/src/__tests__/gmail-archive-fallback.test.ts +193 -0
  78. package/src/__tests__/gmail-archive-gate.test.ts +246 -0
  79. package/src/__tests__/gmail-preferences.test.ts +117 -0
  80. package/src/__tests__/headless-browser-interactions.test.ts +43 -0
  81. package/src/__tests__/headless-browser-mode.test.ts +614 -0
  82. package/src/__tests__/headless-browser-navigate.test.ts +142 -5
  83. package/src/__tests__/headless-browser-read-tools.test.ts +11 -0
  84. package/src/__tests__/headless-browser-snapshot.test.ts +10 -0
  85. package/src/__tests__/heartbeat-service.test.ts +70 -17
  86. package/src/__tests__/home-state-routes.test.ts +162 -0
  87. package/src/__tests__/host-bash-proxy.test.ts +0 -5
  88. package/src/__tests__/host-browser-e2e-cloud.test.ts +138 -4
  89. package/src/__tests__/host-browser-e2e-self-hosted.test.ts +4 -4
  90. package/src/__tests__/host-browser-ws-events-e2e.test.ts +103 -0
  91. package/src/__tests__/host-cu-proxy.test.ts +0 -5
  92. package/src/__tests__/identity-intro-cache.test.ts +40 -10
  93. package/src/__tests__/init-feature-flag-overrides.test.ts +38 -112
  94. package/src/__tests__/jobs-store-upsert-debounced.test.ts +141 -0
  95. package/src/__tests__/llm-context-normalization.test.ts +488 -0
  96. package/src/__tests__/llm-context-route-provider.test.ts +86 -5
  97. package/src/__tests__/llm-usage-store.test.ts +363 -0
  98. package/src/__tests__/media-stream-output.test.ts +555 -0
  99. package/src/__tests__/media-stream-parser.test.ts +374 -0
  100. package/src/__tests__/media-stream-server-integration.test.ts +1234 -0
  101. package/src/__tests__/media-stream-stt-session.test.ts +588 -0
  102. package/src/__tests__/media-turn-detector.test.ts +440 -0
  103. package/src/__tests__/message-queue.test.ts +125 -0
  104. package/src/__tests__/migration-export-http.test.ts +6 -6
  105. package/src/__tests__/migration-import-commit-http.test.ts +8 -6
  106. package/src/__tests__/migration-import-preflight-http.test.ts +6 -5
  107. package/src/__tests__/migration-validate-http.test.ts +3 -3
  108. package/src/__tests__/mock-gateway-ipc.ts +151 -0
  109. package/src/__tests__/model-intents.test.ts +2 -2
  110. package/src/__tests__/oauth-apps-routes.test.ts +1 -0
  111. package/src/__tests__/oauth-cli.test.ts +2 -0
  112. package/src/__tests__/oauth-connect-orchestrator.test.ts +2 -0
  113. package/src/__tests__/oauth-provider-serializer.test.ts +1 -0
  114. package/src/__tests__/oauth-providers-routes.test.ts +2 -0
  115. package/src/__tests__/oauth-store.test.ts +85 -0
  116. package/src/__tests__/oauth2-gateway-transport.test.ts +249 -6
  117. package/src/__tests__/onboarding-template-contract.test.ts +6 -13
  118. package/src/__tests__/openai-provider.test.ts +176 -0
  119. package/src/__tests__/openai-responses-cutover-guard.test.ts +184 -0
  120. package/src/__tests__/openai-responses-provider.test.ts +1105 -0
  121. package/src/__tests__/openrouter-token-estimation.test.ts +100 -0
  122. package/src/__tests__/outlook-unsubscribe.test.ts +31 -2
  123. package/src/__tests__/persona-resolver.test.ts +251 -0
  124. package/src/__tests__/platform-bash-auto-approve.test.ts +4 -0
  125. package/src/__tests__/platform.test.ts +92 -1
  126. package/src/__tests__/post-turn-tool-result-truncation.test.ts +47 -0
  127. package/src/__tests__/prechat-onboarding-contract.test.ts +267 -0
  128. package/src/__tests__/pricing.test.ts +174 -0
  129. package/src/__tests__/qdrant-manager.test.ts +29 -8
  130. package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +194 -0
  131. package/src/__tests__/relationship-state-contract.test.ts +175 -0
  132. package/src/__tests__/relay-server.test.ts +423 -5
  133. package/src/__tests__/search-skills-unified.test.ts +118 -0
  134. package/src/__tests__/secret-scanner-executor.test.ts +4 -0
  135. package/src/__tests__/secure-keys.test.ts +107 -0
  136. package/src/__tests__/send-endpoint-busy.test.ts +5 -1
  137. package/src/__tests__/sequence-store.test.ts +1 -1
  138. package/src/__tests__/server-history-render.test.ts +49 -0
  139. package/src/__tests__/settings-routes.test.ts +201 -0
  140. package/src/__tests__/skill-load-feature-flag.test.ts +1 -0
  141. package/src/__tests__/skills-file-content-endpoint.test.ts +276 -145
  142. package/src/__tests__/skills-files-catalog-fallback.test.ts +381 -93
  143. package/src/__tests__/skills.test.ts +5 -2
  144. package/src/__tests__/skillssh-files.test.ts +446 -0
  145. package/src/__tests__/slack-block-formatting.test.ts +110 -0
  146. package/src/__tests__/slack-channel-config.test.ts +564 -1
  147. package/src/__tests__/stt-catalog-parity.test.ts +282 -0
  148. package/src/__tests__/stt-stream-session.test.ts +535 -0
  149. package/src/__tests__/system-prompt.test.ts +112 -26
  150. package/src/__tests__/telephony-stt-routing.test.ts +329 -0
  151. package/src/__tests__/terminal-tools.test.ts +18 -7
  152. package/src/__tests__/test-preload.ts +18 -0
  153. package/src/__tests__/test-support/browser-skill-harness.ts +4 -1
  154. package/src/__tests__/tool-executor-lifecycle-events.test.ts +9 -5
  155. package/src/__tests__/tool-executor-shell-integration.test.ts +4 -0
  156. package/src/__tests__/tool-executor.test.ts +33 -24
  157. package/src/__tests__/tool-result-truncation.test.ts +36 -0
  158. package/src/__tests__/trust-store.test.ts +7 -1
  159. package/src/__tests__/trusted-contact-approval-notifier.test.ts +1 -1
  160. package/src/__tests__/tts-catalog-parity.test.ts +345 -0
  161. package/src/__tests__/twilio-routes-twiml.test.ts +512 -114
  162. package/src/__tests__/twilio-routes.test.ts +376 -0
  163. package/src/__tests__/unicode.test.ts +293 -0
  164. package/src/__tests__/update-bulletin-format.test.ts +59 -0
  165. package/src/__tests__/update-bulletin.test.ts +206 -5
  166. package/src/__tests__/usage-routes.test.ts +25 -4
  167. package/src/__tests__/user-reference.test.ts +46 -61
  168. package/src/__tests__/verification-control-plane-policy.test.ts +4 -0
  169. package/src/__tests__/voice-config-update.test.ts +403 -0
  170. package/src/__tests__/voice-quality.test.ts +434 -19
  171. package/src/__tests__/workspace-heartbeat-service.test.ts +7 -0
  172. package/src/__tests__/workspace-migration-033-stt-service-explicit-config.test.ts +547 -0
  173. package/src/__tests__/workspace-migration-034-remove-calls-voice-transcription-provider.test.ts +596 -0
  174. package/src/__tests__/workspace-migration-drop-user-md.test.ts +368 -0
  175. package/src/__tests__/workspace-migration-meets.test.ts +244 -0
  176. package/src/__tests__/workspace-migration-seed-device-id.test.ts +14 -20
  177. package/src/__tests__/workspace-policy.test.ts +2 -0
  178. package/src/agent/image-optimize.ts +24 -12
  179. package/src/agent/loop.ts +43 -3
  180. package/src/backup/__tests__/backup-key.test.ts +152 -0
  181. package/src/backup/__tests__/backup-worker.test.ts +767 -0
  182. package/src/backup/__tests__/list-snapshots.test.ts +87 -0
  183. package/src/backup/__tests__/local-writer.test.ts +218 -0
  184. package/src/backup/__tests__/offsite-writer.test.ts +641 -0
  185. package/src/backup/__tests__/paths.test.ts +300 -0
  186. package/src/backup/__tests__/restore.test.ts +498 -0
  187. package/src/backup/__tests__/snapshot-lock.test.ts +352 -0
  188. package/src/backup/__tests__/stream-crypt.test.ts +228 -0
  189. package/src/backup/backup-key.ts +137 -0
  190. package/src/backup/backup-worker.ts +459 -0
  191. package/src/backup/list-snapshots.ts +147 -0
  192. package/src/backup/local-writer.ts +133 -0
  193. package/src/backup/offsite-writer.ts +222 -0
  194. package/src/backup/paths.ts +226 -0
  195. package/src/backup/restore.ts +322 -0
  196. package/src/backup/snapshot-lock.ts +431 -0
  197. package/src/backup/stream-crypt.ts +263 -0
  198. package/src/bundler/package-resolver.ts +4 -0
  199. package/src/calls/audio-store.ts +11 -5
  200. package/src/calls/call-controller.ts +226 -71
  201. package/src/calls/call-domain.ts +9 -0
  202. package/src/calls/call-speech-output.ts +190 -0
  203. package/src/calls/call-transport.ts +77 -0
  204. package/src/calls/media-stream-audio-transcode.ts +173 -0
  205. package/src/calls/media-stream-output.ts +660 -0
  206. package/src/calls/media-stream-parser.ts +300 -0
  207. package/src/calls/media-stream-protocol.ts +166 -0
  208. package/src/calls/media-stream-server.ts +592 -0
  209. package/src/calls/media-stream-stt-session.ts +460 -0
  210. package/src/calls/media-turn-detector.ts +230 -0
  211. package/src/calls/relay-server.ts +90 -75
  212. package/src/calls/resolve-call-tts-provider.ts +136 -0
  213. package/src/calls/telephony-stt-routing.ts +145 -0
  214. package/src/calls/tts-call-strategy.ts +161 -0
  215. package/src/calls/tts-text-sanitizer.ts +32 -16
  216. package/src/calls/twilio-routes.ts +281 -17
  217. package/src/calls/voice-quality.ts +78 -35
  218. package/src/calls/voice-session-bridge.ts +8 -1
  219. package/src/channels/types.ts +16 -0
  220. package/src/cli/__tests__/run-assistant-command.ts +11 -1
  221. package/src/cli/commands/__tests__/backup.test.ts +1165 -0
  222. package/src/cli/commands/__tests__/domain-register.test.ts +234 -0
  223. package/src/cli/commands/__tests__/domain-status.test.ts +132 -0
  224. package/src/cli/commands/__tests__/email-attachment.test.ts +422 -0
  225. package/src/cli/commands/__tests__/email-download.test.ts +16 -1
  226. package/src/cli/commands/__tests__/email-list.test.ts +22 -4
  227. package/src/cli/commands/__tests__/email-register.test.ts +4 -4
  228. package/src/cli/commands/__tests__/email-send.test.ts +37 -4
  229. package/src/cli/commands/__tests__/email-status.test.ts +5 -1
  230. package/src/cli/commands/__tests__/email-unregister.test.ts +34 -5
  231. package/src/cli/commands/backup.ts +993 -0
  232. package/src/cli/commands/conversations.ts +77 -0
  233. package/src/cli/commands/credentials.ts +0 -1
  234. package/src/cli/commands/domain.ts +210 -0
  235. package/src/cli/commands/email.ts +255 -3
  236. package/src/cli/commands/oauth/__tests__/connect.test.ts +12 -0
  237. package/src/cli/commands/oauth/__tests__/providers-delete.test.ts +1 -0
  238. package/src/cli/commands/oauth/__tests__/providers-register.test.ts +1 -0
  239. package/src/cli/commands/oauth/__tests__/providers-update.test.ts +1 -0
  240. package/src/cli/commands/oauth/mode.ts +12 -3
  241. package/src/cli/commands/oauth/providers.ts +15 -0
  242. package/src/cli/commands/oauth/shared.ts +2 -1
  243. package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +4 -9
  244. package/src/cli/commands/platform/__tests__/connect.test.ts +6 -0
  245. package/src/cli/commands/platform/__tests__/disconnect.test.ts +7 -1
  246. package/src/cli/commands/platform/__tests__/status.test.ts +6 -0
  247. package/src/cli/program.ts +30 -4
  248. package/src/config/__tests__/backup-schema.test.ts +134 -0
  249. package/src/config/assistant-feature-flags.ts +61 -62
  250. package/src/config/bundled-skills/app-builder/references/CUSTOM_ROUTES.md +37 -1
  251. package/src/config/bundled-skills/browser/SKILL.md +30 -5
  252. package/src/config/bundled-skills/browser/TOOLS.json +123 -0
  253. package/src/config/bundled-skills/browser/tools/browser-attach.ts +12 -0
  254. package/src/config/bundled-skills/browser/tools/browser-detach.ts +12 -0
  255. package/src/config/bundled-skills/browser/tools/browser-status.ts +12 -0
  256. package/src/config/bundled-skills/browser/tools/browser-wait-for-download.ts +17 -0
  257. package/src/config/bundled-skills/contacts/SKILL.md +2 -2
  258. package/src/config/bundled-skills/gmail/SKILL.md +53 -7
  259. package/src/config/bundled-skills/gmail/TOOLS.json +33 -3
  260. package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +116 -9
  261. package/src/config/bundled-skills/gmail/tools/gmail-outreach-scan.ts +138 -11
  262. package/src/config/bundled-skills/gmail/tools/gmail-preferences-tool.ts +59 -0
  263. package/src/config/bundled-skills/gmail/tools/gmail-preferences.ts +82 -0
  264. package/src/config/bundled-skills/gmail/tools/gmail-sender-digest.ts +113 -17
  265. package/src/config/bundled-skills/gmail/tools/gmail-unsubscribe.ts +2 -2
  266. package/src/config/bundled-skills/media-processing/SKILL.md +3 -9
  267. package/src/config/bundled-skills/media-processing/TOOLS.json +1 -6
  268. package/src/config/bundled-skills/media-processing/__tests__/audio-transcribe.test.ts +125 -0
  269. package/src/config/bundled-skills/media-processing/__tests__/extract-keyframes.test.ts +181 -0
  270. package/src/config/bundled-skills/media-processing/__tests__/preprocess-audio.test.ts +141 -0
  271. package/src/config/bundled-skills/media-processing/services/audio-transcribe.ts +32 -87
  272. package/src/config/bundled-skills/media-processing/services/preprocess.ts +8 -4
  273. package/src/config/bundled-skills/media-processing/tools/extract-keyframes.ts +0 -10
  274. package/src/config/bundled-skills/messaging/SKILL.md +3 -3
  275. package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +2 -2
  276. package/src/config/bundled-skills/outlook/SKILL.md +2 -2
  277. package/src/config/bundled-skills/outlook/tools/outlook-unsubscribe.ts +2 -2
  278. package/src/config/bundled-skills/phone-calls/SKILL.md +2 -2
  279. package/src/config/bundled-skills/phone-calls/references/CONFIG.md +27 -18
  280. package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +3 -3
  281. package/src/config/bundled-skills/settings/TOOLS.json +3 -3
  282. package/src/config/bundled-skills/settings/tools/voice-config-update.ts +26 -22
  283. package/src/config/bundled-skills/slack/SKILL.md +1 -0
  284. package/src/config/bundled-skills/transcribe/SKILL.md +9 -14
  285. package/src/config/bundled-skills/transcribe/TOOLS.json +2 -7
  286. package/src/config/bundled-skills/transcribe/tools/transcribe-media.test.ts +256 -0
  287. package/src/config/bundled-skills/transcribe/tools/transcribe-media.ts +38 -188
  288. package/src/config/bundled-tool-registry.ts +8 -0
  289. package/src/config/env-registry.ts +24 -0
  290. package/src/config/env.ts +34 -10
  291. package/src/config/feature-flag-registry.json +46 -14
  292. package/src/config/loader.ts +26 -12
  293. package/src/config/schema.ts +35 -10
  294. package/src/config/schemas/__tests__/stt.test.ts +43 -0
  295. package/src/config/schemas/analysis.ts +51 -0
  296. package/src/config/schemas/backup.ts +72 -0
  297. package/src/config/schemas/calls.ts +1 -26
  298. package/src/config/schemas/elevenlabs.ts +0 -59
  299. package/src/config/schemas/filing.ts +47 -7
  300. package/src/config/schemas/heartbeat.ts +27 -5
  301. package/src/config/schemas/host-browser.ts +47 -1
  302. package/src/config/schemas/inference.ts +1 -1
  303. package/src/config/schemas/memory-lifecycle.ts +14 -2
  304. package/src/config/schemas/services.ts +44 -0
  305. package/src/config/schemas/stt.ts +59 -0
  306. package/src/config/schemas/tts.ts +230 -0
  307. package/src/config/schemas/updates.ts +14 -0
  308. package/src/config/skills.ts +4 -0
  309. package/src/config/types.ts +4 -0
  310. package/src/contacts/contact-store.ts +56 -11
  311. package/src/contacts/contacts-write.ts +38 -1
  312. package/src/context/post-turn-tool-result-truncation.ts +3 -2
  313. package/src/context/tool-result-truncation.ts +2 -1
  314. package/src/context/window-manager.ts +45 -12
  315. package/src/credential-execution/executable-discovery.ts +12 -2
  316. package/src/credential-execution/process-manager.ts +33 -2
  317. package/src/credential-health/credential-health-service.ts +366 -0
  318. package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +324 -0
  319. package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +497 -0
  320. package/src/daemon/__tests__/conversation-tool-setup.test.ts +17 -8
  321. package/src/daemon/__tests__/lifecycle-startup-ordering.test.ts +127 -0
  322. package/src/daemon/config-watcher.ts +99 -5
  323. package/src/daemon/conversation-agent-loop-handlers.ts +6 -0
  324. package/src/daemon/conversation-agent-loop.ts +101 -24
  325. package/src/daemon/conversation-error.ts +11 -0
  326. package/src/daemon/conversation-history.ts +40 -6
  327. package/src/daemon/conversation-launch.ts +220 -0
  328. package/src/daemon/conversation-lifecycle.ts +59 -9
  329. package/src/daemon/conversation-messaging.ts +37 -3
  330. package/src/daemon/conversation-notifiers.ts +5 -0
  331. package/src/daemon/conversation-process.ts +581 -19
  332. package/src/daemon/conversation-queue-manager.ts +24 -0
  333. package/src/daemon/conversation-runtime-assembly.ts +11 -1
  334. package/src/daemon/conversation-slash.ts +36 -0
  335. package/src/daemon/conversation-surfaces.ts +94 -4
  336. package/src/daemon/conversation-tool-setup.ts +25 -0
  337. package/src/daemon/conversation-usage.ts +7 -4
  338. package/src/daemon/conversation.ts +86 -28
  339. package/src/daemon/handlers/config-slack-channel.ts +269 -94
  340. package/src/daemon/handlers/conversations.ts +4 -1
  341. package/src/daemon/handlers/shared.ts +22 -0
  342. package/src/daemon/handlers/skills.ts +321 -77
  343. package/src/daemon/host-browser-proxy.ts +2 -1
  344. package/src/daemon/lifecycle.ts +122 -25
  345. package/src/daemon/message-protocol.ts +6 -0
  346. package/src/daemon/message-types/conversations.ts +34 -1
  347. package/src/daemon/message-types/home.ts +40 -0
  348. package/src/daemon/message-types/meet.ts +143 -0
  349. package/src/daemon/message-types/messages.ts +14 -0
  350. package/src/daemon/message-types/schedules.ts +34 -2
  351. package/src/daemon/message-types/skills.ts +16 -0
  352. package/src/daemon/message-types/surfaces.ts +2 -0
  353. package/src/daemon/server.ts +347 -2
  354. package/src/daemon/shutdown-handlers.ts +32 -4
  355. package/src/daemon/shutdown-registry.ts +40 -0
  356. package/src/daemon/tool-side-effects.ts +9 -0
  357. package/src/email/html-renderer.ts +76 -0
  358. package/src/heartbeat/heartbeat-service.ts +93 -7
  359. package/src/home/__tests__/assistant-feed-authoring.test.ts +156 -0
  360. package/src/home/__tests__/emit-feed-event.test.ts +169 -0
  361. package/src/home/__tests__/feed-scheduler.test.ts +194 -0
  362. package/src/home/__tests__/feed-types.test.ts +275 -0
  363. package/src/home/__tests__/feed-writer.test.ts +688 -0
  364. package/src/home/__tests__/phase5-exit-criteria.test.ts +212 -0
  365. package/src/home/__tests__/platform-gmail-digest.test.ts +222 -0
  366. package/src/home/__tests__/progress-formula.test.ts +213 -0
  367. package/src/home/__tests__/relationship-state-writer.test.ts +740 -0
  368. package/src/home/__tests__/rollup-producer.test.ts +398 -0
  369. package/src/home/assistant-feed-authoring.ts +124 -0
  370. package/src/home/emit-feed-event.ts +158 -0
  371. package/src/home/feed-scheduler.ts +247 -0
  372. package/src/home/feed-types.ts +181 -0
  373. package/src/home/feed-writer.ts +469 -0
  374. package/src/home/platform-gmail-digest.ts +163 -0
  375. package/src/home/progress-formula.ts +86 -0
  376. package/src/home/relationship-state-writer.ts +824 -0
  377. package/src/home/relationship-state.ts +143 -0
  378. package/src/home/rollup-producer.ts +384 -0
  379. package/src/hooks/runner.ts +7 -0
  380. package/src/inbound/platform-callback-registration.ts +12 -3
  381. package/src/inbound/public-ingress-urls.ts +12 -0
  382. package/src/instrument.ts +1 -1
  383. package/src/ipc/__tests__/cli-ipc.test.ts +200 -0
  384. package/src/ipc/cli-client.ts +151 -0
  385. package/src/ipc/cli-server.ts +234 -0
  386. package/src/ipc/gateway-client.ts +180 -0
  387. package/src/ipc/routes/index.ts +5 -0
  388. package/src/ipc/routes/wake-conversation.ts +19 -0
  389. package/src/memory/__tests__/auto-analysis-enqueue.test.ts +356 -0
  390. package/src/memory/__tests__/auto-analysis-guard.test.ts +57 -0
  391. package/src/memory/__tests__/conversation-analyze-job.test.ts +232 -0
  392. package/src/memory/__tests__/find-analysis-conversation.test.ts +196 -0
  393. package/src/memory/app-store.ts +1 -1
  394. package/src/memory/attachments-store.ts +70 -0
  395. package/src/memory/auto-analysis-enqueue.ts +127 -0
  396. package/src/memory/auto-analysis-guard.ts +27 -0
  397. package/src/memory/cleanup-schedule-state.ts +37 -0
  398. package/src/memory/conversation-analyze-job.ts +73 -0
  399. package/src/memory/conversation-crud.ts +99 -0
  400. package/src/memory/conversation-disk-view.ts +7 -0
  401. package/src/memory/conversation-group-migration.ts +34 -2
  402. package/src/memory/conversation-queries.ts +6 -5
  403. package/src/memory/db-init.ts +6 -0
  404. package/src/memory/db-maintenance.ts +108 -0
  405. package/src/memory/db.ts +1 -0
  406. package/src/memory/graph/conversation-graph-memory.ts +15 -0
  407. package/src/memory/graph/extraction.test.ts +23 -0
  408. package/src/memory/graph/extraction.ts +8 -0
  409. package/src/memory/graph/retriever.ts +27 -18
  410. package/src/memory/graph/scoring.test.ts +186 -0
  411. package/src/memory/graph/scoring.ts +31 -1
  412. package/src/memory/graph/tools.ts +1 -1
  413. package/src/memory/group-crud.ts +6 -1
  414. package/src/memory/indexer.ts +95 -16
  415. package/src/memory/job-handlers/cleanup.ts +11 -8
  416. package/src/memory/job-handlers/conversation-starters.ts +16 -10
  417. package/src/memory/jobs-store.ts +64 -4
  418. package/src/memory/jobs-worker.ts +22 -9
  419. package/src/memory/llm-usage-store.ts +92 -56
  420. package/src/memory/migrations/219-oauth-providers-token-exchange-body-format.ts +15 -0
  421. package/src/memory/migrations/220-normalize-user-file-by-principal.ts +190 -0
  422. package/src/memory/migrations/221-conversations-archived-at.ts +16 -0
  423. package/src/memory/migrations/index.ts +6 -0
  424. package/src/memory/migrations/registry.ts +8 -0
  425. package/src/memory/qdrant-manager.ts +43 -16
  426. package/src/memory/schema/conversations.ts +2 -0
  427. package/src/memory/schema/oauth.ts +3 -0
  428. package/src/memory/usage-buckets.ts +396 -0
  429. package/src/messaging/providers/gmail/client.ts +57 -6
  430. package/src/messaging/providers/slack/__tests__/adapter-token-routing.test.ts +282 -0
  431. package/src/messaging/providers/slack/adapter.ts +143 -38
  432. package/src/messaging/providers/slack/client.ts +16 -0
  433. package/src/messaging/providers/slack/types.ts +4 -0
  434. package/src/notifications/decision-engine.ts +3 -3
  435. package/src/notifications/signal.ts +5 -0
  436. package/src/oauth/__tests__/identity-verifier.test.ts +1 -0
  437. package/src/oauth/byo-connection.test.ts +18 -1
  438. package/src/oauth/byo-connection.ts +3 -1
  439. package/src/oauth/connect-orchestrator.ts +2 -0
  440. package/src/oauth/connection-resolver.ts +6 -2
  441. package/src/oauth/connection.ts +2 -0
  442. package/src/oauth/oauth-store.ts +9 -0
  443. package/src/oauth/platform-connection.test.ts +98 -0
  444. package/src/oauth/platform-connection.ts +52 -31
  445. package/src/oauth/seed-providers.ts +7 -0
  446. package/src/permissions/checker.ts +16 -6
  447. package/src/permissions/defaults.ts +49 -1
  448. package/src/permissions/trust-store.ts +3 -3
  449. package/src/permissions/workspace-policy.ts +3 -0
  450. package/src/platform/client.test.ts +10 -0
  451. package/src/platform/sync-identity.ts +129 -0
  452. package/src/prompts/persona-resolver.ts +126 -2
  453. package/src/prompts/system-prompt.ts +59 -18
  454. package/src/prompts/templates/BOOTSTRAP.md +5 -5
  455. package/src/prompts/templates/SOUL.md +3 -1
  456. package/src/prompts/templates/UPDATES.md +12 -0
  457. package/src/prompts/templates/channels/slack.md +20 -0
  458. package/src/prompts/update-bulletin-format.ts +26 -9
  459. package/src/prompts/update-bulletin.ts +34 -23
  460. package/src/prompts/user-reference.ts +20 -17
  461. package/src/providers/__tests__/provider-secret-catalog.test.ts +42 -0
  462. package/src/providers/anthropic/client.ts +157 -61
  463. package/src/providers/fireworks/client.ts +2 -2
  464. package/src/providers/gemini/client.ts +9 -1
  465. package/src/providers/model-catalog.ts +6 -0
  466. package/src/providers/model-intents.ts +4 -4
  467. package/src/providers/ollama/client.ts +2 -2
  468. package/src/providers/openai/chat-completions-provider.ts +474 -0
  469. package/src/providers/openai/client.ts +25 -440
  470. package/src/providers/openai/responses-provider.ts +502 -0
  471. package/src/providers/openrouter/client.ts +101 -4
  472. package/src/providers/provider-secret-catalog.ts +139 -0
  473. package/src/providers/registry.ts +2 -2
  474. package/src/providers/retry.ts +14 -3
  475. package/src/providers/speech-to-text/__tests__/provider-catalog.test.ts +251 -0
  476. package/src/providers/speech-to-text/__tests__/resolve.test.ts +828 -0
  477. package/src/providers/speech-to-text/deepgram-realtime.test.ts +980 -0
  478. package/src/providers/speech-to-text/deepgram-realtime.ts +767 -0
  479. package/src/providers/speech-to-text/deepgram.test.ts +332 -0
  480. package/src/providers/speech-to-text/deepgram.ts +115 -0
  481. package/src/providers/speech-to-text/google-gemini-live-stream.test.ts +743 -0
  482. package/src/providers/speech-to-text/google-gemini-live-stream.ts +625 -0
  483. package/src/providers/speech-to-text/google-gemini.test.ts +226 -0
  484. package/src/providers/speech-to-text/google-gemini.ts +101 -0
  485. package/src/providers/speech-to-text/openai-whisper-stream.test.ts +564 -0
  486. package/src/providers/speech-to-text/openai-whisper-stream.ts +381 -0
  487. package/src/providers/speech-to-text/openai-whisper.test.ts +1 -37
  488. package/src/providers/speech-to-text/openai-whisper.ts +63 -33
  489. package/src/providers/speech-to-text/provider-catalog.ts +306 -0
  490. package/src/providers/speech-to-text/resolve.ts +386 -6
  491. package/src/providers/types.ts +9 -0
  492. package/src/runtime/AGENTS.md +43 -1
  493. package/src/runtime/__tests__/agent-wake.test.ts +831 -0
  494. package/src/runtime/__tests__/runtime-mode.test.ts +62 -0
  495. package/src/runtime/__tests__/slack-block-formatting.test.ts +481 -0
  496. package/src/runtime/agent-wake.ts +512 -0
  497. package/src/runtime/auth/__tests__/route-policy.test.ts +40 -0
  498. package/src/runtime/auth/route-policy.ts +30 -5
  499. package/src/runtime/auth/token-service.ts +56 -1
  500. package/src/runtime/btw-sidechain.ts +2 -0
  501. package/src/runtime/capability-tokens.ts +10 -10
  502. package/src/runtime/channel-invite-transport.ts +1 -1
  503. package/src/runtime/channel-invite-transports/email.ts +14 -6
  504. package/src/runtime/channel-readiness-service.ts +12 -22
  505. package/src/runtime/chrome-extension-registry.ts +38 -2
  506. package/src/runtime/http-server.ts +395 -10
  507. package/src/runtime/http-types.ts +6 -2
  508. package/src/runtime/migrations/__tests__/vbundle-import-credentials.test.ts +36 -0
  509. package/src/runtime/migrations/__tests__/vbundle-legacy-user-md.test.ts +360 -0
  510. package/src/runtime/migrations/migration-transport.ts +1 -0
  511. package/src/runtime/migrations/migration-wizard.ts +1 -0
  512. package/src/runtime/migrations/vbundle-import-analyzer.ts +77 -1
  513. package/src/runtime/migrations/vbundle-importer.ts +34 -0
  514. package/src/runtime/pending-interactions.ts +0 -11
  515. package/src/runtime/routes/__tests__/backup-routes.test.ts +967 -0
  516. package/src/runtime/routes/__tests__/home-feed-routes.test.ts +507 -0
  517. package/src/runtime/routes/__tests__/migration-import-credential-filter.test.ts +208 -0
  518. package/src/runtime/routes/__tests__/stt-routes.test.ts +406 -0
  519. package/src/runtime/routes/__tests__/tts-routes.test.ts +474 -0
  520. package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +148 -17
  521. package/src/runtime/routes/app-management-routes.ts +12 -18
  522. package/src/runtime/routes/attachment-routes.test.ts +9 -3
  523. package/src/runtime/routes/attachment-routes.ts +216 -17
  524. package/src/runtime/routes/backup-routes.ts +519 -0
  525. package/src/runtime/routes/browser-extension-pair-routes.ts +82 -23
  526. package/src/runtime/routes/btw-routes.ts +8 -6
  527. package/src/runtime/routes/contact-routes.test.ts +298 -0
  528. package/src/runtime/routes/contact-routes.ts +132 -5
  529. package/src/runtime/routes/conversation-analysis-routes.ts +22 -142
  530. package/src/runtime/routes/conversation-management-routes.ts +115 -0
  531. package/src/runtime/routes/conversation-routes.ts +367 -146
  532. package/src/runtime/routes/filing-routes.ts +93 -0
  533. package/src/runtime/routes/home-feed-routes.ts +334 -0
  534. package/src/runtime/routes/home-state-routes.ts +138 -0
  535. package/src/runtime/routes/host-browser-routes.ts +3 -14
  536. package/src/runtime/routes/identity-intro-cache.ts +7 -3
  537. package/src/runtime/routes/identity-routes.ts +3 -17
  538. package/src/runtime/routes/inbound-stages/transcribe-audio.test.ts +46 -39
  539. package/src/runtime/routes/inbound-stages/transcribe-audio.ts +15 -15
  540. package/src/runtime/routes/integrations/slack/__tests__/channel.test.ts +137 -0
  541. package/src/runtime/routes/integrations/slack/__tests__/share.test.ts +179 -0
  542. package/src/runtime/routes/integrations/slack/channel.ts +11 -3
  543. package/src/runtime/routes/integrations/slack/share.ts +45 -7
  544. package/src/runtime/routes/llm-context-normalization.ts +303 -0
  545. package/src/runtime/routes/memory-item-routes.test.ts +3 -2
  546. package/src/runtime/routes/migration-routes.ts +40 -5
  547. package/src/runtime/routes/settings-routes.ts +22 -5
  548. package/src/runtime/routes/skills-routes.ts +76 -7
  549. package/src/runtime/routes/stt-routes.ts +233 -0
  550. package/src/runtime/routes/surface-action-routes.ts +41 -2
  551. package/src/runtime/routes/tts-routes.ts +108 -24
  552. package/src/runtime/routes/usage-routes.ts +30 -2
  553. package/src/runtime/routes/user-route-dispatcher.ts +50 -5
  554. package/src/runtime/routes/user-routes.ts +13 -1
  555. package/src/runtime/routes/work-items-routes.ts +8 -1
  556. package/src/runtime/runtime-mode.ts +33 -0
  557. package/src/runtime/services/__tests__/analyze-conversation.test.ts +444 -0
  558. package/src/runtime/services/__tests__/analyze-deps-singleton.test.ts +67 -0
  559. package/src/runtime/services/__tests__/auto-analysis-prompt.test.ts +53 -0
  560. package/src/runtime/services/__tests__/manual-analysis-prompt.test.ts +41 -0
  561. package/src/runtime/services/analyze-conversation.ts +344 -0
  562. package/src/runtime/services/analyze-deps-singleton.ts +32 -0
  563. package/src/runtime/services/auto-analysis-prompt.ts +55 -0
  564. package/src/runtime/skill-route-registry.ts +49 -0
  565. package/src/runtime/slack-block-formatting.ts +437 -10
  566. package/src/schedule/scheduler.ts +50 -0
  567. package/src/security/oauth2.ts +26 -4
  568. package/src/security/secure-keys.ts +25 -2
  569. package/src/security/token-manager.ts +8 -0
  570. package/src/sequence/engine.ts +23 -0
  571. package/src/sequence/types.ts +1 -1
  572. package/src/skills/catalog-files.ts +64 -2
  573. package/src/skills/category-inference.ts +122 -0
  574. package/src/skills/clawhub-files.ts +213 -0
  575. package/src/skills/clawhub.ts +84 -23
  576. package/src/skills/skill-file-provider.ts +40 -0
  577. package/src/skills/skillssh-files.ts +395 -0
  578. package/src/skills/skillssh-registry.ts +4 -4
  579. package/src/stt/__tests__/daemon-batch-transcriber.test.ts +392 -0
  580. package/src/stt/__tests__/types.test.ts +89 -0
  581. package/src/stt/daemon-batch-transcriber.ts +195 -0
  582. package/src/stt/stt-stream-session.ts +499 -0
  583. package/src/stt/types.ts +330 -0
  584. package/src/stt/wav-encoder.test.ts +373 -0
  585. package/src/stt/wav-encoder.ts +175 -0
  586. package/src/subagent/manager.ts +38 -14
  587. package/src/tools/browser/__tests__/browser-mode.test.ts +119 -0
  588. package/src/tools/browser/__tests__/browser-status.test.ts +123 -0
  589. package/src/tools/browser/browser-execution.ts +1163 -23
  590. package/src/tools/browser/browser-manager.ts +45 -0
  591. package/src/tools/browser/browser-mode-constants.ts +12 -0
  592. package/src/tools/browser/browser-mode.ts +92 -0
  593. package/src/tools/browser/browser-status-constants.ts +33 -0
  594. package/src/tools/browser/cdp-client/__tests__/cdp-inspect-client.test.ts +393 -0
  595. package/src/tools/browser/cdp-client/__tests__/extension-cdp-client.test.ts +29 -0
  596. package/src/tools/browser/cdp-client/__tests__/factory.test.ts +1648 -32
  597. package/src/tools/browser/cdp-client/cdp-inspect/__tests__/discovery.test.ts +264 -0
  598. package/src/tools/browser/cdp-client/cdp-inspect/discovery.ts +183 -17
  599. package/src/tools/browser/cdp-client/cdp-inspect-client.ts +254 -21
  600. package/src/tools/browser/cdp-client/errors.ts +15 -0
  601. package/src/tools/browser/cdp-client/extension-cdp-client.ts +39 -16
  602. package/src/tools/browser/cdp-client/factory.ts +797 -87
  603. package/src/tools/browser/cdp-client/index.ts +16 -2
  604. package/src/tools/browser/cdp-client/types.ts +68 -0
  605. package/src/tools/credentials/vault.ts +35 -6
  606. package/src/tools/network/web-fetch.ts +5 -2
  607. package/src/tools/network/web-search.ts +5 -2
  608. package/src/tools/shared/shell-output.ts +3 -1
  609. package/src/tools/side-effects.ts +2 -0
  610. package/src/tools/skills/sandbox-runner.ts +3 -2
  611. package/src/tools/terminal/safe-env.ts +10 -2
  612. package/src/tools/terminal/shell.ts +15 -4
  613. package/src/tools/tool-manifest.ts +21 -0
  614. package/src/tools/types.ts +17 -0
  615. package/src/tools/ui-surface/definitions.ts +6 -1
  616. package/src/tts/__tests__/provider-adapters.test.ts +834 -0
  617. package/src/tts/__tests__/provider-catalog-consistency.test.ts +196 -0
  618. package/src/tts/__tests__/provider-catalog.test.ts +183 -0
  619. package/src/tts/__tests__/provider-registry.test.ts +90 -0
  620. package/src/tts/provider-catalog.ts +201 -0
  621. package/src/tts/provider-registry.ts +73 -0
  622. package/src/tts/providers/deepgram-provider.ts +219 -0
  623. package/src/tts/providers/elevenlabs-provider.ts +211 -0
  624. package/src/tts/providers/fish-audio-provider.ts +183 -0
  625. package/src/tts/providers/index.ts +42 -0
  626. package/src/tts/providers/register-builtins.ts +130 -0
  627. package/src/tts/synthesize-text.ts +110 -0
  628. package/src/tts/tts-config-resolver.ts +78 -0
  629. package/src/tts/types.ts +153 -0
  630. package/src/types/onboarding-context.ts +7 -0
  631. package/src/util/abort-reasons.ts +58 -0
  632. package/src/util/device-id.ts +32 -16
  633. package/src/util/errors.ts +9 -1
  634. package/src/util/platform.ts +54 -10
  635. package/src/util/pricing.ts +66 -3
  636. package/src/util/spawn.ts +1 -1
  637. package/src/util/truncate.ts +4 -2
  638. package/src/util/unicode.ts +201 -0
  639. package/src/version.ts +19 -24
  640. package/src/watcher/engine.ts +23 -0
  641. package/src/watcher/watcher-store.ts +31 -0
  642. package/src/workspace/migrations/003-seed-device-id.ts +9 -3
  643. package/src/workspace/migrations/017-seed-persona-dirs.ts +68 -4
  644. package/src/workspace/migrations/029-seed-pkb.ts +1 -1
  645. package/src/workspace/migrations/031-drop-user-md.ts +317 -0
  646. package/src/workspace/migrations/031-llm-log-retention-zero-to-null.ts +73 -0
  647. package/src/workspace/migrations/032-tts-provider-unification.ts +227 -0
  648. package/src/workspace/migrations/033-stt-service-explicit-config.ts +122 -0
  649. package/src/workspace/migrations/034-remove-calls-voice-transcription-provider.ts +215 -0
  650. package/src/workspace/migrations/035-seed-slack-channel-persona.ts +50 -0
  651. package/src/workspace/migrations/036-update-pkb-index-bar.ts +37 -0
  652. package/src/workspace/migrations/037-create-meets-dir.ts +61 -0
  653. package/src/workspace/migrations/registry.ts +16 -0
  654. package/src/workspace/top-level-renderer.ts +13 -1
  655. package/src/workspace/turn-commit.ts +31 -0
  656. package/src/__tests__/email-cli.test.ts +0 -297
  657. package/src/__tests__/email-service-config-fallback.test.ts +0 -102
  658. package/src/cli/commands/browser-relay.ts +0 -466
  659. package/src/email/guardrails.ts +0 -221
  660. package/src/email/provider.ts +0 -117
  661. package/src/email/providers/agentmail.ts +0 -361
  662. package/src/email/providers/index.ts +0 -65
  663. package/src/email/service.ts +0 -384
  664. package/src/email/types.ts +0 -126
  665. package/src/prompts/templates/USER.md +0 -13
  666. package/src/providers/speech-to-text/types.ts +0 -17
  667. package/src/runtime/routes/browser-cdp-routes.ts +0 -229
@@ -21,6 +21,10 @@ import {
21
21
  startGuardianActionSweep,
22
22
  stopGuardianActionSweep,
23
23
  } from "../calls/guardian-action-sweep.js";
24
+ import {
25
+ activeMediaStreamSessions,
26
+ MediaStreamCallSession,
27
+ } from "../calls/media-stream-server.js";
24
28
  import type { RelayWebSocketData } from "../calls/relay-server.js";
25
29
  import {
26
30
  activeRelayConnections,
@@ -37,6 +41,7 @@ import {
37
41
  hasUngatedHttpAuthDisabled,
38
42
  isHttpAuthDisabled,
39
43
  } from "../config/env.js";
44
+ import { getConfig } from "../config/loader.js";
40
45
  import type { ServerMessage } from "../daemon/message-protocol.js";
41
46
  import { PairingStore } from "../daemon/pairing-store.js";
42
47
  import {
@@ -62,10 +67,15 @@ import {
62
67
  import type { ExternalConversationBinding } from "../memory/external-conversation-store.js";
63
68
  import * as externalConversationStore from "../memory/external-conversation-store.js";
64
69
  import { listGroups } from "../memory/group-crud.js";
70
+ import { resolveStreamingTranscriber } from "../providers/speech-to-text/resolve.js";
65
71
  import {
66
72
  consumeCallback,
67
73
  consumeCallbackError,
68
74
  } from "../security/oauth-callback-registry.js";
75
+ import {
76
+ activeSttStreamSessions,
77
+ SttStreamSession,
78
+ } from "../stt/stt-stream-session.js";
69
79
  import { UserError } from "../util/errors.js";
70
80
  import { getLogger } from "../util/logger.js";
71
81
  import { getRuntimePortFilePath } from "../util/platform.js";
@@ -121,8 +131,8 @@ import { approvalRouteDefinitions } from "./routes/approval-routes.js";
121
131
  import { attachmentRouteDefinitions } from "./routes/attachment-routes.js";
122
132
  import { handleGetAudio } from "./routes/audio-routes.js";
123
133
  import { avatarRouteDefinitions } from "./routes/avatar-routes.js";
134
+ import { backupRouteDefinitions } from "./routes/backup-routes.js";
124
135
  import { brainGraphRouteDefinitions } from "./routes/brain-graph-routes.js";
125
- import { browserCdpRouteDefinitions } from "./routes/browser-cdp-routes.js";
126
136
  import { handleBrowserExtensionPair } from "./routes/browser-extension-pair-routes.js";
127
137
  import { btwRouteDefinitions } from "./routes/btw-routes.js";
128
138
  import { callRouteDefinitions } from "./routes/call-routes.js";
@@ -154,12 +164,15 @@ import { debugRouteDefinitions } from "./routes/debug-routes.js";
154
164
  import { diagnosticsRouteDefinitions } from "./routes/diagnostics-routes.js";
155
165
  import { documentRouteDefinitions } from "./routes/documents-routes.js";
156
166
  import { eventsRouteDefinitions } from "./routes/events-routes.js";
167
+ import { filingRouteDefinitions } from "./routes/filing-routes.js";
157
168
  import { globalSearchRouteDefinitions } from "./routes/global-search-routes.js";
158
169
  import { groupRouteDefinitions } from "./routes/group-routes.js";
159
170
  import { guardianActionRouteDefinitions } from "./routes/guardian-action-routes.js";
160
171
  import { handleGuardianBootstrap } from "./routes/guardian-bootstrap-routes.js";
161
172
  import { handleGuardianRefresh } from "./routes/guardian-refresh-routes.js";
162
173
  import { heartbeatRouteDefinitions } from "./routes/heartbeat-routes.js";
174
+ import { homeFeedRouteDefinitions } from "./routes/home-feed-routes.js";
175
+ import { homeStateRouteDefinitions } from "./routes/home-state-routes.js";
163
176
  import { hostBashRouteDefinitions } from "./routes/host-bash-routes.js";
164
177
  import {
165
178
  hostBrowserRouteDefinitions,
@@ -199,6 +212,7 @@ import { scheduleRouteDefinitions } from "./routes/schedule-routes.js";
199
212
  import { secretRouteDefinitions } from "./routes/secret-routes.js";
200
213
  import { settingsRouteDefinitions } from "./routes/settings-routes.js";
201
214
  import { skillRouteDefinitions } from "./routes/skills-routes.js";
215
+ import { sttRouteDefinitions } from "./routes/stt-routes.js";
202
216
  import { subagentRouteDefinitions } from "./routes/subagents-routes.js";
203
217
  import { surfaceActionRouteDefinitions } from "./routes/surface-action-routes.js";
204
218
  import { surfaceContentRouteDefinitions } from "./routes/surface-content-routes.js";
@@ -213,6 +227,8 @@ import { watchRouteDefinitions } from "./routes/watch-routes.js";
213
227
  import { workItemRouteDefinitions } from "./routes/work-items-routes.js";
214
228
  import { workspaceCommitRouteDefinitions } from "./routes/workspace-commit-routes.js";
215
229
  import { workspaceRouteDefinitions } from "./routes/workspace-routes.js";
230
+ import { setAnalysisDeps } from "./services/analyze-deps-singleton.js";
231
+ import { matchSkillRoute } from "./skill-route-registry.js";
216
232
 
217
233
  // Re-export for consumers
218
234
  export { isPrivateAddress } from "./middleware/auth.js";
@@ -282,6 +298,40 @@ interface BrowserRelayWebSocketData {
282
298
  clientInstanceId?: string;
283
299
  }
284
300
 
301
+ /**
302
+ * WebSocket data attached to `/v1/calls/media-stream` connections.
303
+ * The `wsType` discriminator routes frames to the media-stream call
304
+ * session instead of the ConversationRelay or browser-relay handlers.
305
+ */
306
+ interface MediaStreamWebSocketData {
307
+ wsType: "media-stream";
308
+ callSessionId: string;
309
+ /** Bound at open time so the close handler tears down the exact session
310
+ * that owns *this* socket, avoiding races with reconnects. */
311
+ session?: MediaStreamCallSession;
312
+ }
313
+
314
+ /**
315
+ * WebSocket data attached to `/v1/stt/stream` connections.
316
+ * The `wsType` discriminator routes frames to the STT streaming
317
+ * session orchestrator instead of the other WebSocket handlers.
318
+ *
319
+ * `provider` is optional compatibility metadata from the client/gateway.
320
+ * The runtime is config-authoritative — it always resolves the streaming
321
+ * transcriber from `services.stt.provider` in the assistant config.
322
+ */
323
+ interface SttStreamWebSocketData {
324
+ wsType: "stt-stream";
325
+ /** Optional requested provider — metadata only; runtime uses config. */
326
+ provider?: string;
327
+ mimeType: string;
328
+ sampleRate?: number;
329
+ /** The session ID for tracking in the active sessions registry. */
330
+ sessionId: string;
331
+ /** Bound at open time so the close handler tears down the exact session. */
332
+ session?: SttStreamSession;
333
+ }
334
+
285
335
  export class RuntimeHttpServer {
286
336
  private server: ReturnType<typeof Bun.serve> | null = null;
287
337
  private port: number;
@@ -311,6 +361,7 @@ export class RuntimeHttpServer {
311
361
  private getCesClient?: RuntimeHttpServerOptions["getCesClient"];
312
362
  private onProviderCredentialsChanged?: RuntimeHttpServerOptions["onProviderCredentialsChanged"];
313
363
  private getHeartbeatService?: RuntimeHttpServerOptions["getHeartbeatService"];
364
+ private getFilingService?: RuntimeHttpServerOptions["getFilingService"];
314
365
  private router: HttpRouter;
315
366
 
316
367
  constructor(options: RuntimeHttpServerOptions = {}) {
@@ -335,6 +386,7 @@ export class RuntimeHttpServer {
335
386
  this.getCesClient = options.getCesClient;
336
387
  this.onProviderCredentialsChanged = options.onProviderCredentialsChanged;
337
388
  this.getHeartbeatService = options.getHeartbeatService;
389
+ this.getFilingService = options.getFilingService;
338
390
  this.router = new HttpRouter(this.buildRouteTable());
339
391
  }
340
392
 
@@ -372,7 +424,11 @@ export class RuntimeHttpServer {
372
424
  }
373
425
 
374
426
  async start(): Promise<void> {
375
- type AllWebSocketData = RelayWebSocketData | BrowserRelayWebSocketData;
427
+ type AllWebSocketData =
428
+ | RelayWebSocketData
429
+ | BrowserRelayWebSocketData
430
+ | MediaStreamWebSocketData
431
+ | SttStreamWebSocketData;
376
432
  this.server = Bun.serve<AllWebSocketData>({
377
433
  port: this.port,
378
434
  hostname: this.hostname,
@@ -399,6 +455,94 @@ export class RuntimeHttpServer {
399
455
  }
400
456
  return;
401
457
  }
458
+ if ("wsType" in data && data.wsType === "media-stream") {
459
+ const msData = data as MediaStreamWebSocketData;
460
+ log.info(
461
+ { callSessionId: msData.callSessionId },
462
+ "Media-stream WebSocket opened",
463
+ );
464
+ const session = new MediaStreamCallSession(
465
+ ws,
466
+ msData.callSessionId,
467
+ );
468
+ activeMediaStreamSessions.set(msData.callSessionId, session);
469
+ // Bind the session instance to the websocket so the close
470
+ // handler tears down *this* session, not a replacement that
471
+ // a reconnect may have inserted under the same callSessionId.
472
+ msData.session = session;
473
+ return;
474
+ }
475
+ if ("wsType" in data && data.wsType === "stt-stream") {
476
+ const sttData = data as SttStreamWebSocketData;
477
+
478
+ // The runtime is config-authoritative: always resolve the
479
+ // provider from `services.stt.provider` regardless of what
480
+ // the client/gateway requested.
481
+ //
482
+ // getConfig() can throw (e.g. after invalidateConfigCache()
483
+ // when config.json is temporarily invalid). Wrap in try/catch
484
+ // so the session still starts normally — resolveStreamingTranscriber
485
+ // reads config inside SttStreamSession.start()'s own guarded path.
486
+ let configuredProvider: string | undefined;
487
+ try {
488
+ configuredProvider = getConfig().services.stt.provider;
489
+
490
+ // Mismatch telemetry: when the optional requested provider
491
+ // disagrees with the configured provider, log a warning so
492
+ // operators can detect stale client builds.
493
+ if (sttData.provider && sttData.provider !== configuredProvider) {
494
+ log.warn(
495
+ {
496
+ requestedProvider: sttData.provider,
497
+ configuredProvider,
498
+ sessionId: sttData.sessionId,
499
+ },
500
+ "STT stream provider mismatch — requested provider differs from configured provider; using configured provider",
501
+ );
502
+ }
503
+ } catch (err) {
504
+ log.warn(
505
+ {
506
+ error: err instanceof Error ? err.message : String(err),
507
+ sessionId: sttData.sessionId,
508
+ },
509
+ "Failed to read config for STT provider mismatch telemetry — proceeding without mismatch check",
510
+ );
511
+ }
512
+
513
+ // Fall back to the requested provider (or "unknown") when
514
+ // config reading failed, so the session constructor still
515
+ // gets a usable label for logging/error messages.
516
+ const effectiveProvider =
517
+ configuredProvider ?? sttData.provider ?? "unknown";
518
+
519
+ log.info(
520
+ {
521
+ requestedProvider: sttData.provider ?? "(none)",
522
+ configuredProvider: effectiveProvider,
523
+ mimeType: sttData.mimeType,
524
+ sessionId: sttData.sessionId,
525
+ },
526
+ "STT stream WebSocket opened",
527
+ );
528
+ const session = new SttStreamSession(
529
+ ws,
530
+ effectiveProvider,
531
+ sttData.mimeType,
532
+ { sampleRate: sttData.sampleRate },
533
+ );
534
+ sttData.session = session;
535
+ activeSttStreamSessions.set(sttData.sessionId, session);
536
+
537
+ // Start the session asynchronously — resolves the streaming
538
+ // transcriber and sends a `ready` event on success.
539
+ void session.start(() =>
540
+ resolveStreamingTranscriber({
541
+ sampleRate: sttData.sampleRate,
542
+ }),
543
+ );
544
+ return;
545
+ }
402
546
  const callSessionId = (data as RelayWebSocketData).callSessionId;
403
547
  log.info({ callSessionId }, "ConversationRelay WebSocket opened");
404
548
  if (callSessionId) {
@@ -521,6 +665,14 @@ export class RuntimeHttpServer {
521
665
  }
522
666
  return;
523
667
  }
668
+ case "keepalive": {
669
+ // Extension keepalive frames refresh the connection's
670
+ // activity timestamp without producing log noise or
671
+ // altering routing semantics. Unknown extra keys on
672
+ // the frame are silently ignored (lenient validation).
673
+ getChromeExtensionRegistry().touch(data.connectionId);
674
+ return;
675
+ }
524
676
  default: {
525
677
  log.debug(
526
678
  { connectionId: data.connectionId, type: frame.type },
@@ -530,6 +682,28 @@ export class RuntimeHttpServer {
530
682
  }
531
683
  }
532
684
  }
685
+ if ("wsType" in data && data.wsType === "media-stream") {
686
+ const msData = data as MediaStreamWebSocketData;
687
+ msData.session?.handleMessage(raw);
688
+ return;
689
+ }
690
+ if ("wsType" in data && data.wsType === "stt-stream") {
691
+ const sttData = data as SttStreamWebSocketData;
692
+ const session = sttData.session;
693
+ if (!session) return;
694
+
695
+ if (typeof message === "string") {
696
+ session.handleMessage(message);
697
+ } else {
698
+ // Binary frame — raw audio bytes.
699
+ const buffer =
700
+ message instanceof ArrayBuffer
701
+ ? Buffer.from(new Uint8Array(message))
702
+ : Buffer.from(message);
703
+ session.handleBinaryAudio(buffer);
704
+ }
705
+ return;
706
+ }
533
707
  const callSessionId = (data as RelayWebSocketData).callSessionId;
534
708
  if (callSessionId) {
535
709
  const connection = activeRelayConnections.get(callSessionId);
@@ -547,6 +721,56 @@ export class RuntimeHttpServer {
547
721
  getChromeExtensionRegistry().unregister(data.connectionId);
548
722
  return;
549
723
  }
724
+ if ("wsType" in data && data.wsType === "media-stream") {
725
+ const msData = data as MediaStreamWebSocketData;
726
+ log.info(
727
+ {
728
+ callSessionId: msData.callSessionId,
729
+ code,
730
+ reason: reason?.toString(),
731
+ },
732
+ "Media-stream WebSocket closed",
733
+ );
734
+ // Use the session bound at open time so we tear down the
735
+ // exact session that owns *this* socket, not a replacement
736
+ // that a reconnect may have inserted under the same key.
737
+ const msSession = msData.session;
738
+ if (msSession) {
739
+ msSession.handleTransportClosed(code, reason?.toString());
740
+ msSession.destroy();
741
+ // Only delete from the map if *our* session is still the
742
+ // registered one — a reconnect may have already replaced it.
743
+ if (
744
+ activeMediaStreamSessions.get(msData.callSessionId) ===
745
+ msSession
746
+ ) {
747
+ activeMediaStreamSessions.delete(msData.callSessionId);
748
+ }
749
+ }
750
+ return;
751
+ }
752
+ if ("wsType" in data && data.wsType === "stt-stream") {
753
+ const sttData = data as SttStreamWebSocketData;
754
+ log.info(
755
+ {
756
+ provider: sttData.provider,
757
+ sessionId: sttData.sessionId,
758
+ code,
759
+ reason: reason?.toString(),
760
+ },
761
+ "STT stream WebSocket closed",
762
+ );
763
+ const session = sttData.session;
764
+ if (session) {
765
+ session.handleClose(code, reason?.toString());
766
+ // Only delete from the map if our session is still the
767
+ // registered one — avoids races with reconnects.
768
+ if (activeSttStreamSessions.get(sttData.sessionId) === session) {
769
+ activeSttStreamSessions.delete(sttData.sessionId);
770
+ }
771
+ }
772
+ return;
773
+ }
550
774
  const callSessionId = (data as RelayWebSocketData).callSessionId;
551
775
  log.info(
552
776
  { callSessionId, code, reason: reason?.toString() },
@@ -715,6 +939,15 @@ export class RuntimeHttpServer {
715
939
  clearInterval(this.retrySweepTimer);
716
940
  this.retrySweepTimer = null;
717
941
  }
942
+
943
+ // Deterministic teardown of active STT streaming sessions before
944
+ // stopping the HTTP server so provider sessions are cleaned up
945
+ // and clients receive proper close frames.
946
+ for (const [sessionId, session] of activeSttStreamSessions) {
947
+ session.destroy();
948
+ activeSttStreamSessions.delete(sessionId);
949
+ }
950
+
718
951
  if (this.server) {
719
952
  this.server.stop(true);
720
953
  this.server = null;
@@ -771,6 +1004,24 @@ export class RuntimeHttpServer {
771
1004
  return this.handleRelayUpgrade(req, server);
772
1005
  }
773
1006
 
1007
+ // WebSocket upgrade for Twilio Media Streams — same private-network
1008
+ // restrictions as relay upgrades.
1009
+ if (
1010
+ path.startsWith("/v1/calls/media-stream") &&
1011
+ req.headers.get("upgrade")?.toLowerCase() === "websocket"
1012
+ ) {
1013
+ return this.handleMediaStreamUpgrade(req, server);
1014
+ }
1015
+
1016
+ // WebSocket upgrade for STT streaming — private-network restrictions
1017
+ // and explicit gateway-service token verification before upgrade.
1018
+ if (
1019
+ path === "/v1/stt/stream" &&
1020
+ req.headers.get("upgrade")?.toLowerCase() === "websocket"
1021
+ ) {
1022
+ return this.handleSttStreamUpgrade(req, server);
1023
+ }
1024
+
774
1025
  // Twilio webhook endpoints — before auth check because Twilio
775
1026
  // webhook POSTs don't include bearer tokens.
776
1027
  const twilioResponse = await this.handleTwilioWebhook(req, path);
@@ -810,6 +1061,14 @@ export class RuntimeHttpServer {
810
1061
  return await handleGuardianRefresh(req);
811
1062
  }
812
1063
 
1064
+ // Skill-registered routes (e.g. meet-bot event ingress). Handled before
1065
+ // JWT auth because skills may use their own auth (e.g. per-meeting bearer
1066
+ // tokens minted by a session manager).
1067
+ const skillMatch = matchSkillRoute(path, req.method);
1068
+ if (skillMatch) {
1069
+ return await skillMatch.route.handler(req, skillMatch.match);
1070
+ }
1071
+
813
1072
  // JWT bearer authentication — replaces the old shared-secret comparison.
814
1073
  // authenticateRequest handles dev bypass (DISABLE_HTTP_AUTH) internally.
815
1074
  //
@@ -1060,6 +1319,108 @@ export class RuntimeHttpServer {
1060
1319
  return undefined!;
1061
1320
  }
1062
1321
 
1322
+ private handleMediaStreamUpgrade(
1323
+ req: Request,
1324
+ server: ReturnType<typeof Bun.serve>,
1325
+ ): Response {
1326
+ if (!isPrivateNetworkPeer(server, req) || !isPrivateNetworkOrigin(req)) {
1327
+ return httpError(
1328
+ "FORBIDDEN",
1329
+ "Direct media-stream access disabled — only private network peers allowed",
1330
+ 403,
1331
+ );
1332
+ }
1333
+
1334
+ const wsUrl = new URL(req.url);
1335
+ const callSessionId = wsUrl.searchParams.get("callSessionId");
1336
+ if (!callSessionId) {
1337
+ return new Response("Missing callSessionId", { status: 400 });
1338
+ }
1339
+ // Media-stream connections use a distinct wsType so the open/message/close
1340
+ // handlers route them to MediaStreamCallSession instead of RelayConnection.
1341
+ const upgraded = server.upgrade(req, {
1342
+ data: {
1343
+ wsType: "media-stream",
1344
+ callSessionId,
1345
+ } satisfies MediaStreamWebSocketData,
1346
+ });
1347
+ if (!upgraded) {
1348
+ return new Response("WebSocket upgrade failed", { status: 500 });
1349
+ }
1350
+ // Bun's WebSocket upgrade consumes the request — no Response is sent.
1351
+ return undefined!;
1352
+ }
1353
+
1354
+ /**
1355
+ * Handle WebSocket upgrade for `/v1/stt/stream`.
1356
+ *
1357
+ * Private-network restrictions apply (same as relay/media-stream) so the
1358
+ * runtime remains unreachable from the public internet. The gateway
1359
+ * authenticates the downstream client and proxies the upgrade with a
1360
+ * short-lived gateway service token.
1361
+ */
1362
+ private handleSttStreamUpgrade(
1363
+ req: Request,
1364
+ server: ReturnType<typeof Bun.serve>,
1365
+ ): Response {
1366
+ if (!isPrivateNetworkPeer(server, req) || !isPrivateNetworkOrigin(req)) {
1367
+ return httpError(
1368
+ "FORBIDDEN",
1369
+ "Direct STT stream access disabled — only private network peers allowed",
1370
+ 403,
1371
+ );
1372
+ }
1373
+
1374
+ // Verify the gateway service token before accepting the upgrade.
1375
+ if (!isHttpAuthDisabled()) {
1376
+ const wsUrl = new URL(req.url);
1377
+ const token = wsUrl.searchParams.get("token");
1378
+ if (!token) {
1379
+ return httpError("UNAUTHORIZED", "Unauthorized", 401);
1380
+ }
1381
+ const jwtResult = verifyToken(token, "vellum-daemon");
1382
+ if (!jwtResult.ok) {
1383
+ return httpError("UNAUTHORIZED", "Unauthorized", 401);
1384
+ }
1385
+ // Accept gateway service tokens (svc:gateway:*) — these are the
1386
+ // only tokens the gateway mints for upstream connections.
1387
+ const subResult = parseSub(jwtResult.claims.sub);
1388
+ if (!subResult.ok || subResult.principalType !== "svc_gateway") {
1389
+ return httpError("UNAUTHORIZED", "Unauthorized", 401);
1390
+ }
1391
+ }
1392
+
1393
+ const wsUrl = new URL(req.url);
1394
+ // provider is optional compatibility metadata — the runtime resolves
1395
+ // the streaming transcriber from config (`services.stt.provider`).
1396
+ const provider = wsUrl.searchParams.get("provider") ?? undefined;
1397
+ const mimeType = wsUrl.searchParams.get("mimeType");
1398
+ if (!mimeType) {
1399
+ return new Response("Missing required query parameter: mimeType", {
1400
+ status: 400,
1401
+ });
1402
+ }
1403
+
1404
+ const sampleRateRaw = wsUrl.searchParams.get("sampleRate");
1405
+ const sampleRate = sampleRateRaw ? parseInt(sampleRateRaw, 10) : undefined;
1406
+
1407
+ const sessionId = crypto.randomUUID();
1408
+ const upgraded = server.upgrade(req, {
1409
+ data: {
1410
+ wsType: "stt-stream",
1411
+ provider,
1412
+ mimeType,
1413
+ sampleRate,
1414
+ sessionId,
1415
+ } satisfies SttStreamWebSocketData,
1416
+ });
1417
+ if (!upgraded) {
1418
+ return new Response("WebSocket upgrade failed", { status: 500 });
1419
+ }
1420
+ // Bun's WebSocket upgrade consumes the request — no Response is sent.
1421
+ return undefined!;
1422
+ }
1423
+
1063
1424
  private async handleTwilioWebhook(
1064
1425
  req: Request,
1065
1426
  path: string,
@@ -1237,6 +1598,9 @@ export class RuntimeHttpServer {
1237
1598
  : {}),
1238
1599
  groupId: displayMeta?.groupId ?? null,
1239
1600
  ...(forkParent ? { forkParent } : {}),
1601
+ ...(conversation.archivedAt != null
1602
+ ? { archivedAt: conversation.archivedAt }
1603
+ : {}),
1240
1604
  };
1241
1605
  }
1242
1606
 
@@ -1339,6 +1703,11 @@ export class RuntimeHttpServer {
1339
1703
  ...heartbeatRouteDefinitions({
1340
1704
  getHeartbeatService: this.getHeartbeatService,
1341
1705
  }),
1706
+ ...filingRouteDefinitions({
1707
+ getFilingService: this.getFilingService,
1708
+ }),
1709
+ ...homeStateRouteDefinitions(),
1710
+ ...homeFeedRouteDefinitions(),
1342
1711
  ...notificationRouteDefinitions(),
1343
1712
  ...diagnosticsRouteDefinitions(),
1344
1713
  ...logExportRouteDefinitions(),
@@ -1372,6 +1741,7 @@ export class RuntimeHttpServer {
1372
1741
  : undefined,
1373
1742
  }),
1374
1743
  ...ttsRouteDefinitions(),
1744
+ ...sttRouteDefinitions(),
1375
1745
 
1376
1746
  // Conversation list and seen signal — kept inline because they
1377
1747
  // depend on multiple cross-cutting stores that aren't grouped
@@ -1438,13 +1808,28 @@ export class RuntimeHttpServer {
1438
1808
  ? conversationManagementRouteDefinitions(conversationManagementDeps)
1439
1809
  : []),
1440
1810
 
1441
- ...(this.sendMessageDeps
1442
- ? conversationAnalysisRouteDefinitions({
1443
- sendMessageDeps: this.sendMessageDeps,
1444
- buildConversationDetailResponse: (id) =>
1445
- this.buildConversationDetailResponse(id),
1446
- })
1447
- : []),
1811
+ ...((): RouteDefinition[] => {
1812
+ const sendMessageDeps = this.sendMessageDeps;
1813
+ if (!sendMessageDeps) return [];
1814
+ const analysisDeps = {
1815
+ sendMessageDeps,
1816
+ buildConversationDetailResponse: (id: string) =>
1817
+ this.buildConversationDetailResponse(id),
1818
+ };
1819
+ // Also expose via the module singleton so background callers
1820
+ // (e.g. job handlers) can invoke analyzeConversation() without
1821
+ // HTTP-layer wiring. Daemon startup must never block, so failures
1822
+ // to register the singleton are logged and swallowed.
1823
+ try {
1824
+ setAnalysisDeps(analysisDeps);
1825
+ } catch (err) {
1826
+ log.warn(
1827
+ { err },
1828
+ "Failed to register analysis deps singleton; background analysis jobs will be skipped",
1829
+ );
1830
+ }
1831
+ return conversationAnalysisRouteDefinitions(analysisDeps);
1832
+ })(),
1448
1833
 
1449
1834
  ...groupRouteDefinitions(),
1450
1835
 
@@ -1563,7 +1948,6 @@ export class RuntimeHttpServer {
1563
1948
  ...approvalRouteDefinitions(),
1564
1949
  ...hostBashRouteDefinitions(),
1565
1950
  ...hostBrowserRouteDefinitions(),
1566
- ...browserCdpRouteDefinitions(),
1567
1951
  ...hostCuRouteDefinitions(),
1568
1952
  ...hostFileRouteDefinitions(),
1569
1953
  ...(this.getSkillContext
@@ -1685,6 +2069,7 @@ export class RuntimeHttpServer {
1685
2069
  ...eventsRouteDefinitions(),
1686
2070
  ...traceEventRouteDefinitions(),
1687
2071
  ...migrationRouteDefinitions(),
2072
+ ...backupRouteDefinitions(),
1688
2073
 
1689
2074
  // User-defined routes under /x/* — must be LAST so built-in routes
1690
2075
  // always take priority.
@@ -193,7 +193,7 @@ export interface RuntimeHttpServerOptions {
193
193
  surfaceId: string,
194
194
  actionId: string,
195
195
  data?: Record<string, unknown>,
196
- ): void;
196
+ ): void | Promise<unknown>;
197
197
  surfaceState: Map<
198
198
  string,
199
199
  { surfaceType: SurfaceType; data: SurfaceData; title?: string }
@@ -215,7 +215,7 @@ export interface RuntimeHttpServerOptions {
215
215
  surfaceId: string,
216
216
  actionId: string,
217
217
  data?: Record<string, unknown>,
218
- ): void;
218
+ ): void | Promise<unknown>;
219
219
  surfaceState: Map<
220
220
  string,
221
221
  { surfaceType: SurfaceType; data: SurfaceData; title?: string }
@@ -241,6 +241,10 @@ export interface RuntimeHttpServerOptions {
241
241
  getHeartbeatService?: () =>
242
242
  | import("../heartbeat/heartbeat-service.js").HeartbeatService
243
243
  | undefined;
244
+ /** Accessor for the filing service (for run-now and config routes). */
245
+ getFilingService?: () =>
246
+ | import("../filing/filing-service.js").FilingService
247
+ | undefined;
244
248
  }
245
249
 
246
250
  export interface RuntimeAttachmentMetadata {
@@ -135,6 +135,42 @@ describe("extractCredentialsFromBundle", () => {
135
135
  value: "value with spaces & special=chars!",
136
136
  });
137
137
  });
138
+
139
+ test("extracts vellum:-prefixed credentials (filtering happens in migration-routes)", () => {
140
+ const entries = new Map<string, VBundleTarEntry>();
141
+ entries.set(
142
+ "credentials/vellum:assistant_api_key",
143
+ makeTarEntry("key-123"),
144
+ );
145
+ entries.set(
146
+ "credentials/vellum:platform_assistant_id",
147
+ makeTarEntry("asst-456"),
148
+ );
149
+ entries.set("credentials/openai-key", makeTarEntry("sk-user-789"));
150
+
151
+ const manifest = makeManifest([
152
+ "credentials/vellum:assistant_api_key",
153
+ "credentials/vellum:platform_assistant_id",
154
+ "credentials/openai-key",
155
+ ]);
156
+ const credentials = extractCredentialsFromBundle(entries, manifest);
157
+
158
+ // extractCredentialsFromBundle does NOT filter — it returns all credentials.
159
+ // Filtering of vellum:* platform credentials is done in migration-routes.ts.
160
+ expect(credentials).toHaveLength(3);
161
+ expect(credentials).toContainEqual({
162
+ account: "vellum:assistant_api_key",
163
+ value: "key-123",
164
+ });
165
+ expect(credentials).toContainEqual({
166
+ account: "vellum:platform_assistant_id",
167
+ value: "asst-456",
168
+ });
169
+ expect(credentials).toContainEqual({
170
+ account: "openai-key",
171
+ value: "sk-user-789",
172
+ });
173
+ });
138
174
  });
139
175
 
140
176
  // ---------------------------------------------------------------------------