@vellumai/assistant 0.6.2 → 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 (895) hide show
  1. package/ARCHITECTURE.md +273 -10
  2. package/Dockerfile +2 -3
  3. package/bun.lock +41 -49
  4. package/bunfig.toml +3 -0
  5. package/docs/architecture/memory.md +1 -1
  6. package/docs/backup-troubleshooting.md +52 -0
  7. package/docs/browser-use-architecture-phase2.md +174 -0
  8. package/docs/stt-provider-onboarding.md +120 -0
  9. package/knip.json +12 -2
  10. package/node_modules/@vellumai/ces-contracts/bun.lock +8 -6
  11. package/node_modules/@vellumai/ces-contracts/package.json +3 -3
  12. package/node_modules/@vellumai/ces-contracts/src/rpc.ts +42 -0
  13. package/openapi.yaml +1111 -86
  14. package/package.json +40 -42
  15. package/scripts/generate-openapi.ts +0 -2
  16. package/scripts/test.sh +73 -18
  17. package/src/__tests__/acp-session.test.ts +43 -0
  18. package/src/__tests__/agent-image-optimize.test.ts +28 -0
  19. package/src/__tests__/agent-loop.test.ts +123 -0
  20. package/src/__tests__/anthropic-provider.test.ts +263 -10
  21. package/src/__tests__/app-builder-tool-scripts.test.ts +1 -0
  22. package/src/__tests__/app-executors.test.ts +1 -0
  23. package/src/__tests__/app-source-watcher.test.ts +37 -11
  24. package/src/__tests__/approval-routes-http.test.ts +178 -1
  25. package/src/__tests__/auto-analysis-end-to-end.test.ts +550 -0
  26. package/src/__tests__/auto-analysis-prompt.test.ts +50 -0
  27. package/src/__tests__/browser-fill-credential.test.ts +240 -94
  28. package/src/__tests__/browser-manager.test.ts +40 -27
  29. package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +2 -2
  30. package/src/__tests__/browser-skill-endstate.test.ts +31 -7
  31. package/src/__tests__/btw-routes.test.ts +7 -0
  32. package/src/__tests__/call-controller.test.ts +581 -20
  33. package/src/__tests__/catalog-files.test.ts +1000 -0
  34. package/src/__tests__/channel-approvals.test.ts +53 -0
  35. package/src/__tests__/channel-invite-transport.test.ts +2 -2
  36. package/src/__tests__/channel-readiness-routes.test.ts +16 -20
  37. package/src/__tests__/channel-readiness-service.test.ts +12 -7
  38. package/src/__tests__/checker.test.ts +157 -10
  39. package/src/__tests__/clawhub-files.test.ts +347 -0
  40. package/src/__tests__/commit-message-enrichment-service.test.ts +36 -19
  41. package/src/__tests__/config-analysis.test.ts +100 -0
  42. package/src/__tests__/config-managed-gemini-defaults.test.ts +326 -0
  43. package/src/__tests__/config-schema-cmd.test.ts +2 -2
  44. package/src/__tests__/config-schema.test.ts +1248 -224
  45. package/src/__tests__/config-watcher-cleanup-throttle.test.ts +339 -0
  46. package/src/__tests__/config-watcher.test.ts +43 -8
  47. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +23 -0
  48. package/src/__tests__/contact-store-user-file.test.ts +512 -0
  49. package/src/__tests__/contacts-write.test.ts +197 -0
  50. package/src/__tests__/context-overflow-approval.test.ts +16 -1
  51. package/src/__tests__/context-window-manager.test.ts +88 -0
  52. package/src/__tests__/conversation-abort-tool-results.test.ts +2 -0
  53. package/src/__tests__/conversation-agent-loop-overflow.test.ts +2 -1
  54. package/src/__tests__/conversation-agent-loop.test.ts +99 -3
  55. package/src/__tests__/conversation-analysis-routes.test.ts +2 -2
  56. package/src/__tests__/conversation-attachments.test.ts +80 -4
  57. package/src/__tests__/conversation-confirmation-signals.test.ts +290 -0
  58. package/src/__tests__/conversation-error.test.ts +70 -0
  59. package/src/__tests__/conversation-fork-crud.test.ts +17 -0
  60. package/src/__tests__/conversation-history-web-search.test.ts +12 -4
  61. package/src/__tests__/conversation-host-access-routes.test.ts +229 -0
  62. package/src/__tests__/conversation-init.benchmark.test.ts +6 -1
  63. package/src/__tests__/conversation-inject-context.test.ts +103 -0
  64. package/src/__tests__/conversation-launcher-skill-regression.test.ts +51 -0
  65. package/src/__tests__/conversation-list-source.test.ts +145 -0
  66. package/src/__tests__/conversation-pre-run-repair.test.ts +2 -0
  67. package/src/__tests__/conversation-provider-retry-repair.test.ts +2 -0
  68. package/src/__tests__/conversation-queue.test.ts +946 -62
  69. package/src/__tests__/conversation-routes-disk-view.test.ts +275 -0
  70. package/src/__tests__/conversation-routes-guardian-reply.test.ts +16 -0
  71. package/src/__tests__/conversation-routes-slash-commands.test.ts +1 -0
  72. package/src/__tests__/conversation-runtime-assembly.test.ts +324 -46
  73. package/src/__tests__/conversation-skill-tools.test.ts +7 -4
  74. package/src/__tests__/conversation-slash-commands.test.ts +33 -0
  75. package/src/__tests__/conversation-slash-queue.test.ts +89 -18
  76. package/src/__tests__/conversation-slash-unknown.test.ts +2 -0
  77. package/src/__tests__/conversation-starter-routes.test.ts +126 -0
  78. package/src/__tests__/conversation-starters-cadence.test.ts +161 -0
  79. package/src/__tests__/conversation-store.test.ts +195 -0
  80. package/src/__tests__/conversation-tool-setup-batch-authorized.test.ts +226 -0
  81. package/src/__tests__/conversation-workspace-cache-state.test.ts +193 -0
  82. package/src/__tests__/conversation-workspace-injection.test.ts +2 -0
  83. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +2 -0
  84. package/src/__tests__/credential-execution-approval-bridge.test.ts +32 -1
  85. package/src/__tests__/credential-health-service.test.ts +352 -0
  86. package/src/__tests__/credential-security-invariants.test.ts +6 -3
  87. package/src/__tests__/credential-vault-unit.test.ts +383 -7
  88. package/src/__tests__/credential-vault.test.ts +152 -13
  89. package/src/__tests__/credentials-cli.test.ts +42 -18
  90. package/src/__tests__/cross-provider-web-search.test.ts +146 -35
  91. package/src/__tests__/date-context.test.ts +4 -4
  92. package/src/__tests__/deterministic-verification-control-plane.test.ts +10 -1
  93. package/src/__tests__/device-id.test.ts +112 -0
  94. package/src/__tests__/docker-signing-key-bootstrap.test.ts +167 -4
  95. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +1 -3
  96. package/src/__tests__/email-html-renderer.test.ts +71 -0
  97. package/src/__tests__/email-invite-adapter.test.ts +36 -32
  98. package/src/__tests__/embedding-managed-proxy-selection.test.ts +256 -0
  99. package/src/__tests__/emit-event-signal.test.ts +71 -0
  100. package/src/__tests__/extension-id-sync-guard.test.ts +222 -0
  101. package/src/__tests__/fixtures/mock-chrome-extension.ts +386 -0
  102. package/src/__tests__/gateway-only-enforcement.test.ts +206 -1
  103. package/src/__tests__/gateway-only-guard.test.ts +2 -0
  104. package/src/__tests__/gemini-provider.test.ts +66 -2
  105. package/src/__tests__/get-skill-detail-audit.test.ts +325 -0
  106. package/src/__tests__/gmail-archive-fallback.test.ts +193 -0
  107. package/src/__tests__/gmail-archive-gate.test.ts +246 -0
  108. package/src/__tests__/gmail-preferences.test.ts +117 -0
  109. package/src/__tests__/guardian-routing-invariants.test.ts +70 -2
  110. package/src/__tests__/headless-browser-interactions.test.ts +738 -359
  111. package/src/__tests__/headless-browser-mode.test.ts +614 -0
  112. package/src/__tests__/headless-browser-navigate.test.ts +528 -49
  113. package/src/__tests__/headless-browser-read-tools.test.ts +274 -100
  114. package/src/__tests__/headless-browser-snapshot.test.ts +250 -77
  115. package/src/__tests__/heartbeat-service.test.ts +70 -17
  116. package/src/__tests__/home-state-routes.test.ts +162 -0
  117. package/src/__tests__/host-bash-proxy.test.ts +145 -1
  118. package/src/__tests__/host-browser-e2e-cloud.test.ts +596 -0
  119. package/src/__tests__/host-browser-e2e-self-hosted-capability.test.ts +286 -0
  120. package/src/__tests__/host-browser-e2e-self-hosted.test.ts +374 -0
  121. package/src/__tests__/host-browser-event-routes.test.ts +350 -0
  122. package/src/__tests__/host-browser-proxy.test.ts +444 -0
  123. package/src/__tests__/host-browser-routes.test.ts +198 -0
  124. package/src/__tests__/host-browser-ws-events-e2e.test.ts +423 -0
  125. package/src/__tests__/host-cu-proxy.test.ts +166 -1
  126. package/src/__tests__/host-file-proxy.test.ts +185 -1
  127. package/src/__tests__/host-file-read-tool.test.ts +52 -0
  128. package/src/__tests__/host-proxy-interface.test.ts +165 -0
  129. package/src/__tests__/host-shell-tool.test.ts +1 -11
  130. package/src/__tests__/http-user-message-parity.test.ts +1 -0
  131. package/src/__tests__/identity-intro-cache.test.ts +40 -10
  132. package/src/__tests__/init-feature-flag-overrides.test.ts +38 -112
  133. package/src/__tests__/integration-status.test.ts +6 -7
  134. package/src/__tests__/jobs-store-upsert-debounced.test.ts +141 -0
  135. package/src/__tests__/list-messages-tool-merge.test.ts +37 -12
  136. package/src/__tests__/llm-context-normalization.test.ts +488 -0
  137. package/src/__tests__/llm-context-route-provider.test.ts +86 -5
  138. package/src/__tests__/llm-usage-store.test.ts +363 -0
  139. package/src/__tests__/mcp-client-auth.test.ts +40 -4
  140. package/src/__tests__/mcp-health-check.test.ts +10 -3
  141. package/src/__tests__/media-stream-output.test.ts +555 -0
  142. package/src/__tests__/media-stream-parser.test.ts +374 -0
  143. package/src/__tests__/media-stream-server-integration.test.ts +1234 -0
  144. package/src/__tests__/media-stream-stt-session.test.ts +588 -0
  145. package/src/__tests__/media-turn-detector.test.ts +440 -0
  146. package/src/__tests__/message-queue.test.ts +125 -0
  147. package/src/__tests__/migration-cross-version-compatibility.test.ts +3 -1
  148. package/src/__tests__/migration-export-http.test.ts +67 -8
  149. package/src/__tests__/migration-export-streaming.test.ts +66 -0
  150. package/src/__tests__/migration-import-commit-http.test.ts +109 -7
  151. package/src/__tests__/migration-import-preflight-http.test.ts +6 -5
  152. package/src/__tests__/migration-validate-http.test.ts +3 -3
  153. package/src/__tests__/mock-gateway-ipc.ts +151 -0
  154. package/src/__tests__/model-intents.test.ts +2 -2
  155. package/src/__tests__/native-host-marker-sync-guard.test.ts +157 -0
  156. package/src/__tests__/oauth-apps-routes.test.ts +18 -12
  157. package/src/__tests__/oauth-cli.test.ts +709 -60
  158. package/src/__tests__/oauth-connect-orchestrator.test.ts +118 -24
  159. package/src/__tests__/oauth-provider-seed-logos.test.ts +23 -0
  160. package/src/__tests__/oauth-provider-serializer.test.ts +147 -10
  161. package/src/__tests__/oauth-provider-visibility.test.ts +19 -21
  162. package/src/__tests__/oauth-providers-routes.test.ts +52 -14
  163. package/src/__tests__/oauth-store.test.ts +1465 -176
  164. package/src/__tests__/oauth2-gateway-transport.test.ts +460 -26
  165. package/src/__tests__/onboarding-template-contract.test.ts +81 -70
  166. package/src/__tests__/openai-provider.test.ts +178 -2
  167. package/src/__tests__/openai-responses-cutover-guard.test.ts +184 -0
  168. package/src/__tests__/openai-responses-provider.test.ts +1105 -0
  169. package/src/__tests__/openrouter-token-estimation.test.ts +100 -0
  170. package/src/__tests__/outlook-categories.test.ts +1 -1
  171. package/src/__tests__/outlook-client-automation.test.ts +1 -1
  172. package/src/__tests__/outlook-compose-tools.test.ts +1 -1
  173. package/src/__tests__/outlook-email-watcher.test.ts +1 -1
  174. package/src/__tests__/outlook-follow-up.test.ts +1 -1
  175. package/src/__tests__/outlook-messaging-provider.test.ts +2 -2
  176. package/src/__tests__/outlook-trash.test.ts +1 -1
  177. package/src/__tests__/outlook-unsubscribe.test.ts +32 -3
  178. package/src/__tests__/permission-checker-host-gate.test.ts +74 -14
  179. package/src/__tests__/permission-mode.test.ts +28 -56
  180. package/src/__tests__/persona-resolver.test.ts +251 -0
  181. package/src/__tests__/platform-bash-auto-approve.test.ts +4 -0
  182. package/src/__tests__/platform-callback-registration.test.ts +19 -0
  183. package/src/__tests__/platform.test.ts +92 -1
  184. package/src/__tests__/post-turn-tool-result-truncation.test.ts +343 -0
  185. package/src/__tests__/prechat-onboarding-contract.test.ts +267 -0
  186. package/src/__tests__/pricing.test.ts +174 -0
  187. package/src/__tests__/proxy-approval-callback.test.ts +18 -0
  188. package/src/__tests__/qdrant-manager.test.ts +29 -8
  189. package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +194 -0
  190. package/src/__tests__/relationship-state-contract.test.ts +175 -0
  191. package/src/__tests__/relay-server.test.ts +423 -5
  192. package/src/__tests__/require-fresh-approval.test.ts +40 -1
  193. package/src/__tests__/sanitize-config-for-transfer.test.ts +132 -0
  194. package/src/__tests__/schedule-routes.test.ts +162 -0
  195. package/src/__tests__/search-skills-unified.test.ts +118 -0
  196. package/src/__tests__/secret-detection-handler.test.ts +84 -0
  197. package/src/__tests__/secret-ingress-http.test.ts +1 -0
  198. package/src/__tests__/secret-scanner-executor.test.ts +4 -0
  199. package/src/__tests__/secure-keys.test.ts +107 -0
  200. package/src/__tests__/send-endpoint-busy.test.ts +8 -1
  201. package/src/__tests__/sequence-store.test.ts +1 -1
  202. package/src/__tests__/server-history-render.test.ts +49 -0
  203. package/src/__tests__/set-permission-mode.test.ts +13 -250
  204. package/src/__tests__/settings-routes.test.ts +201 -0
  205. package/src/__tests__/skill-load-feature-flag.test.ts +1 -0
  206. package/src/__tests__/skills-file-content-endpoint.test.ts +801 -0
  207. package/src/__tests__/skills-files-catalog-fallback.test.ts +738 -0
  208. package/src/__tests__/skills.test.ts +5 -2
  209. package/src/__tests__/skillssh-files.test.ts +446 -0
  210. package/src/__tests__/slack-block-formatting.test.ts +110 -0
  211. package/src/__tests__/slack-channel-config.test.ts +576 -16
  212. package/src/__tests__/stt-catalog-parity.test.ts +282 -0
  213. package/src/__tests__/stt-stream-session.test.ts +535 -0
  214. package/src/__tests__/subagent-detail.test.ts +44 -2
  215. package/src/__tests__/subagent-disposal.test.ts +1 -0
  216. package/src/__tests__/subagent-fork-notifications.test.ts +291 -0
  217. package/src/__tests__/subagent-fork-spawn.test.ts +384 -0
  218. package/src/__tests__/subagent-manager-notify.test.ts +1 -0
  219. package/src/__tests__/subagent-notify-parent.test.ts +1 -0
  220. package/src/__tests__/subagent-spawn-tool-fork.test.ts +411 -0
  221. package/src/__tests__/subagent-tools.test.ts +1 -0
  222. package/src/__tests__/subagent-types.test.ts +1 -0
  223. package/src/__tests__/system-prompt-ask-mode.test.ts +27 -71
  224. package/src/__tests__/system-prompt.test.ts +184 -27
  225. package/src/__tests__/task-scheduler.test.ts +32 -6
  226. package/src/__tests__/telegram-config.test.ts +10 -13
  227. package/src/__tests__/telephony-stt-routing.test.ts +329 -0
  228. package/src/__tests__/terminal-tools.test.ts +25 -5
  229. package/src/__tests__/test-preload.ts +18 -0
  230. package/src/__tests__/test-support/browser-skill-harness.ts +4 -1
  231. package/src/__tests__/tool-approval-handler.test.ts +73 -0
  232. package/src/__tests__/tool-executor-lifecycle-events.test.ts +9 -5
  233. package/src/__tests__/tool-executor-shell-integration.test.ts +4 -0
  234. package/src/__tests__/tool-executor.test.ts +33 -24
  235. package/src/__tests__/tool-result-truncation.test.ts +36 -0
  236. package/src/__tests__/tool-side-effects-slack-dm.test.ts +22 -0
  237. package/src/__tests__/top-level-renderer.test.ts +73 -1
  238. package/src/__tests__/transport-hints-queue.test.ts +14 -29
  239. package/src/__tests__/trust-store.test.ts +7 -1
  240. package/src/__tests__/trusted-contact-approval-notifier.test.ts +1 -1
  241. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +109 -0
  242. package/src/__tests__/tts-catalog-parity.test.ts +345 -0
  243. package/src/__tests__/twilio-routes-twiml.test.ts +512 -114
  244. package/src/__tests__/twilio-routes.test.ts +376 -0
  245. package/src/__tests__/unicode.test.ts +293 -0
  246. package/src/__tests__/update-bulletin-format.test.ts +59 -0
  247. package/src/__tests__/update-bulletin.test.ts +206 -5
  248. package/src/__tests__/usage-routes.test.ts +25 -4
  249. package/src/__tests__/user-reference.test.ts +46 -61
  250. package/src/__tests__/v2-consent-policy.test.ts +103 -0
  251. package/src/__tests__/verification-control-plane-policy.test.ts +4 -0
  252. package/src/__tests__/voice-config-update.test.ts +403 -0
  253. package/src/__tests__/voice-quality.test.ts +434 -19
  254. package/src/__tests__/workspace-heartbeat-service.test.ts +7 -0
  255. package/src/__tests__/workspace-migration-033-stt-service-explicit-config.test.ts +547 -0
  256. package/src/__tests__/workspace-migration-034-remove-calls-voice-transcription-provider.test.ts +596 -0
  257. package/src/__tests__/workspace-migration-drop-user-md.test.ts +368 -0
  258. package/src/__tests__/workspace-migration-meets.test.ts +244 -0
  259. package/src/__tests__/workspace-migration-seed-device-id.test.ts +14 -20
  260. package/src/__tests__/workspace-policy.test.ts +2 -0
  261. package/src/acp/client-handler.ts +30 -4
  262. package/src/agent/image-optimize.ts +24 -12
  263. package/src/agent/loop.ts +55 -9
  264. package/src/approvals/guardian-request-resolvers.ts +21 -15
  265. package/src/backup/__tests__/backup-key.test.ts +152 -0
  266. package/src/backup/__tests__/backup-worker.test.ts +767 -0
  267. package/src/backup/__tests__/list-snapshots.test.ts +87 -0
  268. package/src/backup/__tests__/local-writer.test.ts +218 -0
  269. package/src/backup/__tests__/offsite-writer.test.ts +641 -0
  270. package/src/backup/__tests__/paths.test.ts +300 -0
  271. package/src/backup/__tests__/restore.test.ts +498 -0
  272. package/src/backup/__tests__/snapshot-lock.test.ts +352 -0
  273. package/src/backup/__tests__/stream-crypt.test.ts +228 -0
  274. package/src/backup/backup-key.ts +137 -0
  275. package/src/backup/backup-worker.ts +459 -0
  276. package/src/backup/list-snapshots.ts +147 -0
  277. package/src/backup/local-writer.ts +133 -0
  278. package/src/backup/offsite-writer.ts +222 -0
  279. package/src/backup/paths.ts +226 -0
  280. package/src/backup/restore.ts +322 -0
  281. package/src/backup/snapshot-lock.ts +431 -0
  282. package/src/backup/stream-crypt.ts +263 -0
  283. package/src/browser-session/__tests__/manager.test.ts +297 -0
  284. package/src/browser-session/backends/cdp-inspect.ts +30 -0
  285. package/src/browser-session/backends/extension.ts +26 -0
  286. package/src/browser-session/backends/local.ts +24 -0
  287. package/src/browser-session/events.ts +164 -0
  288. package/src/browser-session/index.ts +27 -0
  289. package/src/browser-session/manager.ts +159 -0
  290. package/src/browser-session/types.ts +28 -0
  291. package/src/bundler/package-resolver.ts +4 -0
  292. package/src/calls/audio-store.ts +11 -5
  293. package/src/calls/call-controller.ts +226 -71
  294. package/src/calls/call-domain.ts +9 -0
  295. package/src/calls/call-speech-output.ts +190 -0
  296. package/src/calls/call-transport.ts +77 -0
  297. package/src/calls/media-stream-audio-transcode.ts +173 -0
  298. package/src/calls/media-stream-output.ts +660 -0
  299. package/src/calls/media-stream-parser.ts +300 -0
  300. package/src/calls/media-stream-protocol.ts +166 -0
  301. package/src/calls/media-stream-server.ts +592 -0
  302. package/src/calls/media-stream-stt-session.ts +460 -0
  303. package/src/calls/media-turn-detector.ts +230 -0
  304. package/src/calls/relay-server.ts +90 -75
  305. package/src/calls/resolve-call-tts-provider.ts +136 -0
  306. package/src/calls/telephony-stt-routing.ts +145 -0
  307. package/src/calls/tts-call-strategy.ts +161 -0
  308. package/src/calls/tts-text-sanitizer.ts +32 -16
  309. package/src/calls/twilio-routes.ts +281 -17
  310. package/src/calls/voice-quality.ts +78 -35
  311. package/src/calls/voice-session-bridge.ts +8 -1
  312. package/src/channels/__tests__/types.test.ts +134 -0
  313. package/src/channels/types.ts +69 -3
  314. package/src/cli/__tests__/run-assistant-command.ts +11 -1
  315. package/src/cli/commands/__tests__/backup.test.ts +1165 -0
  316. package/src/cli/commands/__tests__/domain-register.test.ts +234 -0
  317. package/src/cli/commands/__tests__/domain-status.test.ts +132 -0
  318. package/src/cli/commands/__tests__/email-attachment.test.ts +422 -0
  319. package/src/cli/commands/__tests__/email-download.test.ts +16 -1
  320. package/src/cli/commands/__tests__/email-list.test.ts +22 -4
  321. package/src/cli/commands/__tests__/email-register.test.ts +4 -4
  322. package/src/cli/commands/__tests__/email-send.test.ts +37 -4
  323. package/src/cli/commands/__tests__/email-status.test.ts +5 -1
  324. package/src/cli/commands/__tests__/email-unregister.test.ts +34 -5
  325. package/src/cli/commands/backup.ts +993 -0
  326. package/src/cli/commands/conversations.ts +77 -0
  327. package/src/cli/commands/credentials.ts +3 -4
  328. package/src/cli/commands/domain.ts +210 -0
  329. package/src/cli/commands/email.ts +273 -16
  330. package/src/cli/commands/mcp.ts +16 -4
  331. package/src/cli/commands/oauth/__tests__/connect.test.ts +56 -44
  332. package/src/cli/commands/oauth/__tests__/disconnect.test.ts +21 -21
  333. package/src/cli/commands/oauth/__tests__/mode.test.ts +17 -17
  334. package/src/cli/commands/oauth/__tests__/ping.test.ts +16 -16
  335. package/src/cli/commands/oauth/__tests__/providers-delete.test.ts +32 -33
  336. package/src/cli/commands/oauth/__tests__/providers-register.test.ts +330 -0
  337. package/src/cli/commands/oauth/__tests__/providers-update.test.ts +117 -12
  338. package/src/cli/commands/oauth/__tests__/status.test.ts +10 -10
  339. package/src/cli/commands/oauth/__tests__/token.test.ts +7 -7
  340. package/src/cli/commands/oauth/apps.ts +7 -4
  341. package/src/cli/commands/oauth/connect.ts +6 -3
  342. package/src/cli/commands/oauth/disconnect.ts +1 -1
  343. package/src/cli/commands/oauth/mode.ts +12 -3
  344. package/src/cli/commands/oauth/providers.ts +215 -36
  345. package/src/cli/commands/oauth/shared.ts +7 -6
  346. package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +254 -0
  347. package/src/cli/commands/platform/__tests__/connect.test.ts +6 -0
  348. package/src/cli/commands/platform/__tests__/disconnect.test.ts +7 -1
  349. package/src/cli/commands/platform/__tests__/status.test.ts +6 -0
  350. package/src/cli/commands/platform/index.ts +107 -10
  351. package/src/cli/commands/usage.ts +10 -9
  352. package/src/cli/lib/daemon-credential-client.ts +4 -0
  353. package/src/cli/program.ts +30 -4
  354. package/src/config/__tests__/backup-schema.test.ts +134 -0
  355. package/src/config/assistant-feature-flags.ts +61 -62
  356. package/src/config/bundled-skills/app-builder/SKILL.md +26 -249
  357. package/src/config/bundled-skills/app-builder/references/CUSTOM_ROUTES.md +141 -0
  358. package/src/config/bundled-skills/app-builder/references/INTERACTION_HOOKS.md +56 -0
  359. package/src/config/bundled-skills/app-builder/references/WIDGETS.md +125 -0
  360. package/src/config/bundled-skills/browser/SKILL.md +30 -5
  361. package/src/config/bundled-skills/browser/TOOLS.json +123 -0
  362. package/src/config/bundled-skills/browser/tools/browser-attach.ts +12 -0
  363. package/src/config/bundled-skills/browser/tools/browser-detach.ts +12 -0
  364. package/src/config/bundled-skills/browser/tools/browser-status.ts +12 -0
  365. package/src/config/bundled-skills/browser/tools/browser-wait-for-download.ts +17 -0
  366. package/src/config/bundled-skills/contacts/SKILL.md +5 -2
  367. package/src/config/bundled-skills/document/SKILL.md +4 -0
  368. package/src/config/bundled-skills/gmail/SKILL.md +54 -8
  369. package/src/config/bundled-skills/gmail/TOOLS.json +33 -3
  370. package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +116 -9
  371. package/src/config/bundled-skills/gmail/tools/gmail-outreach-scan.ts +138 -11
  372. package/src/config/bundled-skills/gmail/tools/gmail-preferences-tool.ts +59 -0
  373. package/src/config/bundled-skills/gmail/tools/gmail-preferences.ts +82 -0
  374. package/src/config/bundled-skills/gmail/tools/gmail-sender-digest.ts +113 -17
  375. package/src/config/bundled-skills/gmail/tools/gmail-unsubscribe.ts +2 -2
  376. package/src/config/bundled-skills/media-processing/SKILL.md +3 -9
  377. package/src/config/bundled-skills/media-processing/TOOLS.json +1 -6
  378. package/src/config/bundled-skills/media-processing/__tests__/audio-transcribe.test.ts +125 -0
  379. package/src/config/bundled-skills/media-processing/__tests__/extract-keyframes.test.ts +181 -0
  380. package/src/config/bundled-skills/media-processing/__tests__/preprocess-audio.test.ts +141 -0
  381. package/src/config/bundled-skills/media-processing/services/audio-transcribe.ts +32 -87
  382. package/src/config/bundled-skills/media-processing/services/preprocess.ts +8 -4
  383. package/src/config/bundled-skills/media-processing/tools/extract-keyframes.ts +0 -10
  384. package/src/config/bundled-skills/messaging/SKILL.md +3 -3
  385. package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +2 -2
  386. package/src/config/bundled-skills/outlook/SKILL.md +9 -2
  387. package/src/config/bundled-skills/outlook/tools/outlook-unsubscribe.ts +2 -2
  388. package/src/config/bundled-skills/phone-calls/SKILL.md +2 -2
  389. package/src/config/bundled-skills/phone-calls/references/CONFIG.md +27 -18
  390. package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +3 -3
  391. package/src/config/bundled-skills/settings/TOOLS.json +3 -3
  392. package/src/config/bundled-skills/settings/tools/voice-config-update.ts +26 -22
  393. package/src/config/bundled-skills/slack/SKILL.md +1 -0
  394. package/src/config/bundled-skills/subagent/SKILL.md +21 -0
  395. package/src/config/bundled-skills/subagent/TOOLS.json +8 -4
  396. package/src/config/bundled-skills/tasks/SKILL.md +5 -0
  397. package/src/config/bundled-skills/transcribe/SKILL.md +9 -14
  398. package/src/config/bundled-skills/transcribe/TOOLS.json +2 -7
  399. package/src/config/bundled-skills/transcribe/tools/transcribe-media.test.ts +256 -0
  400. package/src/config/bundled-skills/transcribe/tools/transcribe-media.ts +38 -188
  401. package/src/config/bundled-tool-registry.ts +8 -0
  402. package/src/config/env-registry.ts +38 -0
  403. package/src/config/env.ts +49 -4
  404. package/src/config/feature-flag-registry.json +85 -14
  405. package/src/config/loader.ts +82 -13
  406. package/src/config/sanitize-for-transfer.ts +47 -0
  407. package/src/config/schema.ts +81 -15
  408. package/src/config/schemas/__tests__/stt.test.ts +43 -0
  409. package/src/config/schemas/analysis.ts +51 -0
  410. package/src/config/schemas/backup.ts +72 -0
  411. package/src/config/schemas/calls.ts +1 -26
  412. package/src/config/schemas/elevenlabs.ts +0 -59
  413. package/src/config/schemas/filing.ts +47 -7
  414. package/src/config/schemas/heartbeat.ts +27 -5
  415. package/src/config/schemas/host-browser.ts +112 -0
  416. package/src/config/schemas/inference.ts +1 -1
  417. package/src/config/schemas/memory-lifecycle.ts +14 -2
  418. package/src/config/schemas/memory-retrieval.ts +103 -0
  419. package/src/config/schemas/security.ts +0 -6
  420. package/src/config/schemas/services.ts +52 -0
  421. package/src/config/schemas/stt.ts +59 -0
  422. package/src/config/schemas/tts.ts +230 -0
  423. package/src/config/schemas/updates.ts +14 -0
  424. package/src/config/skills.ts +4 -0
  425. package/src/config/types.ts +4 -1
  426. package/src/contacts/contact-store.ts +56 -11
  427. package/src/contacts/contacts-write.ts +38 -1
  428. package/src/context/post-turn-tool-result-truncation.ts +177 -0
  429. package/src/context/tool-result-truncation.ts +2 -1
  430. package/src/context/window-manager.ts +61 -10
  431. package/src/credential-execution/approval-bridge.ts +49 -15
  432. package/src/credential-execution/executable-discovery.ts +12 -2
  433. package/src/credential-execution/process-manager.ts +33 -2
  434. package/src/credential-health/credential-health-service.ts +366 -0
  435. package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +324 -0
  436. package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +497 -0
  437. package/src/daemon/__tests__/conversation-tool-setup.test.ts +195 -0
  438. package/src/daemon/__tests__/lifecycle-startup-ordering.test.ts +127 -0
  439. package/src/daemon/app-source-watcher.ts +35 -0
  440. package/src/daemon/config-watcher.ts +99 -5
  441. package/src/daemon/context-overflow-approval.ts +5 -0
  442. package/src/daemon/conversation-agent-loop-handlers.ts +23 -2
  443. package/src/daemon/conversation-agent-loop.ts +153 -42
  444. package/src/daemon/conversation-attachments.ts +40 -0
  445. package/src/daemon/conversation-error.ts +11 -0
  446. package/src/daemon/conversation-history.ts +40 -6
  447. package/src/daemon/conversation-launch.ts +220 -0
  448. package/src/daemon/conversation-lifecycle.ts +59 -9
  449. package/src/daemon/conversation-messaging.ts +37 -3
  450. package/src/daemon/conversation-notifiers.ts +5 -0
  451. package/src/daemon/conversation-process.ts +622 -13
  452. package/src/daemon/conversation-queue-manager.ts +24 -0
  453. package/src/daemon/conversation-runtime-assembly.ts +128 -36
  454. package/src/daemon/conversation-slash.ts +36 -0
  455. package/src/daemon/conversation-surfaces.ts +131 -40
  456. package/src/daemon/conversation-tool-setup.ts +99 -8
  457. package/src/daemon/conversation-usage.ts +7 -4
  458. package/src/daemon/conversation-workspace.ts +12 -0
  459. package/src/daemon/conversation.ts +292 -16
  460. package/src/daemon/date-context.ts +10 -10
  461. package/src/daemon/first-greeting.ts +3 -2
  462. package/src/daemon/handlers/config-slack-channel.ts +269 -94
  463. package/src/daemon/handlers/conversations.ts +13 -141
  464. package/src/daemon/handlers/shared.ts +80 -0
  465. package/src/daemon/handlers/skills.ts +483 -44
  466. package/src/daemon/host-bash-proxy.ts +48 -13
  467. package/src/daemon/host-browser-proxy.ts +192 -0
  468. package/src/daemon/host-cu-proxy.ts +36 -11
  469. package/src/daemon/host-file-proxy.ts +57 -9
  470. package/src/daemon/lifecycle.ts +179 -28
  471. package/src/daemon/message-protocol.ts +13 -0
  472. package/src/daemon/message-types/conversations.ts +89 -14
  473. package/src/daemon/message-types/home.ts +40 -0
  474. package/src/daemon/message-types/host-browser.ts +100 -0
  475. package/src/daemon/message-types/meet.ts +143 -0
  476. package/src/daemon/message-types/messages.ts +19 -5
  477. package/src/daemon/message-types/schedules.ts +34 -2
  478. package/src/daemon/message-types/skills.ts +26 -0
  479. package/src/daemon/message-types/subagents.ts +2 -0
  480. package/src/daemon/message-types/surfaces.ts +2 -0
  481. package/src/daemon/server.ts +439 -14
  482. package/src/daemon/shutdown-handlers.ts +32 -4
  483. package/src/daemon/shutdown-registry.ts +40 -0
  484. package/src/daemon/tool-side-effects.ts +15 -0
  485. package/src/daemon/transport-hints.ts +5 -24
  486. package/src/email/html-renderer.ts +76 -0
  487. package/src/heartbeat/heartbeat-service.ts +93 -7
  488. package/src/home/__tests__/assistant-feed-authoring.test.ts +156 -0
  489. package/src/home/__tests__/emit-feed-event.test.ts +169 -0
  490. package/src/home/__tests__/feed-scheduler.test.ts +194 -0
  491. package/src/home/__tests__/feed-types.test.ts +275 -0
  492. package/src/home/__tests__/feed-writer.test.ts +688 -0
  493. package/src/home/__tests__/phase5-exit-criteria.test.ts +212 -0
  494. package/src/home/__tests__/platform-gmail-digest.test.ts +222 -0
  495. package/src/home/__tests__/progress-formula.test.ts +213 -0
  496. package/src/home/__tests__/relationship-state-writer.test.ts +740 -0
  497. package/src/home/__tests__/rollup-producer.test.ts +398 -0
  498. package/src/home/assistant-feed-authoring.ts +124 -0
  499. package/src/home/emit-feed-event.ts +158 -0
  500. package/src/home/feed-scheduler.ts +247 -0
  501. package/src/home/feed-types.ts +181 -0
  502. package/src/home/feed-writer.ts +469 -0
  503. package/src/home/platform-gmail-digest.ts +163 -0
  504. package/src/home/progress-formula.ts +86 -0
  505. package/src/home/relationship-state-writer.ts +824 -0
  506. package/src/home/relationship-state.ts +143 -0
  507. package/src/home/rollup-producer.ts +384 -0
  508. package/src/hooks/runner.ts +7 -0
  509. package/src/inbound/platform-callback-registration.ts +30 -20
  510. package/src/inbound/public-ingress-urls.ts +12 -0
  511. package/src/instrument.ts +1 -1
  512. package/src/ipc/__tests__/cli-ipc.test.ts +200 -0
  513. package/src/ipc/cli-client.ts +151 -0
  514. package/src/ipc/cli-server.ts +234 -0
  515. package/src/ipc/gateway-client.ts +180 -0
  516. package/src/ipc/routes/index.ts +5 -0
  517. package/src/ipc/routes/wake-conversation.ts +19 -0
  518. package/src/mcp/client.ts +59 -24
  519. package/src/memory/__tests__/auto-analysis-enqueue.test.ts +356 -0
  520. package/src/memory/__tests__/auto-analysis-guard.test.ts +57 -0
  521. package/src/memory/__tests__/conversation-analyze-job.test.ts +232 -0
  522. package/src/memory/__tests__/find-analysis-conversation.test.ts +196 -0
  523. package/src/memory/app-store.ts +31 -1
  524. package/src/memory/attachments-store.ts +70 -0
  525. package/src/memory/auto-analysis-enqueue.ts +127 -0
  526. package/src/memory/auto-analysis-guard.ts +27 -0
  527. package/src/memory/cleanup-schedule-state.ts +37 -0
  528. package/src/memory/conversation-analyze-job.ts +73 -0
  529. package/src/memory/conversation-crud.ts +122 -0
  530. package/src/memory/conversation-disk-view.ts +7 -0
  531. package/src/memory/conversation-group-migration.ts +34 -2
  532. package/src/memory/conversation-queries.ts +6 -5
  533. package/src/memory/conversation-starters-cadence.ts +76 -0
  534. package/src/memory/conversation-title-service.ts +5 -2
  535. package/src/memory/db-init.ts +18 -0
  536. package/src/memory/db-maintenance.ts +108 -0
  537. package/src/memory/db.ts +1 -0
  538. package/src/memory/embedding-backend.test.ts +75 -0
  539. package/src/memory/embedding-backend.ts +131 -5
  540. package/src/memory/embedding-gemini.test.ts +54 -0
  541. package/src/memory/embedding-gemini.ts +20 -9
  542. package/src/memory/embedding-local.ts +176 -17
  543. package/src/memory/graph/consolidation.ts +10 -23
  544. package/src/memory/graph/conversation-graph-memory.ts +15 -0
  545. package/src/memory/graph/extraction-job.ts +15 -0
  546. package/src/memory/graph/extraction.test.ts +23 -0
  547. package/src/memory/graph/extraction.ts +8 -0
  548. package/src/memory/graph/retriever.ts +67 -40
  549. package/src/memory/graph/scoring.test.ts +186 -0
  550. package/src/memory/graph/scoring.ts +31 -1
  551. package/src/memory/graph/store.test.ts +7 -3
  552. package/src/memory/graph/store.ts +47 -12
  553. package/src/memory/graph/tools.ts +1 -1
  554. package/src/memory/group-crud.ts +6 -1
  555. package/src/memory/indexer.ts +95 -16
  556. package/src/memory/job-handlers/cleanup.ts +11 -8
  557. package/src/memory/job-handlers/conversation-starters.ts +16 -10
  558. package/src/memory/jobs-store.ts +64 -4
  559. package/src/memory/jobs-worker.ts +22 -9
  560. package/src/memory/llm-usage-store.ts +137 -60
  561. package/src/memory/migrations/213-oauth-providers-scope-separator.ts +13 -0
  562. package/src/memory/migrations/214-oauth-providers-refresh-url.ts +11 -0
  563. package/src/memory/migrations/215-oauth-providers-revoke.ts +14 -0
  564. package/src/memory/migrations/216-oauth-providers-token-auth-method.ts +30 -0
  565. package/src/memory/migrations/217-conversation-host-access.ts +40 -0
  566. package/src/memory/migrations/218-oauth-providers-logo-url.ts +11 -0
  567. package/src/memory/migrations/219-oauth-providers-token-exchange-body-format.ts +15 -0
  568. package/src/memory/migrations/220-normalize-user-file-by-principal.ts +190 -0
  569. package/src/memory/migrations/221-conversations-archived-at.ts +16 -0
  570. package/src/memory/migrations/index.ts +12 -0
  571. package/src/memory/migrations/registry.ts +16 -0
  572. package/src/memory/qdrant-manager.ts +43 -16
  573. package/src/memory/schema/conversations.ts +3 -0
  574. package/src/memory/schema/oauth.ts +21 -13
  575. package/src/memory/usage-buckets.ts +396 -0
  576. package/src/messaging/providers/gmail/client.ts +57 -6
  577. package/src/messaging/providers/slack/__tests__/adapter-token-routing.test.ts +282 -0
  578. package/src/messaging/providers/slack/adapter.ts +143 -38
  579. package/src/messaging/providers/slack/client.ts +16 -0
  580. package/src/messaging/providers/slack/types.ts +4 -0
  581. package/src/notifications/decision-engine.ts +3 -3
  582. package/src/notifications/signal.ts +5 -0
  583. package/src/oauth/AGENTS.md +76 -0
  584. package/src/oauth/__tests__/identity-verifier.test.ts +25 -19
  585. package/src/oauth/__tests__/seed-providers-managed.test.ts +32 -0
  586. package/src/oauth/byo-connection.test.ts +26 -9
  587. package/src/oauth/byo-connection.ts +10 -8
  588. package/src/oauth/connect-orchestrator.ts +25 -21
  589. package/src/oauth/connect-types.ts +3 -3
  590. package/src/oauth/connection-resolver.test.ts +17 -4
  591. package/src/oauth/connection-resolver.ts +22 -18
  592. package/src/oauth/connection.ts +3 -1
  593. package/src/oauth/manual-token-connection.ts +13 -13
  594. package/src/oauth/oauth-store.ts +223 -100
  595. package/src/oauth/platform-connection.test.ts +101 -3
  596. package/src/oauth/platform-connection.ts +56 -35
  597. package/src/oauth/provider-serializer.ts +31 -5
  598. package/src/oauth/revoke.ts +76 -0
  599. package/src/oauth/seed-providers.ts +133 -87
  600. package/src/oauth/token-persistence.ts +1 -1
  601. package/src/permissions/checker.ts +16 -6
  602. package/src/permissions/defaults.ts +49 -1
  603. package/src/permissions/permission-mode.ts +4 -11
  604. package/src/permissions/prompter.ts +13 -1
  605. package/src/permissions/trust-store.ts +3 -3
  606. package/src/permissions/v2-consent-policy.ts +87 -0
  607. package/src/permissions/workspace-policy.ts +3 -0
  608. package/src/platform/client.test.ts +10 -0
  609. package/src/platform/sync-identity.ts +129 -0
  610. package/src/prompts/persona-resolver.ts +126 -2
  611. package/src/prompts/system-prompt.ts +76 -38
  612. package/src/prompts/templates/BOOTSTRAP-REFERENCE.md +3 -65
  613. package/src/prompts/templates/BOOTSTRAP.md +59 -105
  614. package/src/prompts/templates/SOUL.md +3 -1
  615. package/src/prompts/templates/UPDATES.md +12 -0
  616. package/src/prompts/templates/channels/slack.md +20 -0
  617. package/src/prompts/update-bulletin-format.ts +26 -9
  618. package/src/prompts/update-bulletin.ts +34 -23
  619. package/src/prompts/user-reference.ts +20 -17
  620. package/src/providers/__tests__/provider-secret-catalog.test.ts +42 -0
  621. package/src/providers/anthropic/client.ts +157 -60
  622. package/src/providers/fireworks/client.ts +2 -2
  623. package/src/providers/gemini/client.ts +9 -1
  624. package/src/providers/model-catalog.ts +6 -0
  625. package/src/providers/model-intents.ts +4 -4
  626. package/src/providers/ollama/client.ts +2 -2
  627. package/src/providers/openai/chat-completions-provider.ts +474 -0
  628. package/src/providers/openai/client.ts +25 -440
  629. package/src/providers/openai/responses-provider.ts +502 -0
  630. package/src/providers/openrouter/client.ts +101 -4
  631. package/src/providers/provider-secret-catalog.ts +139 -0
  632. package/src/providers/registry.ts +2 -2
  633. package/src/providers/retry.ts +14 -3
  634. package/src/providers/speech-to-text/__tests__/provider-catalog.test.ts +251 -0
  635. package/src/providers/speech-to-text/__tests__/resolve.test.ts +828 -0
  636. package/src/providers/speech-to-text/deepgram-realtime.test.ts +980 -0
  637. package/src/providers/speech-to-text/deepgram-realtime.ts +767 -0
  638. package/src/providers/speech-to-text/deepgram.test.ts +332 -0
  639. package/src/providers/speech-to-text/deepgram.ts +115 -0
  640. package/src/providers/speech-to-text/google-gemini-live-stream.test.ts +743 -0
  641. package/src/providers/speech-to-text/google-gemini-live-stream.ts +625 -0
  642. package/src/providers/speech-to-text/google-gemini.test.ts +226 -0
  643. package/src/providers/speech-to-text/google-gemini.ts +101 -0
  644. package/src/providers/speech-to-text/openai-whisper-stream.test.ts +564 -0
  645. package/src/providers/speech-to-text/openai-whisper-stream.ts +381 -0
  646. package/src/providers/speech-to-text/openai-whisper.test.ts +1 -37
  647. package/src/providers/speech-to-text/openai-whisper.ts +63 -33
  648. package/src/providers/speech-to-text/provider-catalog.ts +306 -0
  649. package/src/providers/speech-to-text/resolve.ts +386 -6
  650. package/src/providers/types.ts +10 -1
  651. package/src/runtime/AGENTS.md +65 -0
  652. package/src/runtime/__tests__/agent-wake.test.ts +831 -0
  653. package/src/runtime/__tests__/browser-extension-pair-routes.test.ts +715 -0
  654. package/src/runtime/__tests__/capability-tokens.test.ts +258 -0
  655. package/src/runtime/__tests__/chrome-extension-registry.test.ts +518 -0
  656. package/src/runtime/__tests__/runtime-mode.test.ts +62 -0
  657. package/src/runtime/__tests__/slack-block-formatting.test.ts +481 -0
  658. package/src/runtime/agent-wake.ts +512 -0
  659. package/src/runtime/assistant-event-hub.ts +2 -2
  660. package/src/runtime/auth/__tests__/guard-tests.test.ts +1 -0
  661. package/src/runtime/auth/__tests__/middleware.test.ts +116 -1
  662. package/src/runtime/auth/__tests__/route-policy.test.ts +48 -0
  663. package/src/runtime/auth/middleware.ts +98 -0
  664. package/src/runtime/auth/route-policy.ts +33 -9
  665. package/src/runtime/auth/token-service.ts +56 -1
  666. package/src/runtime/btw-sidechain.ts +2 -0
  667. package/src/runtime/capability-tokens.ts +414 -0
  668. package/src/runtime/channel-approvals.ts +18 -5
  669. package/src/runtime/channel-invite-transport.ts +1 -1
  670. package/src/runtime/channel-invite-transports/email.ts +14 -6
  671. package/src/runtime/channel-readiness-service.ts +12 -22
  672. package/src/runtime/chrome-extension-registry.ts +368 -0
  673. package/src/runtime/confirmation-request-guardian-bridge.ts +6 -0
  674. package/src/runtime/guardian-decision-types.ts +7 -0
  675. package/src/runtime/http-server.ts +815 -75
  676. package/src/runtime/http-types.ts +6 -2
  677. package/src/runtime/migrations/__tests__/rebind-secrets-credentials.test.ts +172 -0
  678. package/src/runtime/migrations/__tests__/vbundle-builder-credentials.test.ts +276 -0
  679. package/src/runtime/migrations/__tests__/vbundle-import-credentials.test.ts +198 -0
  680. package/src/runtime/migrations/__tests__/vbundle-legacy-user-md.test.ts +360 -0
  681. package/src/runtime/migrations/migration-transport.ts +7 -0
  682. package/src/runtime/migrations/migration-wizard.ts +23 -2
  683. package/src/runtime/migrations/rebind-secrets-screen.ts +76 -15
  684. package/src/runtime/migrations/vbundle-builder.ts +145 -38
  685. package/src/runtime/migrations/vbundle-import-analyzer.ts +96 -1
  686. package/src/runtime/migrations/vbundle-importer.ts +89 -5
  687. package/src/runtime/pending-interactions.ts +18 -13
  688. package/src/runtime/routes/__tests__/backup-routes.test.ts +967 -0
  689. package/src/runtime/routes/__tests__/home-feed-routes.test.ts +507 -0
  690. package/src/runtime/routes/__tests__/migration-import-credential-filter.test.ts +208 -0
  691. package/src/runtime/routes/__tests__/stt-routes.test.ts +406 -0
  692. package/src/runtime/routes/__tests__/tts-routes.test.ts +474 -0
  693. package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +148 -17
  694. package/src/runtime/routes/app-management-routes.ts +12 -18
  695. package/src/runtime/routes/approval-routes.ts +90 -16
  696. package/src/runtime/routes/attachment-routes.test.ts +9 -3
  697. package/src/runtime/routes/attachment-routes.ts +216 -17
  698. package/src/runtime/routes/backup-routes.ts +519 -0
  699. package/src/runtime/routes/browser-extension-pair-routes.ts +556 -0
  700. package/src/runtime/routes/btw-routes.ts +8 -6
  701. package/src/runtime/routes/contact-routes.test.ts +298 -0
  702. package/src/runtime/routes/contact-routes.ts +132 -5
  703. package/src/runtime/routes/conversation-analysis-routes.ts +22 -141
  704. package/src/runtime/routes/conversation-management-routes.ts +223 -0
  705. package/src/runtime/routes/conversation-routes.ts +598 -103
  706. package/src/runtime/routes/conversation-starter-routes.ts +78 -16
  707. package/src/runtime/routes/filing-routes.ts +93 -0
  708. package/src/runtime/routes/guardian-action-routes.ts +24 -13
  709. package/src/runtime/routes/home-feed-routes.ts +334 -0
  710. package/src/runtime/routes/home-state-routes.ts +138 -0
  711. package/src/runtime/routes/host-browser-routes.ts +268 -0
  712. package/src/runtime/routes/host-file-routes.ts +9 -1
  713. package/src/runtime/routes/identity-intro-cache.ts +7 -3
  714. package/src/runtime/routes/identity-routes.ts +262 -33
  715. package/src/runtime/routes/inbound-stages/transcribe-audio.test.ts +46 -39
  716. package/src/runtime/routes/inbound-stages/transcribe-audio.ts +15 -15
  717. package/src/runtime/routes/integrations/slack/__tests__/channel.test.ts +137 -0
  718. package/src/runtime/routes/integrations/slack/__tests__/share.test.ts +179 -0
  719. package/src/runtime/routes/integrations/slack/channel.ts +11 -3
  720. package/src/runtime/routes/integrations/slack/share.ts +45 -7
  721. package/src/runtime/routes/llm-context-normalization.ts +303 -0
  722. package/src/runtime/routes/log-export-routes.ts +42 -22
  723. package/src/runtime/routes/memory-item-routes.test.ts +3 -2
  724. package/src/runtime/routes/memory-item-routes.ts +1 -7
  725. package/src/runtime/routes/migration-routes.ts +122 -2
  726. package/src/runtime/routes/oauth-apps.ts +15 -17
  727. package/src/runtime/routes/oauth-providers.ts +4 -0
  728. package/src/runtime/routes/schedule-routes.ts +24 -11
  729. package/src/runtime/routes/settings-routes.ts +31 -102
  730. package/src/runtime/routes/skills-routes.ts +128 -9
  731. package/src/runtime/routes/stt-routes.ts +233 -0
  732. package/src/runtime/routes/subagents-routes.ts +14 -10
  733. package/src/runtime/routes/surface-action-routes.ts +41 -2
  734. package/src/runtime/routes/tts-routes.ts +108 -24
  735. package/src/runtime/routes/usage-routes.ts +38 -9
  736. package/src/runtime/routes/user-route-dispatcher.ts +50 -5
  737. package/src/runtime/routes/user-routes.ts +13 -1
  738. package/src/runtime/routes/work-items-routes.ts +8 -1
  739. package/src/runtime/routes/workspace-routes.test.ts +22 -0
  740. package/src/runtime/routes/workspace-routes.ts +8 -1
  741. package/src/runtime/routes/workspace-utils.ts +2 -0
  742. package/src/runtime/runtime-mode.ts +33 -0
  743. package/src/runtime/services/__tests__/analyze-conversation.test.ts +444 -0
  744. package/src/runtime/services/__tests__/analyze-deps-singleton.test.ts +67 -0
  745. package/src/runtime/services/__tests__/auto-analysis-prompt.test.ts +53 -0
  746. package/src/runtime/services/__tests__/manual-analysis-prompt.test.ts +41 -0
  747. package/src/runtime/services/analyze-conversation.ts +344 -0
  748. package/src/runtime/services/analyze-deps-singleton.ts +32 -0
  749. package/src/runtime/services/auto-analysis-prompt.ts +55 -0
  750. package/src/runtime/skill-route-registry.ts +49 -0
  751. package/src/runtime/slack-block-formatting.ts +437 -10
  752. package/src/schedule/scheduler.ts +57 -5
  753. package/src/security/ces-credential-client.ts +20 -0
  754. package/src/security/ces-rpc-credential-backend.ts +17 -0
  755. package/src/security/credential-backend.ts +5 -0
  756. package/src/security/oauth2.ts +68 -29
  757. package/src/security/secure-keys.ts +143 -27
  758. package/src/security/token-manager.ts +31 -10
  759. package/src/sequence/engine.ts +23 -0
  760. package/src/sequence/types.ts +1 -1
  761. package/src/skills/catalog-files.ts +554 -0
  762. package/src/skills/category-inference.ts +122 -0
  763. package/src/skills/clawhub-files.ts +213 -0
  764. package/src/skills/clawhub.ts +84 -23
  765. package/src/skills/skill-file-provider.ts +40 -0
  766. package/src/skills/skillssh-files.ts +395 -0
  767. package/src/skills/skillssh-registry.ts +4 -4
  768. package/src/stt/__tests__/daemon-batch-transcriber.test.ts +392 -0
  769. package/src/stt/__tests__/types.test.ts +89 -0
  770. package/src/stt/daemon-batch-transcriber.ts +195 -0
  771. package/src/stt/stt-stream-session.ts +499 -0
  772. package/src/stt/types.ts +330 -0
  773. package/src/stt/wav-encoder.test.ts +373 -0
  774. package/src/stt/wav-encoder.ts +175 -0
  775. package/src/subagent/manager.ts +169 -40
  776. package/src/subagent/types.ts +19 -0
  777. package/src/tools/apps/executors.ts +11 -2
  778. package/src/tools/browser/__tests__/auth-detector.test.ts +202 -108
  779. package/src/tools/browser/__tests__/browser-mode.test.ts +119 -0
  780. package/src/tools/browser/__tests__/browser-status.test.ts +123 -0
  781. package/src/tools/browser/auth-detector.ts +43 -12
  782. package/src/tools/browser/browser-execution.ts +1787 -342
  783. package/src/tools/browser/browser-manager.ts +81 -12
  784. package/src/tools/browser/browser-mode-constants.ts +12 -0
  785. package/src/tools/browser/browser-mode.ts +92 -0
  786. package/src/tools/browser/browser-status-constants.ts +33 -0
  787. package/src/tools/browser/cdp-client/__tests__/accessibility-snapshot.test.ts +318 -0
  788. package/src/tools/browser/cdp-client/__tests__/cdp-dom-helpers.test.ts +1175 -0
  789. package/src/tools/browser/cdp-client/__tests__/cdp-inspect-client.test.ts +1263 -0
  790. package/src/tools/browser/cdp-client/__tests__/extension-cdp-client.test.ts +359 -0
  791. package/src/tools/browser/cdp-client/__tests__/factory.test.ts +1993 -0
  792. package/src/tools/browser/cdp-client/__tests__/fixtures/ax-tree-nested-frames.json +64 -0
  793. package/src/tools/browser/cdp-client/__tests__/fixtures/ax-tree-simple.json +69 -0
  794. package/src/tools/browser/cdp-client/__tests__/local-cdp-client.test.ts +310 -0
  795. package/src/tools/browser/cdp-client/__tests__/types.test.ts +96 -0
  796. package/src/tools/browser/cdp-client/accessibility-snapshot.ts +387 -0
  797. package/src/tools/browser/cdp-client/cdp-dom-helpers.ts +695 -0
  798. package/src/tools/browser/cdp-client/cdp-inspect/__tests__/discovery.test.ts +1007 -0
  799. package/src/tools/browser/cdp-client/cdp-inspect/__tests__/ws-transport.test.ts +580 -0
  800. package/src/tools/browser/cdp-client/cdp-inspect/discovery.ts +744 -0
  801. package/src/tools/browser/cdp-client/cdp-inspect/ws-transport.ts +579 -0
  802. package/src/tools/browser/cdp-client/cdp-inspect-client.ts +868 -0
  803. package/src/tools/browser/cdp-client/errors.ts +49 -0
  804. package/src/tools/browser/cdp-client/extension-cdp-client.ts +148 -0
  805. package/src/tools/browser/cdp-client/factory.ts +914 -0
  806. package/src/tools/browser/cdp-client/index.ts +28 -0
  807. package/src/tools/browser/cdp-client/local-cdp-client.ts +187 -0
  808. package/src/tools/browser/cdp-client/types.ts +120 -0
  809. package/src/tools/credentials/vault.ts +35 -6
  810. package/src/tools/filesystem/edit.ts +1 -1
  811. package/src/tools/filesystem/list.ts +1 -1
  812. package/src/tools/filesystem/read.ts +1 -1
  813. package/src/tools/filesystem/write.ts +2 -1
  814. package/src/tools/host-filesystem/edit.ts +1 -1
  815. package/src/tools/host-filesystem/read.ts +12 -15
  816. package/src/tools/host-filesystem/write.ts +1 -1
  817. package/src/tools/host-terminal/host-shell.ts +21 -16
  818. package/src/tools/network/web-fetch.ts +5 -2
  819. package/src/tools/network/web-search.ts +5 -2
  820. package/src/tools/permission-checker.ts +77 -82
  821. package/src/tools/registry.ts +0 -2
  822. package/src/tools/secret-detection-handler.ts +34 -0
  823. package/src/tools/shared/filesystem/image-read.ts +61 -40
  824. package/src/tools/shared/shell-output.ts +3 -1
  825. package/src/tools/side-effects.ts +2 -0
  826. package/src/tools/skills/sandbox-runner.ts +3 -2
  827. package/src/tools/subagent/spawn.ts +47 -3
  828. package/src/tools/subagent/status.ts +2 -0
  829. package/src/tools/system/register.ts +2 -16
  830. package/src/tools/terminal/safe-env.ts +15 -0
  831. package/src/tools/terminal/shell.ts +36 -20
  832. package/src/tools/tool-approval-handler.ts +48 -2
  833. package/src/tools/tool-manifest.ts +21 -0
  834. package/src/tools/types.ts +19 -0
  835. package/src/tools/ui-surface/definitions.ts +6 -1
  836. package/src/tts/__tests__/provider-adapters.test.ts +834 -0
  837. package/src/tts/__tests__/provider-catalog-consistency.test.ts +196 -0
  838. package/src/tts/__tests__/provider-catalog.test.ts +183 -0
  839. package/src/tts/__tests__/provider-registry.test.ts +90 -0
  840. package/src/tts/provider-catalog.ts +201 -0
  841. package/src/tts/provider-registry.ts +73 -0
  842. package/src/tts/providers/deepgram-provider.ts +219 -0
  843. package/src/tts/providers/elevenlabs-provider.ts +211 -0
  844. package/src/tts/providers/fish-audio-provider.ts +183 -0
  845. package/src/tts/providers/index.ts +42 -0
  846. package/src/tts/providers/register-builtins.ts +130 -0
  847. package/src/tts/synthesize-text.ts +110 -0
  848. package/src/tts/tts-config-resolver.ts +78 -0
  849. package/src/tts/types.ts +153 -0
  850. package/src/types/onboarding-context.ts +7 -0
  851. package/src/util/abort-reasons.ts +58 -0
  852. package/src/util/device-id.ts +32 -16
  853. package/src/util/errors.ts +9 -1
  854. package/src/util/platform.ts +63 -24
  855. package/src/util/pricing.ts +66 -3
  856. package/src/util/spawn.ts +1 -1
  857. package/src/util/truncate.ts +4 -2
  858. package/src/util/unicode.ts +201 -0
  859. package/src/version.ts +19 -24
  860. package/src/watcher/engine.ts +23 -0
  861. package/src/watcher/watcher-store.ts +31 -0
  862. package/src/workspace/migrations/003-seed-device-id.ts +9 -3
  863. package/src/workspace/migrations/017-seed-persona-dirs.ts +68 -4
  864. package/src/workspace/migrations/029-seed-pkb.ts +1 -1
  865. package/src/workspace/migrations/031-drop-user-md.ts +317 -0
  866. package/src/workspace/migrations/031-llm-log-retention-zero-to-null.ts +73 -0
  867. package/src/workspace/migrations/032-tts-provider-unification.ts +227 -0
  868. package/src/workspace/migrations/033-stt-service-explicit-config.ts +122 -0
  869. package/src/workspace/migrations/034-remove-calls-voice-transcription-provider.ts +215 -0
  870. package/src/workspace/migrations/035-seed-slack-channel-persona.ts +50 -0
  871. package/src/workspace/migrations/036-update-pkb-index-bar.ts +37 -0
  872. package/src/workspace/migrations/037-create-meets-dir.ts +61 -0
  873. package/src/workspace/migrations/registry.ts +16 -0
  874. package/src/workspace/top-level-renderer.ts +31 -1
  875. package/src/workspace/turn-commit.ts +31 -0
  876. package/src/__tests__/chrome-cdp.test.ts +0 -419
  877. package/src/__tests__/email-cli.test.ts +0 -297
  878. package/src/__tests__/email-service-config-fallback.test.ts +0 -102
  879. package/src/__tests__/permission-mode-sse.test.ts +0 -418
  880. package/src/__tests__/permission-mode-store.test.ts +0 -277
  881. package/src/browser-extension-relay/protocol.ts +0 -63
  882. package/src/browser-extension-relay/server.ts +0 -203
  883. package/src/cli/commands/browser-relay.ts +0 -536
  884. package/src/config/schemas/sandbox.ts +0 -14
  885. package/src/email/guardrails.ts +0 -221
  886. package/src/email/provider.ts +0 -117
  887. package/src/email/providers/agentmail.ts +0 -361
  888. package/src/email/providers/index.ts +0 -65
  889. package/src/email/service.ts +0 -384
  890. package/src/email/types.ts +0 -126
  891. package/src/permissions/permission-mode-store.ts +0 -180
  892. package/src/prompts/templates/USER.md +0 -13
  893. package/src/providers/speech-to-text/types.ts +0 -17
  894. package/src/tools/browser/chrome-cdp.ts +0 -239
  895. package/src/tools/system/set-permission-mode.ts +0 -103
@@ -112,6 +112,168 @@ export function normalizeLlmContextPayloads(
112
112
  function normalizeOpenAiRequestPayload(
113
113
  requestPayload: unknown,
114
114
  allowPlainText = false,
115
+ ): NormalizedPayloadCandidate | null {
116
+ // Try Responses API shape first, then fall back to chat-completions.
117
+ return (
118
+ normalizeOpenAiResponsesRequestPayload(requestPayload, allowPlainText) ??
119
+ normalizeOpenAiChatCompletionsRequestPayload(requestPayload, allowPlainText)
120
+ );
121
+ }
122
+
123
+ /**
124
+ * Detect and normalize OpenAI Responses API request payloads.
125
+ *
126
+ * Responses requests use `input` (array) instead of `messages`, may have a
127
+ * top-level `instructions` string, and tools have `type: "function"` at the
128
+ * top level with the function fields inlined (no nested `function` wrapper).
129
+ */
130
+ function normalizeOpenAiResponsesRequestPayload(
131
+ requestPayload: unknown,
132
+ allowPlainText = false,
133
+ ): NormalizedPayloadCandidate | null {
134
+ const request = asRecord(requestPayload);
135
+ if (!request) {
136
+ return null;
137
+ }
138
+
139
+ const input = asRecordArray(request.input);
140
+ if (!input) {
141
+ return null;
142
+ }
143
+
144
+ // Require at least one Responses-specific signal to avoid matching generic
145
+ // arrays. `instructions` is the strongest signal; otherwise look for
146
+ // Responses-shaped input items or tool objects.
147
+ const hasResponsesSignal =
148
+ typeof request.instructions === "string" ||
149
+ hasOpenAiModelPrefix(asString(request.model)) ||
150
+ input.some(
151
+ (item) =>
152
+ asString(item.type) === "function_call" ||
153
+ asString(item.type) === "function_call_output",
154
+ ) ||
155
+ extractOpenAiResponsesRequestToolNames(request.tools).length > 0;
156
+
157
+ if (!allowPlainText && !hasResponsesSignal) {
158
+ return null;
159
+ }
160
+
161
+ const requestSections: LlmContextSection[] = [];
162
+
163
+ // System-level instructions
164
+ const instructions = asString(request.instructions);
165
+ if (instructions && hasMeaningfulText(instructions)) {
166
+ requestSections.push({
167
+ kind: "system",
168
+ label: "System prompt",
169
+ role: "system",
170
+ text: instructions,
171
+ });
172
+ }
173
+
174
+ // Input items
175
+ let messageIndex = 0;
176
+ for (const item of input) {
177
+ const itemType = asString(item.type);
178
+
179
+ if (itemType === "message") {
180
+ messageIndex++;
181
+ const role = asString(item.role) ?? "unknown";
182
+ const messageText = extractOpenAiContentText(item.content);
183
+ if (messageText !== undefined) {
184
+ requestSections.push({
185
+ kind: "message",
186
+ label: buildMessageLabel(role, messageIndex),
187
+ role,
188
+ text: messageText,
189
+ });
190
+ }
191
+ continue;
192
+ }
193
+
194
+ if (itemType === "function_call") {
195
+ const name = asString(item.name);
196
+ const args = parseJsonValue(asString(item.arguments));
197
+ requestSections.push({
198
+ kind: "function_call",
199
+ label: `Request tool call${name ? ` (${name})` : ""}`,
200
+ role: "assistant",
201
+ toolName: name,
202
+ data: args,
203
+ text: previewStructuredValue(args),
204
+ });
205
+ continue;
206
+ }
207
+
208
+ if (itemType === "function_call_output") {
209
+ const output = asString(item.output);
210
+ requestSections.push({
211
+ kind: "tool_result",
212
+ label: `Tool result${asString(item.call_id) ? ` (${asString(item.call_id)})` : ""}`,
213
+ role: "tool",
214
+ toolName: asString(item.call_id),
215
+ text: output,
216
+ });
217
+ }
218
+ }
219
+
220
+ // Tool definitions (Responses shape: top-level type/name/parameters)
221
+ const requestToolNames = extractOpenAiResponsesRequestToolNames(
222
+ request.tools,
223
+ );
224
+ if (requestToolNames.length > 0) {
225
+ requestSections.push({
226
+ kind: "tool_definitions",
227
+ label: "Available tools",
228
+ data: {
229
+ tools: asRecordArray(request.tools) ?? request.tools,
230
+ },
231
+ language: "json",
232
+ });
233
+ }
234
+
235
+ const requestSettings = omitRecordKeys(request, [
236
+ "instructions",
237
+ "input",
238
+ "tools",
239
+ ]);
240
+ if (hasMeaningfulRequestSettings(requestSettings)) {
241
+ requestSections.push(
242
+ structuredJsonSection("settings", "Request settings", requestSettings),
243
+ );
244
+ }
245
+
246
+ // Count all input items for the message count (includes messages, function
247
+ // calls, and function call outputs — mirrors how chat-completions counts
248
+ // all messages regardless of role).
249
+ return {
250
+ provider: "openai",
251
+ summary: {
252
+ provider: "openai",
253
+ model: asString(request.model),
254
+ inputTokens: undefined,
255
+ outputTokens: undefined,
256
+ cacheCreationInputTokens: undefined,
257
+ cacheReadInputTokens: undefined,
258
+ stopReason: undefined,
259
+ requestMessageCount: input.length,
260
+ requestToolCount: requestToolNames.length,
261
+ responseMessageCount: undefined,
262
+ responseToolCallCount: undefined,
263
+ responsePreview: undefined,
264
+ toolCallNames: undefined,
265
+ },
266
+ requestSections: requestSections.length > 0 ? requestSections : undefined,
267
+ };
268
+ }
269
+
270
+ /**
271
+ * Normalize a legacy OpenAI Chat Completions request payload.
272
+ * Requires `messages` array in the request.
273
+ */
274
+ function normalizeOpenAiChatCompletionsRequestPayload(
275
+ requestPayload: unknown,
276
+ allowPlainText = false,
115
277
  ): NormalizedPayloadCandidate | null {
116
278
  const request = asRecord(requestPayload);
117
279
  if (!request) {
@@ -202,6 +364,130 @@ function normalizeOpenAiRequestPayload(
202
364
 
203
365
  function normalizeOpenAiResponsePayload(
204
366
  responsePayload: unknown,
367
+ ): NormalizedPayloadCandidate | null {
368
+ // Try Responses API shape first, then fall back to chat-completions.
369
+ return (
370
+ normalizeOpenAiResponsesResponsePayload(responsePayload) ??
371
+ normalizeOpenAiChatCompletionsResponsePayload(responsePayload)
372
+ );
373
+ }
374
+
375
+ /**
376
+ * Detect and normalize OpenAI Responses API response payloads.
377
+ *
378
+ * Responses responses have an `output` array of items instead of `choices`.
379
+ * Tool calls are top-level items with `type: "function_call"`.
380
+ * Usage uses `input_tokens`/`output_tokens` (not `prompt_tokens`/`completion_tokens`).
381
+ * `status` replaces `choices[0].finish_reason`.
382
+ */
383
+ function normalizeOpenAiResponsesResponsePayload(
384
+ responsePayload: unknown,
385
+ ): NormalizedPayloadCandidate | null {
386
+ const response = asRecord(responsePayload);
387
+ if (!response) {
388
+ return null;
389
+ }
390
+
391
+ const output = asRecordArray(response.output);
392
+ if (!output) {
393
+ return null;
394
+ }
395
+
396
+ // Require at least one Responses-specific signal
397
+ const hasResponsesSignal =
398
+ typeof response.status === "string" ||
399
+ hasOpenAiModelPrefix(asString(response.model)) ||
400
+ output.some(
401
+ (item) =>
402
+ asString(item.type) === "message" ||
403
+ asString(item.type) === "function_call",
404
+ );
405
+ if (!hasResponsesSignal) {
406
+ return null;
407
+ }
408
+
409
+ const responseSections: LlmContextSection[] = [];
410
+ let responseText: string | undefined;
411
+ const toolCallSections: LlmContextSection[] = [];
412
+ let toolCallIndex = 0;
413
+
414
+ for (const item of output) {
415
+ const itemType = asString(item.type);
416
+
417
+ if (itemType === "message") {
418
+ const role = asString(item.role) ?? "assistant";
419
+ const content = asRecordArray(item.content);
420
+ const text = content ? extractOpenAiContentText(content) : undefined;
421
+ if (text !== undefined) {
422
+ responseText = text;
423
+ responseSections.push({
424
+ kind: "message",
425
+ label: "Assistant response",
426
+ role,
427
+ text,
428
+ });
429
+ }
430
+ continue;
431
+ }
432
+
433
+ if (itemType === "function_call") {
434
+ toolCallIndex++;
435
+ const name = asString(item.name);
436
+ const args = parseJsonValue(asString(item.arguments));
437
+ const section: LlmContextSection = {
438
+ kind: "function_call",
439
+ label: `Response tool call ${toolCallIndex}`,
440
+ role: "assistant",
441
+ toolName: name,
442
+ data: args,
443
+ text: previewStructuredValue(args),
444
+ };
445
+ toolCallSections.push(section);
446
+ responseSections.push(section);
447
+ }
448
+ }
449
+
450
+ const usage = asRecord(response.usage);
451
+ const toolCallNames = toolCallSections
452
+ .map((section) => section.toolName)
453
+ .filter((name): name is string => typeof name === "string");
454
+
455
+ // Map Responses API status to a stop reason string.
456
+ const status = asString(response.status);
457
+ const stopReason = status === "completed" ? "stop" : status;
458
+
459
+ return {
460
+ provider: "openai",
461
+ summary: {
462
+ provider: "openai",
463
+ model: asString(response.model),
464
+ inputTokens: asNumber(usage?.input_tokens),
465
+ outputTokens: asNumber(usage?.output_tokens),
466
+ cacheCreationInputTokens: undefined,
467
+ cacheReadInputTokens: undefined,
468
+ stopReason,
469
+ requestMessageCount: undefined,
470
+ requestToolCount: undefined,
471
+ responseMessageCount:
472
+ responseText !== undefined || toolCallSections.length > 0
473
+ ? 1
474
+ : undefined,
475
+ responseToolCallCount:
476
+ toolCallSections.length > 0 ? toolCallSections.length : undefined,
477
+ responsePreview: responseText ? truncateText(responseText) : undefined,
478
+ toolCallNames: toolCallNames.length > 0 ? toolCallNames : undefined,
479
+ },
480
+ responseSections:
481
+ responseSections.length > 0 ? responseSections : undefined,
482
+ };
483
+ }
484
+
485
+ /**
486
+ * Normalize a legacy OpenAI Chat Completions response payload.
487
+ * Requires `choices` array in the response.
488
+ */
489
+ function normalizeOpenAiChatCompletionsResponsePayload(
490
+ responsePayload: unknown,
205
491
  ): NormalizedPayloadCandidate | null {
206
492
  const response = asRecord(responsePayload);
207
493
  if (!response) {
@@ -739,6 +1025,23 @@ function extractOpenAiRequestToolNames(tools: unknown): string[] {
739
1025
  .filter((name): name is string => typeof name === "string");
740
1026
  }
741
1027
 
1028
+ /**
1029
+ * Extract tool names from Responses API tool definitions.
1030
+ * Responses tools have `type: "function"` at the top level with `name`
1031
+ * directly on the tool object (no nested `function` wrapper).
1032
+ */
1033
+ function extractOpenAiResponsesRequestToolNames(tools: unknown): string[] {
1034
+ return (asRecordArray(tools) ?? [])
1035
+ .map((tool) => {
1036
+ // Responses shape: { type: "function", name: "...", ... }
1037
+ if (asString(tool.type) === "function" && asString(tool.name)) {
1038
+ return asString(tool.name);
1039
+ }
1040
+ return undefined;
1041
+ })
1042
+ .filter((name): name is string => typeof name === "string");
1043
+ }
1044
+
742
1045
  function extractAnthropicToolNames(tools: unknown): string[] {
743
1046
  return (asRecordArray(tools) ?? [])
744
1047
  .map((tool) => asString(tool.name))
@@ -49,6 +49,7 @@ const MAX_LOG_PAYLOAD_BYTES = 10 * 1024 * 1024;
49
49
  interface ExportRequestBody {
50
50
  auditLimit?: number;
51
51
  conversationId?: string; // scope to a single conversation
52
+ full?: boolean; // include all conversation data (messages + LLM logs) — use for test data debugging
52
53
  startTime?: number; // epoch ms — lower bound (inclusive)
53
54
  endTime?: number; // epoch ms — upper bound (inclusive)
54
55
  }
@@ -67,7 +68,7 @@ async function handleExport(body: ExportRequestBody): Promise<Response> {
67
68
  const staging = mkdtempSync(join(tmpdir(), "vellum-export-"));
68
69
 
69
70
  try {
70
- const { conversationId, startTime, endTime } = body;
71
+ const { conversationId, full, startTime, endTime } = body;
71
72
 
72
73
  // --- Audit data ---
73
74
  const limit = body.auditLimit ?? 1000;
@@ -98,14 +99,19 @@ async function handleExport(body: ExportRequestBody): Promise<Response> {
98
99
  "utf-8",
99
100
  );
100
101
 
101
- // --- Conversation-scoped data tables ---
102
- if (conversationId) {
102
+ // --- Conversation data tables ---
103
+ // Included when scoped to a single conversation OR when all conversations are requested.
104
+ if (conversationId || full) {
105
+ const conversationFilter = conversationId
106
+ ? [eq(messages.conversationId, conversationId)]
107
+ : [];
108
+
103
109
  const messageRows = db
104
110
  .select()
105
111
  .from(messages)
106
112
  .where(
107
113
  and(
108
- eq(messages.conversationId, conversationId),
114
+ ...conversationFilter,
109
115
  startTime ? gte(messages.createdAt, startTime) : undefined,
110
116
  endTime ? lte(messages.createdAt, endTime) : undefined,
111
117
  ),
@@ -118,12 +124,16 @@ async function handleExport(body: ExportRequestBody): Promise<Response> {
118
124
  "utf-8",
119
125
  );
120
126
 
127
+ const llmConversationFilter = conversationId
128
+ ? [eq(llmRequestLogs.conversationId, conversationId)]
129
+ : [];
130
+
121
131
  const llmLogRows = db
122
132
  .select()
123
133
  .from(llmRequestLogs)
124
134
  .where(
125
135
  and(
126
- eq(llmRequestLogs.conversationId, conversationId),
136
+ ...llmConversationFilter,
127
137
  startTime ? gte(llmRequestLogs.createdAt, startTime) : undefined,
128
138
  endTime ? lte(llmRequestLogs.createdAt, endTime) : undefined,
129
139
  ),
@@ -136,12 +146,16 @@ async function handleExport(body: ExportRequestBody): Promise<Response> {
136
146
  "utf-8",
137
147
  );
138
148
 
149
+ const usageConversationFilter = conversationId
150
+ ? [eq(llmUsageEvents.conversationId, conversationId)]
151
+ : [];
152
+
139
153
  const usageRows = db
140
154
  .select()
141
155
  .from(llmUsageEvents)
142
156
  .where(
143
157
  and(
144
- eq(llmUsageEvents.conversationId, conversationId),
158
+ ...usageConversationFilter,
145
159
  startTime ? gte(llmUsageEvents.createdAt, startTime) : undefined,
146
160
  endTime ? lte(llmUsageEvents.createdAt, endTime) : undefined,
147
161
  ),
@@ -265,22 +279,21 @@ async function handleExport(body: ExportRequestBody): Promise<Response> {
265
279
  }
266
280
 
267
281
  // --- Export manifest ---
268
- const manifest = conversationId
269
- ? {
270
- type: "conversation-export" as const,
271
- conversationId,
272
- assistantVersion: APP_VERSION,
273
- commitSha: COMMIT_SHA,
274
- ...(startTime !== undefined ? { startTime } : {}),
275
- ...(endTime !== undefined ? { endTime } : {}),
276
- exportedAt: new Date().toISOString(),
277
- }
278
- : {
279
- type: "global-export" as const,
280
- assistantVersion: APP_VERSION,
281
- commitSha: COMMIT_SHA,
282
- exportedAt: new Date().toISOString(),
283
- };
282
+ const manifestType = conversationId
283
+ ? ("conversation-export" as const)
284
+ : full
285
+ ? ("full-export" as const)
286
+ : ("global-export" as const);
287
+ const manifest = {
288
+ type: manifestType,
289
+ ...(conversationId ? { conversationId } : {}),
290
+ ...(full ? { full: true } : {}),
291
+ assistantVersion: APP_VERSION,
292
+ commitSha: COMMIT_SHA,
293
+ ...(startTime !== undefined ? { startTime } : {}),
294
+ ...(endTime !== undefined ? { endTime } : {}),
295
+ exportedAt: new Date().toISOString(),
296
+ };
284
297
  writeFileSync(
285
298
  join(staging, "export-manifest.json"),
286
299
  JSON.stringify(manifest, null, 2),
@@ -294,6 +307,7 @@ async function handleExport(body: ExportRequestBody): Promise<Response> {
294
307
  totalBytes,
295
308
  hasConfig: configSnapshot !== undefined,
296
309
  conversationId: conversationId ?? null,
310
+ full: full ?? false,
297
311
  workspaceEntries: workspaceResult.entries.length,
298
312
  workspaceBytes: workspaceResult.totalBytes,
299
313
  },
@@ -441,6 +455,12 @@ export function logExportRouteDefinitions(): RouteDefinition[] {
441
455
  .string()
442
456
  .optional()
443
457
  .describe("Scope to a single conversation"),
458
+ full: z
459
+ .boolean()
460
+ .optional()
461
+ .describe(
462
+ "Full export — include messages, LLM request logs, and usage events for all conversations. Use for test data debugging.",
463
+ ),
444
464
  startTime: z.number().optional().describe("Lower bound epoch ms"),
445
465
  endTime: z.number().optional().describe("Upper bound epoch ms"),
446
466
  });
@@ -868,14 +868,15 @@ describe("Memory Item Routes", () => {
868
868
  const res = await handler(ctx);
869
869
  expect(res.status).toBe(204);
870
870
 
871
- // Verify the node is gone
871
+ // Verify the node is soft-deleted (fidelity='gone')
872
872
  const db = getDb();
873
873
  const node = db
874
874
  .select()
875
875
  .from(memoryGraphNodes)
876
876
  .where(eq(memoryGraphNodes.id, "i1"))
877
877
  .get();
878
- expect(node).toBeUndefined();
878
+ expect(node).toBeDefined();
879
+ expect(node?.fidelity).toBe("gone");
879
880
  });
880
881
 
881
882
  test("returns 404 for non-existent item", async () => {
@@ -712,15 +712,9 @@ export async function handleDeleteMemoryItem(
712
712
  return httpError("NOT_FOUND", "Memory item not found", 404);
713
713
  }
714
714
 
715
- // Hard-delete the node (cascades to edges and triggers via FK)
715
+ // Soft-delete the node (deleteNode sets fidelity='gone' and enqueues Qdrant cleanup)
716
716
  deleteNode(id);
717
717
 
718
- // Clean up Qdrant vectors asynchronously
719
- enqueueMemoryJob("delete_qdrant_vectors", {
720
- targetType: "graph_node",
721
- targetId: id,
722
- });
723
-
724
718
  return new Response(null, { status: 204 });
725
719
  }
726
720
 
@@ -21,6 +21,11 @@ import { invalidateConfigCache } from "../../config/loader.js";
21
21
  import { getDb, resetDb } from "../../memory/db-connection.js";
22
22
  import { validateMigrationState } from "../../memory/migrations/validate-migration-state.js";
23
23
  import { clearCache as clearTrustCache } from "../../permissions/trust-store.js";
24
+ import {
25
+ bulkSetSecureKeysAsync,
26
+ getSecureKeyResultAsync,
27
+ listSecureKeysAsync,
28
+ } from "../../security/secure-keys.js";
24
29
  import { getLogger } from "../../util/logger.js";
25
30
  import {
26
31
  getDbPath,
@@ -34,9 +39,15 @@ import {
34
39
  analyzeImport,
35
40
  DefaultPathResolver,
36
41
  } from "../migrations/vbundle-import-analyzer.js";
37
- import { commitImport } from "../migrations/vbundle-importer.js";
42
+ import {
43
+ commitImport,
44
+ extractCredentialsFromBundle,
45
+ } from "../migrations/vbundle-importer.js";
38
46
  import { validateVBundle } from "../migrations/vbundle-validator.js";
39
47
 
48
+ /** Credentials with this prefix are platform-identity keys and must not be imported. */
49
+ const PLATFORM_CREDENTIAL_PREFIX = "vellum:";
50
+
40
51
  const log = getLogger("migration-routes");
41
52
 
42
53
  /**
@@ -146,6 +157,27 @@ export async function handleMigrationExport(req: Request): Promise<Response> {
146
157
  let cleanup: (() => Promise<void>) | undefined;
147
158
 
148
159
  try {
160
+ // Read all stored credentials to include in the export bundle
161
+ const credentialList = await listSecureKeysAsync();
162
+ const credentials: Array<{ account: string; value: string }> = [];
163
+ if (credentialList.unreachable) {
164
+ log.warn(
165
+ "Credential store is unreachable — export will not include credentials",
166
+ );
167
+ } else {
168
+ for (const account of credentialList.accounts) {
169
+ const result = await getSecureKeyResultAsync(account);
170
+ if (result.unreachable) {
171
+ log.warn(
172
+ { account },
173
+ "Credential store unreachable when reading credential — skipping",
174
+ );
175
+ } else if (result.value != null) {
176
+ credentials.push({ account, value: result.value });
177
+ }
178
+ }
179
+ }
180
+
149
181
  const result = await streamExportVBundle({
150
182
  // hooksDir is intentionally omitted — hooks now live under workspace/hooks/
151
183
  // and are included in the workspace walk. Passing hooksDir separately would
@@ -153,6 +185,7 @@ export async function handleMigrationExport(req: Request): Promise<Response> {
153
185
  workspaceDir: getWorkspaceDir(),
154
186
  source: "runtime-export",
155
187
  description,
188
+ credentials,
156
189
  checkpoint: () => {
157
190
  const dbPath = getDbPath();
158
191
  try {
@@ -196,6 +229,7 @@ export async function handleMigrationExport(req: Request): Promise<Response> {
196
229
  "Content-Length": String(size),
197
230
  "X-Vbundle-Schema-Version": manifest.schema_version,
198
231
  "X-Vbundle-Manifest-Sha256": manifest.manifest_sha256,
232
+ "X-Vbundle-Credentials-Included": String(credentials.length),
199
233
  },
200
234
  });
201
235
  } catch (err) {
@@ -444,6 +478,89 @@ export async function handleMigrationImport(req: Request): Promise<Response> {
444
478
  );
445
479
  }
446
480
 
481
+ // Import credentials from the bundle into CES (non-blocking — failures
482
+ // are logged as warnings but do not fail the overall import).
483
+ let credentialsImported:
484
+ | {
485
+ total: number;
486
+ succeeded: number;
487
+ failed: number;
488
+ failedAccounts: string[];
489
+ skippedPlatform: number;
490
+ }
491
+ | undefined;
492
+
493
+ if (validation.entries) {
494
+ const bundleCredentials = extractCredentialsFromBundle(
495
+ validation.entries,
496
+ validation.manifest!,
497
+ );
498
+
499
+ // Filter out platform-identity credentials (vellum:*) — these are
500
+ // environment-specific and must not overwrite the target's own identity.
501
+ const userCredentials = bundleCredentials.filter(
502
+ (c) => !c.account.startsWith(PLATFORM_CREDENTIAL_PREFIX),
503
+ );
504
+ const skippedPlatform = bundleCredentials.length - userCredentials.length;
505
+ if (skippedPlatform > 0) {
506
+ log.info(
507
+ `Skipped ${skippedPlatform} platform credential(s) from import`,
508
+ );
509
+ }
510
+
511
+ if (userCredentials.length > 0) {
512
+ try {
513
+ const credResults = await bulkSetSecureKeysAsync(userCredentials);
514
+ const failedResults = credResults.filter((r) => !r.ok);
515
+ if (failedResults.length > 0) {
516
+ log.warn(
517
+ { failed: failedResults.map((f) => f.account) },
518
+ "Some credentials failed to import",
519
+ );
520
+ }
521
+ log.info(
522
+ { total: userCredentials.length, failed: failedResults.length },
523
+ "Credential import complete",
524
+ );
525
+ const succeeded = userCredentials.length - failedResults.length;
526
+ credentialsImported = {
527
+ total: userCredentials.length,
528
+ succeeded,
529
+ failed: failedResults.length,
530
+ failedAccounts: failedResults.map((f) => f.account),
531
+ skippedPlatform,
532
+ };
533
+ if (failedResults.length > 0) {
534
+ result.report.warnings.push(
535
+ `Imported ${succeeded} credential(s), ${failedResults.length} failed`,
536
+ );
537
+ }
538
+ } catch (err) {
539
+ log.warn({ err }, "Credential import failed entirely");
540
+ result.report.warnings.push(
541
+ `Credential import failed: ${err instanceof Error ? err.message : String(err)}`,
542
+ );
543
+ credentialsImported = {
544
+ total: userCredentials.length,
545
+ succeeded: 0,
546
+ failed: userCredentials.length,
547
+ failedAccounts: userCredentials.map((c) => c.account),
548
+ skippedPlatform,
549
+ };
550
+ }
551
+ } else if (skippedPlatform > 0) {
552
+ // All credentials in the bundle were platform credentials — report
553
+ // the skip count even though nothing was sent to CES.
554
+ credentialsImported = {
555
+ total: userCredentials.length,
556
+ succeeded: 0,
557
+ failed: 0,
558
+ failedAccounts: [],
559
+ skippedPlatform,
560
+ };
561
+ }
562
+ }
563
+
447
564
  // Invalidate in-process caches so imported settings.json and trust.json take effect
448
565
  invalidateConfigCache();
449
566
  clearTrustCache();
@@ -463,7 +580,10 @@ export async function handleMigrationImport(req: Request): Promise<Response> {
463
580
  // Don't fail the import if validation itself errors
464
581
  }
465
582
 
466
- return Response.json(result.report);
583
+ return Response.json({
584
+ ...result.report,
585
+ ...(credentialsImported ? { credentialsImported } : {}),
586
+ });
467
587
  } catch (err) {
468
588
  log.error({ err }, "Unexpected error during import commit");
469
589
  return httpError(