@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
@@ -0,0 +1,143 @@
1
+ /**
2
+ * Relationship state data contract.
3
+ *
4
+ * This is the shared wire format that describes the assistant's current
5
+ * relationship with the user: which tier they're at, what facts the
6
+ * assistant has learned about them, and which capabilities are unlocked.
7
+ *
8
+ * The TypeScript types here are the source of truth. A structurally
9
+ * identical Swift definition lives at
10
+ * `clients/shared/Models/RelationshipState.swift` — any change here must
11
+ * be mirrored there (and the contract test guards the default list).
12
+ */
13
+
14
+ export const RELATIONSHIP_STATE_VERSION = 1 as const;
15
+
16
+ export type RelationshipTier = 1 | 2 | 3 | 4;
17
+
18
+ export interface TierInfo {
19
+ label: string;
20
+ description: string;
21
+ nextTierHint?: string;
22
+ }
23
+
24
+ export const TIER_INFO: Record<RelationshipTier, TierInfo> = {
25
+ 1: {
26
+ label: "Getting to know you",
27
+ description: "We just met — learning the basics",
28
+ nextTierHint: "A few more conversations and I'll start to find my footing",
29
+ },
30
+ 2: {
31
+ label: "Finding my footing",
32
+ description: "Starting to understand how you work",
33
+ nextTierHint: "Keep working with me and we'll hit our stride",
34
+ },
35
+ 3: {
36
+ label: "Hitting our stride",
37
+ description: "We have a real working relationship",
38
+ nextTierHint:
39
+ "Give me more context and autonomy and we'll be fully in sync",
40
+ },
41
+ 4: {
42
+ label: "In sync",
43
+ description: "Full partnership",
44
+ },
45
+ };
46
+
47
+ export type FactCategory = "voice" | "world" | "priorities";
48
+ export type FactConfidence = "strong" | "uncertain";
49
+ export type FactSource = "onboarding" | "inferred";
50
+
51
+ export interface Fact {
52
+ id: string;
53
+ category: FactCategory;
54
+ text: string;
55
+ confidence: FactConfidence;
56
+ source: FactSource;
57
+ }
58
+
59
+ export type CapabilityTier = "unlocked" | "next-up" | "earned";
60
+
61
+ export interface Capability {
62
+ id: string;
63
+ name: string;
64
+ description: string;
65
+ tier: CapabilityTier;
66
+ /** Human-readable unlock requirement. */
67
+ gate: string;
68
+ /** Shown on "earned" tier: why, not when. */
69
+ unlockHint?: string;
70
+ /** Shown on "next-up" tier: e.g. "Connect Google →". */
71
+ ctaLabel?: string;
72
+ }
73
+
74
+ export interface RelationshipState {
75
+ version: typeof RELATIONSHIP_STATE_VERSION;
76
+ /** Forward-compat for multi-assistant. Only one assistant is supported in v1. */
77
+ assistantId: string;
78
+ tier: RelationshipTier;
79
+ /** 0-100 */
80
+ progressPercent: number;
81
+ facts: Fact[];
82
+ capabilities: Capability[];
83
+ conversationCount: number;
84
+ /** ISO 8601 */
85
+ hatchedDate: string;
86
+ assistantName: string;
87
+ userName?: string;
88
+ /** ISO 8601 */
89
+ updatedAt: string;
90
+ }
91
+
92
+ /**
93
+ * Seed list of capabilities the relationship-state writer should project,
94
+ * minus the `tier` field (which is computed at write time based on what
95
+ * the assistant has learned and which integrations are connected).
96
+ *
97
+ * Order and ids are part of the public contract — the contract test
98
+ * asserts this list matches the TDD so drift causes a failure.
99
+ */
100
+ export const DEFAULT_CAPABILITIES: Omit<Capability, "tier">[] = [
101
+ {
102
+ id: "email",
103
+ name: "Email access",
104
+ description: "Read, draft, and manage your email",
105
+ gate: "Connect Google",
106
+ ctaLabel: "Connect Google →",
107
+ },
108
+ {
109
+ id: "calendar",
110
+ name: "Calendar awareness",
111
+ description: "Know your schedule, prep for meetings",
112
+ gate: "Connect calendar",
113
+ ctaLabel: "Connect Calendar →",
114
+ },
115
+ {
116
+ id: "slack",
117
+ name: "Slack monitoring",
118
+ description: "Watch channels, surface what matters",
119
+ gate: "Set up Slack app",
120
+ ctaLabel: "Set up Slack →",
121
+ },
122
+ {
123
+ id: "voice-writing",
124
+ name: "Write in your voice",
125
+ description: "Draft messages and docs that sound like you",
126
+ gate: "Usage — needs conversation history",
127
+ unlockHint: "I need to learn how you communicate first",
128
+ },
129
+ {
130
+ id: "proactive",
131
+ name: "Proactive suggestions",
132
+ description: "Flag things before you ask",
133
+ gate: "Trust — needs priority understanding",
134
+ unlockHint: "I need to understand your priorities first",
135
+ },
136
+ {
137
+ id: "autonomous",
138
+ name: "Act on your behalf",
139
+ description: "Send messages, file things, take action",
140
+ gate: "Trust — deepest level",
141
+ unlockHint: "We need a deeper working relationship first",
142
+ },
143
+ ];
@@ -0,0 +1,384 @@
1
+ /**
2
+ * Activity-log roll-up producer for the home feed.
3
+ *
4
+ * On a tick, reads the recent `action` items that background jobs have
5
+ * deposited in the feed (via `emit-feed-event.ts`) and asks the
6
+ * configured inference provider "consolidate these raw actions into a
7
+ * small set of digests or threads." This is the replacement for the
8
+ * old "reflect from nothing" producer: the roll-up starts from real
9
+ * side effects instead of prompting the model to hallucinate signal
10
+ * from relationship state alone.
11
+ *
12
+ * Mirrors the background-inference pattern established in
13
+ * `approval-generators.ts`: resolve the provider from config, call
14
+ * `provider.sendMessage` with a `tool_use`-shaped structured output
15
+ * schema, validate each returned block, and hand the validated
16
+ * shapes to `writeAssistantFeedItem`.
17
+ *
18
+ * Budget notes:
19
+ *
20
+ * - Hard cap: {@link MAX_ITEMS_PER_ROLLUP} items per tick so a
21
+ * single run can never flood the feed.
22
+ * - Timeout: {@link ROLLUP_TIMEOUT_MS} so a stalled provider can't
23
+ * stall the tick loop.
24
+ * - Token budget: {@link ROLLUP_MAX_TOKENS} — tight, because the
25
+ * output is a list of short feed items, not a long essay.
26
+ * - Input cap: at most {@link MAX_ACTIONS_IN_PROMPT} recent action
27
+ * items are serialized into the user prompt. Callers' volume is
28
+ * already bounded by the writer's per-source action cap, but
29
+ * this second cap protects against pathological inputs.
30
+ *
31
+ * Failure modes degrade gracefully: an unavailable provider, a
32
+ * malformed tool_use block, a schema-rejected item, or an exception
33
+ * in the inner loop all return a {@link RollupResult} with the
34
+ * appropriate `skippedReason`. The scheduler logs these but never
35
+ * surfaces them to the user.
36
+ */
37
+
38
+ import { loadConfig } from "../config/loader.js";
39
+ import { getProvider, listProviders } from "../providers/registry.js";
40
+ import type { Provider } from "../providers/types.js";
41
+ import { getLogger } from "../util/logger.js";
42
+ import {
43
+ writeAssistantFeedItem,
44
+ type WriteAssistantFeedItemParams,
45
+ } from "./assistant-feed-authoring.js";
46
+ import type { FeedItem } from "./feed-types.js";
47
+ import { readHomeFeed } from "./feed-writer.js";
48
+ import { computeRelationshipState } from "./relationship-state-writer.js";
49
+
50
+ const log = getLogger("home-feed-rollup");
51
+
52
+ const ROLLUP_TIMEOUT_MS = 30_000;
53
+ const ROLLUP_MAX_TOKENS = 800;
54
+ const MAX_ITEMS_PER_ROLLUP = 3;
55
+ const MAX_ACTIONS_IN_PROMPT = 30;
56
+
57
+ const ROLLUP_TOOL_NAME = "write_feed_items";
58
+
59
+ const ROLLUP_SYSTEM_PROMPT = [
60
+ "You are a roll-up loop for a personal assistant's home activity feed.",
61
+ "Raw `action` items land in the feed as a deterministic side effect of background jobs.",
62
+ "Your job is to CONSOLIDATE those raw actions into higher-signal summary rows — never to invent signal from nothing.",
63
+ "",
64
+ "Rules:",
65
+ "- Emit only `digest` or `thread` items. Do NOT emit `action` items — those come from the background jobs themselves.",
66
+ "- A `digest` collapses several related raw actions into one summary row (e.g. '3 scheduled jobs ran this morning').",
67
+ "- A `thread` tracks an ongoing multi-action situation worth surfacing (e.g. 'Outreach to Alice — 2 emails sent, awaiting reply').",
68
+ "- Each digest/thread must be grounded in specific action items from the list below. Do not invent events.",
69
+ "- Never duplicate a consolidation that already describes the same set of actions — the writer's one-per-source replacement for digests will collapse repeats but you shouldn't rely on it.",
70
+ "- Prefer 0 items over low-signal filler. An empty activity log should always produce 0 items.",
71
+ "- You may emit up to 3 items total.",
72
+ "",
73
+ "Use the `write_feed_items` tool to emit items. If nothing is worth rolling up, call the tool with an empty `items` array.",
74
+ ].join("\n");
75
+
76
+ const ROLLUP_TOOL_SCHEMA = {
77
+ name: ROLLUP_TOOL_NAME,
78
+ description:
79
+ "Record the set of roll-up feed items (digests or threads) that consolidate recent activity-log actions. " +
80
+ "Pass an empty `items` array if nothing is worth rolling up right now.",
81
+ input_schema: {
82
+ type: "object" as const,
83
+ properties: {
84
+ items: {
85
+ type: "array",
86
+ maxItems: MAX_ITEMS_PER_ROLLUP,
87
+ items: {
88
+ type: "object",
89
+ properties: {
90
+ type: {
91
+ type: "string",
92
+ enum: ["digest", "thread"],
93
+ description:
94
+ "`digest` collapses multiple related actions into one summary row; `thread` tracks an ongoing multi-action situation.",
95
+ },
96
+ source: {
97
+ type: "string",
98
+ enum: ["gmail", "slack", "calendar", "assistant"],
99
+ description:
100
+ "Origin hint used for the icon. Use `assistant` for cross-source roll-ups of assistant-driven work.",
101
+ },
102
+ title: {
103
+ type: "string",
104
+ description:
105
+ "Short headline, 4–10 words. Lowercase-sentence-case, no period.",
106
+ },
107
+ summary: {
108
+ type: "string",
109
+ description:
110
+ "One-sentence body copy explaining the roll-up. 1–25 words. Must reference specific actions from the activity log.",
111
+ },
112
+ priority: {
113
+ type: "integer",
114
+ minimum: 0,
115
+ maximum: 100,
116
+ description:
117
+ "Relative importance (higher = more prominent). Use 70 for digests, 55 for background threads.",
118
+ },
119
+ minTimeAway: {
120
+ type: "integer",
121
+ minimum: 0,
122
+ description:
123
+ "Seconds the user must be away before this item appears. Use 0 for a roll-up the user should see immediately.",
124
+ },
125
+ },
126
+ required: ["type", "title", "summary"],
127
+ additionalProperties: false,
128
+ },
129
+ },
130
+ },
131
+ required: ["items"],
132
+ additionalProperties: false,
133
+ },
134
+ };
135
+
136
+ export interface RollupResult {
137
+ /** Number of items actually written to the feed. */
138
+ wroteCount: number;
139
+ /**
140
+ * When non-null, indicates the producer short-circuited and no LLM
141
+ * call was made (or the call's result was unusable). The scheduler
142
+ * logs this but does not treat it as an error.
143
+ *
144
+ * `no_actions` means there was nothing to roll up — a quiet but
145
+ * normal outcome that does not advance the cooldown gate (no point
146
+ * re-running until new actions land).
147
+ */
148
+ skippedReason:
149
+ | "no_provider"
150
+ | "no_actions"
151
+ | "empty_items"
152
+ | "provider_error"
153
+ | "malformed_output"
154
+ | null;
155
+ }
156
+
157
+ /**
158
+ * Dependency seams exposed for tests. Production callers pass
159
+ * `undefined` so the producer uses the real helpers. Tests pass
160
+ * stubs to avoid `mock.module`, which leaks across files in Bun's
161
+ * test runner and causes cross-file isolation bugs.
162
+ */
163
+ export interface RollupProducerDeps {
164
+ writeItem?: (params: WriteAssistantFeedItemParams) => Promise<unknown>;
165
+ loadRelationshipState?: () => Promise<
166
+ Awaited<ReturnType<typeof computeRelationshipState>>
167
+ >;
168
+ loadRecentActions?: () => FeedItem[];
169
+ resolveProvider?: () => Provider | null;
170
+ }
171
+
172
+ /**
173
+ * Run one roll-up pass. Loads recent action items from the feed plus
174
+ * relationship state, builds a user prompt around them, asks the
175
+ * provider for a `write_feed_items` tool call, and invokes
176
+ * {@link writeAssistantFeedItem} for each item in the returned array.
177
+ */
178
+ export async function runRollupProducer(
179
+ now: Date = new Date(),
180
+ deps: RollupProducerDeps = {},
181
+ ): Promise<RollupResult> {
182
+ const writeItem = deps.writeItem ?? writeAssistantFeedItem;
183
+ const loadRelationshipState =
184
+ deps.loadRelationshipState ?? computeRelationshipState;
185
+ const loadRecentActions = deps.loadRecentActions ?? defaultLoadRecentActions;
186
+
187
+ const provider = deps.resolveProvider
188
+ ? deps.resolveProvider()
189
+ : resolveDefaultProvider();
190
+ if (!provider) {
191
+ return { wroteCount: 0, skippedReason: "no_provider" };
192
+ }
193
+
194
+ const actions = loadRecentActions();
195
+ if (actions.length === 0) {
196
+ return { wroteCount: 0, skippedReason: "no_actions" };
197
+ }
198
+
199
+ const state = await loadRelationshipState();
200
+ const userPrompt = buildUserPrompt(actions, state, now);
201
+
202
+ let response;
203
+ try {
204
+ response = await provider.sendMessage(
205
+ [{ role: "user", content: [{ type: "text", text: userPrompt }] }],
206
+ [ROLLUP_TOOL_SCHEMA],
207
+ ROLLUP_SYSTEM_PROMPT,
208
+ {
209
+ config: { max_tokens: ROLLUP_MAX_TOKENS },
210
+ signal: AbortSignal.timeout(ROLLUP_TIMEOUT_MS),
211
+ },
212
+ );
213
+ } catch (err) {
214
+ log.warn({ err }, "Rollup provider.sendMessage failed");
215
+ return { wroteCount: 0, skippedReason: "provider_error" };
216
+ }
217
+
218
+ const toolUse = response.content.find(
219
+ (block) => block.type === "tool_use" && block.name === ROLLUP_TOOL_NAME,
220
+ );
221
+ if (!toolUse || toolUse.type !== "tool_use") {
222
+ return { wroteCount: 0, skippedReason: "malformed_output" };
223
+ }
224
+
225
+ const input = toolUse.input as Record<string, unknown>;
226
+ const rawItems = Array.isArray(input.items) ? input.items : null;
227
+ if (!rawItems || rawItems.length === 0) {
228
+ return { wroteCount: 0, skippedReason: "empty_items" };
229
+ }
230
+
231
+ const capped = rawItems.slice(0, MAX_ITEMS_PER_ROLLUP);
232
+ const accepted: WriteAssistantFeedItemParams[] = [];
233
+ for (const raw of capped) {
234
+ const params = coerceRollupItem(raw);
235
+ if (params) accepted.push(params);
236
+ }
237
+
238
+ // If the model returned items but every single one failed coercion,
239
+ // that's a schema-drift signal we want loud in production logs — a
240
+ // silent "wroteCount: 0, skippedReason: null" would look like a
241
+ // normal quiet tick and bury the bug. Report it as malformed_output.
242
+ if (accepted.length === 0) {
243
+ return { wroteCount: 0, skippedReason: "malformed_output" };
244
+ }
245
+
246
+ let wroteCount = 0;
247
+ for (const params of accepted) {
248
+ try {
249
+ await writeItem(params);
250
+ wroteCount += 1;
251
+ } catch (err) {
252
+ // Schema rejection is a model-output bug, not a regression in the
253
+ // writer — log and keep going so a single malformed item doesn't
254
+ // block the rest of the batch.
255
+ log.warn({ err, params }, "Failed to write rollup item");
256
+ }
257
+ }
258
+
259
+ return { wroteCount, skippedReason: null };
260
+ }
261
+
262
+ function resolveDefaultProvider(): ReturnType<typeof getProvider> | null {
263
+ const config = loadConfig();
264
+ if (!listProviders().includes(config.services.inference.provider)) {
265
+ return null;
266
+ }
267
+ return getProvider(config.services.inference.provider);
268
+ }
269
+
270
+ /**
271
+ * Default recent-actions loader. Reads the TTL-filtered home feed,
272
+ * keeps only `action` items, and returns them sorted by `createdAt`
273
+ * descending so the most recent signals land at the top of the
274
+ * prompt. Non-action items (digests, threads, nudges) are excluded
275
+ * — the roll-up's input is the raw activity log, not the existing
276
+ * consolidations.
277
+ */
278
+ function defaultLoadRecentActions(): FeedItem[] {
279
+ const feed = readHomeFeed();
280
+ return feed.items
281
+ .filter((i) => i.type === "action")
282
+ .sort((a, b) => {
283
+ const am = Date.parse(a.createdAt);
284
+ const bm = Date.parse(b.createdAt);
285
+ if (Number.isNaN(am) && Number.isNaN(bm)) return 0;
286
+ if (Number.isNaN(am)) return 1;
287
+ if (Number.isNaN(bm)) return -1;
288
+ return bm - am;
289
+ });
290
+ }
291
+
292
+ /**
293
+ * Build the user-prompt context for one roll-up pass. Keeps the
294
+ * relationship-state block small and bounds the action list at
295
+ * {@link MAX_ACTIONS_IN_PROMPT} so a pathological input can't blow
296
+ * the token budget.
297
+ */
298
+ function buildUserPrompt(
299
+ actions: FeedItem[],
300
+ state: Awaited<ReturnType<typeof computeRelationshipState>>,
301
+ now: Date,
302
+ ): string {
303
+ const actionLines = actions
304
+ .slice(0, MAX_ACTIONS_IN_PROMPT)
305
+ .map((a) => {
306
+ const src = a.source ? `[${a.source}]` : "[-]";
307
+ return ` - ${a.createdAt} ${src} ${a.title} — ${a.summary}`;
308
+ })
309
+ .join("\n");
310
+
311
+ const factLines = state.facts
312
+ .slice(0, 10)
313
+ .map((f) => ` - ${f.category}: ${f.text}`)
314
+ .join("\n");
315
+
316
+ return [
317
+ `Current time: ${now.toISOString()}`,
318
+ `Assistant name: ${state.assistantName}`,
319
+ state.userName ? `User name: ${state.userName}` : "User name: (unknown)",
320
+ `Relationship tier: ${state.tier} / 4`,
321
+ "",
322
+ `Recent activity log entries (most recent first, up to ${MAX_ACTIONS_IN_PROMPT}):`,
323
+ actionLines.length > 0 ? actionLines : " (none)",
324
+ "",
325
+ "Known facts about the user (for context only — do NOT invent roll-ups from these):",
326
+ factLines.length > 0 ? factLines : " (none yet)",
327
+ "",
328
+ "Consolidate the activity log above into a small set of `digest` or `thread` roll-up items. Remember: prefer 0 items over filler, and only roll up when several related actions cluster into a coherent story. Use the `write_feed_items` tool.",
329
+ ].join("\n");
330
+ }
331
+
332
+ /**
333
+ * Coerce a raw tool_use item into
334
+ * {@link WriteAssistantFeedItemParams}, returning null if the shape is
335
+ * unrecoverable. The schema on the provider side enforces most of
336
+ * this, but the runtime check guards against model drift — including
337
+ * the `type` narrowing to digest/thread (actions and nudges are
338
+ * rejected here even if the model ignores the tool schema).
339
+ */
340
+ function coerceRollupItem(
341
+ raw: unknown,
342
+ ): WriteAssistantFeedItemParams | null {
343
+ if (!raw || typeof raw !== "object") return null;
344
+ const obj = raw as Record<string, unknown>;
345
+
346
+ const type = obj.type;
347
+ if (type !== "digest" && type !== "thread") {
348
+ return null;
349
+ }
350
+
351
+ const title = typeof obj.title === "string" ? obj.title.trim() : "";
352
+ const summary = typeof obj.summary === "string" ? obj.summary.trim() : "";
353
+ if (!title || !summary) return null;
354
+
355
+ const source = obj.source;
356
+ let coercedSource: WriteAssistantFeedItemParams["source"];
357
+ if (
358
+ source === "gmail" ||
359
+ source === "slack" ||
360
+ source === "calendar" ||
361
+ source === "assistant"
362
+ ) {
363
+ coercedSource = source;
364
+ }
365
+
366
+ const priority =
367
+ typeof obj.priority === "number" && Number.isInteger(obj.priority)
368
+ ? Math.max(0, Math.min(100, obj.priority))
369
+ : undefined;
370
+
371
+ const minTimeAway =
372
+ typeof obj.minTimeAway === "number" && Number.isInteger(obj.minTimeAway)
373
+ ? Math.max(0, obj.minTimeAway)
374
+ : undefined;
375
+
376
+ return {
377
+ type,
378
+ source: coercedSource,
379
+ title,
380
+ summary,
381
+ priority,
382
+ minTimeAway,
383
+ };
384
+ }
@@ -49,6 +49,13 @@ export async function runHookScript(
49
49
  // @deprecated — usage of VELLUM_ROOT_DIR by hook scripts is deprecated.
50
50
  // Removing this requires an LLM-based migration or declarative migration
51
51
  // file to update existing user-authored hooks to use VELLUM_WORKSPACE_DIR.
52
+ //
53
+ // VELLUM_ROOT_DIR is kept at the legacy `~/.vellum` value even when
54
+ // vellumRoot() resolves per-instance via BASE_DATA_DIR. User hook
55
+ // scripts written against this env var expected the legacy path;
56
+ // changing it would be a silent contract break. Hooks that need the
57
+ // per-instance root should read BASE_DATA_DIR themselves or use the
58
+ // new env vars the environment-layout plan adds.
52
59
  VELLUM_ROOT_DIR: join(homedir(), ".vellum"),
53
60
  VELLUM_WORKSPACE_DIR: getWorkspaceDir(),
54
61
  VELLUM_HOOK_SETTINGS: JSON.stringify(
@@ -110,12 +110,15 @@ interface RegisterCallbackRouteResponse {
110
110
  * by the platform.
111
111
  * @param type - The route type identifier (e.g. "twilio_voice",
112
112
  * "twilio_status", "oauth", "telegram").
113
+ * @param sourceIdentifier - Optional human-readable source identifier
114
+ * (e.g. bot handle, phone number) for display in admin UI.
113
115
  * @returns The platform-provided callback URL that external services should use.
114
116
  * @throws If the platform request fails.
115
117
  */
116
118
  export async function registerCallbackRoute(
117
119
  callbackPath: string,
118
120
  type: string,
121
+ sourceIdentifier?: string,
119
122
  ): Promise<string> {
120
123
  const context = await resolvePlatformCallbackRegistrationContext();
121
124
  if (!context.enabled || !context.authHeader) {
@@ -134,11 +137,15 @@ export async function registerCallbackRoute(
134
137
  Authorization: context.authHeader,
135
138
  };
136
139
 
137
- const body = JSON.stringify({
140
+ const payload: Record<string, string> = {
138
141
  assistant_id: assistantId,
139
142
  callback_path: callbackPath,
140
143
  type,
141
- });
144
+ };
145
+ if (sourceIdentifier) {
146
+ payload.source_identifier = sourceIdentifier;
147
+ }
148
+ const body = JSON.stringify(payload);
142
149
 
143
150
  log.debug({ callbackPath, type }, "Registering platform callback route");
144
151
 
@@ -184,6 +191,7 @@ export async function registerCallbackRoute(
184
191
  * @param callbackPath - The path to register (e.g. "webhooks/twilio/voice").
185
192
  * @param type - The route type identifier.
186
193
  * @param queryParams - Optional query parameters to append to the resolved URL.
194
+ * @param sourceIdentifier - Optional human-readable source identifier for admin display.
187
195
  * @returns The resolved callback URL.
188
196
  */
189
197
  export async function resolveCallbackUrl(
@@ -191,13 +199,14 @@ export async function resolveCallbackUrl(
191
199
  callbackPath: string,
192
200
  type: string,
193
201
  queryParams?: Record<string, string>,
202
+ sourceIdentifier?: string,
194
203
  ): Promise<string> {
195
204
  if (!shouldUsePlatformCallbacks()) {
196
205
  return directUrl();
197
206
  }
198
207
 
199
208
  try {
200
- let url = await registerCallbackRoute(callbackPath, type);
209
+ let url = await registerCallbackRoute(callbackPath, type, sourceIdentifier);
201
210
  if (queryParams && Object.keys(queryParams).length > 0) {
202
211
  const params = new URLSearchParams(queryParams);
203
212
  const separator = url.includes("?") ? "&" : "?";
@@ -120,6 +120,18 @@ export function getTwilioRelayUrl(config: IngressConfig): string {
120
120
  return `${wsBase}/webhooks/twilio/relay`;
121
121
  }
122
122
 
123
+ /**
124
+ * Build the Twilio media-stream WebSocket URL.
125
+ * Used for the `<Stream>` TwiML path when the STT provider requires
126
+ * custom server-side transcription (e.g. OpenAI Whisper).
127
+ * Converts http:// → ws:// and https:// → wss://.
128
+ */
129
+ export function getTwilioMediaStreamUrl(config: IngressConfig): string {
130
+ const base = getPublicBaseUrl(config);
131
+ const wsBase = base.replace(/^http(s?)/, "ws$1");
132
+ return `${wsBase}/webhooks/twilio/media-stream`;
133
+ }
134
+
123
135
  /**
124
136
  * Build the OAuth callback URL.
125
137
  */
package/src/instrument.ts CHANGED
@@ -52,7 +52,7 @@ export function initSentry(): void {
52
52
  dsn,
53
53
  release: `vellum-assistant@${APP_VERSION}`,
54
54
  dist: COMMIT_SHA,
55
- environment: APP_VERSION === "0.0.0-dev" ? "development" : "production",
55
+ environment: process.env.VELLUM_ENVIRONMENT ?? "production",
56
56
  sendDefaultPii: false,
57
57
  serverName: hostname(),
58
58
  initialScope: {