@vellumai/assistant 0.6.3 → 0.6.5

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 (1114) hide show
  1. package/.prettierignore +5 -0
  2. package/ARCHITECTURE.md +298 -39
  3. package/Dockerfile +14 -3
  4. package/README.md +3 -4
  5. package/bun.lock +13 -16
  6. package/docs/architecture/integrations.md +1 -20
  7. package/docs/architecture/security.md +16 -16
  8. package/docs/backup-troubleshooting.md +52 -0
  9. package/docs/browser-use-architecture-phase2.md +174 -0
  10. package/docs/error-handling.md +111 -0
  11. package/docs/skills.md +10 -10
  12. package/docs/stt-provider-onboarding.md +121 -0
  13. package/knip.json +20 -3
  14. package/node_modules/@vellumai/ces-contracts/bun.lock +8 -6
  15. package/node_modules/@vellumai/ces-contracts/package.json +5 -4
  16. package/node_modules/@vellumai/ces-contracts/src/__tests__/trust-rules.test.ts +471 -0
  17. package/node_modules/@vellumai/ces-contracts/src/trust-rules.ts +398 -4
  18. package/node_modules/@vellumai/credential-storage/bun.lock +2 -2
  19. package/node_modules/@vellumai/credential-storage/package.json +2 -2
  20. package/node_modules/@vellumai/credential-storage/src/oauth-runtime.ts +20 -2
  21. package/node_modules/@vellumai/egress-proxy/bun.lock +2 -2
  22. package/node_modules/@vellumai/egress-proxy/package.json +2 -2
  23. package/openapi.yaml +1094 -72
  24. package/package.json +9 -8
  25. package/scripts/generate-openapi.ts +50 -12
  26. package/scripts/test.sh +73 -18
  27. package/src/__tests__/agent-image-optimize.test.ts +28 -0
  28. package/src/__tests__/agent-loop-callsite-precedence.test.ts +318 -0
  29. package/src/__tests__/agent-loop-sentry-hygiene.test.ts +137 -0
  30. package/src/__tests__/agent-loop.test.ts +235 -1
  31. package/src/__tests__/anthropic-error-formatting.test.ts +98 -0
  32. package/src/__tests__/anthropic-provider.test.ts +434 -12
  33. package/src/__tests__/approval-cascade.test.ts +31 -10
  34. package/src/__tests__/approval-routes-http.test.ts +134 -10
  35. package/src/__tests__/assistant-attachments.test.ts +44 -0
  36. package/src/__tests__/assistant-feature-flags-integration.test.ts +29 -0
  37. package/src/__tests__/auto-analysis-end-to-end.test.ts +550 -0
  38. package/src/__tests__/auto-analysis-prompt.test.ts +50 -0
  39. package/src/__tests__/browser-fill-credential.test.ts +12 -1
  40. package/src/__tests__/browser-identifier-parity-guard.test.ts +53 -0
  41. package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +23 -33
  42. package/src/__tests__/browser-skill-endstate.test.ts +52 -159
  43. package/src/__tests__/btw-routes.test.ts +54 -1
  44. package/src/__tests__/call-controller.test.ts +582 -22
  45. package/src/__tests__/call-site-routing-provider.test.ts +214 -0
  46. package/src/__tests__/catalog-cache.test.ts +27 -4
  47. package/src/__tests__/catalog-files.test.ts +138 -0
  48. package/src/__tests__/channel-approval-routes.test.ts +4 -4
  49. package/src/__tests__/channel-invite-transport.test.ts +2 -2
  50. package/src/__tests__/channel-readiness-routes.test.ts +16 -20
  51. package/src/__tests__/channel-readiness-service.test.ts +12 -7
  52. package/src/__tests__/channel-reply-delivery.test.ts +300 -2
  53. package/src/__tests__/checker.test.ts +576 -502
  54. package/src/__tests__/clawhub-files.test.ts +347 -0
  55. package/src/__tests__/cli-command-risk-guard.test.ts +30 -33
  56. package/src/__tests__/commit-message-enrichment-service.test.ts +36 -19
  57. package/src/__tests__/compaction-circuit-breaker.test.ts +336 -0
  58. package/src/__tests__/compaction.benchmark.test.ts +1 -1
  59. package/src/__tests__/config-analysis.test.ts +83 -0
  60. package/src/__tests__/config-loader-backfill.test.ts +174 -0
  61. package/src/__tests__/config-loader-corrupt.test.ts +183 -0
  62. package/src/__tests__/config-loader-quarantine-bulletin.test.ts +202 -0
  63. package/src/__tests__/config-schema-cmd.test.ts +11 -5
  64. package/src/__tests__/config-schema.test.ts +1458 -198
  65. package/src/__tests__/config-watcher-cleanup-throttle.test.ts +339 -0
  66. package/src/__tests__/config-watcher.test.ts +45 -10
  67. package/src/__tests__/contact-store-user-file.test.ts +511 -0
  68. package/src/__tests__/contacts-write.test.ts +197 -0
  69. package/src/__tests__/context-token-estimator.test.ts +191 -1
  70. package/src/__tests__/context-window-manager.test.ts +618 -2
  71. package/src/__tests__/conversation-abort-tool-results.test.ts +32 -16
  72. package/src/__tests__/conversation-agent-loop-overflow.test.ts +62 -17
  73. package/src/__tests__/conversation-agent-loop.test.ts +510 -84
  74. package/src/__tests__/conversation-attachments.test.ts +1 -1
  75. package/src/__tests__/conversation-confirmation-signals.test.ts +165 -9
  76. package/src/__tests__/conversation-error.test.ts +102 -1
  77. package/src/__tests__/conversation-history-web-search.test.ts +17 -4
  78. package/src/__tests__/conversation-init.benchmark.test.ts +42 -1
  79. package/src/__tests__/conversation-launcher-skill-regression.test.ts +51 -0
  80. package/src/__tests__/conversation-lifecycle.test.ts +336 -0
  81. package/src/__tests__/conversation-list-source.test.ts +145 -0
  82. package/src/__tests__/conversation-load-history-repair.test.ts +27 -10
  83. package/src/__tests__/conversation-pre-run-repair.test.ts +32 -16
  84. package/src/__tests__/conversation-process-callsite.test.ts +306 -0
  85. package/src/__tests__/conversation-provider-retry-repair.test.ts +32 -16
  86. package/src/__tests__/conversation-queue.test.ts +932 -76
  87. package/src/__tests__/conversation-routes-disk-view.test.ts +299 -1
  88. package/src/__tests__/conversation-routes-slash-commands.test.ts +31 -3
  89. package/src/__tests__/conversation-runtime-assembly.test.ts +2790 -55
  90. package/src/__tests__/conversation-runtime-workspace.test.ts +12 -12
  91. package/src/__tests__/conversation-skill-tools.test.ts +12 -143
  92. package/src/__tests__/conversation-slash-commands.test.ts +33 -0
  93. package/src/__tests__/conversation-slash-queue.test.ts +120 -34
  94. package/src/__tests__/conversation-slash-unknown.test.ts +32 -16
  95. package/src/__tests__/conversation-speed-override.test.ts +30 -11
  96. package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +1035 -0
  97. package/src/__tests__/conversation-surfaces-standalone.test.ts +630 -0
  98. package/src/__tests__/conversation-title-service.test.ts +2 -2
  99. package/src/__tests__/conversation-tool-setup-batch-authorized.test.ts +226 -0
  100. package/src/__tests__/conversation-unread-route.test.ts +2 -2
  101. package/src/__tests__/conversation-usage.test.ts +3 -1
  102. package/src/__tests__/conversation-workspace-cache-state.test.ts +31 -10
  103. package/src/__tests__/conversation-workspace-injection.test.ts +45 -15
  104. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +46 -16
  105. package/src/__tests__/credential-broker-browser-fill.test.ts +110 -0
  106. package/src/__tests__/credential-health-service.test.ts +352 -0
  107. package/src/__tests__/credential-security-invariants.test.ts +8 -3
  108. package/src/__tests__/credential-storage-oauth-compat.test.ts +18 -0
  109. package/src/__tests__/credential-storage-static-compat.test.ts +28 -0
  110. package/src/__tests__/credential-vault-unit.test.ts +495 -3
  111. package/src/__tests__/credentials-cli.test.ts +32 -16
  112. package/src/__tests__/cross-provider-web-search.test.ts +230 -35
  113. package/src/__tests__/daemon-server-persist-and-process-callsite.test.ts +92 -0
  114. package/src/__tests__/delete-propagation.test.ts +437 -0
  115. package/src/__tests__/deterministic-verification-control-plane.test.ts +10 -1
  116. package/src/__tests__/device-id.test.ts +112 -0
  117. package/src/__tests__/dm-backfill.test.ts +417 -0
  118. package/src/__tests__/dm-persistence.test.ts +227 -0
  119. package/src/__tests__/docker-signing-key-bootstrap.test.ts +167 -4
  120. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +1 -3
  121. package/src/__tests__/edit-propagation.test.ts +280 -0
  122. package/src/__tests__/email-html-renderer.test.ts +71 -0
  123. package/src/__tests__/email-invite-adapter.test.ts +36 -32
  124. package/src/__tests__/emit-event-signal.test.ts +71 -0
  125. package/src/__tests__/ephemeral-permissions.test.ts +93 -3
  126. package/src/__tests__/estimator-calibration-integration.test.ts +208 -0
  127. package/src/__tests__/estimator-calibration.test.ts +213 -0
  128. package/src/__tests__/extension-id-sync-guard.test.ts +101 -15
  129. package/src/__tests__/file-write-tool.test.ts +151 -1
  130. package/src/__tests__/filing-service.test.ts +255 -0
  131. package/src/__tests__/fixtures/mock-chrome-extension.ts +11 -0
  132. package/src/__tests__/gateway-only-enforcement.test.ts +206 -1
  133. package/src/__tests__/gateway-only-guard.test.ts +0 -1
  134. package/src/__tests__/gemini-provider.test.ts +64 -3
  135. package/src/__tests__/get-skill-detail-audit.test.ts +325 -0
  136. package/src/__tests__/guardian-grant-minting.test.ts +8 -0
  137. package/src/__tests__/headless-browser-interactions.test.ts +44 -1
  138. package/src/__tests__/headless-browser-mode.test.ts +614 -0
  139. package/src/__tests__/headless-browser-navigate.test.ts +142 -5
  140. package/src/__tests__/headless-browser-read-tools.test.ts +11 -0
  141. package/src/__tests__/headless-browser-snapshot.test.ts +10 -0
  142. package/src/__tests__/heartbeat-service.test.ts +166 -32
  143. package/src/__tests__/home-state-routes.test.ts +162 -0
  144. package/src/__tests__/host-bash-proxy.test.ts +0 -5
  145. package/src/__tests__/host-browser-e2e-cloud.test.ts +138 -4
  146. package/src/__tests__/host-browser-e2e-self-hosted.test.ts +4 -4
  147. package/src/__tests__/host-browser-ws-events-e2e.test.ts +103 -0
  148. package/src/__tests__/host-cu-proxy.test.ts +0 -5
  149. package/src/__tests__/host-shell-tool.test.ts +124 -18
  150. package/src/__tests__/http-user-message-parity.test.ts +29 -1
  151. package/src/__tests__/identity-intro-cache.test.ts +40 -10
  152. package/src/__tests__/inbound-slack-persistence.test.ts +340 -0
  153. package/src/__tests__/init-feature-flag-overrides.test.ts +38 -112
  154. package/src/__tests__/intent-routing.test.ts +1 -40
  155. package/src/__tests__/jobs-store-upsert-debounced.test.ts +141 -0
  156. package/src/__tests__/llm-catalog-parity.test.ts +174 -0
  157. package/src/__tests__/llm-context-normalization.test.ts +609 -0
  158. package/src/__tests__/llm-context-route-provider.test.ts +86 -5
  159. package/src/__tests__/llm-resolver.test.ts +214 -0
  160. package/src/__tests__/llm-schema.test.ts +223 -0
  161. package/src/__tests__/llm-usage-store.test.ts +363 -0
  162. package/src/__tests__/managed-proxy-context.test.ts +6 -2
  163. package/src/__tests__/media-stream-output.test.ts +555 -0
  164. package/src/__tests__/media-stream-parser.test.ts +374 -0
  165. package/src/__tests__/media-stream-server-integration.test.ts +1234 -0
  166. package/src/__tests__/media-stream-stt-session.test.ts +588 -0
  167. package/src/__tests__/media-turn-detector.test.ts +440 -0
  168. package/src/__tests__/message-queue.test.ts +125 -0
  169. package/src/__tests__/messaging-skill-split.test.ts +3 -34
  170. package/src/__tests__/migration-export-http.test.ts +6 -6
  171. package/src/__tests__/migration-import-commit-http.test.ts +8 -6
  172. package/src/__tests__/migration-import-from-url.test.ts +684 -0
  173. package/src/__tests__/migration-import-preflight-http.test.ts +6 -5
  174. package/src/__tests__/migration-validate-http.test.ts +3 -3
  175. package/src/__tests__/mock-gateway-ipc.ts +151 -0
  176. package/src/__tests__/model-intents.test.ts +10 -84
  177. package/src/__tests__/notification-decision-fallback.test.ts +0 -10
  178. package/src/__tests__/notification-decision-identity.test.ts +0 -9
  179. package/src/__tests__/notification-decision-recipient-context.test.ts +0 -9
  180. package/src/__tests__/oauth-apps-routes.test.ts +1 -0
  181. package/src/__tests__/oauth-cli.test.ts +2 -0
  182. package/src/__tests__/oauth-connect-orchestrator.test.ts +2 -0
  183. package/src/__tests__/oauth-provider-serializer.test.ts +1 -0
  184. package/src/__tests__/oauth-providers-routes.test.ts +2 -0
  185. package/src/__tests__/oauth-store.test.ts +95 -7
  186. package/src/__tests__/oauth2-gateway-transport.test.ts +257 -9
  187. package/src/__tests__/oauth2-refresh-retry.test.ts +279 -0
  188. package/src/__tests__/onboarding-template-contract.test.ts +6 -13
  189. package/src/__tests__/openai-provider.test.ts +183 -0
  190. package/src/__tests__/openai-responses-cutover-guard.test.ts +184 -0
  191. package/src/__tests__/openai-responses-provider.test.ts +1501 -0
  192. package/src/__tests__/openrouter-provider-only.test.ts +135 -0
  193. package/src/__tests__/openrouter-token-estimation.test.ts +100 -0
  194. package/src/__tests__/outbound-slack-persistence.test.ts +293 -0
  195. package/src/__tests__/permission-checker-host-gate.test.ts +1 -1
  196. package/src/__tests__/permission-mode.test.ts +16 -0
  197. package/src/__tests__/permission-types.test.ts +0 -1
  198. package/src/__tests__/persona-resolver.test.ts +251 -0
  199. package/src/__tests__/pkb-autoinject.test.ts +37 -1
  200. package/src/__tests__/platform-bash-auto-approve.test.ts +5 -1
  201. package/src/__tests__/platform.test.ts +92 -1
  202. package/src/__tests__/post-turn-tool-result-truncation.test.ts +47 -0
  203. package/src/__tests__/prechat-onboarding-contract.test.ts +267 -0
  204. package/src/__tests__/pricing.test.ts +224 -3
  205. package/src/__tests__/profiler-routes.test.ts +1 -1
  206. package/src/__tests__/provider-commit-message-generator.test.ts +14 -84
  207. package/src/__tests__/provider-env-vars-scope.test.ts +52 -0
  208. package/src/__tests__/provider-error-scenarios.test.ts +135 -6
  209. package/src/__tests__/provider-managed-proxy-integration.test.ts +42 -11
  210. package/src/__tests__/provider-registry-ollama.test.ts +1 -2
  211. package/src/__tests__/proxy-approval-callback.test.ts +0 -1
  212. package/src/__tests__/qdrant-manager.test.ts +29 -8
  213. package/src/__tests__/reaction-persistence.test.ts +560 -0
  214. package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +194 -0
  215. package/src/__tests__/relationship-state-contract.test.ts +175 -0
  216. package/src/__tests__/relay-server.test.ts +424 -6
  217. package/src/__tests__/require-fresh-approval.test.ts +1 -1
  218. package/src/__tests__/retry-openrouter-only-normalization.test.ts +136 -0
  219. package/src/__tests__/retry-thinking-tool-choice.test.ts +226 -0
  220. package/src/__tests__/risk-classifier-parity.test.ts +230 -0
  221. package/src/__tests__/sanitize-config-for-transfer.test.ts +78 -1
  222. package/src/__tests__/search-skills-unified.test.ts +118 -0
  223. package/src/__tests__/secret-ingress-http.test.ts +28 -0
  224. package/src/__tests__/secret-prompter-channel-fallback.test.ts +125 -0
  225. package/src/__tests__/secret-routes-managed-proxy.test.ts +2 -3
  226. package/src/__tests__/secret-scanner-executor.test.ts +5 -1
  227. package/src/__tests__/secure-keys.test.ts +107 -0
  228. package/src/__tests__/send-endpoint-busy.test.ts +34 -2
  229. package/src/__tests__/sequence-store.test.ts +1 -1
  230. package/src/__tests__/server-history-render.test.ts +80 -0
  231. package/src/__tests__/settings-routes.test.ts +201 -0
  232. package/src/__tests__/shell-parser-property.test.ts +13 -13
  233. package/src/__tests__/skill-cache-store.test.ts +182 -0
  234. package/src/__tests__/skill-load-feature-flag.test.ts +1 -0
  235. package/src/__tests__/skills-file-content-endpoint.test.ts +276 -145
  236. package/src/__tests__/skills-files-catalog-fallback.test.ts +381 -93
  237. package/src/__tests__/skills.test.ts +19 -30
  238. package/src/__tests__/skillssh-files.test.ts +446 -0
  239. package/src/__tests__/slack-app-setup-skill-regression.test.ts +3 -1
  240. package/src/__tests__/slack-block-formatting.test.ts +110 -0
  241. package/src/__tests__/slack-channel-config.test.ts +564 -1
  242. package/src/__tests__/slack-skill.test.ts +3 -8
  243. package/src/__tests__/starter-bundle.test.ts +35 -0
  244. package/src/__tests__/stt-catalog-parity.test.ts +282 -0
  245. package/src/__tests__/stt-stream-session.test.ts +535 -0
  246. package/src/__tests__/subagent-call-site-routing.test.ts +280 -0
  247. package/src/__tests__/suggestion-routes.test.ts +160 -3
  248. package/src/__tests__/system-prompt.test.ts +126 -53
  249. package/src/__tests__/task-runner.test.ts +3 -1
  250. package/src/__tests__/tcc-sandbox-deny.test.ts +198 -0
  251. package/src/__tests__/telephony-stt-routing.test.ts +329 -0
  252. package/src/__tests__/terminal-tools.test.ts +26 -7
  253. package/src/__tests__/test-preload.ts +18 -0
  254. package/src/__tests__/test-support/browser-skill-harness.ts +2 -49
  255. package/src/__tests__/thread-backfill.test.ts +941 -0
  256. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +2 -2
  257. package/src/__tests__/tool-executor-lifecycle-events.test.ts +10 -6
  258. package/src/__tests__/tool-executor-shell-integration.test.ts +4 -0
  259. package/src/__tests__/tool-executor.test.ts +88 -113
  260. package/src/__tests__/tool-result-truncation.test.ts +36 -0
  261. package/src/__tests__/trust-store.test.ts +442 -103
  262. package/src/__tests__/trusted-contact-approval-notifier.test.ts +1 -1
  263. package/src/__tests__/tts-catalog-parity.test.ts +345 -0
  264. package/src/__tests__/twilio-routes-twiml.test.ts +512 -114
  265. package/src/__tests__/twilio-routes.test.ts +376 -0
  266. package/src/__tests__/unicode.test.ts +293 -0
  267. package/src/__tests__/update-bulletin-job.test.ts +389 -0
  268. package/src/__tests__/usage-cache-backfill-migration.test.ts +3 -1
  269. package/src/__tests__/usage-routes.test.ts +25 -4
  270. package/src/__tests__/user-reference.test.ts +46 -61
  271. package/src/__tests__/verification-control-plane-policy.test.ts +5 -22
  272. package/src/__tests__/voice-config-update.test.ts +403 -0
  273. package/src/__tests__/voice-quality.test.ts +434 -19
  274. package/src/__tests__/voice-session-bridge.test.ts +39 -0
  275. package/src/__tests__/volume-security-guard.test.ts +3 -2
  276. package/src/__tests__/web-search-history.test.ts +337 -0
  277. package/src/__tests__/workspace-heartbeat-service.test.ts +7 -0
  278. package/src/__tests__/workspace-migration-033-stt-service-explicit-config.test.ts +547 -0
  279. package/src/__tests__/workspace-migration-034-remove-calls-voice-transcription-provider.test.ts +596 -0
  280. package/src/__tests__/workspace-migration-039-drop-legacy-llm-keys.test.ts +343 -0
  281. package/src/__tests__/workspace-migration-043-release-notes-latex-rendering.test.ts +202 -0
  282. package/src/__tests__/workspace-migration-045-release-notes-meet-avatar.test.ts +210 -0
  283. package/src/__tests__/workspace-migration-drop-user-md.test.ts +368 -0
  284. package/src/__tests__/workspace-migration-meets.test.ts +244 -0
  285. package/src/__tests__/workspace-migration-seed-device-id.test.ts +14 -20
  286. package/src/__tests__/workspace-migration-unify-llm-callsite-configs.test.ts +841 -0
  287. package/src/__tests__/workspace-policy.test.ts +1 -11
  288. package/src/acp/client-handler.ts +1 -2
  289. package/src/agent/image-optimize.ts +24 -12
  290. package/src/agent/loop.ts +251 -19
  291. package/src/avatar/resvg-lazy.test.ts +136 -0
  292. package/src/avatar/resvg-lazy.ts +82 -9
  293. package/src/avatar/traits-png-sync.ts +21 -1
  294. package/src/backup/__tests__/backup-key.test.ts +152 -0
  295. package/src/backup/__tests__/backup-worker.test.ts +767 -0
  296. package/src/backup/__tests__/list-snapshots.test.ts +87 -0
  297. package/src/backup/__tests__/local-writer.test.ts +218 -0
  298. package/src/backup/__tests__/offsite-writer.test.ts +641 -0
  299. package/src/backup/__tests__/paths.test.ts +300 -0
  300. package/src/backup/__tests__/restore.test.ts +498 -0
  301. package/src/backup/__tests__/snapshot-lock.test.ts +352 -0
  302. package/src/backup/__tests__/stream-crypt.test.ts +228 -0
  303. package/src/backup/backup-key.ts +137 -0
  304. package/src/backup/backup-worker.ts +459 -0
  305. package/src/backup/list-snapshots.ts +147 -0
  306. package/src/backup/local-writer.ts +133 -0
  307. package/src/backup/offsite-writer.ts +222 -0
  308. package/src/backup/paths.ts +226 -0
  309. package/src/backup/restore.ts +322 -0
  310. package/src/backup/snapshot-lock.ts +431 -0
  311. package/src/backup/stream-crypt.ts +263 -0
  312. package/src/browser/__tests__/operations.test.ts +163 -0
  313. package/src/browser/identifiers.ts +51 -0
  314. package/src/browser/operations.ts +660 -0
  315. package/src/browser/types.ts +81 -0
  316. package/src/bundler/package-resolver.ts +4 -0
  317. package/src/calls/audio-store.ts +11 -5
  318. package/src/calls/call-controller.ts +226 -71
  319. package/src/calls/call-domain.ts +9 -0
  320. package/src/calls/call-speech-output.ts +190 -0
  321. package/src/calls/call-transport.ts +77 -0
  322. package/src/calls/guardian-question-copy.ts +2 -2
  323. package/src/calls/media-stream-audio-transcode.ts +173 -0
  324. package/src/calls/media-stream-output.ts +660 -0
  325. package/src/calls/media-stream-parser.ts +300 -0
  326. package/src/calls/media-stream-protocol.ts +166 -0
  327. package/src/calls/media-stream-server.ts +592 -0
  328. package/src/calls/media-stream-stt-session.ts +460 -0
  329. package/src/calls/media-turn-detector.ts +230 -0
  330. package/src/calls/relay-server.ts +90 -75
  331. package/src/calls/resolve-call-tts-provider.ts +136 -0
  332. package/src/calls/telephony-stt-routing.ts +145 -0
  333. package/src/calls/tts-call-strategy.ts +161 -0
  334. package/src/calls/tts-text-sanitizer.ts +32 -16
  335. package/src/calls/twilio-routes.ts +281 -17
  336. package/src/calls/voice-quality.ts +78 -35
  337. package/src/calls/voice-session-bridge.ts +9 -1
  338. package/src/channels/types.ts +16 -0
  339. package/src/cli/AGENTS.md +1 -1
  340. package/src/cli/__tests__/run-assistant-command.ts +11 -1
  341. package/src/cli/commands/__tests__/attachment.test.ts +438 -0
  342. package/src/cli/commands/__tests__/backup.test.ts +1165 -0
  343. package/src/cli/commands/__tests__/browser.test.ts +554 -0
  344. package/src/cli/commands/__tests__/cache.test.ts +623 -0
  345. package/src/cli/commands/__tests__/domain-register.test.ts +234 -0
  346. package/src/cli/commands/__tests__/domain-status.test.ts +132 -0
  347. package/src/cli/commands/__tests__/email-attachment.test.ts +422 -0
  348. package/src/cli/commands/__tests__/email-download.test.ts +16 -1
  349. package/src/cli/commands/__tests__/email-list.test.ts +28 -4
  350. package/src/cli/commands/__tests__/email-register.test.ts +4 -4
  351. package/src/cli/commands/__tests__/email-send.test.ts +130 -5
  352. package/src/cli/commands/__tests__/email-status.test.ts +5 -1
  353. package/src/cli/commands/__tests__/email-unregister.test.ts +34 -5
  354. package/src/cli/commands/__tests__/image-generation.test.ts +666 -0
  355. package/src/cli/commands/__tests__/inference-send.test.ts +451 -0
  356. package/src/cli/commands/__tests__/stt-transcribe.test.ts +454 -0
  357. package/src/cli/commands/__tests__/task.test.ts +913 -0
  358. package/src/cli/commands/__tests__/tts-synthesize.test.ts +594 -0
  359. package/src/cli/commands/__tests__/ui-confirm.test.ts +650 -0
  360. package/src/cli/commands/__tests__/ui.test.ts +1215 -0
  361. package/src/cli/commands/__tests__/watchers.test.ts +716 -0
  362. package/src/cli/commands/attachment.ts +182 -0
  363. package/src/cli/commands/backup.ts +993 -0
  364. package/src/cli/commands/browser.ts +350 -0
  365. package/src/cli/commands/cache.ts +341 -0
  366. package/src/cli/commands/completions.ts +0 -3
  367. package/src/cli/commands/config.ts +6 -6
  368. package/src/cli/commands/conversations-import.ts +347 -0
  369. package/src/cli/commands/conversations.ts +90 -0
  370. package/src/cli/commands/credentials.ts +0 -1
  371. package/src/cli/commands/domain.ts +210 -0
  372. package/src/cli/commands/email.ts +308 -16
  373. package/src/cli/commands/image-generation.ts +300 -0
  374. package/src/cli/commands/inference.ts +200 -0
  375. package/src/cli/commands/memory.ts +127 -17
  376. package/src/cli/commands/oauth/__tests__/connect.test.ts +12 -0
  377. package/src/cli/commands/oauth/__tests__/providers-delete.test.ts +1 -0
  378. package/src/cli/commands/oauth/__tests__/providers-register.test.ts +1 -0
  379. package/src/cli/commands/oauth/__tests__/providers-update.test.ts +1 -0
  380. package/src/cli/commands/oauth/mode.ts +12 -3
  381. package/src/cli/commands/oauth/providers.ts +15 -0
  382. package/src/cli/commands/oauth/shared.ts +2 -1
  383. package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +4 -10
  384. package/src/cli/commands/platform/__tests__/connect.test.ts +6 -1
  385. package/src/cli/commands/platform/__tests__/disconnect.test.ts +7 -2
  386. package/src/cli/commands/platform/__tests__/status.test.ts +6 -1
  387. package/src/cli/commands/stt.ts +339 -0
  388. package/src/cli/commands/task.ts +795 -0
  389. package/src/cli/commands/trust.ts +50 -19
  390. package/src/cli/commands/tts.ts +273 -0
  391. package/src/cli/commands/ui.ts +670 -0
  392. package/src/cli/commands/watchers.ts +509 -0
  393. package/src/cli/lib/daemon-credential-client.ts +0 -19
  394. package/src/cli/program.ts +53 -8
  395. package/src/cli.ts +0 -37
  396. package/src/config/__tests__/backup-schema.test.ts +134 -0
  397. package/src/config/assistant-feature-flags.ts +61 -62
  398. package/src/config/bundled-skills/app-builder/references/CUSTOM_ROUTES.md +37 -1
  399. package/src/config/bundled-skills/contacts/SKILL.md +2 -2
  400. package/src/config/bundled-skills/conversations/tools/rename-conversation.ts +23 -1
  401. package/src/config/bundled-skills/media-processing/SKILL.md +3 -9
  402. package/src/config/bundled-skills/media-processing/TOOLS.json +1 -6
  403. package/src/config/bundled-skills/media-processing/__tests__/audio-transcribe.test.ts +125 -0
  404. package/src/config/bundled-skills/media-processing/__tests__/extract-keyframes.test.ts +181 -0
  405. package/src/config/bundled-skills/media-processing/__tests__/preprocess-audio.test.ts +141 -0
  406. package/src/config/bundled-skills/media-processing/services/audio-transcribe.ts +32 -87
  407. package/src/config/bundled-skills/media-processing/services/preprocess.ts +8 -4
  408. package/src/config/bundled-skills/media-processing/services/reduce.ts +1 -1
  409. package/src/config/bundled-skills/media-processing/tools/extract-keyframes.ts +0 -10
  410. package/src/config/bundled-skills/messaging/SKILL.md +5 -5
  411. package/src/config/bundled-skills/messaging/TOOLS.json +4 -0
  412. package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +9 -2
  413. package/src/config/bundled-skills/messaging/tools/messaging-read.ts +15 -1
  414. package/src/config/bundled-skills/messaging/tools/messaging-search.ts +21 -1
  415. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +11 -12
  416. package/src/config/bundled-skills/phone-calls/SKILL.md +2 -2
  417. package/src/config/bundled-skills/phone-calls/references/CONFIG.md +28 -18
  418. package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +3 -3
  419. package/src/config/bundled-skills/settings/TOOLS.json +3 -3
  420. package/src/config/bundled-skills/settings/tools/voice-config-update.ts +26 -22
  421. package/src/config/bundled-skills/transcribe/SKILL.md +9 -14
  422. package/src/config/bundled-skills/transcribe/TOOLS.json +2 -7
  423. package/src/config/bundled-skills/transcribe/tools/transcribe-media.test.ts +256 -0
  424. package/src/config/bundled-skills/transcribe/tools/transcribe-media.ts +38 -188
  425. package/src/config/bundled-tool-registry.ts +0 -167
  426. package/src/config/env-registry.ts +24 -0
  427. package/src/config/env.ts +39 -10
  428. package/src/config/feature-flag-registry.json +63 -15
  429. package/src/config/llm-resolver.ts +128 -0
  430. package/src/config/loader.ts +220 -22
  431. package/src/config/raw-config-utils.ts +30 -2
  432. package/src/config/sanitize-for-transfer.ts +35 -0
  433. package/src/config/schema.ts +65 -51
  434. package/src/config/schemas/__tests__/stt.test.ts +43 -0
  435. package/src/config/schemas/analysis.ts +32 -0
  436. package/src/config/schemas/backup.ts +72 -0
  437. package/src/config/schemas/calls.ts +1 -30
  438. package/src/config/schemas/elevenlabs.ts +0 -59
  439. package/src/config/schemas/filing.ts +49 -14
  440. package/src/config/schemas/heartbeat.ts +27 -10
  441. package/src/config/schemas/host-browser.ts +47 -1
  442. package/src/config/schemas/inference.ts +3 -23
  443. package/src/config/schemas/llm.ts +318 -0
  444. package/src/config/schemas/memory-lifecycle.ts +14 -2
  445. package/src/config/schemas/memory-processing.ts +1 -9
  446. package/src/config/schemas/notifications.ts +4 -11
  447. package/src/config/schemas/platform.ts +3 -9
  448. package/src/config/schemas/security.ts +33 -0
  449. package/src/config/schemas/services.ts +53 -4
  450. package/src/config/schemas/stt.ts +60 -0
  451. package/src/config/schemas/tts.ts +283 -0
  452. package/src/config/schemas/updates.ts +14 -0
  453. package/src/config/schemas/workspace-git.ts +3 -40
  454. package/src/config/skills.ts +6 -2
  455. package/src/config/types.ts +4 -0
  456. package/src/contacts/contact-store.ts +56 -11
  457. package/src/contacts/contacts-write.ts +38 -1
  458. package/src/context/__tests__/compact-prompt.test.ts +45 -0
  459. package/src/context/__tests__/microcompact.test.ts +805 -0
  460. package/src/context/estimator-calibration.ts +136 -0
  461. package/src/context/microcompact.ts +443 -0
  462. package/src/context/post-turn-tool-result-truncation.ts +3 -2
  463. package/src/context/prompts/compact.md +12 -0
  464. package/src/context/token-estimator.ts +61 -3
  465. package/src/context/tool-result-truncation.ts +2 -1
  466. package/src/context/window-manager.ts +272 -35
  467. package/src/credential-execution/approval-bridge.ts +0 -1
  468. package/src/credential-execution/executable-discovery.ts +23 -2
  469. package/src/credential-execution/process-manager.test.ts +109 -0
  470. package/src/credential-execution/process-manager.ts +96 -2
  471. package/src/credential-health/credential-health-service.ts +366 -0
  472. package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +324 -0
  473. package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +497 -0
  474. package/src/daemon/__tests__/conversation-tool-setup.test.ts +17 -8
  475. package/src/daemon/__tests__/lifecycle-startup-ordering.test.ts +127 -0
  476. package/src/daemon/approval-generators.ts +29 -4
  477. package/src/daemon/assistant-attachments.ts +24 -13
  478. package/src/daemon/classifier.ts +2 -2
  479. package/src/daemon/config-watcher.ts +99 -6
  480. package/src/daemon/context-overflow-reducer.ts +4 -1
  481. package/src/daemon/conversation-agent-loop-handlers.ts +85 -12
  482. package/src/daemon/conversation-agent-loop.ts +563 -104
  483. package/src/daemon/conversation-attachments.ts +2 -6
  484. package/src/daemon/conversation-error.ts +46 -0
  485. package/src/daemon/conversation-history.ts +40 -6
  486. package/src/daemon/conversation-launch.ts +220 -0
  487. package/src/daemon/conversation-lifecycle.ts +85 -11
  488. package/src/daemon/conversation-messaging.ts +110 -7
  489. package/src/daemon/conversation-notifiers.ts +5 -0
  490. package/src/daemon/conversation-process.ts +591 -23
  491. package/src/daemon/conversation-queue-manager.ts +27 -0
  492. package/src/daemon/conversation-runtime-assembly.ts +769 -28
  493. package/src/daemon/conversation-slash.ts +38 -2
  494. package/src/daemon/conversation-surfaces.ts +483 -5
  495. package/src/daemon/conversation-tool-setup.ts +35 -5
  496. package/src/daemon/conversation-usage.ts +8 -5
  497. package/src/daemon/conversation.ts +193 -47
  498. package/src/daemon/external-skills-bootstrap.ts +41 -0
  499. package/src/daemon/guardian-action-generators.ts +34 -14
  500. package/src/daemon/handlers/config-model.test.ts +86 -0
  501. package/src/daemon/handlers/config-model.ts +54 -12
  502. package/src/daemon/handlers/config-slack-channel.ts +269 -94
  503. package/src/daemon/handlers/conversations.ts +13 -3
  504. package/src/daemon/handlers/shared.ts +51 -1
  505. package/src/daemon/handlers/skills.ts +323 -79
  506. package/src/daemon/handlers/slack-channel-oauth-install.ts +197 -0
  507. package/src/daemon/host-browser-proxy.ts +2 -1
  508. package/src/daemon/lifecycle.ts +185 -26
  509. package/src/daemon/message-protocol.ts +6 -0
  510. package/src/daemon/message-types/conversations.ts +48 -1
  511. package/src/daemon/message-types/home.ts +40 -0
  512. package/src/daemon/message-types/meet.ts +143 -0
  513. package/src/daemon/message-types/messages.ts +23 -1
  514. package/src/daemon/message-types/schedules.ts +34 -2
  515. package/src/daemon/message-types/skills.ts +16 -0
  516. package/src/daemon/message-types/surfaces.ts +2 -0
  517. package/src/daemon/message-types/trust.ts +0 -2
  518. package/src/daemon/parse-actual-tokens-from-error.test.ts +57 -1
  519. package/src/daemon/parse-actual-tokens-from-error.ts +66 -0
  520. package/src/daemon/pkb-context-tracker.test.ts +169 -0
  521. package/src/daemon/pkb-context-tracker.ts +125 -0
  522. package/src/daemon/pkb-reminder-builder.test.ts +70 -0
  523. package/src/daemon/pkb-reminder-builder.ts +31 -0
  524. package/src/daemon/providers-setup.ts +6 -0
  525. package/src/daemon/server.ts +463 -10
  526. package/src/daemon/shutdown-handlers.ts +32 -4
  527. package/src/daemon/shutdown-registry.ts +40 -0
  528. package/src/daemon/tool-side-effects.ts +9 -9
  529. package/src/daemon/watch-handler.ts +4 -4
  530. package/src/daemon/web-search-history.ts +126 -0
  531. package/src/email/html-renderer.ts +76 -0
  532. package/src/events/domain-events.ts +0 -1
  533. package/src/filing/filing-service.ts +9 -10
  534. package/src/heartbeat/heartbeat-service.ts +156 -22
  535. package/src/home/__tests__/assistant-feed-authoring.test.ts +156 -0
  536. package/src/home/__tests__/emit-feed-event.test.ts +169 -0
  537. package/src/home/__tests__/feed-scheduler.test.ts +222 -0
  538. package/src/home/__tests__/feed-types.test.ts +275 -0
  539. package/src/home/__tests__/feed-writer.test.ts +688 -0
  540. package/src/home/__tests__/phase5-exit-criteria.test.ts +212 -0
  541. package/src/home/__tests__/platform-gmail-digest.test.ts +222 -0
  542. package/src/home/__tests__/progress-formula.test.ts +213 -0
  543. package/src/home/__tests__/relationship-state-writer.test.ts +740 -0
  544. package/src/home/__tests__/rollup-producer.test.ts +442 -0
  545. package/src/home/assistant-feed-authoring.ts +128 -0
  546. package/src/home/emit-feed-event.ts +162 -0
  547. package/src/home/feed-scheduler.ts +263 -0
  548. package/src/home/feed-types.ts +235 -0
  549. package/src/home/feed-writer.ts +469 -0
  550. package/src/home/platform-gmail-digest.ts +163 -0
  551. package/src/home/progress-formula.ts +86 -0
  552. package/src/home/relationship-state-writer.ts +824 -0
  553. package/src/home/relationship-state.ts +143 -0
  554. package/src/home/rollup-producer.ts +413 -0
  555. package/src/home/suggested-prompts.ts +101 -0
  556. package/src/hooks/runner.ts +7 -0
  557. package/src/inbound/platform-callback-registration.ts +12 -3
  558. package/src/inbound/public-ingress-urls.ts +12 -0
  559. package/src/instrument.ts +1 -1
  560. package/src/ipc/__tests__/attachment-ipc.test.ts +213 -0
  561. package/src/ipc/__tests__/browser-ipc.test.ts +339 -0
  562. package/src/ipc/__tests__/cache-ipc.test.ts +266 -0
  563. package/src/ipc/__tests__/cli-ipc.test.ts +200 -0
  564. package/src/ipc/__tests__/socket-path.test.ts +73 -0
  565. package/src/ipc/__tests__/task-ipc.test.ts +577 -0
  566. package/src/ipc/__tests__/ui-request-route.test.ts +495 -0
  567. package/src/ipc/__tests__/watcher-ipc.test.ts +295 -0
  568. package/src/ipc/cli-client.ts +152 -0
  569. package/src/ipc/cli-server.ts +252 -0
  570. package/src/ipc/gateway-client.ts +180 -0
  571. package/src/ipc/routes/attachment.ts +114 -0
  572. package/src/ipc/routes/browser-context.ts +61 -0
  573. package/src/ipc/routes/browser.ts +96 -0
  574. package/src/ipc/routes/cache.ts +96 -0
  575. package/src/ipc/routes/index.ts +21 -0
  576. package/src/ipc/routes/task-queue.ts +226 -0
  577. package/src/ipc/routes/task.ts +173 -0
  578. package/src/ipc/routes/ui-request.ts +50 -0
  579. package/src/ipc/routes/wake-conversation.ts +19 -0
  580. package/src/ipc/routes/watcher.ts +203 -0
  581. package/src/ipc/socket-path.ts +100 -0
  582. package/src/memory/__tests__/auto-analysis-enqueue.test.ts +356 -0
  583. package/src/memory/__tests__/auto-analysis-guard.test.ts +57 -0
  584. package/src/memory/__tests__/conversation-analyze-job.test.ts +233 -0
  585. package/src/memory/__tests__/conversation-group-migration.test.ts +99 -0
  586. package/src/memory/__tests__/find-analysis-conversation.test.ts +196 -0
  587. package/src/memory/admin.ts +18 -0
  588. package/src/memory/app-store.ts +1 -1
  589. package/src/memory/attachments-store.ts +70 -0
  590. package/src/memory/auto-analysis-enqueue.ts +127 -0
  591. package/src/memory/auto-analysis-guard.ts +27 -0
  592. package/src/memory/cleanup-schedule-state.ts +37 -0
  593. package/src/memory/conversation-analyze-job.ts +74 -0
  594. package/src/memory/conversation-attention-store.ts +13 -6
  595. package/src/memory/conversation-crud.ts +199 -0
  596. package/src/memory/conversation-disk-view.ts +7 -0
  597. package/src/memory/conversation-group-migration.ts +65 -1
  598. package/src/memory/conversation-queries.ts +6 -5
  599. package/src/memory/conversation-title-service.ts +7 -4
  600. package/src/memory/db-init.ts +8 -0
  601. package/src/memory/db-maintenance.ts +108 -0
  602. package/src/memory/db.ts +1 -0
  603. package/src/memory/embedding-backend.ts +1 -1
  604. package/src/memory/graph/compaction.ts +299 -0
  605. package/src/memory/graph/consolidation.ts +4 -4
  606. package/src/memory/graph/conversation-graph-memory.ts +104 -29
  607. package/src/memory/graph/extraction.test.ts +295 -2
  608. package/src/memory/graph/extraction.ts +181 -51
  609. package/src/memory/graph/graph-search.test.ts +92 -0
  610. package/src/memory/graph/graph-search.ts +4 -1
  611. package/src/memory/graph/narrative.ts +2 -2
  612. package/src/memory/graph/pattern-scan.ts +2 -2
  613. package/src/memory/graph/retriever.test.ts +459 -0
  614. package/src/memory/graph/retriever.ts +257 -66
  615. package/src/memory/graph/scoring.test.ts +186 -0
  616. package/src/memory/graph/scoring.ts +31 -1
  617. package/src/memory/graph/store.ts +41 -0
  618. package/src/memory/graph/tool-handlers.ts +27 -0
  619. package/src/memory/graph/tools.ts +6 -1
  620. package/src/memory/group-crud.ts +6 -1
  621. package/src/memory/indexer.ts +95 -16
  622. package/src/memory/job-handlers/cleanup.ts +11 -8
  623. package/src/memory/job-handlers/conversation-starters.ts +39 -30
  624. package/src/memory/job-handlers/summarization.ts +2 -2
  625. package/src/memory/job-utils.ts +7 -1
  626. package/src/memory/jobs/embed-pkb-file.test.ts +168 -0
  627. package/src/memory/jobs/embed-pkb-file.ts +54 -0
  628. package/src/memory/jobs-store.ts +106 -5
  629. package/src/memory/jobs-worker.ts +26 -9
  630. package/src/memory/llm-usage-store.ts +92 -56
  631. package/src/memory/migrations/140-backfill-usage-cache-accounting.ts +1 -1
  632. package/src/memory/migrations/219-oauth-providers-token-exchange-body-format.ts +15 -0
  633. package/src/memory/migrations/220-normalize-user-file-by-principal.ts +190 -0
  634. package/src/memory/migrations/221-conversations-archived-at.ts +16 -0
  635. package/src/memory/migrations/222-strip-placeholder-sentinels-from-messages.ts +82 -0
  636. package/src/memory/migrations/index.ts +7 -0
  637. package/src/memory/migrations/registry.ts +8 -0
  638. package/src/memory/pkb/pkb-index.test.ts +368 -0
  639. package/src/memory/pkb/pkb-index.ts +255 -0
  640. package/src/memory/pkb/pkb-reconcile.test.ts +251 -0
  641. package/src/memory/pkb/pkb-reconcile.ts +148 -0
  642. package/src/memory/pkb/pkb-search.test.ts +438 -0
  643. package/src/memory/pkb/pkb-search.ts +137 -0
  644. package/src/memory/pkb/types.ts +53 -0
  645. package/src/memory/qdrant-client.ts +122 -1
  646. package/src/memory/qdrant-manager.ts +43 -16
  647. package/src/memory/schema/conversations.ts +2 -0
  648. package/src/memory/schema/oauth.ts +3 -0
  649. package/src/memory/slack-thread-store.ts +37 -0
  650. package/src/memory/usage-buckets.ts +396 -0
  651. package/src/messaging/providers/gmail/adapter.ts +6 -16
  652. package/src/messaging/providers/gmail/client.ts +79 -6
  653. package/src/messaging/providers/gmail/types.ts +7 -0
  654. package/src/messaging/providers/slack/__tests__/adapter-token-routing.test.ts +282 -0
  655. package/src/messaging/providers/slack/adapter.ts +155 -38
  656. package/src/messaging/providers/slack/backfill.test.ts +257 -0
  657. package/src/messaging/providers/slack/backfill.ts +101 -0
  658. package/src/messaging/providers/slack/client.ts +16 -0
  659. package/src/messaging/providers/slack/message-metadata.test.ts +316 -0
  660. package/src/messaging/providers/slack/message-metadata.ts +123 -0
  661. package/src/messaging/providers/slack/render-transcript.test.ts +1373 -0
  662. package/src/messaging/providers/slack/render-transcript.ts +443 -0
  663. package/src/messaging/providers/slack/types.ts +4 -0
  664. package/src/messaging/style-analyzer.ts +5 -2
  665. package/src/notifications/README.md +9 -5
  666. package/src/notifications/decision-engine.ts +6 -12
  667. package/src/notifications/preference-extractor.ts +2 -6
  668. package/src/notifications/signal.ts +5 -0
  669. package/src/oauth/__tests__/identity-verifier.test.ts +1 -0
  670. package/src/oauth/byo-connection.test.ts +18 -1
  671. package/src/oauth/byo-connection.ts +3 -1
  672. package/src/oauth/connect-orchestrator.ts +2 -0
  673. package/src/oauth/connection-resolver.ts +6 -2
  674. package/src/oauth/connection.ts +2 -0
  675. package/src/oauth/oauth-store.ts +10 -0
  676. package/src/oauth/platform-connection.test.ts +145 -0
  677. package/src/oauth/platform-connection.ts +62 -31
  678. package/src/oauth/seed-providers.ts +10 -1
  679. package/src/permissions/approval-policy.test.ts +948 -0
  680. package/src/permissions/approval-policy.ts +257 -0
  681. package/src/permissions/bash-risk-classifier.test.ts +1208 -0
  682. package/src/permissions/bash-risk-classifier.ts +707 -0
  683. package/src/permissions/checker.ts +218 -699
  684. package/src/permissions/command-registry.test.ts +535 -0
  685. package/src/permissions/command-registry.ts +825 -0
  686. package/src/permissions/defaults.ts +71 -75
  687. package/src/permissions/file-risk-classifier.test.ts +535 -0
  688. package/src/permissions/file-risk-classifier.ts +274 -0
  689. package/src/permissions/risk-types.ts +205 -0
  690. package/src/permissions/secret-prompter.ts +53 -2
  691. package/src/permissions/skill-risk-classifier.test.ts +311 -0
  692. package/src/permissions/skill-risk-classifier.ts +214 -0
  693. package/src/permissions/trust-client.ts +52 -25
  694. package/src/permissions/trust-store-interface.ts +1 -6
  695. package/src/permissions/trust-store.ts +164 -65
  696. package/src/permissions/types.ts +23 -14
  697. package/src/permissions/web-risk-classifier.test.ts +170 -0
  698. package/src/permissions/web-risk-classifier.ts +89 -0
  699. package/src/permissions/workspace-policy.ts +1 -13
  700. package/src/platform/client.test.ts +10 -0
  701. package/src/platform/client.ts +19 -1
  702. package/src/platform/sync-identity.ts +129 -0
  703. package/src/prompts/persona-resolver.ts +127 -3
  704. package/src/prompts/system-prompt.ts +78 -38
  705. package/src/prompts/templates/BOOTSTRAP.md +5 -5
  706. package/src/prompts/templates/SOUL.md +5 -3
  707. package/src/prompts/templates/channels/slack.md +20 -0
  708. package/src/prompts/update-bulletin-job.ts +190 -0
  709. package/src/prompts/user-reference.ts +20 -17
  710. package/src/providers/__tests__/context-overflow-error.test.ts +328 -0
  711. package/src/providers/__tests__/provider-env-vars.test.ts +102 -0
  712. package/src/providers/__tests__/provider-secret-catalog.test.ts +42 -0
  713. package/src/providers/__tests__/retry-callsite.test.ts +424 -0
  714. package/src/providers/anthropic/client.ts +335 -70
  715. package/src/providers/call-site-routing.ts +71 -0
  716. package/src/providers/fireworks/client.ts +2 -2
  717. package/src/providers/gemini/client.ts +74 -3
  718. package/src/providers/managed-proxy/constants.ts +2 -1
  719. package/src/providers/model-catalog.ts +502 -28
  720. package/src/providers/model-intents.ts +8 -8
  721. package/src/providers/ollama/client.ts +2 -2
  722. package/src/providers/openai/chat-completions-provider.ts +530 -0
  723. package/src/providers/openai/client.ts +25 -440
  724. package/src/providers/openai/responses-provider.ts +579 -0
  725. package/src/providers/openrouter/client.ts +168 -4
  726. package/src/providers/provider-env-vars.ts +56 -0
  727. package/src/providers/provider-secret-catalog.ts +139 -0
  728. package/src/providers/provider-send-message.ts +22 -5
  729. package/src/providers/ratelimit.ts +4 -0
  730. package/src/providers/registry.ts +21 -10
  731. package/src/providers/retry.ts +185 -39
  732. package/src/providers/speech-to-text/__tests__/provider-catalog.test.ts +251 -0
  733. package/src/providers/speech-to-text/__tests__/resolve.test.ts +883 -0
  734. package/src/providers/speech-to-text/deepgram-realtime.test.ts +980 -0
  735. package/src/providers/speech-to-text/deepgram-realtime.ts +767 -0
  736. package/src/providers/speech-to-text/deepgram.test.ts +332 -0
  737. package/src/providers/speech-to-text/deepgram.ts +115 -0
  738. package/src/providers/speech-to-text/google-gemini-live-stream.test.ts +743 -0
  739. package/src/providers/speech-to-text/google-gemini-live-stream.ts +625 -0
  740. package/src/providers/speech-to-text/google-gemini.test.ts +226 -0
  741. package/src/providers/speech-to-text/google-gemini.ts +101 -0
  742. package/src/providers/speech-to-text/openai-whisper-stream.test.ts +564 -0
  743. package/src/providers/speech-to-text/openai-whisper-stream.ts +381 -0
  744. package/src/providers/speech-to-text/openai-whisper.test.ts +1 -37
  745. package/src/providers/speech-to-text/openai-whisper.ts +63 -33
  746. package/src/providers/speech-to-text/provider-catalog.ts +323 -0
  747. package/src/providers/speech-to-text/resolve.ts +393 -6
  748. package/src/providers/speech-to-text/xai-realtime.test.ts +578 -0
  749. package/src/providers/speech-to-text/xai-realtime.ts +796 -0
  750. package/src/providers/speech-to-text/xai.test.ts +155 -0
  751. package/src/providers/speech-to-text/xai.ts +97 -0
  752. package/src/providers/types.ts +102 -3
  753. package/src/runtime/AGENTS.md +45 -3
  754. package/src/runtime/__tests__/agent-wake.test.ts +872 -0
  755. package/src/runtime/__tests__/interactive-ui.test.ts +673 -0
  756. package/src/runtime/__tests__/runtime-mode.test.ts +62 -0
  757. package/src/runtime/__tests__/slack-block-formatting.test.ts +481 -0
  758. package/src/runtime/agent-wake.ts +553 -0
  759. package/src/runtime/auth/__tests__/route-policy.test.ts +40 -0
  760. package/src/runtime/auth/route-policy.ts +34 -5
  761. package/src/runtime/auth/token-service.ts +56 -1
  762. package/src/runtime/btw-sidechain.ts +15 -3
  763. package/src/runtime/capability-tokens.ts +10 -10
  764. package/src/runtime/channel-invite-transport.ts +1 -1
  765. package/src/runtime/channel-invite-transports/email.ts +14 -6
  766. package/src/runtime/channel-readiness-service.ts +12 -22
  767. package/src/runtime/channel-reply-delivery.ts +106 -2
  768. package/src/runtime/chrome-extension-registry.ts +38 -2
  769. package/src/runtime/decision-token.ts +116 -0
  770. package/src/runtime/gateway-client.ts +2 -2
  771. package/src/runtime/http-router.ts +32 -0
  772. package/src/runtime/http-server.ts +447 -11
  773. package/src/runtime/http-types.ts +29 -3
  774. package/src/runtime/interactive-ui.ts +362 -0
  775. package/src/runtime/invite-instruction-generator.ts +2 -2
  776. package/src/runtime/migrations/__tests__/gcs-signed-url.test.ts +176 -0
  777. package/src/runtime/migrations/__tests__/vbundle-import-credentials.test.ts +36 -0
  778. package/src/runtime/migrations/__tests__/vbundle-legacy-user-md.test.ts +360 -0
  779. package/src/runtime/migrations/__tests__/vbundle-metadata-merge-integration.test.ts +390 -0
  780. package/src/runtime/migrations/__tests__/vbundle-metadata-merge.test.ts +221 -0
  781. package/src/runtime/migrations/__tests__/vbundle-streaming-importer.test.ts +1540 -0
  782. package/src/runtime/migrations/__tests__/vbundle-streaming-validator.test.ts +453 -0
  783. package/src/runtime/migrations/__tests__/vbundle-tar-stream.test.ts +222 -0
  784. package/src/runtime/migrations/gcs-signed-url.ts +162 -0
  785. package/src/runtime/migrations/migration-transport.ts +1 -0
  786. package/src/runtime/migrations/migration-wizard.ts +1 -0
  787. package/src/runtime/migrations/vbundle-import-analyzer.ts +77 -1
  788. package/src/runtime/migrations/vbundle-importer.ts +187 -8
  789. package/src/runtime/migrations/vbundle-metadata-merge.ts +124 -0
  790. package/src/runtime/migrations/vbundle-streaming-importer.ts +2522 -0
  791. package/src/runtime/migrations/vbundle-streaming-validator.ts +244 -0
  792. package/src/runtime/migrations/vbundle-tar-stream.ts +217 -0
  793. package/src/runtime/migrations/vbundle-validator.ts +15 -6
  794. package/src/runtime/pending-interactions.ts +0 -11
  795. package/src/runtime/routes/__tests__/backup-routes.test.ts +967 -0
  796. package/src/runtime/routes/__tests__/home-feed-routes.test.ts +618 -0
  797. package/src/runtime/routes/__tests__/migration-import-credential-filter.test.ts +247 -0
  798. package/src/runtime/routes/__tests__/migration-vellum-metadata-reconcile.test.ts +246 -0
  799. package/src/runtime/routes/__tests__/stt-routes.test.ts +406 -0
  800. package/src/runtime/routes/__tests__/tts-routes.test.ts +474 -0
  801. package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +148 -17
  802. package/src/runtime/routes/app-management-routes.ts +12 -18
  803. package/src/runtime/routes/approval-prompt-ts-tracker.ts +58 -0
  804. package/src/runtime/routes/approval-routes.ts +12 -17
  805. package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +9 -0
  806. package/src/runtime/routes/attachment-routes.test.ts +9 -3
  807. package/src/runtime/routes/attachment-routes.ts +216 -17
  808. package/src/runtime/routes/avatar-routes.ts +20 -4
  809. package/src/runtime/routes/backup-routes.ts +519 -0
  810. package/src/runtime/routes/browser-extension-pair-routes.ts +82 -23
  811. package/src/runtime/routes/btw-routes.ts +9 -10
  812. package/src/runtime/routes/contact-routes.test.ts +298 -0
  813. package/src/runtime/routes/contact-routes.ts +132 -5
  814. package/src/runtime/routes/conversation-analysis-routes.ts +22 -142
  815. package/src/runtime/routes/conversation-management-routes.ts +133 -0
  816. package/src/runtime/routes/conversation-routes.ts +487 -160
  817. package/src/runtime/routes/debug-routes.ts +1 -1
  818. package/src/runtime/routes/diagnostics-routes.ts +6 -4
  819. package/src/runtime/routes/events-routes.ts +16 -0
  820. package/src/runtime/routes/filing-routes.ts +93 -0
  821. package/src/runtime/routes/guardian-approval-interception.ts +33 -3
  822. package/src/runtime/routes/guardian-approval-prompt.ts +13 -3
  823. package/src/runtime/routes/home-feed-routes.ts +452 -0
  824. package/src/runtime/routes/home-state-routes.ts +138 -0
  825. package/src/runtime/routes/host-browser-routes.ts +3 -14
  826. package/src/runtime/routes/identity-intro-cache.ts +7 -3
  827. package/src/runtime/routes/identity-routes.ts +3 -17
  828. package/src/runtime/routes/inbound-message-handler.ts +912 -2
  829. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +113 -2
  830. package/src/runtime/routes/inbound-stages/background-dispatch.ts +61 -3
  831. package/src/runtime/routes/inbound-stages/edit-intercept.ts +129 -6
  832. package/src/runtime/routes/inbound-stages/transcribe-audio.test.ts +46 -39
  833. package/src/runtime/routes/inbound-stages/transcribe-audio.ts +15 -15
  834. package/src/runtime/routes/integrations/slack/__tests__/channel.test.ts +137 -0
  835. package/src/runtime/routes/integrations/slack/__tests__/share.test.ts +179 -0
  836. package/src/runtime/routes/integrations/slack/channel.ts +36 -6
  837. package/src/runtime/routes/integrations/slack/share.ts +45 -7
  838. package/src/runtime/routes/llm-context-normalization.ts +325 -0
  839. package/src/runtime/routes/memory-item-routes.test.ts +3 -2
  840. package/src/runtime/routes/migration-routes.ts +722 -91
  841. package/src/runtime/routes/settings-routes.ts +26 -7
  842. package/src/runtime/routes/skills-routes.ts +76 -7
  843. package/src/runtime/routes/stt-routes.ts +233 -0
  844. package/src/runtime/routes/surface-action-routes.ts +41 -2
  845. package/src/runtime/routes/trust-rules-routes.ts +30 -14
  846. package/src/runtime/routes/tts-routes.ts +108 -24
  847. package/src/runtime/routes/usage-routes.ts +30 -2
  848. package/src/runtime/routes/user-route-dispatcher.ts +50 -5
  849. package/src/runtime/routes/user-routes.ts +13 -1
  850. package/src/runtime/routes/work-items-routes.test.ts +1 -1
  851. package/src/runtime/routes/work-items-routes.ts +11 -3
  852. package/src/runtime/runtime-mode.ts +33 -0
  853. package/src/runtime/services/__tests__/analyze-conversation.test.ts +426 -0
  854. package/src/runtime/services/__tests__/analyze-deps-singleton.test.ts +67 -0
  855. package/src/runtime/services/__tests__/auto-analysis-prompt.test.ts +53 -0
  856. package/src/runtime/services/__tests__/manual-analysis-prompt.test.ts +41 -0
  857. package/src/runtime/services/analyze-conversation.ts +340 -0
  858. package/src/runtime/services/analyze-deps-singleton.ts +32 -0
  859. package/src/runtime/services/auto-analysis-prompt.ts +55 -0
  860. package/src/runtime/skill-route-registry.ts +71 -0
  861. package/src/runtime/slack-block-formatting.ts +437 -10
  862. package/src/schedule/scheduler.ts +58 -0
  863. package/src/security/__tests__/provider-key-env-fallback.test.ts +119 -0
  864. package/src/security/__tests__/untrusted-content.test.ts +109 -0
  865. package/src/security/oauth2.ts +122 -37
  866. package/src/security/secure-keys.ts +32 -10
  867. package/src/security/token-manager.ts +35 -13
  868. package/src/security/untrusted-content.ts +102 -0
  869. package/src/sequence/engine.ts +23 -0
  870. package/src/sequence/types.ts +1 -1
  871. package/src/skills/catalog-cache.ts +26 -7
  872. package/src/skills/catalog-files.ts +64 -2
  873. package/src/skills/catalog-install.ts +31 -3
  874. package/src/skills/category-inference.ts +122 -0
  875. package/src/skills/clawhub-files.ts +213 -0
  876. package/src/skills/clawhub.ts +84 -23
  877. package/src/skills/skill-cache-store.ts +97 -0
  878. package/src/skills/skill-file-provider.ts +40 -0
  879. package/src/skills/skillssh-files.ts +395 -0
  880. package/src/skills/skillssh-registry.ts +4 -4
  881. package/src/stt/__tests__/daemon-batch-transcriber.test.ts +468 -0
  882. package/src/stt/__tests__/types.test.ts +89 -0
  883. package/src/stt/daemon-batch-transcriber.ts +228 -0
  884. package/src/stt/stt-stream-session.ts +506 -0
  885. package/src/stt/types.ts +334 -0
  886. package/src/stt/wav-encoder.test.ts +373 -0
  887. package/src/stt/wav-encoder.ts +175 -0
  888. package/src/subagent/manager.ts +79 -27
  889. package/src/tasks/ephemeral-permissions.ts +9 -4
  890. package/src/telemetry/usage-telemetry-reporter.ts +27 -5
  891. package/src/tools/browser/__tests__/browser-mode.test.ts +119 -0
  892. package/src/tools/browser/__tests__/browser-status.test.ts +166 -0
  893. package/src/tools/browser/browser-execution.ts +1208 -41
  894. package/src/tools/browser/browser-manager.ts +45 -0
  895. package/src/tools/browser/browser-mode-constants.ts +12 -0
  896. package/src/tools/browser/browser-mode.ts +92 -0
  897. package/src/tools/browser/browser-status-constants.ts +33 -0
  898. package/src/tools/browser/cdp-client/__tests__/cdp-inspect-client.test.ts +393 -0
  899. package/src/tools/browser/cdp-client/__tests__/extension-cdp-client.test.ts +29 -0
  900. package/src/tools/browser/cdp-client/__tests__/factory.test.ts +1648 -32
  901. package/src/tools/browser/cdp-client/cdp-inspect/__tests__/discovery.test.ts +264 -0
  902. package/src/tools/browser/cdp-client/cdp-inspect/discovery.ts +205 -17
  903. package/src/tools/browser/cdp-client/cdp-inspect-client.ts +254 -21
  904. package/src/tools/browser/cdp-client/errors.ts +15 -0
  905. package/src/tools/browser/cdp-client/extension-cdp-client.ts +39 -16
  906. package/src/tools/browser/cdp-client/factory.ts +797 -87
  907. package/src/tools/browser/cdp-client/index.ts +16 -2
  908. package/src/tools/browser/cdp-client/types.ts +68 -0
  909. package/src/tools/credentials/tool-policy.ts +39 -5
  910. package/src/tools/credentials/vault.ts +41 -7
  911. package/src/tools/executor.ts +4 -0
  912. package/src/tools/filesystem/write.ts +52 -0
  913. package/src/tools/host-terminal/host-shell.ts +45 -5
  914. package/src/tools/memory/register.test.ts +185 -0
  915. package/src/tools/memory/register.ts +3 -1
  916. package/src/tools/network/web-fetch.ts +25 -12
  917. package/src/tools/network/web-search.ts +20 -2
  918. package/src/tools/permission-checker.ts +36 -15
  919. package/src/tools/policy-context.ts +25 -8
  920. package/src/tools/registry.ts +55 -3
  921. package/src/tools/shared/shell-output.ts +3 -1
  922. package/src/tools/side-effects.ts +0 -9
  923. package/src/tools/skills/execute.ts +2 -2
  924. package/src/tools/skills/sandbox-runner.ts +6 -2
  925. package/src/tools/terminal/backends/native.ts +51 -2
  926. package/src/tools/terminal/safe-env.ts +11 -2
  927. package/src/tools/terminal/shell.ts +16 -4
  928. package/src/tools/tool-manifest.ts +6 -0
  929. package/src/tools/types.ts +29 -3
  930. package/src/tools/ui-surface/definitions.ts +6 -1
  931. package/src/tools/verification-control-plane-policy.ts +1 -1
  932. package/src/tts/__tests__/provider-adapters.test.ts +1061 -0
  933. package/src/tts/__tests__/provider-catalog-consistency.test.ts +196 -0
  934. package/src/tts/__tests__/provider-catalog.test.ts +183 -0
  935. package/src/tts/__tests__/provider-registry.test.ts +90 -0
  936. package/src/tts/provider-catalog.ts +219 -0
  937. package/src/tts/provider-registry.ts +73 -0
  938. package/src/tts/providers/deepgram-provider.ts +219 -0
  939. package/src/tts/providers/elevenlabs-provider.ts +211 -0
  940. package/src/tts/providers/fish-audio-provider.ts +183 -0
  941. package/src/tts/providers/index.ts +44 -0
  942. package/src/tts/providers/register-builtins.ts +130 -0
  943. package/src/tts/providers/xai-provider.ts +224 -0
  944. package/src/tts/synthesize-text.ts +110 -0
  945. package/src/tts/tts-config-resolver.ts +78 -0
  946. package/src/tts/types.ts +199 -0
  947. package/src/types/onboarding-context.ts +7 -0
  948. package/src/types/tar-stream.d.ts +66 -0
  949. package/src/util/abort-reasons.ts +58 -0
  950. package/src/util/device-id.ts +32 -16
  951. package/src/util/errors.ts +9 -1
  952. package/src/util/json.ts +17 -0
  953. package/src/util/platform.ts +56 -12
  954. package/src/util/pricing.ts +78 -5
  955. package/src/util/spawn.ts +1 -1
  956. package/src/util/truncate.ts +4 -2
  957. package/src/util/unicode.ts +201 -0
  958. package/src/version.ts +19 -24
  959. package/src/watcher/engine.ts +24 -1
  960. package/src/watcher/providers/google-calendar.ts +134 -8
  961. package/src/watcher/providers/outlook-calendar.ts +42 -2
  962. package/src/watcher/watcher-store.ts +31 -0
  963. package/src/workspace/git-service.ts +23 -4
  964. package/src/workspace/migrations/003-seed-device-id.ts +9 -3
  965. package/src/workspace/migrations/017-seed-persona-dirs.ts +68 -4
  966. package/src/workspace/migrations/029-seed-pkb.ts +1 -1
  967. package/src/workspace/migrations/031-drop-user-md.ts +317 -0
  968. package/src/workspace/migrations/031-llm-log-retention-zero-to-null.ts +73 -0
  969. package/src/workspace/migrations/032-tts-provider-unification.ts +227 -0
  970. package/src/workspace/migrations/033-stt-service-explicit-config.ts +122 -0
  971. package/src/workspace/migrations/034-remove-calls-voice-transcription-provider.ts +215 -0
  972. package/src/workspace/migrations/035-seed-slack-channel-persona.ts +50 -0
  973. package/src/workspace/migrations/036-update-pkb-index-bar.ts +37 -0
  974. package/src/workspace/migrations/037-create-meets-dir.ts +61 -0
  975. package/src/workspace/migrations/038-unify-llm-callsite-configs.ts +516 -0
  976. package/src/workspace/migrations/039-drop-legacy-llm-keys.ts +171 -0
  977. package/src/workspace/migrations/040-seed-latency-callsite-defaults.ts +154 -0
  978. package/src/workspace/migrations/041-backfill-google-gmail-settings-scope.ts +57 -0
  979. package/src/workspace/migrations/042-fix-backfill-google-gmail-settings-scope.ts +70 -0
  980. package/src/workspace/migrations/043-release-notes-latex-rendering.ts +75 -0
  981. package/src/workspace/migrations/044-bump-stale-provider-stream-timeout.ts +51 -0
  982. package/src/workspace/migrations/045-release-notes-meet-avatar.ts +130 -0
  983. package/src/workspace/migrations/AGENTS.md +1 -1
  984. package/src/workspace/migrations/registry.ts +32 -0
  985. package/src/workspace/provider-commit-message-generator.ts +19 -38
  986. package/src/workspace/top-level-renderer.ts +13 -1
  987. package/src/workspace/turn-commit.ts +31 -0
  988. package/src/__tests__/email-cli.test.ts +0 -297
  989. package/src/__tests__/email-service-config-fallback.test.ts +0 -102
  990. package/src/__tests__/outlook-attachments.test.ts +0 -301
  991. package/src/__tests__/outlook-automation-tools.test.ts +0 -425
  992. package/src/__tests__/outlook-categories.test.ts +0 -212
  993. package/src/__tests__/outlook-compose-tools.test.ts +0 -325
  994. package/src/__tests__/outlook-declutter-tools.test.ts +0 -585
  995. package/src/__tests__/outlook-follow-up.test.ts +0 -196
  996. package/src/__tests__/outlook-trash.test.ts +0 -77
  997. package/src/__tests__/outlook-unsubscribe.test.ts +0 -250
  998. package/src/__tests__/update-bulletin-format.test.ts +0 -122
  999. package/src/__tests__/update-bulletin-state.test.ts +0 -135
  1000. package/src/__tests__/update-bulletin.test.ts +0 -277
  1001. package/src/__tests__/update-template-contract.test.ts +0 -29
  1002. package/src/cli/commands/browser-relay.ts +0 -466
  1003. package/src/cli/commands/doctor.ts +0 -341
  1004. package/src/config/bundled-skills/browser/SKILL.md +0 -63
  1005. package/src/config/bundled-skills/browser/TOOLS.json +0 -393
  1006. package/src/config/bundled-skills/browser/tools/browser-click.ts +0 -12
  1007. package/src/config/bundled-skills/browser/tools/browser-close.ts +0 -12
  1008. package/src/config/bundled-skills/browser/tools/browser-extract.ts +0 -12
  1009. package/src/config/bundled-skills/browser/tools/browser-fill-credential.ts +0 -12
  1010. package/src/config/bundled-skills/browser/tools/browser-hover.ts +0 -12
  1011. package/src/config/bundled-skills/browser/tools/browser-navigate.ts +0 -12
  1012. package/src/config/bundled-skills/browser/tools/browser-press-key.ts +0 -12
  1013. package/src/config/bundled-skills/browser/tools/browser-screenshot.ts +0 -12
  1014. package/src/config/bundled-skills/browser/tools/browser-scroll.ts +0 -12
  1015. package/src/config/bundled-skills/browser/tools/browser-select-option.ts +0 -12
  1016. package/src/config/bundled-skills/browser/tools/browser-snapshot.ts +0 -12
  1017. package/src/config/bundled-skills/browser/tools/browser-type.ts +0 -12
  1018. package/src/config/bundled-skills/browser/tools/browser-wait-for-download.ts +0 -32
  1019. package/src/config/bundled-skills/browser/tools/browser-wait-for.ts +0 -12
  1020. package/src/config/bundled-skills/chatgpt-import/SKILL.md +0 -27
  1021. package/src/config/bundled-skills/chatgpt-import/TOOLS.json +0 -27
  1022. package/src/config/bundled-skills/chatgpt-import/tools/chatgpt-import.ts +0 -378
  1023. package/src/config/bundled-skills/gmail/SKILL.md +0 -175
  1024. package/src/config/bundled-skills/gmail/TOOLS.json +0 -558
  1025. package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +0 -149
  1026. package/src/config/bundled-skills/gmail/tools/gmail-attachments.ts +0 -112
  1027. package/src/config/bundled-skills/gmail/tools/gmail-draft.ts +0 -44
  1028. package/src/config/bundled-skills/gmail/tools/gmail-filters.ts +0 -81
  1029. package/src/config/bundled-skills/gmail/tools/gmail-follow-up.ts +0 -108
  1030. package/src/config/bundled-skills/gmail/tools/gmail-forward.ts +0 -146
  1031. package/src/config/bundled-skills/gmail/tools/gmail-label.ts +0 -53
  1032. package/src/config/bundled-skills/gmail/tools/gmail-outreach-scan.ts +0 -220
  1033. package/src/config/bundled-skills/gmail/tools/gmail-send-draft.ts +0 -26
  1034. package/src/config/bundled-skills/gmail/tools/gmail-sender-digest.ts +0 -251
  1035. package/src/config/bundled-skills/gmail/tools/gmail-trash.ts +0 -29
  1036. package/src/config/bundled-skills/gmail/tools/gmail-unsubscribe.ts +0 -122
  1037. package/src/config/bundled-skills/gmail/tools/gmail-vacation.ts +0 -67
  1038. package/src/config/bundled-skills/gmail/tools/scan-result-store.ts +0 -100
  1039. package/src/config/bundled-skills/gmail/tools/shared.ts +0 -47
  1040. package/src/config/bundled-skills/google-calendar/SKILL.md +0 -51
  1041. package/src/config/bundled-skills/google-calendar/TOOLS.json +0 -226
  1042. package/src/config/bundled-skills/google-calendar/calendar-client.ts +0 -223
  1043. package/src/config/bundled-skills/google-calendar/tools/calendar-check-availability.ts +0 -27
  1044. package/src/config/bundled-skills/google-calendar/tools/calendar-create-event.ts +0 -48
  1045. package/src/config/bundled-skills/google-calendar/tools/calendar-get-event.ts +0 -19
  1046. package/src/config/bundled-skills/google-calendar/tools/calendar-list-events.ts +0 -36
  1047. package/src/config/bundled-skills/google-calendar/tools/calendar-rsvp.ts +0 -58
  1048. package/src/config/bundled-skills/google-calendar/tools/shared.ts +0 -17
  1049. package/src/config/bundled-skills/google-calendar/types.ts +0 -97
  1050. package/src/config/bundled-skills/outlook/SKILL.md +0 -196
  1051. package/src/config/bundled-skills/outlook/TOOLS.json +0 -530
  1052. package/src/config/bundled-skills/outlook/tools/outlook-attachments.ts +0 -85
  1053. package/src/config/bundled-skills/outlook/tools/outlook-categories.ts +0 -77
  1054. package/src/config/bundled-skills/outlook/tools/outlook-draft.ts +0 -84
  1055. package/src/config/bundled-skills/outlook/tools/outlook-follow-up.ts +0 -94
  1056. package/src/config/bundled-skills/outlook/tools/outlook-forward.ts +0 -49
  1057. package/src/config/bundled-skills/outlook/tools/outlook-outreach-scan.ts +0 -237
  1058. package/src/config/bundled-skills/outlook/tools/outlook-rules.ts +0 -161
  1059. package/src/config/bundled-skills/outlook/tools/outlook-send-draft.ts +0 -32
  1060. package/src/config/bundled-skills/outlook/tools/outlook-sender-digest.ts +0 -272
  1061. package/src/config/bundled-skills/outlook/tools/outlook-trash.ts +0 -29
  1062. package/src/config/bundled-skills/outlook/tools/outlook-unsubscribe.ts +0 -129
  1063. package/src/config/bundled-skills/outlook/tools/outlook-vacation.ts +0 -87
  1064. package/src/config/bundled-skills/outlook/tools/shared.ts +0 -20
  1065. package/src/config/bundled-skills/outlook-calendar/SKILL.md +0 -51
  1066. package/src/config/bundled-skills/outlook-calendar/TOOLS.json +0 -221
  1067. package/src/config/bundled-skills/outlook-calendar/calendar-client.ts +0 -252
  1068. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-check-availability.ts +0 -53
  1069. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-create-event.ts +0 -74
  1070. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-get-event.ts +0 -18
  1071. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-list-events.ts +0 -46
  1072. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-rsvp.ts +0 -36
  1073. package/src/config/bundled-skills/outlook-calendar/tools/shared.ts +0 -17
  1074. package/src/config/bundled-skills/outlook-calendar/types.ts +0 -120
  1075. package/src/config/bundled-skills/slack/SKILL.md +0 -107
  1076. package/src/config/bundled-skills/tasks/SKILL.md +0 -37
  1077. package/src/config/bundled-skills/tasks/TOOLS.json +0 -353
  1078. package/src/config/bundled-skills/tasks/icon.svg +0 -34
  1079. package/src/config/bundled-skills/tasks/tools/task-delete.ts +0 -12
  1080. package/src/config/bundled-skills/tasks/tools/task-list-add.ts +0 -12
  1081. package/src/config/bundled-skills/tasks/tools/task-list-remove.ts +0 -12
  1082. package/src/config/bundled-skills/tasks/tools/task-list-show.ts +0 -12
  1083. package/src/config/bundled-skills/tasks/tools/task-list-update.ts +0 -12
  1084. package/src/config/bundled-skills/tasks/tools/task-list.ts +0 -12
  1085. package/src/config/bundled-skills/tasks/tools/task-queue-run.ts +0 -12
  1086. package/src/config/bundled-skills/tasks/tools/task-run.ts +0 -12
  1087. package/src/config/bundled-skills/tasks/tools/task-save.ts +0 -12
  1088. package/src/config/bundled-skills/watcher/SKILL.md +0 -31
  1089. package/src/config/bundled-skills/watcher/TOOLS.json +0 -167
  1090. package/src/config/bundled-skills/watcher/tools/watcher-create.ts +0 -12
  1091. package/src/config/bundled-skills/watcher/tools/watcher-delete.ts +0 -12
  1092. package/src/config/bundled-skills/watcher/tools/watcher-digest.ts +0 -12
  1093. package/src/config/bundled-skills/watcher/tools/watcher-list.ts +0 -12
  1094. package/src/config/bundled-skills/watcher/tools/watcher-update.ts +0 -12
  1095. package/src/email/guardrails.ts +0 -221
  1096. package/src/email/provider.ts +0 -117
  1097. package/src/email/providers/agentmail.ts +0 -361
  1098. package/src/email/providers/index.ts +0 -65
  1099. package/src/email/service.ts +0 -384
  1100. package/src/email/types.ts +0 -126
  1101. package/src/prompts/templates/UPDATES.md +0 -38
  1102. package/src/prompts/templates/USER.md +0 -13
  1103. package/src/prompts/update-bulletin-format.ts +0 -68
  1104. package/src/prompts/update-bulletin-state.ts +0 -58
  1105. package/src/prompts/update-bulletin-template-path.ts +0 -13
  1106. package/src/prompts/update-bulletin.ts +0 -128
  1107. package/src/providers/speech-to-text/types.ts +0 -17
  1108. package/src/runtime/routes/browser-cdp-routes.ts +0 -229
  1109. package/src/shared/provider-env-vars.ts +0 -19
  1110. package/src/tools/watcher/create.ts +0 -86
  1111. package/src/tools/watcher/delete.ts +0 -36
  1112. package/src/tools/watcher/digest.ts +0 -54
  1113. package/src/tools/watcher/list.ts +0 -83
  1114. package/src/tools/watcher/update.ts +0 -71
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Route handlers for conversation messages and suggestions.
3
3
  */
4
- import { existsSync, readdirSync, statSync } from "node:fs";
4
+ import { existsSync, readdirSync, statSync, writeFileSync } from "node:fs";
5
5
  import { join, relative } from "node:path";
6
6
 
7
7
  import { z } from "zod";
@@ -12,8 +12,10 @@ import {
12
12
  createUserMessage,
13
13
  } from "../../agent/message-types.js";
14
14
  import {
15
+ canServiceRegistryBrowser,
15
16
  CHANNEL_IDS,
16
17
  INTERFACE_IDS,
18
+ type InterfaceId,
17
19
  isInteractiveInterface,
18
20
  parseChannelId,
19
21
  parseInterfaceId,
@@ -21,6 +23,7 @@ import {
21
23
  } from "../../channels/types.js";
22
24
  import { isHttpAuthDisabled } from "../../config/env.js";
23
25
  import { getConfig } from "../../config/loader.js";
26
+ import type { Conversation } from "../../daemon/conversation.js";
24
27
  import {
25
28
  buildModelInfoEvent,
26
29
  formatCompactResult,
@@ -45,6 +48,10 @@ import type {
45
48
  NonHostProxyTransportMetadata,
46
49
  } from "../../daemon/message-types/conversations.js";
47
50
  import type { HeartbeatService } from "../../heartbeat/heartbeat-service.js";
51
+ import {
52
+ writeOnboardingSidecar,
53
+ writeRelationshipState,
54
+ } from "../../home/relationship-state-writer.js";
48
55
  import * as attachmentsStore from "../../memory/attachments-store.js";
49
56
  import {
50
57
  createCanonicalGuardianRequest,
@@ -58,6 +65,7 @@ import {
58
65
  getLastAssistantTimestampBefore,
59
66
  getMessages,
60
67
  getMessagesPaginated,
68
+ hasMessages,
61
69
  type MessageRow,
62
70
  provenanceFromTrustContext,
63
71
  setConversationOriginChannelIfUnset,
@@ -74,6 +82,7 @@ import { checkIngressForSecrets } from "../../security/secret-ingress.js";
74
82
  import { redactSecrets } from "../../security/secret-scanner.js";
75
83
  import { summarizeToolInput } from "../../tools/tool-input-summary.js";
76
84
  import { getLogger } from "../../util/logger.js";
85
+ import { getWorkspacePromptPath } from "../../util/platform.js";
77
86
  import { silentlyWithLog } from "../../util/silently.js";
78
87
  import { buildAssistantEvent } from "../assistant-event.js";
79
88
  import { DAEMON_INTERNAL_ASSISTANT_ID } from "../assistant-scope.js";
@@ -107,7 +116,7 @@ const SUGGESTION_CACHE_MAX = 100;
107
116
  function collectCanonicalGuardianRequestHintIds(
108
117
  conversationId: string,
109
118
  sourceChannel: string,
110
- conversation: import("../../daemon/conversation.js").Conversation,
119
+ conversation: Conversation,
111
120
  ): string[] {
112
121
  const requests = listPendingRequestsByConversationScope(
113
122
  conversationId,
@@ -172,7 +181,7 @@ async function tryConsumeCanonicalGuardianReply(params: {
172
181
  data: string;
173
182
  filePath?: string;
174
183
  }>;
175
- conversation: import("../../daemon/conversation.js").Conversation;
184
+ conversation: Conversation;
176
185
  onEvent: (msg: ServerMessage) => void;
177
186
  approvalConversationGenerator?: ApprovalConversationGenerator;
178
187
  /** Verified actor identity from actor-token middleware. */
@@ -967,7 +976,7 @@ function mergeConsecutiveAssistantMessages(messages: MessageRow[]): {
967
976
  function makeHubPublisher(
968
977
  deps: SendMessageDeps,
969
978
  conversationId: string,
970
- conversation: import("../../daemon/conversation.js").Conversation,
979
+ conversation: Conversation,
971
980
  ): (msg: ServerMessage) => void {
972
981
  let hubChain: Promise<void> = Promise.resolve();
973
982
  return (msg: ServerMessage) => {
@@ -1048,30 +1057,8 @@ function makeHubPublisher(
1048
1057
  conversationId,
1049
1058
  kind: "secret",
1050
1059
  });
1051
- } else if (msg.type === "host_bash_request") {
1052
- pendingInteractions.register(msg.requestId, {
1053
- conversation,
1054
- conversationId,
1055
- kind: "host_bash",
1056
- });
1057
- } else if (msg.type === "host_browser_request") {
1058
- pendingInteractions.register(msg.requestId, {
1059
- conversation,
1060
- conversationId,
1061
- kind: "host_browser",
1062
- });
1063
- } else if (msg.type === "host_file_request") {
1064
- pendingInteractions.register(msg.requestId, {
1065
- conversation,
1066
- conversationId,
1067
- kind: "host_file",
1068
- });
1069
- } else if (msg.type === "host_cu_request") {
1070
- pendingInteractions.register(msg.requestId, {
1071
- conversation,
1072
- conversationId,
1073
- kind: "host_cu",
1074
- });
1060
+ } else {
1061
+ registerHostProxyPendingInteraction(msg, conversation, conversationId);
1075
1062
  }
1076
1063
 
1077
1064
  // ServerMessage is a large union; conversationId exists on most but not all variants.
@@ -1080,7 +1067,20 @@ function makeHubPublisher(
1080
1067
  typeof (msg as { conversationId?: unknown }).conversationId === "string"
1081
1068
  ? (msg as { conversationId: string }).conversationId
1082
1069
  : undefined;
1083
- const resolvedConversationId = msgConversationId ?? conversationId;
1070
+ // `conversation_list_invalidated` is a list-level system event: it
1071
+ // describes no particular conversation and every connected client
1072
+ // should refresh its sidebar. Publish it unscoped so the SSE hub does
1073
+ // not filter it out by the subscriber's `filter.conversationId`.
1074
+ // Other events (including `conversation_title_updated`) stay scoped to
1075
+ // their conversation — unscoped scoped-events would leak foreign
1076
+ // `conversationId` values to native clients' speculative ID-resolution
1077
+ // path. For `conversation_title_updated` we instead enqueue a matching
1078
+ // unscoped `conversation_list_invalidated` below so other clients'
1079
+ // sidebars can refresh and pick up the new title.
1080
+ const resolvedConversationId =
1081
+ msg.type === "conversation_list_invalidated"
1082
+ ? undefined
1083
+ : (msgConversationId ?? conversationId);
1084
1084
  const event = buildAssistantEvent(
1085
1085
  DAEMON_INTERNAL_ASSISTANT_ID,
1086
1086
  msg,
@@ -1096,10 +1096,229 @@ function makeHubPublisher(
1096
1096
  "assistant-events hub subscriber threw during POST /messages",
1097
1097
  );
1098
1098
  }
1099
+
1100
+ // When the agent loop auto-generates a conversation title, also
1101
+ // broadcast an unscoped `conversation_list_invalidated` so every
1102
+ // connected client's sidebar can refresh and pick up the new title.
1103
+ // Without this, clients viewing other conversations (or a draft)
1104
+ // would never learn that the title for this conversation changed.
1105
+ // The scoped `conversation_title_updated` above still handles the
1106
+ // in-place update for the client currently viewing this conversation.
1107
+ if (msg.type === "conversation_title_updated") {
1108
+ try {
1109
+ await deps.assistantEventHub.publish(
1110
+ buildAssistantEvent(DAEMON_INTERNAL_ASSISTANT_ID, {
1111
+ type: "conversation_list_invalidated",
1112
+ reason: "renamed",
1113
+ }),
1114
+ );
1115
+ } catch (err) {
1116
+ log.warn(
1117
+ { err },
1118
+ "Failed to publish conversation_list_invalidated after title update",
1119
+ );
1120
+ }
1121
+ }
1099
1122
  })();
1100
1123
  };
1101
1124
  }
1102
1125
 
1126
+ /**
1127
+ * Register pending interactions for host proxy request envelopes so
1128
+ * standalone result endpoints can resolve by requestId.
1129
+ *
1130
+ * Returns the registered requestId when a host proxy request was registered.
1131
+ * Callers that route through non-hub transports (e.g. registry-routed
1132
+ * host_browser sends) can use this to clean up the registration if send fails.
1133
+ */
1134
+ function registerHostProxyPendingInteraction(
1135
+ msg: ServerMessage,
1136
+ conversation: Conversation,
1137
+ conversationId: string,
1138
+ ): string | undefined {
1139
+ if (msg.type === "host_bash_request") {
1140
+ pendingInteractions.register(msg.requestId, {
1141
+ conversation,
1142
+ conversationId,
1143
+ kind: "host_bash",
1144
+ });
1145
+ return msg.requestId;
1146
+ }
1147
+ if (msg.type === "host_browser_request") {
1148
+ pendingInteractions.register(msg.requestId, {
1149
+ conversation,
1150
+ conversationId,
1151
+ kind: "host_browser",
1152
+ });
1153
+ return msg.requestId;
1154
+ }
1155
+ if (msg.type === "host_file_request") {
1156
+ pendingInteractions.register(msg.requestId, {
1157
+ conversation,
1158
+ conversationId,
1159
+ kind: "host_file",
1160
+ });
1161
+ return msg.requestId;
1162
+ }
1163
+ if (msg.type === "host_cu_request") {
1164
+ pendingInteractions.register(msg.requestId, {
1165
+ conversation,
1166
+ conversationId,
1167
+ kind: "host_cu",
1168
+ });
1169
+ return msg.requestId;
1170
+ }
1171
+ return undefined;
1172
+ }
1173
+
1174
+ /**
1175
+ * Resolve the host_browser sender function for a conversation turn.
1176
+ *
1177
+ * When the guardian has an active extension connection in the
1178
+ * ChromeExtensionRegistry, returns a registry-routed sender that forwards
1179
+ * `host_browser_request` / `host_browser_cancel` frames through the
1180
+ * WebSocket to the connected extension. Otherwise returns the SSE hub
1181
+ * emitter (`onEvent`).
1182
+ *
1183
+ * For `chrome-extension` turns the registry sender is **always** returned
1184
+ * regardless of the POST-time connection check. The chrome-extension
1185
+ * interface has no SSE consumer for `host_browser_request` frames, so
1186
+ * falling back to `onEvent` would cause CDP calls to stall until the proxy
1187
+ * timeout (30 s) instead of failing immediately at send time when the
1188
+ * registry throws on a missing connection.
1189
+ *
1190
+ * This helper is interface-agnostic: both chrome-extension and macOS turns
1191
+ * can obtain a registry-routed sender when extension connectivity exists.
1192
+ * The `isRegistryRouted` flag lets the caller decide whether to set
1193
+ * `hostBrowserSenderOverride` and whether to provision a `HostBrowserProxy`
1194
+ * for interfaces that don't statically support host_browser (e.g. macOS).
1195
+ */
1196
+ function resolveHostBrowserSender(
1197
+ conversation: Conversation,
1198
+ conversationId: string,
1199
+ authContext: AuthContext,
1200
+ onEvent: (msg: ServerMessage) => void,
1201
+ sourceInterface: InterfaceId,
1202
+ ): { sender: (msg: ServerMessage) => void; isRegistryRouted: boolean } {
1203
+ // Check whether the guardian has any active extension connection.
1204
+ const guardianId =
1205
+ conversation.trustContext?.guardianPrincipalId ??
1206
+ authContext.actorPrincipalId;
1207
+ const hasExtensionConnection =
1208
+ !!guardianId && !!getChromeExtensionRegistry().get(guardianId);
1209
+
1210
+ // For chrome-extension, always use the registry sender so that send-time
1211
+ // failures produce immediate errors rather than 30-second proxy timeouts.
1212
+ // The SSE hub has no extension consumer, so falling back to onEvent is
1213
+ // never correct for this interface.
1214
+ if (!hasExtensionConnection && sourceInterface !== "chrome-extension") {
1215
+ return { sender: onEvent, isRegistryRouted: false };
1216
+ }
1217
+
1218
+ // Build a registry-routed sender. The guardian principal ID is resolved
1219
+ // at send time rather than captured here so that queue-drain restores
1220
+ // (which re-fire this closure outside the original POST context) follow
1221
+ // the conversation's bound guardian identity rather than a stale
1222
+ // authContext.actorPrincipalId.
1223
+ const registrySender = (msg: ServerMessage): void => {
1224
+ const requestId = registerHostProxyPendingInteraction(
1225
+ msg,
1226
+ conversation,
1227
+ conversationId,
1228
+ );
1229
+ const gid =
1230
+ conversation.trustContext?.guardianPrincipalId ??
1231
+ authContext.actorPrincipalId;
1232
+ if (!gid) {
1233
+ if (requestId) pendingInteractions.resolve(requestId);
1234
+ throw new Error(
1235
+ "host_browser send skipped: no guardianId on AuthContext",
1236
+ );
1237
+ }
1238
+ const ok = getChromeExtensionRegistry().send(gid, msg);
1239
+ if (!ok) {
1240
+ if (requestId) pendingInteractions.resolve(requestId);
1241
+ throw new Error(
1242
+ `host_browser send failed: no active connection for guardian ${gid}`,
1243
+ );
1244
+ }
1245
+ };
1246
+
1247
+ return { sender: registrySender, isRegistryRouted: true };
1248
+ }
1249
+
1250
+ /**
1251
+ * Persist the pre-chat onboarding payload to disk.
1252
+ *
1253
+ * Runs only on the very first message of a fresh conversation. Three
1254
+ * artifacts are produced:
1255
+ *
1256
+ * 1. `data/onboarding-context.json` — sidecar read by the
1257
+ * relationship-state writer so onboarding-sourced facts survive
1258
+ * the pure-recomputation write cycle (every turn boundary rebuilds
1259
+ * facts from markdown; the sidecar is the durable source for the
1260
+ * tool/task/tone chips).
1261
+ * 2. `IDENTITY.md` / `USER.md` — persona seed files, only written
1262
+ * when missing so we never clobber existing content. These feed
1263
+ * the system prompt and the relationship-state writer's
1264
+ * `parseIdentity` / `parseUserName` helpers after a daemon
1265
+ * restart when the in-memory onboarding context is gone.
1266
+ * 3. `data/relationship-state.json` — kicked off fire-and-forget so
1267
+ * the Home page can populate immediately on first visit instead
1268
+ * of waiting for the first agent-turn boundary.
1269
+ *
1270
+ * Never throws: every write is guarded and logged as a warning on
1271
+ * failure. The route handler path must never reject because of a
1272
+ * best-effort persistence step.
1273
+ */
1274
+ function persistOnboardingArtifacts(onboarding: {
1275
+ tools: string[];
1276
+ tasks: string[];
1277
+ tone: string;
1278
+ userName?: string;
1279
+ assistantName?: string;
1280
+ }): void {
1281
+ writeOnboardingSidecar(onboarding);
1282
+
1283
+ const assistantName = onboarding.assistantName?.trim();
1284
+ if (assistantName) {
1285
+ const identityPath = getWorkspacePromptPath("IDENTITY.md");
1286
+ if (!existsSync(identityPath)) {
1287
+ try {
1288
+ writeFileSync(
1289
+ identityPath,
1290
+ `# Identity\n\n- Name: ${assistantName}\n`,
1291
+ "utf-8",
1292
+ );
1293
+ } catch (err) {
1294
+ log.warn(
1295
+ { err, identityPath },
1296
+ "Failed to seed IDENTITY.md from onboarding",
1297
+ );
1298
+ }
1299
+ }
1300
+ }
1301
+
1302
+ const userName = onboarding.userName?.trim();
1303
+ if (userName) {
1304
+ const userPath = getWorkspacePromptPath("USER.md");
1305
+ if (!existsSync(userPath)) {
1306
+ try {
1307
+ writeFileSync(userPath, `# User\n\n- Name: ${userName}\n`, "utf-8");
1308
+ } catch (err) {
1309
+ log.warn({ err, userPath }, "Failed to seed USER.md from onboarding");
1310
+ }
1311
+ }
1312
+ }
1313
+
1314
+ void writeRelationshipState().catch((err) => {
1315
+ log.warn(
1316
+ { err },
1317
+ "Failed to kick off relationship-state write after onboarding",
1318
+ );
1319
+ });
1320
+ }
1321
+
1103
1322
  export async function handleSendMessage(
1104
1323
  req: Request,
1105
1324
  deps: {
@@ -1120,9 +1339,19 @@ export async function handleSendMessage(
1120
1339
  bypassSecretCheck?: boolean;
1121
1340
  hostHomeDir?: string;
1122
1341
  hostUsername?: string;
1342
+ clientMessageId?: string;
1343
+ onboarding?: {
1344
+ tools: string[];
1345
+ tasks: string[];
1346
+ tone: string;
1347
+ userName?: string;
1348
+ assistantName?: string;
1349
+ };
1123
1350
  };
1124
1351
 
1125
1352
  const { conversationKey, content, attachmentIds } = body;
1353
+ const clientMessageId =
1354
+ typeof body.clientMessageId === "string" ? body.clientMessageId : undefined;
1126
1355
  if (!body.sourceChannel || typeof body.sourceChannel !== "string") {
1127
1356
  return httpError("BAD_REQUEST", "sourceChannel is required", 400);
1128
1357
  }
@@ -1222,8 +1451,32 @@ export async function handleSendMessage(
1222
1451
  const mapping = getOrCreateConversation(resolvedConversationKey, {
1223
1452
  conversationType,
1224
1453
  });
1454
+
1225
1455
  const smDeps = deps.sendMessageDeps;
1226
1456
 
1457
+ // Notify all connected clients that the conversation list changed when
1458
+ // this is the first message in a standard conversation, so sidebars on
1459
+ // other devices can refresh. We check for first-message rather than
1460
+ // first-create because the SSE subscribe handler (events-routes.ts) may
1461
+ // have already materialised the conversation from a draft key before any
1462
+ // message was sent — in that case `mapping.created` is `false` even
1463
+ // though, from the user's perspective, this is a brand-new conversation
1464
+ // that other clients don't yet know about.
1465
+ if (mapping.conversationType === "standard") {
1466
+ if (!hasMessages(mapping.conversationId)) {
1467
+ smDeps.assistantEventHub
1468
+ .publish(
1469
+ buildAssistantEvent(DAEMON_INTERNAL_ASSISTANT_ID, {
1470
+ type: "conversation_list_invalidated",
1471
+ reason: "created",
1472
+ }),
1473
+ )
1474
+ .catch((err) => {
1475
+ log.warn({ err }, "Failed to publish conversation_list_invalidated");
1476
+ });
1477
+ }
1478
+ }
1479
+
1227
1480
  // Build transport metadata from the request so the daemon can inject
1228
1481
  // host environment hints (home directory, username) into the LLM context.
1229
1482
  // The `supportsHostProxy` type predicate narrows `sourceInterface` to
@@ -1247,6 +1500,17 @@ export async function handleSendMessage(
1247
1500
  { transport },
1248
1501
  );
1249
1502
 
1503
+ // Store pre-chat onboarding context on the conversation when this is the
1504
+ // very first message (no prior messages loaded). Also persist the
1505
+ // onboarding selections so the Home page shows onboarding-sourced
1506
+ // chips immediately, and seed IDENTITY.md / USER.md so subsequent
1507
+ // turn-boundary recomputes of relationship-state have a stable
1508
+ // persona source beyond the in-memory conversation object.
1509
+ if (body.onboarding && conversation.messages.length === 0) {
1510
+ conversation.setOnboardingContext(body.onboarding);
1511
+ persistOnboardingArtifacts(body.onboarding);
1512
+ }
1513
+
1250
1514
  // Resolve guardian context from the AuthContext's actorPrincipalId.
1251
1515
  // The JWT-verified principal is used as the sender identity through
1252
1516
  // the same trust resolution pipeline that channel ingress uses.
@@ -1328,66 +1592,44 @@ export async function handleSendMessage(
1328
1592
  } else if (!conversation.isProcessing()) {
1329
1593
  conversation.setHostBashProxy(undefined);
1330
1594
  }
1331
- // For the chrome-extension interface we route host_browser_request /
1332
- // host_browser_cancel frames through the in-process ChromeExtensionRegistry
1333
- // to the WebSocket opened against /v1/browser-relay by the connected
1334
- // extension, instead of the SSE/onEvent hub used by macOS. The registry
1335
- // lookup is keyed by the JWT-derived actor principal id, which the
1336
- // runtime captured at WebSocket upgrade time.
1337
- //
1338
- // A single guardian may have multiple parallel extension installs
1339
- // connected at once (two Chrome profiles, two desktops). The registry
1340
- // tracks them under (guardianId, clientInstanceId) pairs and the
1341
- // default `send(guardianId, msg)` path routes to whichever instance
1342
- // has the most recent activity — typically the one the user is
1343
- // currently driving. Pinning to a specific instance can be done via
1344
- // `sendToInstance` if a caller ever needs it.
1345
- //
1346
- // macOS (and any other interface that supports host_browser in the
1347
- // future via the SSE hub) keeps using `onEvent` — see the else branch.
1348
- const browserProxySendToClient: (msg: ServerMessage) => void =
1349
- sourceInterface === "chrome-extension"
1350
- ? (msg) => {
1351
- // Resolve the guardian principal id at send time rather than
1352
- // capturing it from the POST-time authContext. This closure can be
1353
- // re-fired on queue drain — if a different actor's POST lands while
1354
- // the queue is still draining an earlier turn, a captured
1355
- // authContext.actorPrincipalId would mis-route the earlier turn's
1356
- // host_browser frames to the *new* actor. Preferring
1357
- // conversation.trustContext?.guardianPrincipalId makes the routing
1358
- // follow the conversation's bound guardian, which is stable across
1359
- // subsequent POSTs. Falls back to the per-POST authContext for
1360
- // turns that haven't been bound to a trust context yet.
1361
- const gid =
1362
- conversation.trustContext?.guardianPrincipalId ??
1363
- authContext.actorPrincipalId;
1364
- if (!gid) {
1365
- // No guardian identity on this turn — nothing to route to.
1366
- // The proxy will observe this via its try/catch and surface a
1367
- // transport error back to the caller.
1368
- throw new Error(
1369
- "chrome-extension host_browser send skipped: no guardianId on AuthContext",
1370
- );
1371
- }
1372
- const ok = getChromeExtensionRegistry().send(gid, msg);
1373
- if (!ok) {
1374
- throw new Error(
1375
- `chrome-extension host_browser send failed: no active connection for guardian ${gid}`,
1376
- );
1377
- }
1378
- }
1379
- : onEvent;
1595
+ // Resolve the host_browser sender — registry-routed when the guardian has
1596
+ // an active extension connection, SSE hub otherwise. This applies to both
1597
+ // chrome-extension and macOS interfaces so that macOS turns can route
1598
+ // browser automation through the user's real Chrome session when available.
1599
+ const { sender: browserProxySendToClient, isRegistryRouted } =
1600
+ resolveHostBrowserSender(
1601
+ conversation,
1602
+ mapping.conversationId,
1603
+ authContext,
1604
+ onEvent,
1605
+ sourceInterface,
1606
+ );
1607
+
1380
1608
  // Stash the registry-routed sender on the conversation so queue-drain
1381
1609
  // restores (which run outside of conversation-routes.ts and only have
1382
1610
  // access to `sendToClient`) can preserve it when calling
1383
- // `restoreBrowserProxyAvailability()`. For non-chrome-extension
1384
- // interfaces the override is cleared so the SSE hub sender is used.
1385
- if (sourceInterface === "chrome-extension") {
1611
+ // `restoreBrowserProxyAvailability()`. The override is set when the
1612
+ // sender is registry-routed (regardless of interface) and cleared when
1613
+ // the SSE hub sender is used, so the drain path always restores the
1614
+ // correct transport.
1615
+ if (isRegistryRouted) {
1386
1616
  conversation.hostBrowserSenderOverride = browserProxySendToClient;
1387
1617
  } else {
1388
1618
  conversation.hostBrowserSenderOverride = undefined;
1389
1619
  }
1390
- if (supportsHostProxy(sourceInterface, "host_browser")) {
1620
+
1621
+ // Provision the host browser proxy. For interfaces that natively support
1622
+ // host_browser (chrome-extension), always provision it. For macOS, the
1623
+ // static capability check returns false (supportsHostProxy("macos",
1624
+ // "host_browser") === false) because the extension isn't guaranteed to be
1625
+ // attached — but when the registry confirms an active extension
1626
+ // connection, we provision the proxy anyway so macOS turns can drive the
1627
+ // user's real Chrome session. When no extension is connected, macOS skips
1628
+ // provisioning and browser tools fall through to cdp-inspect/local.
1629
+ const shouldProvisionBrowserProxy =
1630
+ supportsHostProxy(sourceInterface, "host_browser") ||
1631
+ (canServiceRegistryBrowser(sourceInterface) && isRegistryRouted);
1632
+ if (shouldProvisionBrowserProxy) {
1391
1633
  if (!conversation.isProcessing() || !conversation.hostBrowserProxy) {
1392
1634
  const browserProxy = new HostBrowserProxy(
1393
1635
  browserProxySendToClient,
@@ -1445,18 +1687,17 @@ export async function handleSendMessage(
1445
1687
  conversation.updateClient(onEvent, !isInteractive, {
1446
1688
  skipProxySenderUpdate: preservingProxies,
1447
1689
  });
1448
- // For non-interactive interfaces that DO support host_browser
1449
- // (chrome-extension), explicitly re-enable just the browser proxy. The
1450
- // helper bypasses the `hasNoClient` gate so the single-capability
1451
- // chrome-extension turn can drive the browser via CDP without leaking
1452
- // host_bash/host_file tool availability into tool gating.
1690
+ // Re-enable the browser proxy for turns that provisioned one. This covers:
1691
+ // - chrome-extension: natively supports host_browser (non-interactive but
1692
+ // has a connected client for host_browser_request events)
1693
+ // - macOS with extension: provisioned above when isRegistryRouted is true
1453
1694
  //
1454
- // `restoreBrowserProxyAvailability()` reads `hostBrowserSenderOverride`
1455
- // (set above for chrome-extension) and applies the registry-routed
1456
- // sender, so the chrome-extension path gets the correct sender here
1457
- // including after queue-drain restores run from conversation-process.ts,
1458
- // which only have access to the conversation instance.
1459
- if (supportsHostProxy(sourceInterface, "host_browser")) {
1695
+ // The helper bypasses the `hasNoClient` gate so chrome-extension turns can
1696
+ // drive the browser via CDP without leaking host_bash/host_file tool
1697
+ // availability. It reads `hostBrowserSenderOverride` (set above when
1698
+ // registry-routed) and applies the correct sender including after
1699
+ // queue-drain restores run from conversation-process.ts.
1700
+ if (shouldProvisionBrowserProxy) {
1460
1701
  conversation.restoreBrowserProxyAvailability?.();
1461
1702
  }
1462
1703
 
@@ -1522,6 +1763,13 @@ export async function handleSendMessage(
1522
1763
  // fast path) so the HTTP response reaches the client before SSE
1523
1764
  // events arrive.
1524
1765
  setTimeout(() => {
1766
+ onEvent({
1767
+ type: "user_message_echo",
1768
+ text: rawContent,
1769
+ conversationId,
1770
+ messageId: persisted.id,
1771
+ clientMessageId,
1772
+ });
1525
1773
  onEvent({ type: "assistant_text_delta", text: cannedGreeting });
1526
1774
  onEvent({ type: "message_complete", conversationId });
1527
1775
  conversation.processing = false;
@@ -1618,6 +1866,7 @@ export async function handleSendMessage(
1618
1866
  { isInteractive },
1619
1867
  undefined, // displayContent
1620
1868
  transport,
1869
+ clientMessageId,
1621
1870
  );
1622
1871
  if (enqueueResult.rejected) {
1623
1872
  return Response.json(
@@ -1730,9 +1979,9 @@ export async function handleSendMessage(
1730
1979
  messageCount: conversation.getMessages().length,
1731
1980
  inputTokens: conversation.usageStats.inputTokens,
1732
1981
  outputTokens: conversation.usageStats.outputTokens,
1733
- maxInputTokens: config.contextWindow.maxInputTokens,
1734
- model: config.services.inference.model,
1735
- provider: config.services.inference.provider,
1982
+ maxInputTokens: config.llm.default.contextWindow.maxInputTokens,
1983
+ model: config.llm.default.model,
1984
+ provider: config.llm.default.provider,
1736
1985
  estimatedCost: conversation.usageStats.estimatedCost,
1737
1986
  userMessageInterface: sourceInterface,
1738
1987
  };
@@ -1815,6 +2064,13 @@ export async function handleSendMessage(
1815
2064
  const conversationId = mapping.conversationId;
1816
2065
  const message = slashResult.message;
1817
2066
  setTimeout(() => {
2067
+ onEvent({
2068
+ type: "user_message_echo",
2069
+ text: rawContent,
2070
+ conversationId,
2071
+ messageId: persisted.id,
2072
+ clientMessageId,
2073
+ });
1818
2074
  if (modelInfoEvent) {
1819
2075
  onEvent(modelInfoEvent);
1820
2076
  }
@@ -1841,80 +2097,89 @@ export async function handleSendMessage(
1841
2097
 
1842
2098
  if (slashResult.kind === "compact") {
1843
2099
  conversation.processing = true;
1844
- let cleanupDeferred = false;
1845
- try {
1846
- const provenance = provenanceFromTrustContext(conversation.trustContext);
1847
- const channelMeta = {
1848
- ...provenance,
1849
- userMessageChannel: sourceChannel,
1850
- assistantMessageChannel: sourceChannel,
1851
- userMessageInterface: sourceInterface,
1852
- assistantMessageInterface: sourceInterface,
1853
- };
1854
- const cleanMsg = createUserMessage(rawContent, attachments);
1855
- const persisted = await addMessage(
1856
- mapping.conversationId,
1857
- "user",
1858
- JSON.stringify(cleanMsg.content),
1859
- channelMeta,
1860
- );
1861
- conversation.getMessages().push(cleanMsg);
1862
-
1863
- conversation.emitActivityState(
1864
- "thinking",
1865
- "context_compacting",
1866
- "assistant_turn",
1867
- );
1868
- const result = await conversation.forceCompact();
1869
- const responseText = formatCompactResult(result);
2100
+ const provenance = provenanceFromTrustContext(conversation.trustContext);
2101
+ const channelMeta = {
2102
+ ...provenance,
2103
+ userMessageChannel: sourceChannel,
2104
+ assistantMessageChannel: sourceChannel,
2105
+ userMessageInterface: sourceInterface,
2106
+ assistantMessageInterface: sourceInterface,
2107
+ };
2108
+ const cleanMsg = createUserMessage(rawContent, attachments);
2109
+ const persisted = await addMessage(
2110
+ mapping.conversationId,
2111
+ "user",
2112
+ JSON.stringify(cleanMsg.content),
2113
+ channelMeta,
2114
+ );
2115
+ conversation.getMessages().push(cleanMsg);
1870
2116
 
1871
- const assistantMsg = createAssistantMessage(responseText);
1872
- await addMessage(
1873
- mapping.conversationId,
1874
- "assistant",
1875
- JSON.stringify(assistantMsg.content),
1876
- channelMeta,
1877
- );
1878
- conversation.getMessages().push(assistantMsg);
2117
+ const conversationId = mapping.conversationId;
1879
2118
 
1880
- const response = Response.json(
1881
- {
1882
- accepted: true,
2119
+ // Fire-and-forget: return 202 immediately, run compaction async.
2120
+ // forceCompact() makes an LLM call that can exceed the client's
2121
+ // HTTP timeout on large contexts, causing a false "Failed to send".
2122
+ (async () => {
2123
+ try {
2124
+ onEvent({
2125
+ type: "user_message_echo",
2126
+ text: rawContent,
2127
+ conversationId,
1883
2128
  messageId: persisted.id,
1884
- conversationId: mapping.conversationId,
1885
- },
1886
- { status: 202 },
1887
- );
2129
+ clientMessageId,
2130
+ });
2131
+ conversation.emitActivityState(
2132
+ "thinking",
2133
+ "context_compacting",
2134
+ "assistant_turn",
2135
+ );
2136
+ const result = await conversation.forceCompact();
2137
+ const responseText = formatCompactResult(result);
2138
+
2139
+ const assistantMsg = createAssistantMessage(responseText);
2140
+ await addMessage(
2141
+ conversationId,
2142
+ "assistant",
2143
+ JSON.stringify(assistantMsg.content),
2144
+ channelMeta,
2145
+ );
2146
+ conversation.getMessages().push(assistantMsg);
1888
2147
 
1889
- const conversationId = mapping.conversationId;
1890
- setTimeout(() => {
1891
2148
  onEvent({ type: "assistant_text_delta", text: responseText });
2149
+ onEvent({ type: "message_complete", conversationId });
2150
+ } catch (err) {
2151
+ log.error({ err, conversationId }, "Compact command failed");
1892
2152
  onEvent({
1893
- type: "message_complete",
2153
+ type: "conversation_error",
1894
2154
  conversationId,
2155
+ code: "UNKNOWN",
2156
+ userMessage: `Compaction failed: ${err instanceof Error ? err.message : String(err)}`,
2157
+ retryable: true,
1895
2158
  });
2159
+ } finally {
1896
2160
  conversation.processing = false;
1897
2161
  silentlyWithLog(
1898
2162
  conversation.drainQueue(),
1899
2163
  "compact-command queue drain",
1900
2164
  );
1901
- }, 0);
1902
-
1903
- cleanupDeferred = true;
1904
- return response;
1905
- } finally {
1906
- if (!cleanupDeferred && conversation.processing) {
1907
- conversation.processing = false;
1908
- silentlyWithLog(conversation.drainQueue(), "error-path queue drain");
1909
2165
  }
1910
- }
2166
+ })();
2167
+
2168
+ return Response.json(
2169
+ {
2170
+ accepted: true,
2171
+ messageId: persisted.id,
2172
+ conversationId,
2173
+ },
2174
+ { status: 202 },
2175
+ );
1911
2176
  }
1912
2177
 
1913
2178
  const resolvedContent = slashResult.content;
1914
2179
 
2180
+ const requestId = crypto.randomUUID();
1915
2181
  let messageId: string;
1916
2182
  try {
1917
- const requestId = crypto.randomUUID();
1918
2183
  messageId = await conversation.persistUserMessage(
1919
2184
  resolvedContent,
1920
2185
  attachments,
@@ -1925,6 +2190,15 @@ export async function handleSendMessage(
1925
2190
  throw err;
1926
2191
  }
1927
2192
 
2193
+ onEvent({
2194
+ type: "user_message_echo",
2195
+ text: resolvedContent,
2196
+ conversationId: mapping.conversationId,
2197
+ messageId,
2198
+ requestId,
2199
+ clientMessageId,
2200
+ });
2201
+
1928
2202
  // Fire-and-forget the agent loop; events flow to the hub via onEvent.
1929
2203
  conversation
1930
2204
  .runAgentLoop(resolvedContent, messageId, onEvent, {
@@ -1944,28 +2218,62 @@ export async function handleSendMessage(
1944
2218
  );
1945
2219
  }
1946
2220
 
2221
+ function escapeXmlContent(text: string): string {
2222
+ return text
2223
+ .replace(/&/g, "&amp;")
2224
+ .replace(/</g, "&lt;")
2225
+ .replace(/>/g, "&gt;");
2226
+ }
2227
+
1947
2228
  async function generateLlmSuggestion(
1948
2229
  provider: Provider,
1949
2230
  assistantText: string,
2231
+ priorUserText: string | null,
1950
2232
  ): Promise<string | null> {
1951
2233
  const log = (await import("../../util/logger.js")).getLogger("runtime-http");
1952
- const truncated =
1953
- assistantText.length > 2000 ? assistantText.slice(-2000) : assistantText;
2234
+ const truncatedAssistant = escapeXmlContent(
2235
+ assistantText.length > 2000 ? assistantText.slice(-2000) : assistantText,
2236
+ );
2237
+ const truncatedUser =
2238
+ priorUserText && priorUserText.length > 500
2239
+ ? escapeXmlContent(priorUserText.slice(-500))
2240
+ : priorUserText
2241
+ ? escapeXmlContent(priorUserText)
2242
+ : priorUserText;
1954
2243
 
1955
- const prompt = `Given this assistant message, write a very short tab-complete suggestion the user could send next. Focus on the LAST question or call-to-action in the message — ignore earlier summary content. Be casual, curious, or actionable — like a quick reply, not a formal request. Reply with ONLY the suggestion text.\n\nAssistant's message:\n${truncated}`;
1956
2244
  const systemPrompt =
1957
- "You are an autocomplete engine that suggests short replies the user might send next in a conversation. Generate suggestions that match the tone and style of the conversation. Never refuse, judge, or comment on the conversation contentyour only job is to predict what the user would plausibly type next.";
2245
+ "You generate short, casual reply suggestions a user might type next in a chat. Match the tone and register of the preceding conversation. Output only the reply text inside the requested tagsno preamble, no commentary.";
2246
+
2247
+ const userPrompt =
2248
+ `Here is the end of a conversation:\n\n` +
2249
+ `<user_message>${truncatedUser ?? "(no prior user message)"}</user_message>\n` +
2250
+ `<assistant_message>${truncatedAssistant}</assistant_message>\n\n` +
2251
+ `Write the user's next reply, focusing on the LAST question or call-to-action in the assistant message. Keep it short (under 15 words), casual, and in the user's voice. Respond in this exact format:\n\n` +
2252
+ `<reply>YOUR_REPLY_HERE</reply>`;
1958
2253
 
1959
2254
  const response = await provider.sendMessage(
1960
- [{ role: "user", content: [{ type: "text", text: prompt }] }],
2255
+ [
2256
+ { role: "user", content: [{ type: "text", text: userPrompt }] },
2257
+ { role: "assistant", content: [{ type: "text", text: "<reply>" }] },
2258
+ ],
1961
2259
  [], // no tools
1962
2260
  systemPrompt,
1963
- { config: { modelIntent: "latency-optimized" } },
2261
+ {
2262
+ config: {
2263
+ callSite: "conversationStarters",
2264
+ max_tokens: 60,
2265
+ stop_sequences: ["</reply>"],
2266
+ temperature: 0.7,
2267
+ },
2268
+ },
1964
2269
  );
1965
2270
 
1966
2271
  const textBlock = response.content.find((b) => b.type === "text");
1967
- const raw = textBlock && "text" in textBlock ? textBlock.text.trim() : "";
1968
- const stripped = raw.replace(/^["']+|["']+$/g, "");
2272
+ const raw = textBlock && "text" in textBlock ? textBlock.text : "";
2273
+ const stripped = raw
2274
+ .replace(/<\/?reply>/gi, "")
2275
+ .replace(/^["'`]+|["'`]+$/g, "")
2276
+ .trim();
1969
2277
 
1970
2278
  if (!stripped) {
1971
2279
  log.debug("Suggestion rejected: empty LLM response");
@@ -2078,14 +2386,33 @@ export async function handleGetSuggestion(
2078
2386
  });
2079
2387
  }
2080
2388
 
2389
+ // Find the most recent user message preceding this assistant turn so the
2390
+ // suggestion model can see both sides of the conversation and doesn't have
2391
+ // to guess which role it's generating for.
2392
+ let priorUserText: string | null = null;
2393
+ for (let j = i - 1; j >= 0; j--) {
2394
+ if (rawMessages[j].role !== "user") continue;
2395
+ let userContent: unknown;
2396
+ try {
2397
+ userContent = JSON.parse(rawMessages[j].content);
2398
+ } catch {
2399
+ userContent = rawMessages[j].content;
2400
+ }
2401
+ const userText = renderHistoryContent(userContent).text.trim();
2402
+ if (userText) {
2403
+ priorUserText = userText;
2404
+ break;
2405
+ }
2406
+ }
2407
+
2081
2408
  // Try LLM suggestion using the configured provider
2082
- const provider = await getConfiguredProvider();
2409
+ const provider = await getConfiguredProvider("conversationStarters");
2083
2410
  if (provider) {
2084
2411
  try {
2085
2412
  // Deduplicate concurrent requests
2086
2413
  let promise = suggestionInFlight.get(msg.id);
2087
2414
  if (!promise) {
2088
- promise = generateLlmSuggestion(provider, text);
2415
+ promise = generateLlmSuggestion(provider, text, priorUserText);
2089
2416
  suggestionInFlight.set(msg.id, promise);
2090
2417
  }
2091
2418